Мне нужно разрешить загрузку файлов, но я должен отслеживать, сколько раз они были загружены каждым пользователем.
У меня есть простой кусок кода, который позволяет пользователям загружать файл, а затем обратный вызов увеличивает счетчик в хранилище данных для этого пользователя, когда это будет сделано.
Это прекрасно работает, если пользователь НЕ использует менеджер загрузок. Но если они (то есть: 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-запросы с заголовком и информацией о браузере, а затем группировать несколько http-запросов в выделенном окне по ip / header как один счетчик. 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);