我正在尝试使用 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请求?
如果请求为:"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"
,则响应仅包含头而没有正文,响应后连接不会关闭。
它必须使用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
。 - Matti Virkkunenprintf 'GET / HTTP/1.1\r\nHost: localhost 80\r\n\r\n' | nc localhost 80
。谢谢! - Naftuli Kaylocalhost
,而不是 localhost 80
。 - slebetmanHost
格式定义为 Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
,因此它应该是 localhost
或 localhost:80
。 - Pijusn注意以下内容:
客户端请求(在本例中仅由请求行和一个标头组成)后跟着一个空行,因此请求以双重换行符结束,每个都是回车符后跟随一个换行符的形式。 "Host"标头区分了共享单个IP地址的各种DNS名称,允许基于名称的虚拟主机。虽然在HTTP / 1.0中是可选的,但在HTTP / 1.1中是强制要求的。
最小的请求(如果允许删除Host)是 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
Host:
头是强制性的。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:~$
const std::string host = "example.com";
std::stringstream http;
http << "GET /index.html HTTP/1.1\r\n";
http << "Host: " << host << "\r\n";
http << "Connection: close\r\n";
//end
http << "\r\n";
\n\n
到末尾后可行。但我认为 HTTP 对行结尾的特性比较敏感,所以最好再检查一下。 - Kerrek SB