请教一个关于断点下载的问题

MakeHui

经测试使用curl -i --range 20-50可以正常读取出该部分的数据
但是使用wget -c就出现如下报错

Connecting to 192.168.1.224:8001... connected.
HTTP request sent, awaiting response... -1
2021-06-01 23:41:25 ERROR -1: Malformed status line.
Retrying.

跟踪执行过程有运行到send()

header 信息如下:

array(20) {
  ["QUERY_STRING"]=>
  string(1049) "object_id=5000000038"
  ["REQUEST_METHOD"]=>
  string(3) "GET"
  ["REQUEST_URI"]=>
  string(1065) "/api/object/obi?object_id=5000000038"
  ["SERVER_PROTOCOL"]=>
  string(8) "HTTP/1.1"
  ["SERVER_SOFTWARE"]=>
  string(16) "workerman/3.5.31"
  ["SERVER_NAME"]=>
  string(13) "192.168.1.224"
  ["HTTP_HOST"]=>
  string(18) "192.168.1.224:8001"
  ["HTTP_USER_AGENT"]=>
  string(21) "Wget/1.14 (linux-gnu)"
  ["HTTP_ACCEPT"]=>
  string(3) "*/*"
  ["HTTP_ACCEPT_LANGUAGE"]=>
  string(0) ""
  ["HTTP_ACCEPT_ENCODING"]=>
  string(0) ""
  ["HTTP_COOKIE"]=>
  string(0) ""
  ["HTTP_CONNECTION"]=>
  string(10) "Keep-Alive"
  ["CONTENT_TYPE"]=>
  string(0) ""
  ["REMOTE_ADDR"]=>
  string(13) "192.168.1.225"
  ["REMOTE_PORT"]=>
  int(43526)
  ["REQUEST_TIME"]=>
  int(1622605285)
  ["REQUEST_TIME_FLOAT"]=>
  float(1622605285.0338)
  ["HTTP_RANGE"]=>
  string(15) "bytes=40257712-"
  ["SERVER_PORT"]=>
  string(4) "8001"
}
string(471) "HTTP /1.1 206 Partial Content
Accenpt-Ranges: bytes
Content-Length: 65227761
Content-Range: bytes 40257712-105485472/105485473
Content-Type: application/octet-stream
Cache-Control: public
Pragma: public
Etag: 3c7358115ae8e7bef4c3c79e0906cfc4b360a4bffa11bdb28aa2dce4f89b00df
Content-Disposition:attachment; filename=3c7358115ae8e7bef4c3c79e0906cfc4b360a4bffa11bdb28aa2dce4f89b00df
Connection: keep-alive
Last-Modified: Tue, 01 Jun 2021 14:44:28 Asia/Shanghai

"

这里是代码:

protected function sendFile($connection, $filePath)
    {
        $fileinfo = \pathinfo($filePath);
        $filename = isset($fileinfo['filename']) ? $fileinfo['filename'] : '';
        $filesize = \filesize($filePath);
        $start = 0;
        $contentLength = $filesize;
        $info = \stat($filePath);
        $modified_time = $info ? \date('D, d M Y H:i:s', $info['mtime']) . ' ' . \date_default_timezone_get() : '';

        if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $info) {
            // Http 304.
            if ($modified_time === $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
                // 304
                Http::header('HTTP/1.1 304 Not Modified');
                // Send nothing but http headers..
                if (\strtolower($_SERVER['HTTP_CONNECTION']) === "keep-alive") {
                    $connection->send('');
                } else {
                    $connection->close('');
                }
                return;
            }
        }

        if ($modified_time) {
            $modified_time = "Last-Modified: $modified_time\r\n";
        }

        if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])) {
            [, $range] = explode('=', $_SERVER['HTTP_RANGE'], 2);
            [$start, $end] = explode('-', $range);
            $end = $end ?: $filesize - 1;
            $contentLength = $end - $start + 1;

            $header = "HTTP /1.1 206 Partial Content\r\n";
            $header .= "Accenpt-Ranges: bytes\r\n";
            $header .= "Content-Length: ${contentLength}\r\n";
            $header .= "Content-Range: bytes ${start}-${end}/${filesize}\r\n";
        } else {
            $header = "HTTP/1.1 200 OK\r\n";
            $header .= "Content-Length: ${contentLength}\r\n";
//            $header .= "Content-Range: bytes 0-${end}/${filesize}\r\n";
        }

        $header .= "Content-Type: application/octet-stream\r\n";
        $header .= "Cache-Control: public\r\n";
        $header .= "Pragma: public\r\n";
        $header .= "Etag: ${filename}\r\n";
        $header .= "Content-Disposition:attachment; filename=${filename}\r\n";
        $header .= "Connection: keep-alive\r\n";
        $header .= $modified_time;

        $header .= "\r\n";

        $connection->send($header, true);

        // Read file content from disk piece by piece and send to client.
        $connection->fileHandler = \fopen($filePath, 'r');
        \fseek($connection->fileHandler, $start);
        $do_write = function() use ($connection, $contentLength) {
            // Send buffer not full.
            $stepLength = 8192;
            while(empty($connection->bufferFull)) {
                $readCount = $contentLength > $stepLength ? $stepLength : $contentLength;
                $contentLength -= $readCount;
                    // Read from disk.
                $buffer = \fread($connection->fileHandler, $readCount);
                // Read eof.
                if($buffer === '' || $buffer === false) {
                    return;
                }
                if ($contentLength === 0) {
                    $connection->close($buffer, true);
                    return;
                } else {
                    $connection->send($buffer, true);
                }
            }
        };
        // Send buffer full.
        $connection->onBufferFull = function($connection) {
            $connection->bufferFull = true;
        };
        // Send buffer drain.
        $connection->onBufferDrain = function($connection) use ($do_write) {
            $connection->bufferFull = false;
            $do_write();
        };
        $do_write();
    }
1990 0 0
0个回答

年代过于久远,无法发表回答
🔝