簡體   English   中英

如何在沒有Content-Length標頭的情況下流式傳輸HTTP文件?

[英]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消息 如果您想要流式傳輸該實體主體並且不知道其長度,則基本上這是必需的。

如何對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.

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