0

我有一个用 PHP 和 Yii 编写的 Web 应用程序,它允许用户使用swfupload上传图像和视频。有两种类型的用户:高级用户和普通用户。

我想限制普通用户的上传速度,但我找不到任何非全球性的方式。

PHP、Yii 或 swfupload 是否可以限制每个用户的上传速度?

4

2 回答 2

0

有溪流php://input……</p>

不适用于 enctype="multipart/form-data"。

如果你没有这个限制,你可以注册一个流过滤器并在上面做一些令牌桶,例如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);
于 2015-08-08T22:31:36.860 回答
-1

这是下载的限速解决方案。您可以使用相同的上传。.ie 将文件读入较小的块,然后使用 sleep 上传每个块 :)

假设我们要限制在 /images/ 文件夹中找到的图像的带宽。

首先,我们需要一个带宽 php 脚本,我们在其中设置下载速度的限制。我们通过从请求的文件中读取小数据包来实现这一点,读取之间有一个超时:

<?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);
?>

现在,您可以创建一个 .htaccess 文件,将您需要限制的所有请求重定向到该带宽脚本:

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

如果您愿意,您可以仅限制某些 ip 或某些引用的带宽。在 htaccess 文件中,您将拥有:

RewriteEngine on

在下面输入要限制的 ip 或 ip 类别,在它们之间用 [OR]

所有其他 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]

在下面输入要限制的 ip 或 ip 类别,在它们之间用 [OR]

所有其他 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]

通过这种方式,您可以限制来自 leecher 站点的流量,而不会禁止它们,我认为这是一个更优雅的解决方案。

于 2012-09-06T12:13:31.323 回答