В чем разница между использованием netcat (nc) и curl для HTTP-запросов?

В чем разница между использованием netcat (nc) и curl для HTTP-запросов?

Я использую curl для запроса определенного URL и получаю ответ 200 OK:

curl -v www.youtypeitwepostit.com
* About to connect() to www.youtypeitwepostit.com port 80 (#0)
*   Trying 54.197.246.21...
* Connected to www.youtypeitwepostit.com (54.197.246.21) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.youtypeitwepostit.com
> Accept: */*
>
< HTTP/1.1 200 OK
...

Если я сохраню заголовки в файл как:

GET / HTTP/1.1
User-Agent: curl/7.29.0
Host: www.youtypeitwepostit.com
Accept: */*

и попробуйте выполнить ncкоманду (netcat):

nc www.youtypeitwepostit.com 80 < file
HTTP/1.1 505 HTTP Version Not Supported
Connection: close
Server: Cowboy
Date: Wed, 02 Nov 2016 04:08:34 GMT
Content-Length: 0

Я получаю другой ответ. В чем разница и как мне получить 200 ОК с помощью nc?

Я пробовал с разными версиями HTTP в заголовке запроса, пробовал вручную вводить запрос, чтобы избежать неправильных CRLF, пробовал исключать необязательные заголовки. Результаты похожи.

решение1

Соответствующий RFC,Протокол передачи гипертекста (HTTP/1.1): синтаксис сообщений и маршрутизациясодержит ответ на ваш вопрос: каждая строка HTTP-запроса должна заканчиваться символами CR/LF.


Грамматика для HTTPФормат сообщенияуказывает, что каждая строка заголовка должна заканчиваться символом возврата каретки ( 0x0dв ASCII), за которым следует символ перевода строки ( 0x0a):

 HTTP-message   = start-line
                  *( header-field CRLF )
                  CRLF
                  [ message-body ]

Это более четко выражено в описанииЗапрос линии:

Строка запроса начинается с токена метода, за которым следует один пробел (SP), цель запроса, еще один пробел (SP), версия протокола и заканчивается CRLF.

 request-line   = method SP request-target SP HTTP-version CRLF

Так как curlэто специально разработано для HTTP-запросов, то оно уже использует соответствующие окончания строк при выполнении HTTP-запросов. Однако netcat — это более универсальная программа. Как утилита Unix, она по умолчанию использует символы перевода строки для окончания строк, требуя от пользователя убедиться, что строки завершены правильно.

Вы можете использовать unix2dosутилиту для преобразования файла, содержащего заголовки запроса, для использования в качестве окончаний символов возврата каретки/перевода строки.

Если вы хотите ввести HTTP-запрос вручную и у вас установлена ​​последняя версия nc, вам следует использовать ее -Cопцию CRLFдля завершения строк:

nc -C www.youtypeitwepostit.com 80

Кстати, стоит отметить, что большинство популярных интернет-протоколов (например, SMTP) используют окончания строк CR/LF.


Обратите внимание, что некоторые веб-серверы (например, Apache) более снисходительны и принимают строки запроса, которые завершаются только символом перевода строки. Спецификация HTTP допускает это, как указано вНадежность анализа сообщенийраздел:

Хотя признаком конца строки для полей начальной строки и заголовка является последовательность CRLF, получатель МОЖЕТ распознать один LF как признак конца строки и игнорировать любой предшествующий CR.

Связанный контент