ПОЛУЧЕНИЕ URL-адреса с косой чертой в кодировке URL - PullRequest
33 голосов
/ 23 апреля 2009

Я хочу отправить HTTP GET на http://example.com/%2F. Моим первым предположением было бы что-то вроде этого:

using (WebClient webClient = new WebClient())
{
  webClient.DownloadData("http://example.com/%2F");
}

К сожалению, я вижу, что на самом деле отправляется по проводам:

GET // HTTP/1.1
Host: example.com
Connection: Keep-Alive

Итак, http://example.com/%2F переводится в http://example.com// перед передачей.

Есть ли способ на самом деле отправить этот GET-запрос?

Протокол OCSP предписывает отправлять url-кодировку base-64-кодировки при использовании OCSP по HTTP / GET, поэтому необходимо отправить фактический% 2F, а не '/' для соответствия.

EDIT:

Вот соответствующая часть стандарта протокола OCSP ( RFC 2560 Приложение A.1.1):

Запрос OCSP с использованием метода GET строится следующим образом:

GET {url} / {url-кодировка base-64, кодировка DER, кодировка OCSPRequest}

Я очень открыт для других прочтений этого, но я не могу понять, что еще могло быть в виду.

Ответы [ 4 ]

46 голосов
/ 24 апреля 2009

Это ужасный хак, неизбежно несовместимый с будущими версиями фреймворка и так далее.

Но это работает!

(на моей машине ...)

Uri uri = new Uri("http://example.com/%2F");
ForceCanonicalPathAndQuery(uri);
using (WebClient webClient = new WebClient())
{
  webClient.DownloadData(uri);
}

void ForceCanonicalPathAndQuery(Uri uri){
  string paq = uri.PathAndQuery; // need to access PathAndQuery
  FieldInfo flagsFieldInfo = typeof(Uri).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic);
  ulong flags = (ulong) flagsFieldInfo.GetValue(uri);
  flags &= ~((ulong) 0x30); // Flags.PathNotCanonical|Flags.QueryNotCanonical
  flagsFieldInfo.SetValue(uri, flags);
}
25 голосов
/ 29 августа 2012

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

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

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

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

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

(Перенесено из https://stackoverflow.com/a/10415482, потому что это «официальный» способ избежать этой ошибки без использования отражения для изменения приватных полей.)

Редактировать: Отчет об ошибке подключения больше не отображается, но документация для <schemeSettings> рекомендует использовать этот подход, чтобы разрешить экранирование / символов в URI. Обратите внимание (согласно этой статье), что могут быть последствия для безопасности компонентов, которые неправильно обрабатывают экранированные косые черты.

11 голосов
/ 23 декабря 2013

Обновление: похоже, поведение класса Uri по умолчанию изменилось в .NET 4.5, и теперь вы можете использовать экранированные косые черты, и они не будут затронуты.

Я запустил следующий код в .NET 3.5, .NET 4.0, .NET 4.5 / 4.5.1

static void Main(string[] args)
{
    var uri = new Uri("http://www.yahooo.com/%2F");
    var client = new WebClient();
    client.DownloadString(uri);
}

В .NET 3.5 / 4.0 трассировка показывает, что% 2F на самом деле был неэкранированным, как ожидалось.

Fiddler trace

Однако в .NET 4.5 / 4.5.1 видно, что% 2F не был удален (обратите внимание на GET /% 2F)

Fiddler trace

Теперь вы можете даже использовать ToString () в Uri, и вы получите тот же результат.

Итак, в заключение, если вы используете .NET> = .NET 4.5, то все будет работать так, как должно соответствовать RFC.

Я только что провел исследование, пытаясь заставить тот же подход работать с Mono. Я отправил свой вопрос о подходе здесь: Получение Uri с экранированными слешами на моно

0 голосов
/ 23 апреля 2009

Двойное кодирование: % 252F

Но также, если вы используете HttpWebRequest, вы можете запретить кодировать URL-адрес, в любом случае он должен работать.

Кроме того, если WebClient принимает URI, вы можете создать новый URI и настроить его на отсутствие кодирования.

...