想拦截POST文件上传,用lua验证http头,如果通过才允许上传

229 views
Skip to first unread message

野马

unread,
May 14, 2012, 8:21:56 AM5/14/12
to openresty
想拦截POST文件上传,用lua验证http头,如果通过才允许上传,试了一下lua-nginx-module无法实现。大家有好的办法吗?

野马

unread,
May 14, 2012, 8:23:34 AM5/14/12
to openresty
不一定是lua,其他任何一种语言或方法都可以,目标是验证HTTP header之前不接收HTTP body

Wendal Chen

unread,
May 14, 2012, 8:24:48 AM5/14/12
to open...@googlegroups.com
能实现啊

用access_by_lua 且不要设置lua_need_body on;


2012/5/14 野马 <yuen...@gmail.com>
想拦截POST文件上传,用lua验证http头,如果通过才允许上传,试了一下lua-nginx-module无法实现。大家有好的办法吗?



--
Wendal Chen
GuangDong China

agentzh

unread,
May 14, 2012, 8:39:21 AM5/14/12
to open...@googlegroups.com
On Mon, May 14, 2012 at 8:21 PM, 野马 <yuen...@gmail.com> wrote:
> 想拦截POST文件上传,用lua验证http头,如果通过才允许上传,试了一下lua-nginx-module无法实现。大家有好的办法吗?
>

location /foo {
access_by_lua '
-- if the value of the request header Some-Header is not
equal to "Blah":
if ngx.var.http_some_header ~= "Blah" then
ngx.exit(413) -- or return ngx.exec("/error_page")
end
';
...
}

Regards,
-agentzh

野马

unread,
May 14, 2012, 8:49:04 AM5/14/12
to openresty
user _www _www;
worker_processes 1;
error_log logs/error.log debug;
events {
worker_connections 10;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /Users/yuenshui/Documents/website/test;
index index.html index.htm;
}
location = /upload.php {
root /Users/yuenshui/Documents/website/test;
access_by_lua '
ngx.exit(406);
';
return 444;
}
}
}
这样配置,拦不住,还是看到浏览器在慢慢上传文件。


On May 14, 8:24 pm, Wendal Chen <wendal1...@gmail.com> wrote:
> 能实现啊
>
> 用access_by_lua 且不要设置lua_need_body on;
>
> 2012/5/14 野马 <yuens...@gmail.com>
>
> > 想拦截POST文件上传,用lua验证http头,如果通过才允许上传,试了一下lua-nginx-module无法实现。大家有好的办法吗?
>
> > --
> > 邮件自: 列表"openresty",专用于技术讨论!
> > 发言: 请发邮件到 open...@googlegroups.com
> > 退订: 请发邮件至 openresty+...@googlegroups.com
> > 详情:http://groups.google.com/group/openresty
> > 官网:http://openresty.org/
> > 仓库:https://github.com/agentzh/ngx_openresty
> > 建议: 提问的智慧http://wiki.woodpecker.org.cn/moin/AskForHelp

agentzh

unread,
May 14, 2012, 9:01:22 AM5/14/12
to open...@googlegroups.com
2012/5/14 野马 <yuen...@gmail.com>:
> user _www _www;
> worker_processes 1;
> error_log logs/error.log debug;
> events {
> worker_connections 10;
> }
> http {
> include mime.types;
> default_type application/octet-stream;
> sendfile on;
> keepalive_timeout 65;
> server {
> listen 80;
> server_name localhost;
> location / {
> root /Users/yuenshui/Documents/website/test;
> index index.html index.htm;
> }
> location = /upload.php {
> root /Users/yuenshui/Documents/website/test;
> access_by_lua '
> ngx.exit(406);
> ';
> return 444;
> }
> }
> }
> 这样配置,拦不住,还是看到浏览器在慢慢上传文件。
>

最简单的做法是直接断开下游连接,即直接在 access_lua 中使用 ngx.exit(444) 或者
ngx.exit(ngx.ERROR) 便是了,不过那样就没有合法响应了 :)

另一种更优雅的做法是使用 ngx.req.discard_body() 随读随丢 :)

-agentzh

