HTTP请求至少需要什么?


72

我正在尝试netcat通过执行以下操作向本地服务器发出GET命令:

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

不幸的是,我HTTP/1.1 400 Bad Request对此有所回应。HTTP请求至少需要什么?


1
不确定,添加\n\n到背面后,它对我(Bash,Apache,Ubuntu)有效。但是我认为HTTP对行尾的性质很敏感,因此也许要仔细检查一下。
Kerrek SB 2011年

Echo在处理\ r \ n字符时存在一些问题,因此使用printf的相同命令有效,但对echo无效。unix.stackexchange.com/questions/65803/…–
哈里(Harry)

Answers:


66

它必须使用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

此外,我喜欢printfecho,我添加一个额外的头让服务器关闭连接,但这些都是没有必要的。


1
并且请记住,标准HTTP中的换行符始终为\r\n
Matti Virkkunen 2011年

1
很好,就我的目的而言,我要做的就是printf 'GET / HTTP/1.1\r\nHost: localhost 80\r\n\r\n' | nc localhost 80。谢谢!
Naftuli Kay 2011年

3
主人应该localhost不是localhost 80
slebetman

1
@NaftuliTzviKayHost格式定义为,Host = "Host" ":" host [ ":" port ] ; Section 3.2.2因此应为localhostlocalhost:80
Pijusn 2015年

71

如果请求是:"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"则响应仅包含标头,没有正文,并且响应后连接不会关闭。


1
它是特定于特定的http服务器还是由http rfcs强制执行?
jfs

1
@JFSebastian对于HTTP 1.1连接:tools.ietf.org/html/rfc2616#section-8,对于HTTP 1.1主机:tools.ietf.org/html/rfc2616#section-14.23,对于HTTP 1.0 tools.ietf.org/html / rfc1945,对于HTTP 0.9 w3.org/Protocols/HTTP/AsImplemented.html,HTTP持久连接:en.wikipedia.org/wiki/…(关于持久连接的说明,我提供了Wikipedia链接,因为它有更好的解释)
Abhishek Oza 2014年

4
RFC 2616已过时。除非出于历史目的,否则请勿再引用。
朱利安·雷施克

根据@JulianReschke的评论,在此我给出另一个链接:w3.org/Protocols/#rfc723x,用于HTTP规范。请在该页面的“ RFC 723X”下找到链接,以了解有关HTTP规范的最新RFC。
Abhishek Oza 2014年

是否符合“ GET /\r\n\r\n”http/1.1?
肯尼斯(Kenneth)

12

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

请注意以下几点:

客户端请求(在此情况下是请求行,只有一个标头)后跟空白行,以便请求以双换行符结束,每条换行符以回车符和换行符的形式出现。“主机”标头区分共享单个IP地址的各种DNS名称,从而允许基于名称的虚拟主机。虽然在HTTP / 1.0中是可选的,但在HTTP / 1.1中是必需的

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

快乐编码


这就是我想要的。谢谢。(也是实际上回答上述HTTP / 1.1请求出了什么问题的人)
Wyatt8740 '16

9

只能从请求的文档中获得Apache服务器的响应,而没有响应标头,而只有

GET /\r\n

如果您想要响应头(包括状态代码),则需要此处的其他答案之一。


6
有趣。这使用了90年代初的原始HTTP / 0.9协议。我印象非常深刻,Apache仍然对此做出了回应。
本·罗素

Nginx仍然支持这一点。从我所看到的来看,每当有人开发新的HTTP服务器时,他们都将复制其他现有实现的所有错误,这就是为什么这些事情会持续数十年的原因。
L.Kärkkäinen'19

5

400 Bad Request错误本身的事实并不表示您的请求违反了HTTP。服务器很可能出于其他原因给出此响应。

据我所知,绝对最小有效HTTP请求是:

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

7
实际上,绝对最小值是“ GET / \ r \ n”。如果未指定版本,则服务器应采用HTTP / 0.9。在HTTP / 0.9中,不允许使用请求标头,因此不需要空行来终止它们。我不希望在任何地方都支持此功能,因为实际上HTTP / 0.9客户端非常少见,因此服务器很可能无法对其进行测试。
Jules 2012年

3
HTTP / 1.0不接受任何标头,HTTP / 1.1具有强制标头:主机。
Pedro

4

拜托,拜托,拜托,请先阅读相关规范,然后再实现自己的HTTP客户端。请阅读并确保至少完全了解RFC 2616。(如果您有野心,请参阅RFC 7230到7235)。

虽然HTTP看起来像一个简单的协议,但实际上有许多微妙之处。编写HTTP服务器的任何人都将告诉您他为了应对不正确但部署广泛的客户端而必须实施的变通方法。除非您要阅读规范,否则请使用完善的客户端库。卷发是一个不错的选择,但我敢肯定还有其他人。

如果您要实现自己的:

  • 不要使用HTTP / 0.9;
  • HTTP / 1.0需要查询行和空行;
  • 在HTTP / 1.1中,Host:除了上述内容之外,标头也是必填的。

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


在2019年,HTTP / 1.0似乎终于消失了,您只需要支持HTTP / 1.1(如果需要,还可以支持HTTP / 2和HTTP / 3)。
L.Kärkkäinen'19


0

真正的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:~$ 

1
实际上,这是无效的HTTP / 1.1请求。1.应使用CRLF进行线路端接。2.它应该包含Host标题。
Pijusn 2015年

Web服务器以200 OK而不是400 Bad Request响应。
Marcel

4
这并不意味着请求符合HTTP / 1.1。已知生产环境中的Web服务器会接受不100%与HTTP / 1.1兼容的请求。原因可能会有所不同,但是如果发送无效请求,则永远不要依赖服务器来理解所需的内容。例如,缺少Host标头是400的一个很常见的原因,因为如果没有它,服务器根本无法知道您想要什么(例如Apache使用它进行路由)。
Pijusn

是的,apache的虚拟主机路由可以做到这一点,但是我的示例请求的是simplehttpserver localhost。
Marcel

1
一些善良的灵魂使我对这个答案十分关注。我真的不明白为什么我在这里得到负分。我已经严格回答了。
Marcel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.