summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2014-01-14 16:24:45 +0400
committerValentin Bartenev <vbart@nginx.com>2014-01-14 16:24:45 +0400
commitac8bb7a9e5bfbf466f165702053ab847f9815e12 (patch)
tree1ca64e1c54238de01b5faeb3e4370ce1ffb9c9e6 /src
parent6ddb578b2223f5a4b4fb7f555be8115a946471d0 (diff)
downloadnginx-ac8bb7a9e5bfbf466f165702053ab847f9815e12.tar.gz
nginx-ac8bb7a9e5bfbf466f165702053ab847f9815e12.tar.bz2
SPDY: elimination of r->blocked counter usage for queuing frames.
It was used to prevent destroying of request object when there are unsent frames in queue for the stream. Since it was incremented for each frame and is only 8 bits long, so it was not very hard to overflow the counter. Now the stream->queued counter is checked instead.
Diffstat (limited to 'src')
-rw-r--r--src/http/ngx_http_spdy.c16
-rw-r--r--src/http/ngx_http_spdy_filter_module.c10
2 files changed, 10 insertions, 16 deletions
diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c
index f68b82ff4..e57619654 100644
--- a/src/http/ngx_http_spdy.c
+++ b/src/http/ngx_http_spdy.c
@@ -2642,9 +2642,16 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
sc = stream->connection;
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy close stream %ui, processing %ui",
- stream->id, sc->processing);
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
+ "spdy close stream %ui, queued %ui, processing %ui",
+ stream->id, stream->queued, sc->processing);
+
+ fc = stream->request->connection;
+
+ if (stream->queued) {
+ fc->write->handler = ngx_http_spdy_close_stream_handler;
+ return;
+ }
if (!stream->out_closed) {
if (ngx_http_spdy_send_rst_stream(sc, stream->id,
@@ -2685,8 +2692,6 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
index = &s->index;
}
- fc = stream->request->connection;
-
ngx_http_free_request(stream->request, rc);
ev = fc->read;
@@ -2862,7 +2867,6 @@ ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
fc->error = 1;
if (stream->queued) {
- r->blocked -= stream->queued;
stream->queued = 0;
ev = fc->write;
diff --git a/src/http/ngx_http_spdy_filter_module.c b/src/http/ngx_http_spdy_filter_module.c
index 23067407e..b3e41c177 100644
--- a/src/http/ngx_http_spdy_filter_module.c
+++ b/src/http/ngx_http_spdy_filter_module.c
@@ -597,8 +597,6 @@ ngx_http_spdy_header_filter(ngx_http_request_t *r)
ngx_http_spdy_queue_blocked_frame(sc, frame);
- r->blocked++;
-
cln = ngx_http_cleanup_add(r, 0);
if (cln == NULL) {
return NGX_ERROR;
@@ -697,8 +695,6 @@ ngx_http_spdy_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
stream->queued++;
- r->main->blocked++;
-
return ngx_http_spdy_filter_send(r->connection, stream);
}
@@ -923,7 +919,6 @@ ngx_http_spdy_handle_frame(ngx_http_spdy_stream_t *stream,
r = stream->request;
r->connection->sent += frame->size;
- r->blocked--;
if (frame->fin) {
stream->out_closed = 1;
@@ -962,15 +957,12 @@ ngx_http_spdy_filter_cleanup(void *data)
{
ngx_http_spdy_stream_t *stream = data;
- ngx_http_request_t *r;
ngx_http_spdy_out_frame_t *frame, **fn;
if (stream->queued == 0) {
return;
}
- r = stream->request;
-
fn = &stream->connection->last_out;
for ( ;; ) {
@@ -981,9 +973,7 @@ ngx_http_spdy_filter_cleanup(void *data)
}
if (frame->stream == stream && !frame->blocked) {
-
stream->queued--;
- r->blocked--;
*fn = frame->next;
continue;