URI编码奇怪

时间:2009-07-09 17:11:01

标签: c#

这与另一个open question of mine有关。虽然没有任何实际的答案,但dtb让我在这条赛道上走下坡路,所以如果它结出硕果,我会接受他的回答。

我正在为一些(相当毛茸茸的)C#代码生成BitTorrent跟踪器的通知URL。

最终结果如下:

http://208.106.250.207:8192/announce?info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started

如果我将其粘贴到地址栏中,我会从跟踪器获得有效的响应。但是,我的代码收到错误消息(无效的info_hash)。

调度请求的代码:

... Code building the URI ...
String uri = BuildURI(); //This results in the above URI string.
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Proxy = new WebProxy();  //Some examples online suggest this is required, so WARNING: here be voodoo (determine if necessary later)
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
... Code parsing the stream ...

如果我调试并拔出req.RequestUri的字符串版本,我得到:

http://208.106.250.207:8192/announce?info_hash=-Ê8ÁÉrDb­Lí´*iZ¸%25F%25C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started

我实际上无法告诉“在线”发送给跟踪器的是什么,但看起来我在做一些关于URI的愚蠢行为。谁知道什么?

2 个答案:

答案 0 :(得分:5)

使用System.Uri中的.AbsoluteUri(作为Request.RequestUri的类型)获取原始网址,而不是“munged”

这里的“问题”是.Net System.Uri类的工作方式(我在引号中说“问题”,因为它实际上表现正常)。

您原来的info_hash查询字符串是一个url编码字节的加载。当你使用Uri.ToString()检索Uri实例时,它有助于解码这些(通过执行url-decode)并将这些字节(例如%CA)转换为它们各自的字符(在你的情况下Ê,但这可能取决于您的本地代码页设置,因为这是一个“上半部分”ANSI字符,将根据代码页更改。

在内部,查询字符串实际上正确存储; System.Uri类只是试图提供帮助。

这段代码应该更好地说明:

 string myUrl = "http://208.106.250.207:8192/announce?info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started";

            Uri myUri = new Uri(myUrl);
            Console.WriteLine("ToString: " + myUri.ToString());
            Console.WriteLine("Query: " + myUri.Query);
            Console.WriteLine("AbsoluteUri: " + myUri.AbsoluteUri);

我猜想,在线上,事情很好,这只是你如何从System.Uri中检索网址的工件。

答案 1 :(得分:1)

你发表评论“无法告诉发送的内容”,让我记得你可以使用的名为“Fiddler”的实用程序。

它是一个Web调试代理,因此它可以充当所有Web请求的中间人。

通过这种方式,您可以并排比较浏览器请求和基于代码的请求,看看存在差异。

这是一个很棒的实用工具,并且用这样的东西多次帮助过我。