Запретить неэкранированный URL в исходящем запросе - PullRequest
2 голосов
/ 21 января 2020

Если я сделаю это в. Net Core 3.1:

await new HttpClient().GetAsync("http://test.com/page?parameter=%2D%2E%5F%2E%2D");

, тогда это произойдет:

GET http://test.com/page?parameter=-._.- HTTP/1.1

но это то, что я хочу:

GET http://test.com/page?parameter=%2D%2E%5F%2E%2D HTTP/1.1

Справочная информация заключается в том, что я получаю подписанный URL-адрес от третьей стороны, и мне нужно использовать URL-адрес, как он есть, не являющийся эскейпом. Мне удается найти ресурс с неэкранированным URL-адресом, но проверка подписи завершается неудачно на другом конце, поскольку URL-адрес, который они видят в запросе, не является URL-адресом, который был подписан.

Я могу вставить URL-адрес в любой браузер и получить ресурс, но проверка подписи завершается неудачно, когда я делаю это программно в. Net Core 3.1.

Предполагается, что эскапинг будет происходить в соответствии с документацией по классу Uri :

Экранированные символы (также называемые октетами в процентах), которые не имеют зарезервированной цели, декодируются (также известны как неэкранированные). Эти незарезервированные символы включают заглавные и строчные буквы (% 41-% 5A и% 61-% 7A), десятичные цифры (% 30-% 39), дефис (% 2D), точку (% 2E), подчеркивание (% 5F), и тильда (% 7E).

Я пробовал решения, перечисленные в следующих вопросах:

Итак, кто-нибудь знает, как я могу использовать подписанный URL как есть, не исключен ли, включен. Net Core 3.1?

1 Ответ

0 голосов
/ 23 января 2020

Итак, немного повозившись, я пришел к следующему:

private static Uri CreateNonUnescapedUri(string url)
{
    // Initiate Uri as e.g "http://test.com" so internal flags will indicate that the url does not include characters that needs unescaping
    int offset = url.IndexOf("://");
    offset = url.IndexOf('/', offset + 4);
    var uri = new Uri(url.Substring(0, offset));

    // Then replace internal field with complete url that would otherwise be unescaped
    typeof(Uri).GetField("_string", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(uri, url);
    return uri;
}

Я проверил его на 300 подписанных URL.

Конечно, изменение внутреннего состояния Ури, которое составляет 5600 строк чистого безумия, неизбежно провалится в будущем, но мне нужна эта работа к понедельнику, и это то, что у меня есть. Дайте мне знать, если у кого-то есть реальное решение.

...