我需要允许下载文件,但必须跟踪每个用户下载文件的次数。
我在这里有一个简单的代码块,它允许用户下载一个文件,然后回调在完成后为该用户增加数据存储中的计数器。
如果用户未使用下载管理器,则此操作效果良好。但是如果它们是(即: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);