aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event/ngx_event_pipe.c28
-rw-r--r--src/http/modules/ngx_http_scgi_module.c36
-rw-r--r--src/http/modules/ngx_http_uwsgi_module.c36
-rw-r--r--src/http/ngx_http_upstream.c19
-rw-r--r--src/http/ngx_http_upstream.h2
5 files changed, 116 insertions, 5 deletions
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 531b13aad..54412e130 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -960,6 +960,22 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
return NGX_OK;
}
+ if (p->upstream_done) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "input data after close");
+ return NGX_OK;
+ }
+
+ if (p->length == 0) {
+ p->upstream_done = 1;
+
+ ngx_log_error(NGX_LOG_WARN, p->log, 0,
+ "upstream sent more data than specified in "
+ "\"Content-Length\" header");
+
+ return NGX_OK;
+ }
+
cl = ngx_chain_get_free_buf(p->pool, &p->free);
if (cl == NULL) {
return NGX_ERROR;
@@ -987,6 +1003,18 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
return NGX_OK;
}
+ if (b->last - b->pos > p->length) {
+
+ ngx_log_error(NGX_LOG_WARN, p->log, 0,
+ "upstream sent more data than specified in "
+ "\"Content-Length\" header");
+
+ b->last = b->pos + p->length;
+ p->upstream_done = 1;
+
+ return NGX_OK;
+ }
+
p->length -= b->last - b->pos;
return NGX_OK;
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 7216f781d..600999c88 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -49,6 +49,7 @@ static ngx_int_t ngx_http_scgi_create_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_scgi_reinit_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_scgi_process_status_line(ngx_http_request_t *r);
static ngx_int_t ngx_http_scgi_process_header(ngx_http_request_t *r);
+static ngx_int_t ngx_http_scgi_input_filter_init(void *data);
static void ngx_http_scgi_abort_request(ngx_http_request_t *r);
static void ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
@@ -534,6 +535,10 @@ ngx_http_scgi_handler(ngx_http_request_t *r)
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
u->pipe->input_ctx = r;
+ u->input_filter_init = ngx_http_scgi_input_filter_init;
+ u->input_filter = ngx_http_upstream_non_buffered_filter;
+ u->input_filter_ctx = r;
+
if (!scf->upstream.request_buffering
&& scf->upstream.pass_request_body
&& !r->headers_in.chunked)
@@ -1145,6 +1150,37 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
}
+static ngx_int_t
+ngx_http_scgi_input_filter_init(void *data)
+{
+ ngx_http_request_t *r = data;
+ ngx_http_upstream_t *u;
+
+ u = r->upstream;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http scgi filter init s:%ui l:%O",
+ u->headers_in.status_n, u->headers_in.content_length_n);
+
+ if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
+ || u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
+ {
+ u->pipe->length = 0;
+ u->length = 0;
+
+ } else if (r->method == NGX_HTTP_HEAD) {
+ u->pipe->length = -1;
+ u->length = -1;
+
+ } else {
+ u->pipe->length = u->headers_in.content_length_n;
+ u->length = u->headers_in.content_length_n;
+ }
+
+ return NGX_OK;
+}
+
+
static void
ngx_http_scgi_abort_request(ngx_http_request_t *r)
{
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index bfc8b1d78..fe15ee80d 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -67,6 +67,7 @@ static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
+static ngx_int_t ngx_http_uwsgi_input_filter_init(void *data);
static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
ngx_int_t rc);
@@ -703,6 +704,10 @@ ngx_http_uwsgi_handler(ngx_http_request_t *r)
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
u->pipe->input_ctx = r;
+ u->input_filter_init = ngx_http_uwsgi_input_filter_init;
+ u->input_filter = ngx_http_upstream_non_buffered_filter;
+ u->input_filter_ctx = r;
+
if (!uwcf->upstream.request_buffering
&& uwcf->upstream.pass_request_body
&& !r->headers_in.chunked)
@@ -1356,6 +1361,37 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
}
+static ngx_int_t
+ngx_http_uwsgi_input_filter_init(void *data)
+{
+ ngx_http_request_t *r = data;
+ ngx_http_upstream_t *u;
+
+ u = r->upstream;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http uwsgi filter init s:%ui l:%O",
+ u->headers_in.status_n, u->headers_in.content_length_n);
+
+ if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
+ || u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
+ {
+ u->pipe->length = 0;
+ u->length = 0;
+
+ } else if (r->method == NGX_HTTP_HEAD) {
+ u->pipe->length = -1;
+ u->length = -1;
+
+ } else {
+ u->pipe->length = u->headers_in.content_length_n;
+ u->length = u->headers_in.content_length_n;
+ }
+
+ return NGX_OK;
+}
+
+
static void
ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
{
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index be96be47a..354370c5a 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -77,9 +77,6 @@ static void
static void
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
ngx_uint_t do_write);
-static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
-static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
- ssize_t bytes);
#if (NGX_THREADS)
static ngx_int_t ngx_http_upstream_thread_handler(ngx_thread_task_t *task,
ngx_file_t *file);
@@ -3705,14 +3702,14 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
}
-static ngx_int_t
+ngx_int_t
ngx_http_upstream_non_buffered_filter_init(void *data)
{
return NGX_OK;
}
-static ngx_int_t
+ngx_int_t
ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
{
ngx_http_request_t *r = data;
@@ -3748,6 +3745,18 @@ ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
return NGX_OK;
}
+ if (bytes > u->length) {
+
+ ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
+ "upstream sent more data than specified in "
+ "\"Content-Length\" header");
+
+ cl->buf->last = cl->buf->pos + u->length;
+ u->length = 0;
+
+ return NGX_OK;
+ }
+
u->length -= bytes;
return NGX_OK;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index 6079d7236..2c93a324b 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -414,6 +414,8 @@ typedef struct {
ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
void ngx_http_upstream_init(ngx_http_request_t *r);
+ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
+ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes);
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
ngx_url_t *u, ngx_uint_t flags);
char *ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,