使用 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。

相關內容