summaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
Diffstat (limited to 'src/http')
-rw-r--r--src/http/modules/ngx_http_range_filter_module.c13
-rw-r--r--src/http/ngx_http_core_module.c4
-rw-r--r--src/http/ngx_http_parse.c12
-rw-r--r--src/http/ngx_http_request.c5
-rw-r--r--src/http/ngx_http_spdy.c52
5 files changed, 77 insertions, 9 deletions
diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c
index 6a65e4849..bb9a42c54 100644
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -274,7 +274,7 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
ngx_uint_t ranges)
{
u_char *p;
- off_t start, end, size, content_length;
+ off_t start, end, size, content_length, cutoff, cutlim;
ngx_uint_t suffix;
ngx_http_range_t *range;
@@ -282,6 +282,9 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
size = 0;
content_length = r->headers_out.content_length_n;
+ cutoff = NGX_MAX_OFF_T_VALUE / 10;
+ cutlim = NGX_MAX_OFF_T_VALUE % 10;
+
for ( ;; ) {
start = 0;
end = 0;
@@ -295,6 +298,10 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
}
while (*p >= '0' && *p <= '9') {
+ if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) {
+ return NGX_HTTP_RANGE_NOT_SATISFIABLE;
+ }
+
start = start * 10 + *p++ - '0';
}
@@ -321,6 +328,10 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
}
while (*p >= '0' && *p <= '9') {
+ if (end >= cutoff && (end > cutoff || *p - '0' > cutlim)) {
+ return NGX_HTTP_RANGE_NOT_SATISFIABLE;
+ }
+
end = end * 10 + *p++ - '0';
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 4484a5ed4..1bcd1045c 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1935,6 +1935,10 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
ngx_int_t
ngx_http_send_header(ngx_http_request_t *r)
{
+ if (r->post_action) {
+ return NGX_OK;
+ }
+
if (r->header_sent) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"header already sent");
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 02b4a0fd1..8d38a1920 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -2104,6 +2104,10 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
goto invalid;
case sw_chunk_size:
+ if (ctx->size > NGX_MAX_OFF_T_VALUE / 16) {
+ goto invalid;
+ }
+
if (ch >= '0' && ch <= '9') {
ctx->size = ctx->size * 16 + (ch - '0');
break;
@@ -2253,6 +2257,10 @@ data:
ctx->state = state;
b->pos = pos;
+ if (ctx->size > NGX_MAX_OFF_T_VALUE - 5) {
+ goto invalid;
+ }
+
switch (state) {
case sw_chunk_start:
@@ -2289,10 +2297,6 @@ data:
}
- if (ctx->size < 0 || ctx->length < 0) {
- goto invalid;
- }
-
return rc;
done:
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 845ada322..560c5f512 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1227,12 +1227,11 @@ ngx_http_process_request_headers(ngx_event_t *rev)
if (len > NGX_MAX_ERROR_STR - 300) {
len = NGX_MAX_ERROR_STR - 300;
- p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
}
ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent too long header line: \"%*s\"",
- len, r->header_name_start);
+ "client sent too long header line: \"%*s...\"",
+ len, r->header_name_start);
ngx_http_finalize_request(r,
NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c
index 9bd624c82..bd6d73d82 100644
--- a/src/http/ngx_http_spdy.c
+++ b/src/http/ngx_http_spdy.c
@@ -3156,8 +3156,10 @@ ngx_http_spdy_close_stream_handler(ngx_event_t *ev)
void
ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
{
+ int tcp_nodelay;
ngx_event_t *ev;
- ngx_connection_t *fc;
+ ngx_connection_t *c, *fc;
+ ngx_http_core_loc_conf_t *clcf;
ngx_http_spdy_stream_t **index, *s;
ngx_http_spdy_srv_conf_t *sscf;
ngx_http_spdy_connection_t *sc;
@@ -3183,6 +3185,54 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
{
sc->connection->error = 1;
}
+
+ } else {
+ c = sc->connection;
+
+ if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
+ if (ngx_tcp_push(c->fd) == -1) {
+ ngx_connection_error(c, ngx_socket_errno,
+ ngx_tcp_push_n " failed");
+ c->error = 1;
+ tcp_nodelay = 0;
+
+ } else {
+ c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
+ tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
+ }
+
+ } else {
+ tcp_nodelay = 1;
+ }
+
+ clcf = ngx_http_get_module_loc_conf(stream->request,
+ ngx_http_core_module);
+
+ if (tcp_nodelay
+ && clcf->tcp_nodelay
+ && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
+ {
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+ (const void *) &tcp_nodelay, sizeof(int))
+ == -1)
+ {
+#if (NGX_SOLARIS)
+ /* Solaris returns EINVAL if a socket has been shut down */
+ c->log_error = NGX_ERROR_IGNORE_EINVAL;
+#endif
+
+ ngx_connection_error(c, ngx_socket_errno,
+ "setsockopt(TCP_NODELAY) failed");
+
+ c->log_error = NGX_ERROR_INFO;
+ c->error = 1;
+
+ } else {
+ c->tcp_nodelay = NGX_TCP_NODELAY_SET;
+ }
+ }
}
if (sc->stream == stream) {