C# WebRequest.getResponse(): 400 неверный запрос

Я пытаюсь загрузить файл с сервера с помощью System.Web. Это на самом деле работает, но некоторые ссылки доставляют мне неприятности. Ссылки выглядят так:

http://cdn.somesite.com/r1KH3Z%2FaMY6kLQ9Y4nVxYtlfrcewvKO9HLTCUBjU8IBAYnA3vzE1LGrkqMrR9Nh3jTMVFZzC7mxMBeNK5uY3nx5K0MjUaegM3crVpFNGk6a6TW6NJ3hnlvFuaugE65SQ4yM5754BM%2BLagqYvwvLAhG3DKU9SGUI54UAq3dwMDU%2BMl9lUO18hJF3OtzKiQfrC/the_file.ext

Код выглядит в основном так:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);
WebResponse response = request.getResponse();

getResponse () всегда выдает исключение (ошибка 400 Bad Request). Тем не менее, я знаю, что ссылка работает, потому что я могу скачать файл с Firefox без проблем.

Я также пытался расшифровать ссылку с помощью Uri.UnescapeDataString(ссылка), но эта ссылка даже не работает в Firefox.

Другие ссылки прекрасно работают таким образом... только они не будут работать.

Редактировать:

Хорошо, я нашел кое-что, используя wireshark:

Если я открою ссылку с помощью Firefox, это будет отправлено:

&ME3@"dM*PNyAo PA:]GET /r1KH3Z%2FaMY6kLQ9Y4nVxYp5DyNc49t5kJBybvjbcsJJZ0IUJBtBWCgri3zfTERQught6S8ws1a%2BCo0RS5w3KTmbL7i5yytRpn2QELEPUXZTGYWbAg5eyGO2yIIbmGOcFP41WdrFRFcfk4hAIyZ7rs4QgbudzcrJivrAaOTYkEnozqmdoSCCY8yb1i22YtEAV/epd_outpost_12adb.flv HTTP/1.1
Host: cdn.somesite.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive

Я думаю, что только первая строка является проблемой, потому что WebRequest.Create(ссылка) декодирует URL:

&MEz.@!dM/nP9@~P>.GET /r1KH3Z/aMY6kLQ9Y4nVxYp5DyNc49t5kJBybvjbcsJJZ0IUJBtBWCgri3zfTERQught6S8ws1a%2BCo0RS5w3KTmbL7i5yytRpn2QELEPUXZTGYWbAg5eyGO2yIIbmGOcFP41WdrFRFcfk4hAIyZ7rs6Mmh1EsQQ4vJVYUwtbLBDNx9AwCHlWDfzfSWIHzaaIo/epd_outpost_12adb.flv HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20100101 Firefox/12.0
Host: cdn.somesite.com

(% 2F заменяется на /)

Другое редактирование:

Я обнаружил, что класс Uri автоматически декодирует URL: Uri uri = new Uri(ссылка); // ссылка не декодируется Debug.WriteLine(uri.ToString()); // ссылка здесь декодируется

Как я могу предотвратить это?

Заранее спасибо за помощь.

2 ответа

Решение

По умолчанию Uri класс не позволит сбежать / персонаж (%2f) в URI (хотя это кажется законным в моем чтении RFC 3986).

Uri uri = new Uri("http://example.com/embed%2fded");
Console.WriteLine(uri.AbsoluteUri); // prints: http://example.com/embed/ded

(Примечание: не используйте Uri.ToString для печати URI.)

Согласно отчету об ошибке для этой проблемы в Microsoft Connect, такое поведение является заданным, но вы можете обойти это, добавив следующее в файл app.config или web.config:

<uri>
  <schemeSettings>
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
  </schemeSettings>
</uri>

(Поскольку WebRequest.Create(string) просто делегаты WebRequest.Create(Uri) вам нужно будет использовать этот обходной путь независимо от того, какой метод вы вызываете.)

Теперь это изменилось в.NET 4.5. По умолчанию теперь вы можете использовать экранированные косые черты. Я разместил больше информации об этом (включая скриншоты) в комментариях здесь: ПОЛУЧЕНИЕ URL с косой чертой в кодировке URL

Другие вопросы по тегам