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