简体   繁体   English

使用PHP或swfupload限制每个用户的上传速度

[英]Limit upload speed per user with PHP or swfupload

I have a web application written in PHP and Yii that lets users upload images and videos using swfupload . 我有一个用PHP和Yii编写的Web应用程序,允许用户使用swfupload上传图像和视频。 There are two types of users: premium and regular. 用户有两种类型:高级用户和普通用户。

I want to limit the upload speed for regular users but I cannot find any way that is not global. 我想限制普通用户的上传速度,但是找不到任何非全局的方式。

Can the upload speed be limited per user from PHP, Yii or swfupload? 是否可以限制每个用户从PHP,Yii或swfupload的上传速度?

There is the stream php://input which… 有流php://input

is not available with enctype="multipart/form-data". 不适用于enctype =“ multipart / form-data”。

If you don't have that restriction you could register a stream filter and do some token bucket on it, eg with bandwidth-throttle/bandwidth-throttle 如果没有该限制,则可以注册一个流过滤器并对其进行一些令牌存储,例如,使用bandwidth-throttle/bandwidth-throttle

use bandwidthThrottle\BandwidthThrottle;

$in  = fopen("php://input", "r");
$out = fopen(__DIR__ . "/upload.txt", "w");

$throttle = new BandwidthThrottle();
$throttle->setRate(100, BandwidthThrottle::KIBIBYTES); // Set limit to 100KiB/s
$throttle->throttle($in);

stream_copy_to_stream($in, $out);

Here is a speed limit solution for download. 这是下载的速度限制解决方案。 You can use same for upload. 您可以将其用于上传。 .ieread the file into smaller chunk and then upload each chunk with sleep :) .ieread将文件分成较小的块,然后在睡眠时上传每个块:)

Let's assume we want to limit the bandwidth for images found in /images/ folder. 假设我们想限制在/ images /文件夹中找到的图像的带宽。

First, we need a bandwidth php script, in which we setup the limit of the downloading speed. 首先,我们需要一个带宽php脚本,在其中设置下载速度的限制。 We achieve that by reading small packets from the file requested, with a timeout between readings: 我们通过从请求的文件中读取小包来实现这一目的,并且两次读取之间存在超时:

<?php
//Enter the bandwidth here
$bandwidth = '32'; // KB/s
//For security reason, we will add here all the pattern that we allow for the filename
//Change this to your own needs
$allowed_file_patterns = array('/images\/(\w+)\.(jpg|gif|jpeg|png)/i');

function getMimeType($file_path)
{
    $mtype = '';
    if (function_exists('mime_content_type')){
        $mtype = mime_content_type($file_path);
    }
    elseif (function_exists('finfo_file')){
        $finfo = finfo_open(FILEINFO_MIME);
        $mtype = finfo_file($finfo, $file_path);
        finfo_close($finfo);
    } elseif (function_exists('getimagesize')){
        $finfo = @getimagesize($file_path);
        //var_dump($finfo);
        $mtype = !empty($finfo['mime'])?$finfo['mime']:'';
    }
    if ($mtype == ''){
             $mtype = "application/force-download";
    }
    return $mtype;
}
$accepted_pattern = false;
foreach ($allowed_file_patterns as $pattern){
    if (preg_match($pattern,$_GET['file'])){
        $accepted_pattern = true;
    }
}
if (!$accepted_pattern){
    //Stop the script if is not a valid access
    header("HTTP/1.1 403 Forbidden");
    echo 'Forbidden request';
    exit;

}

$fileName = $_GET['file'];
$fh = @fopen($fileName,'rb');
if (!$fh){
    echo 'Unable to open file';
    exit;
}
$fileSize = filesize($fileName);
header("Content-Type: ".getMimeType($fileName));
header("Content-Length: " . $fileSize);
while(!feof($fh))
{
    //Read the allowed bandwidth, and then just wait a second
    print(fread($fh, $bandwidth*1024));
    usleep(1000000);
}
fclose($fh);
?>

Now, you can create an .htaccess file, to redirect all the requests you need to be limited, to that bandwidth script: 现在,您可以创建一个.htaccess文件,以将需要限制的所有请求重定向到该带宽脚本:

RewriteEngine on
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png|GIF|JPG|JPEG|PNG)$
RewriteRule (.*) bandwidth.php?file=$1 [L]

If you want you can limit the bandwidth only for some ip's or some referals. 如果需要,可以仅对某些IP或某些引荐资源限制带宽。 In the htaccess file you will have: 在htaccess文件中,您将具有:

RewriteEngine on

Enter the ip's or class of ip's you want to limit bellow, with [OR] between them 输入您要限制以下的IP或IP类别,并在它们之间使用[OR]

All the other ip's will access the url directly, without going through bandwidth.php 所有其他ip都将直接访问该url,而无需通过bandwidth.php

RewriteCond %{REMOTE_ADDR} ^123\.45\.6\.78$ [NC,OR]
RewriteCond %{REMOTE_ADDR} ^127\.0\.0 [NC]
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png|GIF|JPG|JPEG|PNG)$
RewriteRule (.*) bandwidth.php?file=$1 [L]

Enter the ip's or class of ip's you want to limit bellow, with [OR] between them 输入您要限制以下的IP或IP类别,并在它们之间使用[OR]

All the other ip's will access the url directly, without going through bandwidth.php 所有其他ip都将直接访问该url,而无需通过bandwidth.php

RewriteCond %{HTTP_REFERER} ^http://(www\.)?php-code.net/.*$ [NC,OR]
RewriteCond %{HTTP_REFERER} ^http://(www\.)?example.com/.*$ [NC]
RewriteCond %{REQUEST_URI} \.(gif|jpg|jpeg|png|GIF|JPG|JPEG|PNG)$
RewriteRule (.*) bandwidth.php?file=$1 [L]

In this way you can limit the traffic from leecher sites, without forbidden them, which I think is a more elegant solution. 这样,您可以限制来自leecher网站的访问量,而不会禁止它们,我认为这是一个更优雅的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM