对于HTTP请求,最起码需要什么?

我试图通过执行以下操作使用netcat向本地服务器发出GET命令:

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

不幸的是,我得到了一个HTTP/1.1 400 Bad Request响应。 HTTP请求至less需要什么?

它必须使用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 over echo ,并且添加一个额外的头让服务器closures连接,但是这些不是必需的。

如果请求是"GET / HTTP/1.0\r\n\r\n"那么响应包含标题和正文,并且连接在响应之后closures。

如果请求是: "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"那么响应包含标题和正文,连接在响应之后也不会closures。

如果你的请求是: "GET /\r\n\r\n"那么响应中不包含头和只有主体,并且连接在响应之后closures。

如果你的请求是: "HEAD / HTTP/1.0\r\n\r\n"那么响应只包含头部和不包含主体,并且连接在响应之后closures。

如果请求是"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"那么响应只包含头文件和没有主体,并且连接在响应之后不会closures。

请参阅Wiki:HTTP客户端请求(示例) 。

请注意以下几点:

一个客户端请求(在这种情况下的请求行和只有一个标题)后面跟着一个空行,以便请求以双换行符结束,每个换行符都是一个回车符,后跟一个换行符 。 “主机”标题区分共享一个IP地址的各种DNS名称,允许基于名称的虚拟主机。 虽然在HTTP / 1.0中是可选的,但在HTTP / 1.1中是强制的

绝对最小值(如果删除主机是允许的;-)则是GET / HTTP/1.0\r\n\r\n

快乐的编码

只能使用请求的文档,没有响应头,就能从我的Apache服务器得到响应

 GET /\r\n 

如果你想要响应头文件,包括状态码,你需要其他的答案。

400 Bad Request错误本身的事实并不意味着您的请求违反了HTTP。 服务器很好,可以给这个回应的另一个原因。

据我所知绝对最低有效的HTTP请求是:

 GET / HTTP/1.0\r\n\r\n 

请不要在没有先阅读相关规范的情况下实现自己的HTTP客户端。 请阅读并确保您已经完全理解RFC 2616 。 (如果你是雄心勃勃的,从RFC 7230到7235)。

虽然HTTP看起来像一个简单的协议,实际上有一些微妙的点。 任何写过HTTP服务器的人都会告诉你他必须实现的解决方法才能处理不正确但广泛部署的客户机。 除非您正在阅读规范,否则请使用完善的客户端库; curl是一个不错的select,但是我确定还有其他的。

如果你要实现你自己的:

  • 不要使用HTTP / 0.9;
  • HTTP / 1.0需要查询行和空行;
  • 在HTTP / 1.1中,除上述之外, Host:头是强制的。

省略HTTP / 1.1中的Host:头是导致400错误的最常见原因。

真正的最低限度,不是使用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:~$