nginx文件上传限速
·
https://github.com/cfsego/limit_upload_rate 这个模块,通过修改nginx核心源码,可以支持设置文件上传限速
首先下载 nginx-1.2.6 稳定版本
解压后目录结构如下
在局域网环境下我发现如果 文件在60s内没有上传完毕,服务器会丢弃此连接,需要配置client_body_timeout为一个更大的值
默认值是60s。(nginx官方手册对这个参数的介绍如下)
“Defines a timeout for reading client request body. A timeout is only set between two successive read operations, not for the transmission of the whole request body. If a client does not transmit anything within this time, the client error 408 (Request Time-out) is returned.”
大概看了一下这个模块对限速的实现,通过对连接的write事件添加定时器,降低服务器的数据处理能力(其实这时客户端已经把全部数据发送给服务端了的),间接影响read事件就会超时。或者做下面的处理,每次延迟write事件的时候重置read事件的超时( 添加下面注释的三行即可)
首先下载 nginx-1.2.6 稳定版本
解压后目录结构如下
$ ls
for-nginx.patch
nginx
— addon
— limit_upload_rate
— src
— ...
执行 patch -p0 < for-nginx.patch将补丁替换源代码
./configure --without-http_gzip_module --add-module=./addon/limit_upload_rate-master
make
配置nginx.conf
location ~ .*\.php$ {
limit_upload_rate 500k;
limit_upload_rate_after 1m;
fastcgi_index index.php;
fastcgi_pass unix:/usr/local/ciaos/php_fcgi.socket;
include /usr/local/ciaos/fastcgi.conf;
}
测试文件upload.html
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<body>
<form enctype="multipart/form-data" action="up.php" method="POST">
<!-- Name of input element determines name in $_FILES array -->
Send file: <input name="Filedata" id="Filedata" type="file" />
<input name="submit" type="submit" value="Send File" />
</form>
</body>
</html>
上传处理up.php
<?php
// Define a destination
$targetFolder = '/files'; // Relative to the root
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
$targetFile = rtrim($targetPath,'/') . '/' . $_FILES['Filedata']['name'];
if (file_exists($tempFile)) {
move_uploaded_file($tempFile,$targetFile);
//move_uploaded_file($tempFile,$targetFile);
echo 'Upload succeed';
} else {
echo 'Invalid file type.';
}
}
?>
记得修改files目录的权限为777,最后可以用chrome浏览器测试了,文件上传达到限速效果。
在局域网环境下我发现如果 文件在60s内没有上传完毕,服务器会丢弃此连接,需要配置client_body_timeout为一个更大的值
默认值是60s。(nginx官方手册对这个参数的介绍如下)
“Defines a timeout for reading client request body. A timeout is only set between two successive read operations, not for the transmission of the whole request body. If a client does not transmit anything within this time, the client error 408 (Request Time-out) is returned.”
大概看了一下这个模块对限速的实现,通过对连接的write事件添加定时器,降低服务器的数据处理能力(其实这时客户端已经把全部数据发送给服务端了的),间接影响read事件就会超时。或者做下面的处理,每次延迟write事件的时候重置read事件的超时( 添加下面注释的三行即可)
ngx_http_limit_upload_input_body_filter(ngx_http_request_t *r, ngx_buf_t *buf)
{
off_t excess;
ngx_int_t rc;
ngx_msec_t delay;
ngx_http_limit_upload_ctx_t *ctx;
ngx_http_limit_upload_conf_t *llcf;
// add line below
// ngx_http_core_loc_conf_t *clcf;
rc = ngx_http_next_input_body_filter(r, buf);
if (rc != NGX_OK) {
return rc;
}
ctx = ngx_http_get_module_ctx(r, ngx_http_limit_upload_module);
llcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_upload_module);
if (ctx->limit_rate == 0) {
ctx->limit_rate = llcf->limit_rate;
}
if (ctx->limit_rate) {
ctx->received += ngx_buf_size(buf);
excess = ctx->received - llcf->limit_rate_after
- ctx->limit_rate * (ngx_time() - r->start_sec + 1);
ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"limit upload: ctx=%p, received=%O, "
"excess=%O, limit_rate=%z, period=%M",
ctx, ctx->received, excess, ctx->limit_rate,
ngx_time() - r->start_sec + 1);
if (excess > 0) {
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
delay = excess * 1000 / ctx->limit_rate;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"limit upload: delay=%M", delay);
ctx->read_event_handler = r->read_event_handler;
ctx->write_event_handler = r->write_event_handler;
r->read_event_handler = ngx_http_test_reading;
r->write_event_handler = ngx_http_limit_req_delay;
ngx_add_timer(r->connection->write, delay);
// add two lines below
// clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
// ngx_add_timer(r->connection->read, clcf->client_body_timeout);
return NGX_AGAIN;
}
}
return NGX_OK;
}
此外还有一个文件上传模块可做参考;
nginx_upload_module更多推荐
已为社区贡献2条内容
所有评论(0)