Я делаю HTTP-прокси в C++; когда клиент отправляет GET или CONNECT на прокси, прокси анализирует заголовок HTTP пакета, разрешает имя хоста в нем, открывает другой сокет для назначения на сервере и отправляет запрос клиента. Затем прокси отправит ответ сервера клиенту.

Вот, например, что прокси-сервер отправляет на сервер, когда он получает запрос GET или запрос CONNECT от клиента:

GET http://www.gstatic.com/generate_204 HTTP/1.1

CONNECT cr-input.getspeakit.com:443 HTTP/1.1

Но когда я анализирую GET ответ от сервера, я нахожу код состояния 400, т. Bad Request: похоже, (из Википедии):

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

Я отправляю неправильные аргументы на сервер в запросе GET ?

1 ответ1

0

Когда HTTP-клиент отправляет запрос GET , имя хоста назначения обычно отсутствует в запрошенном URI. То есть вместо отправки

GET http://www.gstatic.com/generate_204 HTTP/1.1

клиент HTTP 1.1 отправляет:

GET /generate_204 HTTP/1.1
Host: www.gstatic.com

Так как клиент "знает" , что он должен разрешить имя DNS «www.gstatic.com» на IP - адрес, и отправить запрос HTTP на этот IP - адрес, он на самом деле не нужно включать имя хоста снова как часть запрошенный путь. Заголовок Host является подсказкой серверу изначально запрошенного имени хоста.

Обратите внимание, что вышеуказанная семантика описана в RFC 7230, раздел 5.3. И там говорится, что "абсолютная форма" запрошенного / целевого ресурса может включать схему и имя хоста; это "форма происхождения", которую я описал выше. Если ваш сервер отправления / назначения возвращает "400 Bad Request" для "абсолютной формы", которую использует ваш прокси-сервер, он предлагает либо a) что сервер не поддерживает "абсолютную форму", либо b) что-то еще не так (отсутствует Заголовок запроса Host ?).

Это означает, что ваш HTTP-прокси на самом деле не должен полагаться на конечное имя хоста, находящееся в первой строке HTTP-запроса (для HTTP-клиента можно использовать "исходную форму" запрошенного / целевого ресурса; вместо этого ваш прокси-сервер должен искать заголовок Host , если вам нужно знать эту информацию. И чтобы избежать 400 Bad Request от исходного сервера, я рекомендую, чтобы ваш прокси отправлял, например:

GET /generate_204 HTTP/1.1
Host: www.gstatic.com

Семантика метода CONNECT приведена в RFC 7231, раздел 4.3.6. Там мы видим, что запрашиваемый ресурс должен состоять из имени хоста и порта. Любой ответ 2xx от сервера назначения указывает на успех; любой другой код ответа указывает, что запрошенный "туннель" не настроен. Остальная часть RFC там стоит прочитать, для других крайних случаев и поведения.

Надеюсь это поможет!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .