【问题标题】:Nginx: how to view what files are in downloading state?Nginx:如何查看处于下载状态的文件?
【发布时间】:2025-12-17 18:45:02
【问题描述】:

我还在等待答案。

我需要查看此时是否有人正在下载特定文件。最初的问题:我想知道何时有人中断下载文件。

服务器配置:

server 
{

    listen 80;
    server_name mysite.com;

    location /ugp/
    {
        alias /www/ugp/;
    }
    break;
}

用户可以从http://mysite.com/ugp/ 下载文件,例如http://mysite.com/ugp/1.mp3

更新

如何分析access.log 并不那么明显。有些浏览器在用户停止下载时会发送 206 代码(谷歌浏览器),有些则不会(HTC 播放器、移动应用程序):

85.145.8.243 - - [18/Jan/2013:16:08:41 +0300] "GET /ugp/6.mp3 HTTP/1.1" 200 10292776 "-" "HTC Streaming Player htc_wwe / 1.0 / htc_ace / 2.3.5"
85.145.8.243 - - [18/Jan/2013:16:08:41 +0300] "GET /ugp/2.mp3 HTTP/1.1" 200 697216 "-" "HTC Streaming Player htc_wwe / 1.0 / htc_ace / 2.3.5"
85.145.8.243 - - [18/Jan/2013:16:09:44 +0300] "GET /ugp/7.mp3 HTTP/1.1" 200 4587605 "-" "HTC Streaming Player htc_wwe / 1.0 / htc_ace / 2.3.5"

【问题讨论】:

  • 一个/var/log/nginx/mysite-access.log分析(最后一行tail -1 file)不是你想要的?
  • @ring0 如何分析访问日志并不明显。请查看我的更新。

标签: linux web-services web-applications nginx


【解决方案1】:

为了提供更大的灵活性,您可以添加一个 PHP 服务器,并发布类似的 URL

  http://mysite.com/download.php?file=2.mp3

download.php 从其位置(例如/var/www/files/2.mp3)读取文件,并带有建议的代码。 (Headers)

<?php

  // Here you know precisely that a download is requested

  $path = '/home/var/www/files';
  $file = "$path/" . $_GET['file']; // check user input!
  $size = filesize($file);
  $read = 0;

  $state = 'downloading ' . $file;

  // echo headers for a binary file download 

  @ $f = fopen ($file, 'r');
  if ( $f ) {
    // Output 100 bytes in each iteration
    while (($chunk = fread($f, 100)) !== false) {
      // specify somewhere $state, still downloading
      echo $chunk;
      $read += strlen($chunk);
    }
    fclose ($f);
  }
  if ($read >= $size) 
    $state = 'done';
  else
    $state = 'fail';
?>

这是一个提供算法的例子——没有测试过!但是应该离下载代码很近(通常使用readfile,但它会一次性读取文件)

【讨论】:

  • 有很多关于如何在 Linux 上安装 nginx+php-fpm 的文献,例如 this,因为 PHP 文件需要特殊的识别模式并在 nginx 中进行处理。
  • 谢谢。我们使用什么编程语言并不重要,不是吗?我了解您的 PHP 代码。
  • PHP 更容易实现和编程。当然,它也适用于 Java、Perl 甚至 C...
  • 我不明白(在您的代码中)为什么我们希望 fread 在用户中断下载时返回 false?音频文件在服务器上,只有在到达文件末尾时,该函数才返回 false。
  • 已编辑以指定如何检测故障。在 fread 页面中,当连接发生超时时,有一种情况会返回 false。该循环允许知道下载开始,然后仍在进行中,大小检查以检测异常。不幸的是,对于小文件,可能无法检测到超时(PHP 脚本将在检测到连接问题/中断之前缓冲整个输出)。除非您使用 java appletflash 脚本(两者的实现都比较复杂),否则这可能是您能得到的最多的。
【解决方案2】:

看看nginxextended status module

【讨论】:

  • 对不起,我不知道如何使用该模块。我找不到文档。能给我参考一下吗?