workerman icon indicating copy to clipboard operation
workerman copied to clipboard

[Feature request?] Support Transfer-Encoding chunked with no Content-Length

Open krissss opened this issue 4 months ago • 1 comments

目前上传未知大小的流式数据,服务端会报 400 错误(HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n)。 发现原因是代码中做了 header 中必须有 Content-Length 的限制(Workerman\Protocols\Http::input 内)。 但是当上传未知大小的数据时,仅使用 Transfer-Encoding: chunked 是符合标准的。 希望支持下。

测试代码: 客户端:

$fp = fopen('php://temp', 'r+');
fwrite($fp, 'hello');
$response = \Symfony\Component\HttpClient\HttpClient::create()
    ->request('POST', 'http://127.0.0.1:8787/upload', [
        'body' => $fp
    ]);
dd($response->getStatusCode());

服务端:webman header 头信息打印(打印位置:Workerman\Protocols\Http::input):

POST /upload HTTP/1.1\r\n
Host: 127.0.0.1:8787\r\n
Accept: */*\r\n
User-Agent: Symfony HttpClient (Curl)\r\n
Accept-Encoding: gzip\r\n
Transfer-Encoding: chunked\r\n
Content-Type: application/x-www-form-urlencoded

krissss avatar Aug 25 '25 02:08 krissss

先提个临时处理方法,那就是主动计算 fopen 后文件的 Content-Size (尝试了下,Guzzle 是会做这个计算的)

$fp = fopen('php://temp', 'r+');
fwrite($fp, 'hello');
// 计算 length
rewind($fp);
fseek($fp, 0, SEEK_END);
$length = ftell($fp);

$response = \Symfony\Component\HttpClient\HttpClient::create()
    ->request('POST', 'http://127.0.0.1:8787/upload', [
        'body' => $fp,
        'headers' => [
              'content-length' => $length,
        ],
    ]);
dd($response->getStatusCode());

krissss avatar Aug 25 '25 03:08 krissss