diff options
author | Valentin Bartenev <vbart@nginx.com> | 2018-07-05 16:43:45 +0300 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2018-07-05 16:43:45 +0300 |
commit | 7e3de003c7e6078be822b64c40042cb4385210fd (patch) | |
tree | af9fcbc3d4ca640ddc10b81b8f6ac987eaac691c /src/nxt_php_sapi.c | |
parent | 234deb51f48b43a5fb080d16746838f355b725b4 (diff) | |
download | unit-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 'src/nxt_php_sapi.c')
-rw-r--r-- | src/nxt_php_sapi.c | 39 |
1 files changed, 37 insertions, 2 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; } |