summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2013-04-23 10:04:12 +0000
committerMaxim Dounin <mdounin@mdounin.ru>2013-04-23 10:04:12 +0000
commite584341792eab4b3b35277c14c0acd93eee75688 (patch)
treeddad12b209e583d686137d185fb4f50e21d8d84a /src
parent9d4e3c36123d4e796e3c630ee89ca958b5393d9e (diff)
downloadnginx-e584341792eab4b3b35277c14c0acd93eee75688.tar.gz
nginx-e584341792eab4b3b35277c14c0acd93eee75688.tar.bz2
Perl: request body handling fixed.
As of 1.3.9, chunked request body may be available with r->headers_in.content_length_n <= 0. Additionally, request body may be in multiple buffers even if r->request_body_in_single_buf was requested.
Diffstat (limited to 'src')
-rw-r--r--src/http/modules/perl/nginx.xs39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index ed9743911..bbfef079c 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -357,7 +357,7 @@ has_request_body(r, next)
ngx_http_perl_set_request(r);
- if (r->headers_in.content_length_n <= 0) {
+ if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) {
XSRETURN_UNDEF;
}
@@ -386,7 +386,10 @@ request_body(r)
dXSTARG;
ngx_http_request_t *r;
+ u_char *p, *data;
size_t len;
+ ngx_buf_t *buf;
+ ngx_chain_t *cl;
ngx_http_perl_set_request(r);
@@ -397,13 +400,43 @@ request_body(r)
XSRETURN_UNDEF;
}
- len = r->request_body->bufs->buf->last - r->request_body->bufs->buf->pos;
+ cl = r->request_body->bufs;
+ buf = cl->buf;
+
+ if (cl->next == NULL) {
+ len = buf->last - buf->pos;
+ data = buf->pos;
+ goto done;
+ }
+
+ len = buf->last - buf->pos;
+ cl = cl->next;
+
+ for ( /* void */ ; cl; cl = cl->next) {
+ buf = cl->buf;
+ len += buf->last - buf->pos;
+ }
+
+ p = ngx_pnalloc(r->pool, len);
+ if (p == NULL) {
+ return XSRETURN_UNDEF;
+ }
+
+ data = p;
+ cl = r->request_body->bufs;
+
+ for ( /* void */ ; cl; cl = cl->next) {
+ buf = cl->buf;
+ p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
+ }
+
+ done:
if (len == 0) {
XSRETURN_UNDEF;
}
- ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len);
+ ngx_http_perl_set_targ(data, len);
ST(0) = TARG;