Пользовательский заголовок HttpClient со скобкой - C # - PullRequest
0 голосов
/ 26 июня 2018

Мне нужно подключиться к RESTAPI, для которого требуется несколько различных заголовков. Один из них вызывает у меня проблему, потому что его имя заключено в квадратные скобки - имя заголовка "(request-target)".

Это мой код, но когда я попадаю в строку, где я добавляю это значение - он говорит: «Неверный формат имени заголовка»

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("(request-target)", "host date");
client.DefaultRequestHeaders.Date = DateTime.Now;
client.DefaultRequestHeaders.Host = "localhost:50414";
int count = client.DefaultRequestHeaders.Count();

Я пытался

client.DefaultRequestHeaders.TryAddWithoutValidation("(request-target)", "host date");

Это не сбой - но мой подсчет количества заголовков не включает этот заголовок. Я пробовал этот код - он дает мне ту же ошибку о "неверный формат имени заголовка"

    HttpRequestMessage httpreqmsg = new HttpRequestMessage();
    httpreqmsg.Headers.Add("(request-target)", "host date");

Может кто-нибудь сказать мне, как обойти это, прежде чем я сойду с ума!

Спасибо, мельница.

Дальнейшее обновление

Они предоставили код Java - для извлечения подробностей заголовка, а имя определенно включает в себя скобки. Заголовки используются для построения строки, подписанной ключом из цифрового сертификата.

public String buildStringToBeSigned(HttpServletRequest request, List<String> signatureHeaders) {

    Integer counter = 0;
    StringBuilder sb = new StringBuilder();
    for (String s : signatureHeaders) {

        counter++;
        if ("(request-target)".equalsIgnoreCase(s)) {
            sb.append(s + ": " + request.getMethod().toLowerCase()
                    + " " + request.getRequestURI() + (counter < signatureHeaders.size() ? "\n" : ""));
        }else{
            sb.append(s + ": " + request.getHeader(s) + (counter < signatureHeaders.size() ? "\n" : ""));
        }
    }


    return sb.toString();
}

1 Ответ

0 голосов
/ 26 июня 2018

Итак, в классе HttpHeaders при вызове DefaultRequestHeaders.Add он вызывает закрытый метод с именем CheckHeaderName.

.

Внутри этого он выполняет проверку по ключу заголовка в вашем случае (request-target). Сначала он проверяет, пусто ли оно, затем проверяет что-то, что называется TokenLength. По сути, эта проверка проходит через каждый символ ключа заголовка и проверяет набор TokenChars. Следующие char s не разрешены:

40
41
60
62
64
44
59
58
92
34
47
91
93
63
61
123
125

И символы ( и ) оба равны 40 и 41.

Похоже, что он встроен в .Net framework, что ключ заголовка не разрешен ни для одного из вышеперечисленных символов.

Чек TokenLength также вызывается при вызове TryAddWithoutValidation. TryAddWithoutValidation также возвращает bool, если заголовок был добавлен в коллекцию, так что вы можете использовать его в коде, чтобы увидеть, был ли он добавлен.

Примечание: это было проверено на .Net Framework 4.7.2

Обновление:

Поскольку легче просматривать исходный код .Net Core, я также посмотрел, не изменилось ли что-нибудь, и это почти такая же логика.

Здесь вы можете увидеть запрещенные значения здесь Он проверяет, имеет ли ключ заголовка значение здесь , которое вызывается с здесь , так как он вернет false, поскольку содержит недопустимые символы, исключение будет выдано.

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