400 Bad Request
Maxim Dounin
mdounin на mdounin.ru
Вт Ноя 22 13:55:46 UTC 2016
Hello!
On Tue, Nov 22, 2016 at 06:00:52AM -0500, nerjin wrote:
> Nginx ругается на такой запрос:
>
> "GET http://ankerch-crimea.ru?page=home HTTP/1.1" 400
>
> Я так понимаю из-за того, что нет слеша после домена, но по спецификации
> такой вариант возможен, если в нем нет логина-пароля (правда я дальше
> википедии не проверял):
>
> scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
>
> A path, which contains data, usually organized in hierarchical form, that
> appears as a sequence of segments separated by slashes. Such a sequence may
> resemble or map exactly to a file system path, but does not always imply a
> relation to one. The path must begin with a single slash (/) if an authority
> part was present, and may also if one was not, but must not begin with a
> double slash.
>
> Браузеры такую ситуацию обрабатывают, сами добавляют слеш. А вот если из
> кода делать запрос, то напарываешься на 400
Актуальный до недавнего времени RFC 2616 даёт такой синтаксис,
https://tools.ietf.org/html/rfc2616#section-3.2.2:
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
Т.е. без пути - нельзя, если есть query. В свежем RFC 7230
синтаксис позволяет пустой путь при наличии query,
https://tools.ietf.org/html/rfc7230#section-2.7.1:
http-URI = "http:" "//" authority path-abempty [ "?" query ]
[ "#" fragment ]
Patches, что называется, are welcome (правда, вряд ли это
получится хорошо обработать без копирования).
Непонятно, впрочем, зачем вы вообще пытаетесь использовать форму
запроса с абсолютным URI в строке запроса. В HTTP это используют
исключительно для запросов к forward proxy (в HTTP/1.0 только
это и было разрешено), обычная же форма запроса подразумевает путь
в строке запроса:
GET /?page=home HTTP/1.1
Host: example.com
И, с учётом того, что заголовок Host так или иначе в HTTP/1.1
обязателен - такой запрос получается компактнее. Отмечу в
скобках, что для подобной формы - "/" обязателен (ну и в добавок
RFC 7230 как бы намекает, что по другому к origin-серверу ходить
нельзя), https://tools.ietf.org/html/rfc7230#section-5.3.1:
When making a request directly to an origin server, other than a
CONNECT or server-wide OPTIONS request (as detailed below), a client
MUST send only the absolute path and query components of the target
URI as the request-target. If the target URI's path component is
empty, the client MUST send "/" as the path within the origin-form of
request-target. A Host header field is also sent, as defined in
Section 5.4.
--
Maxim Dounin
http://nginx.org/
Подробная информация о списке рассылки nginx-ru