谁能告诉我为什么我bad request
在执行这个命令时会出现这样的情况
echo -e "GET http://www.yellowpages.com.eg/Mjg3NF9VUkxfMTEwX2h0dHA6Ly93d3cubG90dXMtYWlyLmNvbV8=/Lotus-Air/profile.html HTTP/1.1\n\n" | nc www.yellowpages.com 80
同一个网站在浏览器中可以正常打开。
答案1
HTTP 请求中的标头必须使用 CRLF (Windows) 行结尾。 (看维基百科或者RFC 2616.) 许多服务器支持 LF (Unix) 行结尾作为扩展,但这个不支持。
此外,HTTP 1.1 需要一个Host:
标头行,如沃伦·杨指出。 (看维基百科或者RFC 2616)。
echo -e "GET http://www.yellowpages.com.eg/Mjg3NF9VUkxfMTEwX2h0dHA6Ly93d3cubG90dXMtYWlyLmNvbV8=/Lotus-Air/profile.html HTTP/1.1\r\nHost: www.yellowpages.com.eg\r\n\r\n" | nc www.yellowpages.com 80
或者更清晰
sed $'s/$/\r/' <<EOF | nc www.yellowpages.com 80
GET http://www.yellowpages.com.eg/Mjg3NF9VUkxfMTEwX2h0dHA6Ly93d3cubG90dXMtYWlyLmNvbV8=/Lotus-Air/profile.html HTTP/1.1
Host: www.yellowpages.com.eg
EOF
但是为什么不使用 wget 或curl,它们可以毫不费力地构建有效的请求,并且仍然允许您在必要时指定自定义标头?
答案2
您需要在 GET 请求中包含域名。您已经告诉nc
要连接的域名,它知道在哪里可以找到服务器,但nc
不会将其传递给服务器。如果服务器托管多个域,它将不知道向您发送哪一个。您传递的请求标头echo
应包含完整的域,如下所示:
echo "GET http://domain.tld/path" | nc domain.tld 80
请注意,您还可以将-e
参数放在 echo 中并在末尾删除转义换行符。这-e
是抑制回声添加换行符的自然倾向,然后您自己添加一个换行符。
编辑1:curl
是否有某种原因您不使用像这样可以处理所有标头可能性并为您提供有用输出的普通下载工具?您真的需要自己处理标题聊天吗?curl http://domain.tld/path
应该为您提供更可靠的输出,因为程序员已经为您解决了所有可能性。
编辑2:看沃伦的回答有关协议规范的信息。 TL;DR:如果您指定 1.1,则必须遵守该协议。如果你指定1.0,通常可以按照上面的方式提出要求。
使用 HTTP/1.1 通过 echo 和 netcat 发出请求,试试这个:
echo "GET http://domain.tld/path HTTP/1.1\nHost: domain.tld\n" | nc domain.tld 80
答案3
HTTP 1.1需要您至少Host
在 GET 请求中发送一个标头。也就是说,最低的法律要求如下:
GET http://www.example.com/noise/and/junk HTTP/1.1
Host: www.example.com
(当然,还要加上一个额外的 CRLF 来终止标头部分。)
可能有一些 HTTP 服务器可以处理声称需要 HTTP 1.1 但不包含Host
标头的请求,但您的服务器拒绝此类请求是正确的。
Host
是支持基于名称的虚拟主机所需的 HTTP 1.1 扩展。如果您尝试访问的站点有专用服务器(或者至少有专用 IP),您可以安全地返回到 HTTP 1.0,它允许您发出单行 HTTP 请求:
GET http://www.example.com/noise/and/junk HTTP/1.0