![](/img/trans.png)
[英]Why is the Content-Length HTTP header from not the same as on disk file size?
[英]How to stream an HTTP file upload without the Content-Length header?
是否可以將文件上傳到apache php服務器而不包含內容長度標題?
我正在嘗試將我正在創建的文件作為文件上傳流式傳輸。 當我不使用內容長度標題時,我得到了apache“501 Method Not Implemented”。
$sock = fsockopen($host,80,$errno, $error);
fwrite($sock, "POST $resource HTTP/1.1\r\n" .
"Host: $host\r\n\r\n");
fwrite($sock,fread($readHandle,filesize($file)));
如果我包含內容長度,它工作正常。
服務器正在從php://輸入讀取
根據HTTP規范,技術上不需要指定Content-Length標頭。 來自RFC 2616 14.13 :
應用程序應該使用此字段來指示消息正文的傳輸長度,除非4.4節中的規則禁止這樣做。
但是,對於大多數服務器來說,這是一個非常標准的要求,如果Content-Length
標頭丟失或指定不正確,它們通常會發回錯誤響應。 出於所有意圖和目的,在這種情況下應該等同於必須 。
問題是(特別是對於保持活動連接),服務器不知道您的請求消息何時實際結束而沒有Content-Length
標頭。 如果您正在流式傳輸請求實體主體,則另一個選項是發送Transfer-Encoding: chunked
標頭並一次手動發送一個實體主體塊。
總而言之,如果您希望發送帶有消息的實體主體但又不想發送Content-Length
標頭,那么您唯一真正的選擇是發送分塊的HTTP消息 。 如果您想要流式傳輸該實體主體並且不知道其長度,則基本上這是必需的。
Transfer-Encoding: chunked
意味着您根據RFC2616 Sec3.6.1中規定的約束對HTTP消息的實體主體進行編碼。 這種編碼格式可以應用於請求或響應(duh,它們都是HTTP消息)。 這種格式非常有用,因為它允許您在知道實體主體的大小之前立即開始發送HTTP消息,甚至可以確切地知道該實體主體的內容。 實際上,這正是PHP在沒有發送像header('Content-Length: 42')
這樣的長度header('Content-Length: 42')
情況echo
任何輸出時透明地為你做的事情。
我不打算詳細介紹分塊編碼 - 這就是HTTP規范的用途 - 但是如果你想要流一個請求實體,你需要做這樣的事情:
<?php
$sock = fsockopen($host,80,$errno, $error);
$readStream = fopen('/some/file/path.txt', 'r+');
fwrite($sock, "POST /somePath HTTP/1.1\r\n" .
"Host: www.somehost.com\r\n" .
"Transfer-Encoding: chunked\r\n\r\n");
while (!feof($readStream)) {
$chunkData = fread($readStream, $chunkSize);
$chunkLength = strlen($chunkData);
$chunkData = dechex($chunkLength) . "\r\n$chunkData\r\n";
fwrite($sock, $chunkData);
}
fwrite($sock, "0\r\n\r\n");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.