我正在尝试netcat
通过执行以下操作向本地服务器发出GET命令:
echo -e "GET / HTTP/1.1\nHost: localhost" | nc localhost 80
不幸的是,我HTTP/1.1 400 Bad Request
对此有所回应。HTTP请求至少需要什么?
我正在尝试netcat
通过执行以下操作向本地服务器发出GET命令:
echo -e "GET / HTTP/1.1\nHost: localhost" | nc localhost 80
不幸的是,我HTTP/1.1 400 Bad Request
对此有所回应。HTTP请求至少需要什么?
Answers:
它必须使用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
,我添加一个额外的头让服务器关闭连接,但这些都是没有必要的。
\r\n
。
printf 'GET / HTTP/1.1\r\nHost: localhost 80\r\n\r\n' | nc localhost 80
。谢谢!
localhost
不是localhost 80
Host
格式定义为,Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
因此应为localhost
或localhost:80
。
如果请求是:"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"
则响应仅包含标头,没有正文,并且响应后连接不会关闭。
请注意以下几点:
客户端请求(在此情况下是请求行,只有一个标头)后跟空白行,以便请求以双换行符结束,每条换行符以回车符和换行符的形式出现。“主机”标头区分共享单个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服务器的任何人都将告诉您他为了应对不正确但部署广泛的客户端而必须实施的变通方法。除非您要阅读规范,否则请使用完善的客户端库。卷发是一个不错的选择,但我敢肯定还有其他人。
如果您要实现自己的:
Host:
除了上述内容之外,标头也是必填的。Host:
在HTTP / 1.1中省略标头是导致400错误的最常见原因。
您应该添加一个空行: \r\n\r\n
http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Client_request
真正的BARE最低要求不是使用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:~$
Host
标题。
Host
标头是400的一个很常见的原因,因为如果没有它,服务器根本无法知道您想要什么(例如Apache使用它进行路由)。
\n\n
到背面后,它对我(Bash,Apache,Ubuntu)有效。但是我认为HTTP对行尾的性质很敏感,因此也许要仔细检查一下。