System.Uri クラス
.NET Frameworkで URI/URLを扱う際、System.Uriクラスを使うと思うけど、その仕様と、使用上の注意の話
結論
System.Uri では、パスデリミタではないパス中の「/」と「\」を送る表現方法がない
.NET Framework のバージョン
ver4 系の話です。
テストコード(URI)
つまり、パスの値として「/」とか「\」とかを与えたい場面はあまりないかと思うけど、、、それでも、まぁ URLエンコードすればいいと思うわけです。
ということで、こんなパスを考えてみる
- abc
- def/ghi\jk\lmn opq%rst?uvwxyz
nとoの間に半角スペースがある
一応、httpスキームで、ホスト127.0.0.1でポート90という事にすると、上記のパスは、
http://127.0.0.1:90/abc/def%2fghi\jk%5clmn%20opq%25rst%3fuvwxyz/
でいいと思うんですよ。
Console.WriteLine("input = " + args[0]);
System.Uri uri = new Uri(args[0]);
Console.WriteLine("uri.PathAndQuery = " + uri.PathAndQuery);
System.Net.HttpWebRequest HttpWebRequestObj = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
System.Net.HttpWebResponse HttpWebResponseObj = (System.Net.HttpWebResponse)HttpWebRequestObj.GetResponse();
ということで、このような C# のプログラムを作って実行してみると・・・
C:\test.exe "http://127.0.0.1:90/abc/def%2fghi\jk%5clmn%20opq%25rst%3fuvwxy%252fz/"
input = http://127.0.0.1:90/abc/def%2fghi\jk%5clmn%20opq%25rst%3fuvwxy%252fz/
uri.PathAndQuery = /abc/def/ghi/jk/lmn%20opq%25rst%3fuvwxy%252fz/
よく見ると
- %2f → /
- \ → /
- %5c → /
となっていることが分かる
ちなみに、一番後ろの z の手前に「%252f」をあえて与えているのだけど、
- %252f → %252f
と、真っ当な状態
つまり、パスデリミタではないパス中の「/」と「\」を表現する方法がない ということ
実際に、先ほどのプログラムをnetcatで受けてみると・・・
C:\>nc.exe -nvv -L -p 90
listening on [any] 90 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 19048
GET /abc/def/ghi/jk/lmn%20opq%25rst%3fuvwxy%252fz/ HTTP/1.1
Host: 127.0.0.1:90
Connection: Keep-Alive
と、HTTPリクエスト・ラインが System.Uri.PathAndQuery と同じ
- %2f → /
- \ → /
- %5c → /
となっていることが分かる
という事で、上記の結論が導かれたわけです。
System.Net.HttpWebRequest に直接文字列を与えればいいのでは!?
と、System.Uriクラス の仕様ならば、System.Net.HttpWebRequestクラス に直接文字列を与えればいいのでは!?と思うわけです。
ということで直接、文字列でインスタンスを作ってみます。
System.Net.HttpWebRequest HttpWebRequestObj = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(args[0]);
System.Net.HttpWebResponse HttpWebResponseObj = (System.Net.HttpWebResponse)HttpWebRequestObj.GetResponse();
これをnetcatで受けてみます。
E:\c>nc.exe -nvv -L -p 90
listening on [any] 90 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 19155
GET /abc/def/ghi/jk/lmn%20opq%25rst%3fuvwxy%252fz/ HTTP/1.1
Host: 127.0.0.1:90
Connection: Keep-Alive
結果は同じ。
つまり、上記の結論と同じなわけです。
sWebMachineGun.exe の仕様上の注意
sWebMachineGun.exe は、System.Net.HttpWebRequestクラスを利用しているため、パスに対して、置換処理ができますが、上記の System.Uri の仕様のため、置換パターンに「/」や「\」が入っていた場合、想定している HTTP リクエスト・メッセージでないメッセージを送信することになります。