增加下载量,支持下载管理器


Increment download w/ support for download manager

我需要允许下载文件,但必须跟踪每个用户下载文件的次数。

我在这里有一个简单的代码块,它允许用户下载一个文件,然后回调在完成后为该用户增加数据存储中的计数器。

如果用户未使用下载管理器,则此操作效果良好。但是如果它们是(即:DownThemAll),那么管理器会发出多个HTTP请求,每次都会调用回调。这会增加下载次数,使其不可靠。我曾尝试通过观察会话变量来缩短多个请求——理论上,这会将多个请求减少到一个。但DownThemAll似乎没有在请求之间共享同一会话,因此它不起作用。

有没有办法做到这一点?

    return 'Response::stream(function() use ($stream, $file, $callback) {
        while (!feof($stream)) {
            echo fread($stream, 1024);
        }
        fclose($stream);
        Log::info('Resource downloaded', ['resource' => $file]);
        if (is_callable($callback)) {
            call_user_func($callback);
        }
    }, 200, $headers);

您可以尝试一个代币系统,只根据消耗的代币增加下载量。

有一个控制器方法,它生成一个令牌来下载文件。此令牌生成是增加下载计数器的内容。接下来,使用一个方法来接收令牌,将其标记为已消耗(因此此令牌不会发生其他请求/增量),然后启动传输。您可以在传输之前或文件末尾标记令牌,但如果在传输之前标记,则下载管理器将无权下载资源。

下载系统的此请求令牌还有助于防止直接链接到资源。

如果你想要一个带计数器的开放下载系统,那么我建议记录所有带有标头和浏览器信息的http请求,然后在分配的窗口中按ip/header将多个http请求分组为一个计数。HTTP_USER_AGENT和REMOTE_ADDR/HTTP_X_REAL_IP可能是团购所需的全部内容,但我不确定。

我能够通过根据下载的大小监控处理程序的位置来实现这一点。看来这是可行的。

        return 'Response::stream(function() use ($stream, $size, $file, $callback) {
            while (!feof($stream)) {
                echo fread($stream, 1024);
            }   
            //  Only log downloaded and increment counter when the EOF
            //  of the stream is ACTUALLY reached. This continues to allow
            //  individual downloads to work, but also allows download
            //  managers to send concurrent requests and only increment
            //  when the whole file is sent.
            if (ftell($stream) == $size) {
                Log::info('Resource downloaded', ['resource' => $file]);
                if (is_callable($callback)) {
                    call_user_func($callback);
                }
            }
            fclose($stream);
        }, 200, $headers);