2007年11月6日火曜日

Http Requestを自前で処理する 続き

昨日の続きで、TcpClientを使って書き直してみた
というのもTcpClientとStreamReader,Writerを使えば文字列処理が楽に出来ると思ったから。
結局あまりスッキリしなかった

コードを書き換えて試験した結果、StreamReaderはChunkedデータを処理すできなかった。
Chunkedデータはbyte単位で処理しなきゃいけないのに、StreamReaderを使うと文字数単位の処理になってしまう

でもまあ目的は果たせたので、これで進めようと思う

これで一応Feedの処理は出来てきた、後はオフラインブラウズの処理とユーザーインターフェイスをどうするか....



public String HttpGet(String url,String param)
{
url = url.Substring(url.IndexOf("://")+3);
String server = url.Substring(0,url.IndexOf("/"));
url = url.Substring(server.Length);
IPHostEntry ipInfo = Dns.GetHostEntry(server);

IPEndPoint hostendp = new IPEndPoint(ipInfo.AddressList[0], 80);

String reqMsg = "GET " + url + " HTTP/1.1\r\n"
+ "HOST: " + server + "\r\n"
+ "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9\r\n"
+ "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
+ "Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n"
+ "Accept-Charset: utf-8;q=0.7,*;q=0.7\r\n";
if (param != null)
reqMsg += param + "\r\n";
reqMsg += "Connection: Close\r\n\r\n";


TcpClient client = new TcpClient();

client.Connect(hostendp);

NetworkStream ns = client.GetStream();

StreamWriter clientWriter = new StreamWriter(ns, Encoding.ASCII);
clientWriter.Write(reqMsg);
clientWriter.Flush();

// ヘッダの解釈
String[] resHdr = ReadLine(ns).Split(' ');
if (!resHdr[0].StartsWith("HTTP/")
|| !resHdr[1].StartsWith("200"))
{
throw new ArgumentException("Http Response Error");
}

// ヘッダの終わりまで読み飛ばす
bool Chunked = false;
while (true)
{
String hdr = ReadLine(ns);
if (hdr.StartsWith("Transfer-Encoding:"))
{
if (hdr.Substring("Transfer-Encoding:".Length).Trim().ToLower() == "chunked")
Chunked = true;
}
else if (hdr == "")
break;
}

// 本文を取得する(Chunkedの場合)
string resMsg="";
if(Chunked)
{
while (true)
{
String lens = ReadLine(ns).TrimEnd(';');
int len = 0;
if (lens != "")
len = Int32.Parse(lens, System.Globalization.NumberStyles.AllowHexSpecifier);
if (len == 0)
break;

byte[] buffer = new byte[len];
int offset = 0;
while (offset<len)
{
int rslt=ns.Read(buffer, offset, len-offset);
if (rslt == -1)
break;
offset += rslt;
}


resMsg += Encoding.UTF8.GetString(buffer, 0, len);
// 改行を捨てる
ReadLine(ns);
}
}
else
{
StreamReader clientReader = new StreamReader(ns, Encoding.UTF8);
resMsg = clientReader.ReadToEnd();
}

//閉じる
client.Close();

return resMsg;

}

0 件のコメント: