使用 netcat (nc) 和curl 进行 HTTP 请求有什么区别?

使用 netcat (nc) 和curl 进行 HTTP 请求有什么区别?

我使用curl 请求特定的URL 并得到200 OK 响应:

curl -v www.youtypeitwepostit.com
* About to connect() to www.youtypeitwepostit.com port 80 (#0)
*   Trying 54.197.246.21...
* Connected to www.youtypeitwepostit.com (54.197.246.21) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.youtypeitwepostit.com
> Accept: */*
>
< HTTP/1.1 200 OK
...

如果我将标题保存到文件中:

GET / HTTP/1.1
User-Agent: curl/7.29.0
Host: www.youtypeitwepostit.com
Accept: */*

并尝试执行nc命令(netcat):

nc www.youtypeitwepostit.com 80 < file
HTTP/1.1 505 HTTP Version Not Supported
Connection: close
Server: Cowboy
Date: Wed, 02 Nov 2016 04:08:34 GMT
Content-Length: 0

我收到另一个回复。有什么区别以及如何使用 200 OK nc

我尝试在请求标头中使用不同版本的 HTTP,尝试手动键入请求以避免错误的 CRLF,尝试排除可选标头。结果是相似的。

答案1

相关的RFC,超文本传输​​协议 (HTTP/1.1):消息语法和路由包含您问题的答案:HTTP 请求的每一行都应以 CR/LF 结尾。


HTTP 语法消息格式指定每个标题行应以回车符(0x0dASCII 格式)结尾,后跟换行符 ( 0x0a):

 HTTP-message   = start-line
                  *( header-field CRLF )
                  CRLF
                  [ message-body ]

这在描述中表达得更清楚请求热线

请求行以方法令牌开头,后跟一个空格 (SP)、请求目标、另一个空格 (SP)、协议版本,并以 CRLF 结束。

 request-line   = method SP request-target SP HTTP-version CRLF

由于curl是专门为 HTTP 请求开发的,因此在发出 HTTP 请求时它已经使用了适当的行结束符。然而,netcat 是一个更通用的程序。作为一个 Unix 实用程序,它默认使用换行符作为行结束符,因此要求用户确保正确终止行。

您可以使用该unix2dos实用程序将包含请求标头的文件转换为使用回车/换行结尾。

如果您想手动键入 HTTP 请求并拥有最新版本的nc,则应使用其-C选项来用于CRLF行结尾:

nc -C www.youtypeitwepostit.com 80

顺便说一句,值得注意的是,大多数流行的 Internet 协议(例如 SMTP)都使用 CR/LF 行结尾。


请注意,某些 Web 服务器(例如 Apache)更宽容,并且会接受仅以换行符终止的请求行。 HTTP 规范允许这样做,如消息解析的鲁棒性部分:

尽管起始行和头字段的行终止符是序列 CRLF,但接收者可以将单个 LF 识别为行终止符并忽略任何前面的 CR。

相关内容