徒然なるままのブログ。日記とも言う。

2009年8月26日水曜日

このエラーは無いんじゃない?

結構はまったのでメモ

Win32上でIISを使用し.NET、例えばC#でコンソールアプリとしてCGIアプリを作る。
例えばこんな感じ。

-------------------------
Console.WriteLine("HTTP/1.0 200 OK");
Console.WriteLine("Content-Type: text/html");
Console.WriteLine("");
Console.WriteLine("<HTML>TEST</HTML>");
-------------------------


ビルドして出来たexeをIISのCGIディレクトリに置き、ブラウザから実行して正常に応答が
帰ってくることを確認する。

で、このCGIをブラウザではなく.NETアプリから呼び出すとして、こんなコードを書く


-------------------------
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest) System.Net.WebRequest.Create("http://hostname/cgi-bin/testcgi.exe");
req.ProtocolVersion = System.Net.HttpVersion.Version11;
req.Timeout = 10000;
req.KeepAlive = false;
req.Method = "GET";

System.Net.WebResponse webresponse = req.GetResponse();
System.IO.Stream st = webresponse.GetResponseStream();

//今回中身は重要じゃないのでここまで通ったという事でOKを出す。
MessageBox.Show("OK");
-------------------------

で、これを実行するとエラー。
Windows32(.NET2.0)ではreq.GetResponse()で
「サーバーによってプロトコル違反が発生しました. Section=ResponseHeader Detail=CR の後には LF を指定しなければなりません。」
というエラーが発生する。
同じコードをCompactFramework2.0上、いわゆるWindowsCEやWindowsMobileで動作させるとreq.GetResponse()で
「HTTP/1.0 および HTTP/1.1 バージョンの要求のみが現在サポートされています。」
というエラーとなる。

Win32の.NET2.0上では
「サーバーによってプロトコル違反が発生しました. Section=ResponseHeader Detail=CR の後には LF を指定しなければなりません。」
のエラーに関してはぐぐればたくさん出てくるようにapp.configの変更で回避できるのだけどCompactFrameworkでは回避できない為
何とかならないかと思って調べてみた。


調査:
パケットキャプチャでパケットを拾ってみた。下記はヘッダの部分

00 01 02 03 04 05 06 07-08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF
+-------------------------------------------------+-----------------+
00000000 | 48 54 54 50 2F 31 2E 31-20 32 30 30 20 4F 4B 0D | HTTP/1.1 200 OK.
00000010 | 0A 53 65 72 76 65 72 3A-20 4D 69 63 72 6F 73 6F | .Server: Microso
00000020 | 66 74 2D 49 49 53 2F 35-2E 31 0D 0A 44 61 74 65 | ft-IIS/5.1..Date
00000030 | 3A 20 57 65 64 2C 20 32-36 20 41 75 67 20 32 30 | : Wed, 26 Aug 20
00000040 | 30 39 20 31 34 3A 30 38-3A 35 38 20 47 4D 54 0D | 09 14:08:58 GMT.
00000050 | 0A 58 2D 50 6F 77 65 72-65 64 2D 42 79 3A 20 41 | .X-Powered-By: A
00000060 | 53 50 2E 4E 45 54 0D 0A-43 6F 6E 74 65 6E 74 2D | SP.NET..Content-
00000070 | 54 79 70 65 3A 20 74 65-78 74 2F 68 74 6D 6C 0D | Type: text/html.
00000080 | 0A 48 54 54 50 2F 31 2E-30 20 32 30 30 20 4F 4B | .HTTP/1.0 200 OK
00000090 | 0D 0A 0D 0A | ....

これを見ればわかるように「ResponseHeader Detail=CR の後には LF を指定しなければなりません。」に
該当する部分はない。(CR=0D,LF=0A)

ただね、よーく見ると
00000080 | 0A 48 54 54 50 2F 31 2E-30 20 32 30 30 20 4F 4B | .HTTP/1.0 200 OK
00000090 | 0D 0A 0D 0A | ....
最後にも200OK応答がくっついてる。^^;

これはCGIアプリ側の
-------------------------
Console.WriteLine("HTTP/1.0 200 OK");  <------ これが原因
Console.WriteLine("Content-Type: text/html");
Console.WriteLine("");
Console.WriteLine("<HTML>TEST</HTML>");
-------------------------
CGI側を直したらちゃんと動いた。
IISでCGIなんてかなーり久しぶりなんだけどIIS側でステータスをつけてくれるみたいね。
Perl+Apacheとかではこれは定番らしく、とりあえず入れちゃったらしいんだけどIIS+.NETCGIでは必要ないみたい。

確かにヘッダがおかしいのは認めるよ。でもさ
「サーバーによってプロトコル違反が発生しました. Section=ResponseHeader Detail=CR の後には LF を指定しなければなりません。」
「HTTP/1.0 および HTTP/1.1 バージョンの要求のみが現在サポートされています。」
このエラーもおかしいだろどう考えても。

どうもCompactFrameworkのWebResponseはヘッダがおかしいと(レスポンス解析でエラーだと?)
「HTTP/1.0 および HTTP/1.1 バージョンの要求のみが現在サポートされています。」
が出るみたい。

パケットキャプチャして正解だったよ。じゃなきゃこれ絶対わかんないよ。

でまたこういう役に立たないナレッジがたまるんだわw。




0 件のコメント:

コメントを投稿