是否可以在不包含content-length header 的情况下将文件上传到apache php服务器?

我正在尝试流式传输正在创建的文件作为文件上传。当我不使用content-length header 时,我得到了apache“未实现501方法”。

$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://input读取

最佳答案

根据HTTP规范,从技术上讲,您无需指定Content-Length header 。从RFC 2616 14.13:



但是,这是大多数服务器的标准要求,如果Content-Length header 丢失或指定不正确,它们通常会发回错误响应。出于所有意图和目的,在这种情况下应等于“必须”。

问题是(特别是在保持事件连接的情况下),如果没有Content-Length header ,服务器将不知道您的请求消息何时真正结束。如果要流式传输请求实体主体,则另一种选择是发送Transfer-Encoding: chunked header ,并一次手动发送一个实体主体块。

因此,总而言之,如果您想随消息一起发送实体主体,但又不想发送Content-Length header ,则唯一的真实选择是发送分块的HTTP消息。如果您要流式传输实体主体并且不提前知道其长度,则这是基本必需的。

如何对HTTP实体进行块编码以进行流传输...
Transfer-Encoding: chunked表示您正在根据RFC2616 Sec3.6.1中列出的约束对HTTP消息的实体正文进行编码。这种编码格式可以应用于请求或响应(不是,它们都是HTTP消息)。此格式非常有用,因为它使您可以立即开始发送HTTP消息,然后再知道实体主体的大小,甚至不知道该实体主体的大小。实际上,这正是PHP在不发送诸如echo之类的长度 header 的情况下对任何输出进行header('Content-Length: 42')时透明地为您执行的操作。

我不打算讨论分块编码的细节-这就是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");

关于php - 如何在没有Content-Length header 的情况下流式传输HTTP文件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12167378/

10-14 13:01
查看更多