Что, как минимум, требуется для HTTP-запроса? - PullRequest
65 голосов
/ 14 июля 2011

Я пытаюсь выполнить команду GET для моего локального сервера, используя netcat, выполнив следующие действия:

echo -e "GET / HTTP/1.1\nHost: localhost" | nc localhost 80

К сожалению, я получаю HTTP/1.1 400 Bad Request ответ на это. Что, как минимум, требуется для HTTP-запроса?

Ответы [ 8 ]

62 голосов
/ 16 марта 2012

если запрос: "GET / HTTP/1.0\r\n\r\n", тогда ответ содержит заголовок и тело, и после ответа соединение закрывается.

если запрос: "GET / HTTP/1.1\r\nHost: host:port\r\nConnection: close\r\n\r\n" тогда ответ содержит заголовок и тело, и после ответа соединение закрывается.

если запрос: "GET / HTTP/1.1\r\nHost: host:port\r\n\r\n", тогда ответ содержит заголовок и тело, и соединение не будет закрываться даже после ответа.

если ваш запрос: "GET /\r\n\r\n", то в ответе нет заголовка и только тела, и после ответа соединение закрывается.

если ваш запрос: "HEAD / HTTP/1.0\r\n\r\n", то ответ содержит только заголовок и не содержит тела, и после ответа соединение закрывается.

если запрос: "HEAD / HTTP/1.1\r\nHost: host:port\r\nConnection: close\r\n\r\n", то ответ содержит только заголовок и не содержит тела, и соединение закрывается после ответа.

если запрос: "HEAD / HTTP/1.1\r\nHost: host:port\r\n\r\n", то ответ содержит только заголовок и не содержит тела, и после ответа соединение не будет закрыто.

59 голосов
/ 14 июля 2011

Он должен использовать окончания строки CRLF и заканчиваться \r\n\r\n, то есть пустой строкой.Вот что я использую:

printf 'GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: close\r\n\r\n' |
  nc www.example.com 80

Кроме того, я предпочитаю printf вместо echo, и я добавляю дополнительный заголовок, чтобы сервер закрывал соединение, но это не нужно.

10 голосов
/ 14 июля 2011

См. Wiki: HTTP-запрос клиента (пример) .

Обратите внимание на следующее:

За клиентским запросом (состоящим в данном случае из строки запроса и только одного заголовка) следует пустая строка, так что запрос заканчивается двойной новой строкой, каждая в форме возврата каретки, за которой следует перевод строки . Заголовок «Host» различает разные DNS-имена, использующие один IP-адрес, что позволяет использовать виртуальный хостинг на основе имен. Хотя необязательно в HTTP / 1.0, оно обязательно в HTTP / 1.1 .

Абсолютный минимум (если разрешено удаление Хоста ;-) равен GET / HTTP/1.0\r\n\r\n.

Счастливое кодирование

9 голосов
/ 26 октября 2011

Мне удалось получить ответ от моего сервера Apache с только запрошенным документом, без заголовка ответа, просто

GET /\r\n

Если вам нужны заголовки ответа, включая статускод, вам нужен один из других ответов здесь.

5 голосов
/ 14 июля 2011

Сам факт ошибки 400 Bad Request не означает, что ваш запрос нарушает HTTP. Сервер вполне может дать этот ответ по другой причине.

Насколько я знаю, абсолютный минимум действительного HTTP-запроса:

GET / HTTP/1.0\r\n\r\n
3 голосов
/ 11 октября 2014

Пожалуйста, пожалуйста, пожалуйста, не реализуйте свой собственный HTTP-клиент без предварительного ознакомления с соответствующими спецификациями.Пожалуйста, прочитайте и убедитесь, что вы полностью поняли хотя бы RFC 2616 .(И если вы амбициозны, RFC с 7230 по 7235).

Хотя HTTP выглядит как простой протокол, на самом деле в нем есть ряд тонких моментов.Любой, кто написал HTTP-сервер, расскажет вам об обходных путях, которые он должен был реализовать, чтобы справиться с некорректными, но широко развернутыми клиентами.Если вы не читаете спецификации, пожалуйста, используйте хорошо зарекомендовавшую себя клиентскую библиотеку; Curl хороший выбор, но я уверен, что есть и другие.

Если вы собираетесь реализовать свой собственный:

  • не используйте HTTP/0.9;
  • HTTP / 1.0 требует строку запроса и пустую строку;
  • в HTTP / 1.1, заголовок Host: является обязательным в дополнение к вышеприведенному.

Пропуск заголовка Host: в HTTP / 1.1 является наиболее распространенной причиной 400 ошибок.

1 голос
/ 14 июля 2011

Вы должны добавить пустую строку: \r\n\r\n

http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Client_request

0 голосов
/ 13 октября 2014

Действительно ДЕЙСТВИТЕЛЬНО минимум, не использует netcat, но использует сам bash:

user@localhost:~$ exec 3<>/dev/tcp/127.0.0.1/80
user@localhost:~$ echo -e "GET / HTTP/1.1\n" >&3
user@localhost:~$ cat <&3
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.6
Date: Mon, 13 Oct 2014 17:55:55 GMT
Content-type: text/html; charset=UTF-8
Content-Length: 514

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
</ul>
<hr>
</body>
</html>
user@localhost:~$ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...