野马

unread,
May 14, 2012, 9:04:41 AM5/14/12
to openresty
如果验证失败,需要立即返回错误;如果验证成功,让用户正常上传。


On May 14, 9:01 pm, agentzh <agen...@gmail.com> wrote:
> 2012/5/14 野马 <yuens...@gmail.com>:

agentzh

unread,
May 14, 2012, 9:09:39 AM5/14/12
to open...@googlegroups.com
2012/5/14 野马 <yuen...@gmail.com>:
> 如果验证失败,需要立即返回错误;如果验证成功,让用户正常上传。
>

这里的一个问题是,浏览器的工作方式一般是先发送请求,再处理响应。让浏览器立即停下来的方式便是断开连接 :)

在服务器端,按照 HTTP 协议的要求,只要不是协议层面的错误,就还是应该读取完所有请求数据(当然不一定保存,可以随读随扔),否则 HTTP
1.1 keepalive 和 pipelining 都有问题了。

Regards,
-agentzh

野马

unread,
May 14, 2012, 9:13:51 AM5/14/12
to openresty
应该可以在接收完http header进行校验,来决定是否接受body吧。

On May 14, 9:09 pm, agentzh <agen...@gmail.com> wrote:
> 2012/5/14 野马 <yuens...@gmail.com>:
>

agentzh

unread,
May 14, 2012, 9:18:31 AM5/14/12
to open...@googlegroups.com
2012/5/14 野马 <yuen...@gmail.com>:
> 应该可以在接收完http header进行校验,来决定是否接受body吧。
>

即使 server 端不读取数据,客户端也会不断尝试发送数据(因为客户端会认为网络太差之类。。。)。

我已经说了,阻止客户端继续发请求数据的最有效的方式是断开连接(通过 ngx.exit(444) 或者 ngx.exit(ngx.ERROR))。

除非客户端足够聪明到一边尝试发送请求的同时一边接收和处理响应,并且在看到响应是出错页时自动停止发送数据。不过 HTTP
协议并没有要求这一点(其实也不允许这一点),所以这样聪明的客户端似乎不存在。

希望我已经把这个问题解释清楚了 :)
-agentzh

野马

unread,
May 14, 2012, 9:22:30 AM5/14/12
to openresty
我明白你说的意思。
新浪S3就支持我说的这个校验,应用案例是微盘PC客户端和微盘iOS端。他们上传的时候都有一个签名验证,验证不通过根本不接收文件数据。

On May 14, 9:18 pm, agentzh <agen...@gmail.com> wrote:
> 2012/5/14 野马 <yuens...@gmail.com>:
>

agentzh

unread,
May 14, 2012, 9:25:28 AM5/14/12
to open...@googlegroups.com
2012/5/14 野马 <yuen...@gmail.com>:

> 我明白你说的意思。
> 新浪S3就支持我说的这个校验,应用案例是微盘PC客户端和微盘iOS端。他们上传的时候都有一个签名验证,验证不通过根本不接收文件数据。
>

这里的“不接收”有两种实现方法:

1. 使用 discard body 机制,随读随丢,正确返回错误页;
2. 立即返回错误页,同时断开连接,而不论错误页是否被客户端完整地接收到。

Regards,
-agentzh

野马

unread,
May 14, 2012, 9:45:11 AM5/14/12
to openresty
感谢agentzh,受教了。我联系了一下新浪S3的朋友,他们也没实现http header的验证。

On May 14, 9:25 pm, agentzh <agen...@gmail.com> wrote:
> 2012/5/14 野马 <yuens...@gmail.com>:
>

Simon

unread,
May 14, 2012, 9:55:55 PM5/14/12
to openresty

On May 14, 9:18 pm, agentzh <agen...@gmail.com> wrote:
> 2012/5/14 野马 <yuens...@gmail.com>:
>

> > 应该可以在接收完http header进行校验,来决定是否接受body吧。
>
> 即使 server 端不读取数据,客户端也会不断尝试发送数据(因为客户端会认为网络太差之类。。。)。

我做过实验,nginx可以阻塞住上传请求,等鉴权之后再继续读取body。这个过程中客户端不会继续发送数据过来。

