HTTP 文件下载:监控下载进度

HTTP File Download: Monitoring Download Progress

本文关键字:下载 监控 文件下载 HTTP      更新时间:2023-09-26

我遇到过这样一种情况,当我必须通过HTTP协议从Web服务器下载大文件(最大4GB)时:Apache 2.4.4。我已经尝试了几种方法,但最好的解决方案似乎是使用 X-SendFile 模块。

由于我为文件上传提供进度条,因此我需要为文件下载提供相同的功能。所以这是我的问题:

  • 有没有办法,包括解决方法,来实现文件下载进度监控?
  • 有什么方法(包括解决方法)可以计算文件下载传输速度吗?
  • 有没有比使用 X-Sendfile 模块更好的方法来从 Web 服务器提供高效的文件下载?

一般来说,是否有更好的文件下载选项,可以让我监控文件下载进度?它可以是客户端(JavaScript)或服务器解决方案(PHP)。是否有任何特定的网络服务器允许这样做?

目前我使用:

  • 阿帕奇 2.4.4
  • 乌班图

很多次谢谢。

2 个想法(未经验证):

第一:

不要在页面上放置指向文件(您要下载的文件)的常规链接,而是放置诸如.../dowanload之类的链接.php它可能看起来像这样:

<?php
    // download.php file
    session_start(); // if needed
    $filename = $_GET['filename']);
    header( 'Content-type: text/plain' ); // use any MIME you want here
    header( 'Content-Disposition: attachment; filename="' . htmlspecialchars($filename) . '"' );
    header( 'Pragma: no-cache' );
    // of course add some error handling
    $filename = 'c:/php/php.ini';
    $handle = fopen($filename, 'rb');
    // do not use file_get_contents as you've said files are up to 4GB - so read in chunks
    while($chunk = fread($handle, 1000)) // chunk size may depend on your filesize
    {
        echo $chunk;
        flush();
        // write progress info to the DB, or session variable in order to update progress bar
    }
    fclose($handle);
?>

这样,您可以密切关注下载过程。同时,您可以将进度信息写入数据库/会话变量,并使用 AJAX 从数据库/会话变量更新进度条读取状态,当然轮询读取进度信息的脚本。

这非常简化,但我认为它可以随心所欲地工作。

第二:

Apache 2.4内置了Lua语言:

  • mod_lua
  • 使用 mod_lua 创建钩子和脚本

我敢打赌,您可以尝试编写LUA Apache处理程序来监视您的下载 - 将进度发送到数据库并使用PHP/AJAX从数据库获取进度信息更新进度条。

类似地 - 有用于perl甚至python的模块(但不是为了win)

我看到的主要问题在于:在 php+apache 解决方案中,输出缓冲可以放置在几个地方:

浏览器 <= 1 => Apache <= 2 => PHP 处理程序 <= 3 => PHP 解释器 过程

您需要控制第一个缓冲区。但是直接从PHP中这是不可能的。

可能的解决方案:

1)您可以编写自己的迷你守护进程,其主要功能将仅发送文件并在80端口8880以外的另一个端口上运行它。并处理下载文件并从那里监控输出缓冲区。您的输出缓冲区将只有一个,您可以控制它:

浏览器 <= 1 => PHP 解释器进程

2)您也可以直接从Apache获取mod_lua和控制输出缓冲区。

3)你也可以使用nginx并使用内置的perl控制nginx输出缓冲区(它是稳定的)

4)尝试使用PHP内置的Web服务器,直接控制PHP输出缓冲区。我不能说它是如何稳定的,对不起。但你可以试试。;)

我认为nginx+php+内置perl是更稳定和强大的解决方案。但是您可以选择并可能使用该列表中没有的其他解决方案。我将关注这个话题,并饶有兴趣地等待您的最终解决方案。

以较短的间隔读取和写入数据库会降低性能。

我建议使用会话(增加循环中发送数据的值),您可以使用它安全地关闭另一个 php 文件,您可以将数据作为 JSON 返回,可供 javascript 函数/插件使用。