Mercurial > hg > nginx-vendor-current
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) |