簡體   English   中英

為什么有些服務器在最后一個塊長度為零后不使用 CRLF?

[英]Why are some servers not using CRLF after the last chunk length of zero?

我正在使用 HTTP 請求工具(類似於 cURL)並且遇到服務器響應問題。 或者我對 HTTP 1.1 和分塊數據的 RFC 的理解。

我所看到的是分塊數據應采用以下格式:

4\r\n
Wiki\r\n
5\r\n
pedia\r\n
e\r\n
 in\r\n\r\nchunks.\r\n
0\r\n
\r\n

我實際看到的是以下內容:

4\r\n
Wiki\r\n
5\r\n
pedia\r\n
e\r\n
 in\r\n\r\nchunks.\r\n
0

換句話說,我測試過的少數服務器在 0.. 之后不再發送數據。不是 CRLF,更不用說 CRLFCRLF。

如果沒有正確的分塊標簽格式,我們怎么知道這是分塊數據的結尾? 超時發生在 0 之后尋找 CRLF,這還不夠。

是的,它違反了標准。 但是我們希望與所有可能的 http 服務器和客戶端兼容,因此我們必須了解如何違反它。

分塊通常用於通過 http 1.1 協議進行內容流傳輸 標准要求以額外的CRLF結束內容。 所以我們可以看到如下偽代碼:

def stream(endpoint)
  Socket.open(endpoint) do |socket|
    sleep 10

    more_data do |data|
      print data.length.to_s(16)
      print data
      print "CRLF"
    end
  end

  print "CRLF"
end

但正確的代碼如下:

def stream(endpoint)
  Socket.open(endpoint) do |socket|
    sleep 10

    more_data do |data|
      print data.length.to_s(16)
      print data
      print "CRLF"
    end
  end

ensure
  print "CRLF"
end

這意味着在輸入套接字中斷后任何其他異常錯誤版本的方法將無法打印額外的“CRLF”到輸出套接字。

如果沒有正確的分塊標簽格式,我們怎么知道這是分塊數據的結尾? 超時發生在 0 之后尋找 CRLF,這還不夠。

許多實現忽略了這種違規,因為它們不需要知道內容的大小。 他們只是嘗試在套接字關閉之前接收盡可能多的數據。

使用 Content-Length,絕對是我知道的時候; 對於文件下載,檢查文件大小在資源方面無關緊要。 對於分塊傳輸,我們不掃描消息正文中的 CRLF 對。 它首先讀取指定數量的字節,然后再讀取兩個字節以確認它們是 CR 和 LF。 如果不是,則消息正文格式錯誤,並且大小指定不正確或數據已損壞。

有關更多信息,請閱讀RCF ,其中說

在響應中使用分塊傳輸編碼的服務器不得對任何標頭字段使用尾部,除非至少滿足以下一項:

a) 請求包含一個 TE 頭字段,表明在響應的傳輸編碼中“trailers”是可接受的,如第 14.39 節所述; 或者,

b) 服務器是響應的源服務器,尾部字段完全由可選的元數據組成,接收者可以使用消息(以源服務器可接受的方式)而無需接收此元數據。 換句話說,源服務器願意接受這樣的可能性,即拖車字段可能會在通往客戶端的路徑上被悄悄丟棄。

確定消息體長度的方法:

如果報頭有傳輸編碼並且分塊傳輸是最終編碼,則消息體長度通過讀取和解碼分塊數據來確定,直到傳輸編碼指示數據完成。

如果 header 有 Transfer-Encoding 並且分塊傳輸不是最終編碼,則消息正文長度通過讀取連接來確定,直到它被服務器關閉。

如果請求頭中有傳輸編碼,並且分塊傳輸不是最終編碼,則無法可靠地確定消息體長度; 服務器必須以 400(錯誤請求)狀態代碼響應,然后關閉連接。

如果接收到的消息同時帶有 Transfer-Encoding 和 Content-Length 頭域,Transfer-Encoding 會覆蓋 Content-Length。 這樣的消息可能表示嘗試執行請求響應拆分,應該作為錯誤處理。 在向下游轉發此類消息之前,發送方必須刪除接收到的 Content-Length 字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM