summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2018-07-05 16:43:45 +0300
committerValentin Bartenev <vbart@nginx.com>2018-07-05 16:43:45 +0300
commit7e3de003c7e6078be822b64c40042cb4385210fd (patch)
treeaf9fcbc3d4ca640ddc10b81b8f6ac987eaac691c /src
parent234deb51f48b43a5fb080d16746838f355b725b4 (diff)
downloadunit-7e3de003c7e6078be822b64c40042cb4385210fd.tar.gz
unit-7e3de003c7e6078be822b64c40042cb4385210fd.tar.bz2
PHP: fixed request body processing.
The implementation of module was based on the assumption that PHP reads request body and headers in the particular order. For the POST request the body goes before headers and vice versa for all other requests. But as it appeared later, this order is unspecified and depends on many factors, including the particular code of PHP application. Among other factors those can affect ordering: - presence of "Content-Type" header; - "variables_order" php.ini setting; - "enable_post_data_reading" php.ini setting; - reading php://input by application; and this list can be incomplete. As a temporary workaround, request body now is always put before headers and it is gracefully skipped whenever PHP wants to get headers. This closes #144 issue on GitHub.
Diffstat (limited to '')
-rw-r--r--src/nxt_php_sapi.c39
-rw-r--r--src/nxt_router.c22
2 files changed, 40 insertions, 21 deletions
diff --git a/src/nxt_php_sapi.c b/src/nxt_php_sapi.c
index db643ed2..7065bb3f 100644
--- a/src/nxt_php_sapi.c
+++ b/src/nxt_php_sapi.c
@@ -799,10 +799,13 @@ static void
nxt_php_register_variables(zval *track_vars_array TSRMLS_DC)
{
u_char *colon;
+ size_t rest, size;
nxt_str_t n, v;
nxt_int_t rc;
nxt_str_t host, server_name, server_port;
+ nxt_buf_t *b, buf;
nxt_task_t *task;
+ nxt_app_rmsg_t *rmsg, rmsg_tmp;
nxt_php_run_ctx_t *ctx;
nxt_app_request_header_t *h;
@@ -904,12 +907,44 @@ nxt_php_register_variables(zval *track_vars_array TSRMLS_DC)
NXT_PHP_SET("REMOTE_ADDR", ctx->r.remote);
NXT_PHP_SET("SERVER_ADDR", ctx->r.local);
- while (nxt_app_msg_read_str(task, ctx->rmsg, &n) == NXT_OK) {
+ rmsg = ctx->rmsg;
+ rest = ctx->body_preread_size;
+
+ if (rest != 0) {
+ /* Skipping request body. */
+
+ b = rmsg->buf;
+
+ do {
+ if (nxt_slow_path(b == NULL)) {
+ return;
+ }
+
+ size = nxt_buf_mem_used_size(&b->mem);
+
+ if (rest < size) {
+ nxt_memcpy(&buf, b, NXT_BUF_MEM_SIZE);
+ buf.mem.pos += rest;
+ b = &buf;
+ break;
+ }
+
+ rest -= size;
+ b = b->next;
+
+ } while (rest != 0);
+
+ rmsg_tmp = *rmsg;
+ rmsg_tmp.buf = b;
+ rmsg = &rmsg_tmp;
+ }
+
+ while (nxt_app_msg_read_str(task, rmsg, &n) == NXT_OK) {
if (nxt_slow_path(n.length == 0)) {
break;
}
- rc = nxt_app_msg_read_str(task, ctx->rmsg, &v);
+ rc = nxt_app_msg_read_str(task, rmsg, &v);
if (nxt_slow_path(rc != NXT_OK)) {
break;
}
diff --git a/src/nxt_router.c b/src/nxt_router.c
index 162e7073..1b4c1596 100644
--- a/src/nxt_router.c
+++ b/src/nxt_router.c
@@ -4375,7 +4375,6 @@ nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
{
nxt_int_t rc;
nxt_buf_t *b;
- nxt_bool_t method_is_post;
nxt_http_field_t *field;
nxt_app_request_header_t *h;
@@ -4432,17 +4431,9 @@ nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
RC(nxt_app_msg_write_size(task, wmsg, h->parsed_content_length));
RC(nxt_app_msg_write_size(task, wmsg, r->body.preread_size));
- method_is_post = h->method.length == 4
- && h->method.start[0] == 'P'
- && h->method.start[1] == 'O'
- && h->method.start[2] == 'S'
- && h->method.start[3] == 'T';
-
- if (method_is_post) {
- for (b = r->body.buf; b != NULL; b = b->next) {
- RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
- nxt_buf_mem_used_size(&b->mem)));
- }
+ for (b = r->body.buf; b != NULL; b = b->next) {
+ RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
+ nxt_buf_mem_used_size(&b->mem)));
}
nxt_list_each(field, h->fields) {
@@ -4455,13 +4446,6 @@ nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
/* end-of-headers mark */
NXT_WRITE(&eof);
- if (!method_is_post) {
- for (b = r->body.buf; b != NULL; b = b->next) {
- RC(nxt_app_msg_write_raw(task, wmsg, b->mem.pos,
- nxt_buf_mem_used_size(&b->mem)));
- }
- }
-
#undef NXT_WRITE
#undef RC