php - 如何在没有 Content-Length header 的情况下流式传输 HTTP 文件上传?

标签 php apache http http-streaming

是否可以在不包含内容长度 header 的情况下将文件上传到 apache php 服务器?

我正在尝试将我正在创建的文件作为文件上传流式传输。当我不使用内容长度 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 :

Applications SHOULD use this field to indicate the transfer-length of the message-body, unless this is prohibited by the rules in section 4.4.

然而,这对大多数服务器来说是一个非常标准的要求,如果 Content-Length header 丢失或指定不正确,它们通常会发回错误响应。对于所有意图和目的,应该在这种情况下等同于必须

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

所以总而言之,如果您想发送带有消息的实体正文但不想发送 Content-Length header ,您唯一的选择是发送分块HTTP 消息。如果您想流式传输该实体主体并且事先不知道其长度,这基本上是必需的。

如何对流式传输的 HTTP 实体主体进行分块编码 ...

Transfer-Encoding: chunked 表示您正在根据 RFC2616 Sec3.6.1 中规定的约束对 HTTP 消息的实体主体进行编码.这种编码格式可以应用于请求或响应(呃,它们都是 HTTP 消息)。这种格式非常有用,因为它允许您在知道实体主体的大小甚至确切知道实体主体将是什么之前立即开始发送 HTTP 消息。事实上,当您 echo 任何输出而没有发送像 header('Content-Length: 42') 这样的长度 header 时,这正是 PHP 透明地为您做的事情。

我不打算详细介绍分块编码——这就是 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/

相关文章:

php - jquery post ajax 调用 session 不起作用

php - 查找最近和即将到来的日期

php正则表达式过滤数据

spring - 带有 Proxypass 和 Spring Security 的 Apache

apache - 在 XAMPP 上设置虚拟主机

http - POST 与 GET 方法——在网络层面,哪个受延迟影响更大?

python - 使用 CherryPy 的 HTTPS 到 HTTP

Symfony2 : use http cache

php - Magento - 无效的 block 类型

apache - 对 WampServer 感到沮丧