[nginx] SPDY: body filter was replaced by c->send_chain() function.
Valentin Bartenev
vbart at nginx.com
Tue Jan 14 12:58:06 UTC 2014
details: http://hg.nginx.org/nginx/rev/311803b21504
branches:
changeset: 5513:311803b21504
user: Valentin Bartenev <vbart at nginx.com>
date: Tue Jan 14 16:24:45 2014 +0400
description:
SPDY: body filter was replaced by c->send_chain() function.
It allows to use ngx_http_write_filter() and all its rate limiting logic.
diffstat:
src/core/ngx_connection.h | 3 +
src/http/ngx_http_spdy_filter_module.c | 90 ++++++++++++--------------------
src/http/ngx_http_write_filter_module.c | 5 +-
3 files changed, 42 insertions(+), 56 deletions(-)
diffs (232 lines):
diff -r 9fffc0c46e5c -r 311803b21504 src/core/ngx_connection.h
--- a/src/core/ngx_connection.h Tue Jan 14 16:24:45 2014 +0400
+++ b/src/core/ngx_connection.h Tue Jan 14 16:24:45 2014 +0400
@@ -112,6 +112,7 @@ typedef enum {
#define NGX_LOWLEVEL_BUFFERED 0x0f
#define NGX_SSL_BUFFERED 0x01
+#define NGX_SPDY_BUFFERED 0x02
struct ngx_connection_s {
@@ -171,6 +172,8 @@ struct ngx_connection_s {
unsigned tcp_nodelay:2; /* ngx_connection_tcp_nodelay_e */
unsigned tcp_nopush:2; /* ngx_connection_tcp_nopush_e */
+ unsigned need_last_buf:1;
+
#if (NGX_HAVE_IOCP)
unsigned accept_context_updated:1;
#endif
diff -r 9fffc0c46e5c -r 311803b21504 src/http/ngx_http_spdy_filter_module.c
--- a/src/http/ngx_http_spdy_filter_module.c Tue Jan 14 16:24:45 2014 +0400
+++ b/src/http/ngx_http_spdy_filter_module.c Tue Jan 14 16:24:45 2014 +0400
@@ -14,8 +14,6 @@
#include <zlib.h>
-#define NGX_SPDY_WRITE_BUFFERED NGX_HTTP_WRITE_BUFFERED
-
#define ngx_http_spdy_nv_nsize(h) (NGX_SPDY_NV_NLEN_SIZE + sizeof(h) - 1)
#define ngx_http_spdy_nv_vsize(h) (NGX_SPDY_NV_VLEN_SIZE + sizeof(h) - 1)
@@ -29,6 +27,10 @@
#define ngx_http_spdy_nv_write_val(p, h) \
ngx_cpymem(ngx_http_spdy_nv_write_vlen(p, sizeof(h) - 1), h, sizeof(h) - 1)
+
+static ngx_chain_t *ngx_http_spdy_send_chain(ngx_connection_t *fc,
+ ngx_chain_t *in, off_t limit);
+
static ngx_inline ngx_int_t ngx_http_spdy_filter_send(
ngx_connection_t *fc, ngx_http_spdy_stream_t *stream);
@@ -82,7 +84,6 @@ ngx_module_t ngx_http_spdy_filter_modul
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
@@ -607,41 +608,35 @@ ngx_http_spdy_header_filter(ngx_http_req
stream->queued = 1;
+ c->send_chain = ngx_http_spdy_send_chain;
+ c->need_last_buf = 1;
+
return ngx_http_spdy_filter_send(c, stream);
}
-static ngx_int_t
-ngx_http_spdy_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
+static ngx_chain_t *
+ngx_http_spdy_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit)
{
off_t size;
ngx_buf_t *b;
ngx_chain_t *cl, *out, **ln;
- ngx_connection_t *fc;
+ ngx_http_request_t *r;
ngx_http_spdy_stream_t *stream;
ngx_http_spdy_out_frame_t *frame;
+ r = fc->data;
stream = r->spdy_stream;
- if (stream == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- fc = r->connection;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, fc->log, 0,
- "spdy body filter \"%V?%V\"", &r->uri, &r->args);
-
- if (in == NULL || r->header_only) {
+ if (in == NULL) {
if (stream->queued) {
fc->write->delayed = 1;
- return NGX_AGAIN;
+ } else {
+ fc->buffered &= ~NGX_SPDY_BUFFERED;
}
- fc->buffered &= ~NGX_SPDY_WRITE_BUFFERED;
-
- return NGX_OK;
+ return NULL;
}
size = 0;
@@ -649,28 +644,10 @@ ngx_http_spdy_body_filter(ngx_http_reque
do {
b = in->buf;
-#if 1
- if (ngx_buf_size(b) == 0 && !ngx_buf_special(b)) {
- ngx_log_error(NGX_LOG_ALERT, fc->log, 0,
- "zero size buf in spdy body filter "
- "t:%d r:%d f:%d %p %p-%p %p %O-%O",
- b->temporary,
- b->recycled,
- b->in_file,
- b->start,
- b->pos,
- b->last,
- b->file,
- b->file_pos,
- b->file_last);
- ngx_debug_point();
- return NGX_ERROR;
- }
-#endif
cl = ngx_alloc_chain_link(r->pool);
if (cl == NULL) {
- return NGX_ERROR;
+ return NGX_CHAIN_ERROR;
}
size += ngx_buf_size(b);
@@ -686,20 +663,24 @@ ngx_http_spdy_body_filter(ngx_http_reque
if (size > NGX_SPDY_MAX_FRAME_SIZE) {
ngx_log_error(NGX_LOG_ALERT, fc->log, 0,
"FIXME: chain too big in spdy filter: %O", size);
- return NGX_ERROR;
+ return NGX_CHAIN_ERROR;
}
frame = ngx_http_spdy_filter_get_data_frame(stream, (size_t) size,
out, cl);
if (frame == NULL) {
- return NGX_ERROR;
+ return NGX_CHAIN_ERROR;
}
ngx_http_spdy_queue_frame(stream->connection, frame);
stream->queued++;
- return ngx_http_spdy_filter_send(fc, stream);
+ if (ngx_http_spdy_filter_send(fc, stream) == NGX_ERROR) {
+ return NGX_CHAIN_ERROR;
+ }
+
+ return NULL;
}
@@ -801,12 +782,12 @@ ngx_http_spdy_filter_send(ngx_connection
stream->blocked = 0;
if (stream->queued) {
- fc->buffered |= NGX_SPDY_WRITE_BUFFERED;
+ fc->buffered |= NGX_SPDY_BUFFERED;
fc->write->delayed = 1;
return NGX_AGAIN;
}
- fc->buffered &= ~NGX_SPDY_WRITE_BUFFERED;
+ fc->buffered &= ~NGX_SPDY_BUFFERED;
return NGX_OK;
}
@@ -939,20 +920,22 @@ static ngx_inline void
ngx_http_spdy_handle_stream(ngx_http_spdy_connection_t *sc,
ngx_http_spdy_stream_t *stream)
{
- ngx_connection_t *fc;
-
- fc = stream->request->connection;
-
- fc->write->delayed = 0;
+ ngx_event_t *wev;
if (stream->handled || stream->blocked) {
return;
}
- stream->handled = 1;
+ wev = stream->request->connection->write;
- stream->next = sc->last_stream;
- sc->last_stream = stream;
+ if (!wev->timer_set) {
+ wev->delayed = 0;
+
+ stream->handled = 1;
+
+ stream->next = sc->last_stream;
+ sc->last_stream = stream;
+ }
}
@@ -994,8 +977,5 @@ ngx_http_spdy_filter_init(ngx_conf_t *cf
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_spdy_header_filter;
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_spdy_body_filter;
-
return NGX_OK;
}
diff -r 9fffc0c46e5c -r 311803b21504 src/http/ngx_http_write_filter_module.c
--- a/src/http/ngx_http_write_filter_module.c Tue Jan 14 16:24:45 2014 +0400
+++ b/src/http/ngx_http_write_filter_module.c Tue Jan 14 16:24:45 2014 +0400
@@ -184,7 +184,10 @@ ngx_http_write_filter(ngx_http_request_t
return NGX_AGAIN;
}
- if (size == 0 && !(c->buffered & NGX_LOWLEVEL_BUFFERED)) {
+ if (size == 0
+ && !(c->buffered & NGX_LOWLEVEL_BUFFERED)
+ && !(last && c->need_last_buf))
+ {
if (last || flush) {
for (cl = r->out; cl; /* void */) {
ln = cl;
More information about the nginx-devel
mailing list