comparison src/http/modules/ngx_http_chunked_filter_module.c @ 640:eb208e0cf44d NGINX_1_1_4

nginx 1.1.4 *) Feature: the ngx_http_upstream_keepalive module. *) Feature: the "proxy_http_version" directive. *) Feature: the "fastcgi_keep_conn" directive. *) Feature: the "worker_aio_requests" directive. *) Bugfix: if nginx was built --with-file-aio it could not be run on Linux kernel which did not support AIO. *) Bugfix: in Linux AIO error processing. Thanks to Hagai Avrahami. *) Bugfix: reduced memory consumption for long-lived requests. *) Bugfix: the module ngx_http_mp4_module did not support 64-bit MP4 "co64" atom.
author Igor Sysoev <http://sysoev.ru>
date Tue, 20 Sep 2011 00:00:00 +0400
parents be4f34123024
children d0f7a625f27c
comparison
equal deleted inserted replaced
639:b516b4e38bc9 640:eb208e0cf44d
5 5
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10
11
12 typedef struct {
13 ngx_chain_t *free;
14 ngx_chain_t *busy;
15 } ngx_http_chunked_filter_ctx_t;
10 16
11 17
12 static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); 18 static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf);
13 19
14 20
48 54
49 55
50 static ngx_int_t 56 static ngx_int_t
51 ngx_http_chunked_header_filter(ngx_http_request_t *r) 57 ngx_http_chunked_header_filter(ngx_http_request_t *r)
52 { 58 {
53 ngx_http_core_loc_conf_t *clcf; 59 ngx_http_core_loc_conf_t *clcf;
60 ngx_http_chunked_filter_ctx_t *ctx;
54 61
55 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED 62 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
56 || r->headers_out.status == NGX_HTTP_NO_CONTENT 63 || r->headers_out.status == NGX_HTTP_NO_CONTENT
57 || r != r->main 64 || r != r->main
58 || (r->method & NGX_HTTP_HEAD)) 65 || (r->method & NGX_HTTP_HEAD))
68 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 75 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
69 76
70 if (clcf->chunked_transfer_encoding) { 77 if (clcf->chunked_transfer_encoding) {
71 r->chunked = 1; 78 r->chunked = 1;
72 79
80 ctx = ngx_pcalloc(r->pool,
81 sizeof(ngx_http_chunked_filter_ctx_t));
82 if (ctx == NULL) {
83 return NGX_ERROR;
84 }
85
86 ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module);
87
73 } else { 88 } else {
74 r->keepalive = 0; 89 r->keepalive = 0;
75 } 90 }
76 } 91 }
77 } 92 }
81 96
82 97
83 static ngx_int_t 98 static ngx_int_t
84 ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in) 99 ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
85 { 100 {
86 u_char *chunk; 101 u_char *chunk;
87 off_t size; 102 off_t size;
88 ngx_buf_t *b; 103 ngx_int_t rc;
89 ngx_chain_t out, tail, *cl, *tl, **ll; 104 ngx_buf_t *b;
105 ngx_chain_t *out, *cl, *tl, **ll;
106 ngx_http_chunked_filter_ctx_t *ctx;
90 107
91 if (in == NULL || !r->chunked || r->header_only) { 108 if (in == NULL || !r->chunked || r->header_only) {
92 return ngx_http_next_body_filter(r, in); 109 return ngx_http_next_body_filter(r, in);
93 } 110 }
94 111
95 out.buf = NULL; 112 ctx = ngx_http_get_module_ctx(r, ngx_http_chunked_filter_module);
96 ll = &out.next; 113
114 out = NULL;
115 ll = &out;
97 116
98 size = 0; 117 size = 0;
99 cl = in; 118 cl = in;
100 119
101 for ( ;; ) { 120 for ( ;; ) {
125 144
126 cl = cl->next; 145 cl = cl->next;
127 } 146 }
128 147
129 if (size) { 148 if (size) {
130 b = ngx_calloc_buf(r->pool); 149 tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
131 if (b == NULL) { 150 if (tl == NULL) {
132 return NGX_ERROR; 151 return NGX_ERROR;
133 } 152 }
134 153
135 /* the "0000000000000000" is 64-bit hexadimal string */ 154 b = tl->buf;
136 155 chunk = b->start;
137 chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1); 156
138 if (chunk == NULL) { 157 if (chunk == NULL) {
139 return NGX_ERROR; 158 /* the "0000000000000000" is 64-bit hexadecimal string */
140 } 159
141 160 chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1);
161 if (chunk == NULL) {
162 return NGX_ERROR;
163 }
164
165 b->start = chunk;
166 b->end = chunk + sizeof("0000000000000000" CRLF) - 1;
167 }
168
169 b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
170 b->memory = 0;
142 b->temporary = 1; 171 b->temporary = 1;
143 b->pos = chunk; 172 b->pos = chunk;
144 b->last = ngx_sprintf(chunk, "%xO" CRLF, size); 173 b->last = ngx_sprintf(chunk, "%xO" CRLF, size);
145 174
146 out.buf = b; 175 tl->next = out;
176 out = tl;
147 } 177 }
148 178
149 if (cl->buf->last_buf) { 179 if (cl->buf->last_buf) {
150 b = ngx_calloc_buf(r->pool); 180 tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
151 if (b == NULL) { 181 if (tl == NULL) {
152 return NGX_ERROR; 182 return NGX_ERROR;
153 } 183 }
154 184
185 b = tl->buf;
186
187 b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
188 b->temporary = 0;
155 b->memory = 1; 189 b->memory = 1;
156 b->last_buf = 1; 190 b->last_buf = 1;
157 b->pos = (u_char *) CRLF "0" CRLF CRLF; 191 b->pos = (u_char *) CRLF "0" CRLF CRLF;
158 b->last = b->pos + 7; 192 b->last = b->pos + 7;
159 193
160 cl->buf->last_buf = 0; 194 cl->buf->last_buf = 0;
161 195
196 *ll = tl;
197
162 if (size == 0) { 198 if (size == 0) {
163 b->pos += 2; 199 b->pos += 2;
164 out.buf = b; 200 }
165 out.next = NULL; 201
166 202 } else if (size > 0) {
167 return ngx_http_next_body_filter(r, &out); 203 tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
168 } 204 if (tl == NULL) {
169
170 } else {
171 if (size == 0) {
172 *ll = NULL;
173 return ngx_http_next_body_filter(r, out.next);
174 }
175
176 b = ngx_calloc_buf(r->pool);
177 if (b == NULL) {
178 return NGX_ERROR; 205 return NGX_ERROR;
179 } 206 }
180 207
208 b = tl->buf;
209
210 b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
211 b->temporary = 0;
181 b->memory = 1; 212 b->memory = 1;
182 b->pos = (u_char *) CRLF; 213 b->pos = (u_char *) CRLF;
183 b->last = b->pos + 2; 214 b->last = b->pos + 2;
184 } 215
185 216 *ll = tl;
186 tail.buf = b; 217
187 tail.next = NULL; 218 } else {
188 *ll = &tail; 219 *ll = NULL;
189 220 }
190 return ngx_http_next_body_filter(r, &out); 221
222 rc = ngx_http_next_body_filter(r, out);
223
224 ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &out,
225 (ngx_buf_tag_t) &ngx_http_chunked_filter_module);
226
227 return rc;
191 } 228 }
192 229
193 230
194 static ngx_int_t 231 static ngx_int_t
195 ngx_http_chunked_filter_init(ngx_conf_t *cf) 232 ngx_http_chunked_filter_init(ngx_conf_t *cf)