fork download
  1. // X2chAuthenticateThreadReader.cs
  2.  
  3. namespace Twin.Bbs
  4. {
  5. using System;
  6. using System.Net;
  7. using System.IO.Compression;
  8. using Twin.Util;
  9. using System.IO;
  10. using System.Text;
  11.  
  12. /// <summary>
  13. /// 認証を使って2ちゃんねる (www.2ch.net) のスレッドを読み込む機能を提供
  14. /// </summary>
  15. public class X2chAuthenticateThreadReader : X2chThreadReader
  16. {
  17. private HttpWebResponse _res = null;
  18. private bool firstRead = true;
  19.  
  20. public X2chRokkaResponseState RokkaResponseState { get; private set; }
  21.  
  22. public X2chAuthenticateThreadReader() : base()
  23. {
  24. RokkaResponseState = X2chRokkaResponseState.None;
  25. }
  26.  
  27. /// <summary>
  28. /// スレッドを開く
  29. /// </summary>
  30. /// <param name="th"></param>
  31. public override bool Open(ThreadHeader header)
  32. {
  33. if (header == null)
  34. {
  35. throw new ArgumentNullException("header");
  36. }
  37. if (IsOpen)
  38. {
  39. throw new InvalidOperationException("既にストリームが開かれています");
  40. }
  41.  
  42. headerInfo = header;
  43. firstRead = true;
  44. RokkaResponseState = X2chRokkaResponseState.None;
  45.  
  46. if (header.Pastlog)
  47. return false;
  48.  
  49. X2chAuthenticator authenticator = X2chAuthenticator.GetInstance();
  50. if (authenticator.HasSession)
  51. {
  52. X2chThreadHeader x2chHeader = header as X2chThreadHeader;
  53. if (x2chHeader != null)
  54. {
  55. HttpWebRequest req = (HttpWebRequest)WebRequest.Create(x2chHeader.AuthenticateUrl);
  56. req.Timeout = 15000;
  57. req.UserAgent = UserAgent;
  58. req.AllowAutoRedirect = false;
  59.  
  60. // ** 9/26 削除 **
  61. // req.Headers.Add("Accept-Encoding", "gzip");
  62.  
  63. // ** 9/26 追加 **
  64. req.AutomaticDecompression = DecompressionMethods.GZip;
  65.  
  66. req.Headers.Add("Pragma", "no-cache");
  67. req.Headers.Add("Cache-Control", "no-cache");
  68.  
  69. if (x2chHeader.ETag != String.Empty)
  70. req.Headers.Add("If-None-Match", x2chHeader.ETag);
  71.  
  72. _res = (HttpWebResponse)req.GetResponse();
  73.  
  74. //baseStream = _res.GetResponseStream();
  75. baseStream = FileUtility.CreateMemoryStream( _res.GetResponseStream() );
  76. baseStream.Position = 0;
  77. length = (int)baseStream.Length;
  78.  
  79. RokkaResponseState = ParseRokkaFirstline( baseStream );
  80.  
  81. if (_res.StatusCode == HttpStatusCode.OK)
  82. {
  83. /* 9 26削除
  84. using (GZipStream gzipInp = new GZipStream(_res.GetResponseStream(), CompressionMode.Decompress))
  85. baseStream = FileUtility.CreateMemoryStream(gzipInp);
  86. */
  87.  
  88. x2chHeader.ETag = _res.Headers["ETag"];
  89. x2chHeader.LastModified = _res.LastModified;
  90.  
  91. index = header.GotResCount + 1;
  92. position = 0;
  93. isOpen = true;
  94. }
  95. else OnPastlog(new PastlogEventArgs(header));
  96. }
  97. }
  98. else
  99. OnPastlog(new PastlogEventArgs(header));
  100.  
  101. // 過去ログなのでdat落ちに設定
  102. headerInfo.Pastlog = true;
  103.  
  104. return isOpen;
  105. }
  106.  
  107. //public override int Read( ResSetCollection resSets , out int byteParsed )
  108. //{
  109. // if ( firstRead )
  110. // {
  111. // byte[] buf = new byte[1];
  112. // int c;
  113.  
  114. // do
  115. // {
  116. // c = baseStream.Read( buf , 0 , buf.Length );
  117. // // 最初の改行が来るまで読み飛ばす
  118. // } while ( c != 0 && buf[0] != '\n' );
  119.  
  120. // firstRead = false;
  121. // }
  122.  
  123. // return base.Read( resSets , out byteParsed );
  124. //}
  125.  
  126. public override void Close()
  127. {
  128. base.Close();
  129. if (_res != null)
  130. {
  131. _res.Close();
  132. _res = null;
  133. }
  134. }
  135.  
  136.  
  137. private X2chRokkaResponseState ParseRokkaFirstline(Stream responseStream)
  138. {
  139. if (responseStream == null)
  140. throw new ArgumentNullException();
  141.  
  142. var statusbytes = new System.Collections.Generic.List<byte>();
  143. byte[] buf = new byte[1];
  144. int c;
  145. do
  146. {
  147. c = baseStream.Read( buf , 0 , buf.Length );
  148. // 最初の改行が来るまで読み飛ばす
  149. // 2013/09/10 初めの行を処理結果コードエリアと定義&宣言したので文字に取り込んでおく
  150. // http://q...content-available-to-author-only...h.net/test/read.cgi/operate/1366640919/119
  151. statusbytes.Add( buf[0] );
  152. } while ( c != 0 && buf[0] != '\n' );
  153.  
  154. var line = base.dataParser.Encoding.GetString( statusbytes.ToArray() );
  155.  
  156. //byte[] buf = new byte[256];
  157. //long firstpos = responseStream.Position;
  158. //responseStream.Read( buf , 0 , buf.Length );
  159.  
  160. //using ( StringReader s = new StringReader( base.dataParser.Encoding.GetString( buf ) ) )
  161. //using ( StreamReader s = new StreamReader( responseStream ) )
  162. //{
  163. // string line = s.ReadLine();
  164. //responseStream.Position += base.dataParser.Encoding.GetByteCount( line ); // 最初の1行分だけストリームを進めておく
  165.  
  166. if (line.StartsWith("Success")) return X2chRokkaResponseState.Success;
  167. else if (line.StartsWith("Error 8008135")) return X2chRokkaResponseState.InvalidServerOrBoardOrThread;
  168. else if (line.StartsWith("Error 69")) return X2chRokkaResponseState.AuthenticationError;
  169. else if (line.StartsWith("Error 666")) return X2chRokkaResponseState.UrlError;
  170. else if (line.StartsWith("Error 420")) return X2chRokkaResponseState.TimeLimitError;
  171. else
  172. {
  173. // ステータスが見つからなかった場合は、ストリームの位置を元に戻しておく
  174. //responseStream.Position = firstpos;
  175. return X2chRokkaResponseState.Unknown;
  176. }
  177. //}
  178. }
  179. }
  180.  
  181.  
  182. /*
  183. "Success"  - The process has successfuly done. Following lines are achieved message with dat format
  184. Error codes:
  185.     inputError = "Error 8008135"      invalid SERVER or BOARD or THREAD
  186.     authenticationError = "Error 69"    invalid SID
  187.     urlError = "Error 666"         invalid OPTIONS
  188.     timeLimitError = "Error 420"       access too fast, interval between requests required
  189. */
  190. public enum X2chRokkaResponseState
  191. {
  192. None = -2,
  193. Unknown = -1, // ステータスが不明
  194. Success = 0,
  195. InvalidServerOrBoardOrThread = 8008135,
  196. AuthenticationError = 89,
  197. UrlError = 666,
  198. TimeLimitError = 420,
  199. }
  200. }
  201.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cs(8,20): error CS0234: The type or namespace name `Util' does not exist in the namespace `Twin'. Are you missing an assembly reference?
prog.cs(31,43): error CS0246: The type or namespace name `ThreadHeader' could not be found. Are you missing a using directive or an assembly reference?
prog.cs(126,38): error CS0115: `Twin.Bbs.X2chAuthenticateThreadReader.Close()' is marked as an override but no suitable method found to override
Compilation failed: 3 error(s), 0 warnings
stdout
Standard output is empty