comparison src/http/modules/perl/nginx.xs @ 5181:4d0ac175f6e4

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.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 23 Apr 2013 10:04:12 +0000
parents 95763fce86a8
children e530b88b088b
comparison
equal deleted inserted replaced
5180:2db6bdcaedc0 5181:4d0ac175f6e4
355 ngx_http_request_t *r; 355 ngx_http_request_t *r;
356 ngx_http_perl_ctx_t *ctx; 356 ngx_http_perl_ctx_t *ctx;
357 357
358 ngx_http_perl_set_request(r); 358 ngx_http_perl_set_request(r);
359 359
360 if (r->headers_in.content_length_n <= 0) { 360 if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) {
361 XSRETURN_UNDEF; 361 XSRETURN_UNDEF;
362 } 362 }
363 363
364 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); 364 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
365 ctx->next = SvRV(ST(1)); 365 ctx->next = SvRV(ST(1));
384 request_body(r) 384 request_body(r)
385 CODE: 385 CODE:
386 386
387 dXSTARG; 387 dXSTARG;
388 ngx_http_request_t *r; 388 ngx_http_request_t *r;
389 u_char *p, *data;
389 size_t len; 390 size_t len;
391 ngx_buf_t *buf;
392 ngx_chain_t *cl;
390 393
391 ngx_http_perl_set_request(r); 394 ngx_http_perl_set_request(r);
392 395
393 if (r->request_body == NULL 396 if (r->request_body == NULL
394 || r->request_body->temp_file 397 || r->request_body->temp_file
395 || r->request_body->bufs == NULL) 398 || r->request_body->bufs == NULL)
396 { 399 {
397 XSRETURN_UNDEF; 400 XSRETURN_UNDEF;
398 } 401 }
399 402
400 len = r->request_body->bufs->buf->last - r->request_body->bufs->buf->pos; 403 cl = r->request_body->bufs;
404 buf = cl->buf;
405
406 if (cl->next == NULL) {
407 len = buf->last - buf->pos;
408 data = buf->pos;
409 goto done;
410 }
411
412 len = buf->last - buf->pos;
413 cl = cl->next;
414
415 for ( /* void */ ; cl; cl = cl->next) {
416 buf = cl->buf;
417 len += buf->last - buf->pos;
418 }
419
420 p = ngx_pnalloc(r->pool, len);
421 if (p == NULL) {
422 return XSRETURN_UNDEF;
423 }
424
425 data = p;
426 cl = r->request_body->bufs;
427
428 for ( /* void */ ; cl; cl = cl->next) {
429 buf = cl->buf;
430 p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
431 }
432
433 done:
401 434
402 if (len == 0) { 435 if (len == 0) {
403 XSRETURN_UNDEF; 436 XSRETURN_UNDEF;
404 } 437 }
405 438
406 ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len); 439 ngx_http_perl_set_targ(data, len);
407 440
408 ST(0) = TARG; 441 ST(0) = TARG;
409 442
410 443
411 void 444 void