是否可以在不包含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/