URI, кодирующий странность - PullRequest
1 голос
/ 09 июля 2009

Это связано с другим открытым вопросом моего . Пока фактических ответов нет, dtb подтолкнуло меня к этому пути, поэтому, если это принесет плоды, я приму его ответ.

Я генерирую URL объявления для BitTorrent-трекера в каком-то (довольно волосатом) коде C #.

Конечный результат выглядит примерно так:

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 ]

5 голосов
/ 10 июля 2009

Используйте .AbsoluteUri из System.Uri (являющийся типом Request.RequestUri), чтобы получить исходный URL без его "кражи"

Здесь "проблема" заключается в том, как работает класс .Net System.Uri (я говорю "проблема" в кавычках, потому что он действительно ведет себя правильно).

Ваша оригинальная строка запроса info_hash представляет собой загрузку байтов в кодировке URL. Когда вы извлекаете экземпляр Uri с помощью Uri.ToString (), он услужливо декодирует их (выполняя url-декодирование) и преобразует эти байты (например,% 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);

Я предполагаю, что в сети все в порядке, и это всего лишь артефакт того, как вы извлекаете URL-адрес из System.Uri.

1 голос
/ 09 июля 2009

Ваш комментарий о том, что вы не можете сказать, что отправлено «в очереди», заставил меня вспомнить утилиту « Fiddler », которую вы можете использовать.

Это прокси-сервер для отладки в Интернете, поэтому он будет служить посредником для всех ваших веб-запросов.

Таким образом, вы можете сравнить ваш запрос браузера и ваш запрос на основе кода рядом и посмотреть, в чем различия.

Это потрясающая утилита, которая много раз мне помогала с такими вещами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...