pengqi

unread,
May 14, 2012, 10:18:37 PM5/14/12
to open...@googlegroups.com
如果客户端发 Expect: 100-continue 头,应该是会等到服务器端响应HTTP/1.1 100 Continue才继续发body.  



--
邮件自: 列表“openresty”,专用于技术讨论!
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
详情: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty



--
Jinglong
Software Engineer
Server Platforms Team at Taobao

Matthieu Tourne

unread,
May 14, 2012, 11:17:25 PM5/14/12
to open...@googlegroups.com
Not entirely sure what you are talking about here, but I think I've fixed that on my lua-nginx-module fork :


If google translate was wrong, just ignore what I said :)

Regards,

Matthieu.


2012/5/14 pengqi <feng...@gmail.com>

agentzh

unread,
May 15, 2012, 10:03:13 AM5/15/12
to open...@googlegroups.com
2012/5/15 Matthieu Tourne <matthie...@gmail.com>:
> Not entirely sure what you are talking about here, but I think I've fixed
> that on my lua-nginx-module fork :
>
> https://github.com/mtourne/lua-nginx-module/commit/e0eea5355cc7077bed1415f78f4264d8bb565b6b
>

I've just merged this patch to the mainstream repository:

https://github.com/chaoslawful/lua-nginx-module/commit/754d547

Because the commit cannot be cherry-picked without merging the new
ngx.req.* API, I apply the patch manually :P Sorry about that.

Thanks!
-agentzh

Matthieu Tourne

unread,
May 15, 2012, 12:36:11 PM5/15/12
to open...@googlegroups.com

You should merge the new ngx.req API. Both can live in parallel.
But the new one has better performance for large post and supports Nginx native buffering to disk.
Regards,
Matthieu

野马

unread,
May 15, 2012, 7:44:33 PM5/15/12
to openresty
感谢 agentzh 和 Matthieu 的热情回复。

On May 16, 12:36 am, Matthieu Tourne <matthieu.tou...@gmail.com>
wrote:
> You should merge the new ngx.req API. Both can live in parallel.
> But the new one has better performance for large post and supports Nginx
> native buffering to disk.
> Regards,
> Matthieu
> On May 15, 2012 7:03 AM, "agentzh" <agen...@gmail.com> wrote:
>
>
>
>
>
>
>
> > 2012/5/15 Matthieu Tourne <matthieu.tou...@gmail.com>:
> > > Not entirely sure what you are talking about here, but I think I've fixed
> > > that on my lua-nginx-module fork :
>
> >https://github.com/mtourne/lua-nginx-module/commit/e0eea5355cc7077bed...
>
> > I've just merged this patch to the mainstream repository:
>
> > https://github.com/chaoslawful/lua-nginx-module/commit/754d547
>
> > Because the commit cannot be cherry-picked without merging the new
> > ngx.req.* API, I apply the patch manually :P Sorry about that.
>
> > Thanks!
> > -agentzh
>
> > --
> > 邮件自: 列表"openresty",专用于技术讨论!
> > 发言: 请发邮件到 open...@googlegroups.com
> > 退订: 请发邮件至 openresty+...@googlegroups.com
> > 详情:http://groups.google.com/group/openresty
> > 官网:http://openresty.org/
> > 仓库:https://github.com/agentzh/ngx_openresty

agentzh

unread,
May 15, 2012, 9:11:45 PM5/15/12
to open...@googlegroups.com
On Wed, May 16, 2012 at 12:36 AM, Matthieu Tourne
<matthie...@gmail.com> wrote:
> You should merge the new ngx.req API. Both can live in parallel.
> But the new one has better performance for large post and supports Nginx
> native buffering to disk.

I'll surely merge your new ngx.req API, but I can only work serially
(and possibly slowly, sorry) and bugfixes always have a higher
priority ;)

Thanks!
-agentzh

Matthieu Tourne

unread,
May 15, 2012, 9:13:47 PM5/15/12
to open...@googlegroups.com
感谢 agentzh :) 
Matthieu
Reply all
Reply to author
Forward
0 new messages