Mercurial > hg > nginx-vendor-0-7
annotate src/http/modules/ngx_http_chunked_filter_module.c @ 508:68c0ae0a4959 NGINX_0_7_66
nginx 0.7.66
*) Security: now nginx/Windows ignores default file stream name.
Thanks to Jose Antonio Vazquez Gonzalez.
*) Change: now the charset filter runs before the SSI filter.
*) Change: now no message is written in an error log if a variable is
not found by $r->variable() method.
*) Change: now keepalive connections after POST requests are not
disabled for MSIE 7.0+.
Thanks to Adam Lounds.
*) Feature: the "proxy_no_cache" and "fastcgi_no_cache" directives.
*) Feature: now the "rewrite" directive does a redirect automatically
if the $scheme variable is used.
Thanks to Piotr Sikora.
*) Feature: the "chunked_transfer_encoding" directive.
*) Feature: the $geoip_city_continent_code, $geoip_latitude, and
$geoip_longitude variables.
Thanks to Arvind Sundararajan.
*) Feature: now the ngx_http_image_filter_module deletes always EXIF
and other application specific data if the data consume more than 5%
of a JPEG file.
*) Feature: now the "msie_padding" directive works for Chrome too.
*) Workaround: now keepalive connections are disabled for Safari.
Thanks to Joshua Sierles.
*) Bugfix: nginx ignored the "private" and "no-store" values in the
"Cache-Control" backend response header line.
*) Bugfix: an "&" character was not escaped when it was copied in
arguments part in a rewrite rule.
*) Bugfix: nginx might be terminated abnormally while a signal
processing or if the directive "timer_resolution" was used on
platforms which do not support kqueue or eventport notification
methods.
Thanks to George Xie and Maxim Dounin.
*) Bugfix: if temporary files and permanent storage area resided at
different file systems, then permanent file modification times were
incorrect.
Thanks to Maxim Dounin.
*) Bugfix: ngx_http_memcached_module might issue the error message
"memcached sent invalid trailer".
Thanks to Maxim Dounin.
*) Bugfix: nginx could not built zlib-1.2.4 library using the library
sources.
Thanks to Maxim Dounin.
*) Bugfix: values of the $query_string, $arg_..., etc. variables cached
in main request were used by the SSI module in subrequests.
*) Bugfix: nginx did not support HTTPS referrers.
*) Bugfix: nginx/Windows might not find file if path in configuration
was given in other character case; the bug had appeared in 0.7.65.
*) Bugfix: the $date_local variable has an incorrect value, if the "%s"
format was used.
Thanks to Maxim Dounin.
*) Bugfix: nginx did not support all ciphers and digests used in client
certificates.
Thanks to Innocenty Enikeew.
*) Bugfix: if ssl_session_cache was not set or was set to "none", then
during client certificate verify the error "session id context
uninitialized" might occur; the bug had appeared in 0.7.1.
*) Bugfix: OpenSSL-1.0.0 compatibility on 64-bit Linux.
Thanks to Maxim Dounin.
*) Bugfix: a geo range returned default value if the range included two
or more /16 networks and did not begin at /16 network boundary.
*) Bugfix: the $uid_got variable might not be used in the SSI and perl
modules.
*) Bugfix: a worker process hung if a FIFO file was requested.
Thanks to Vicente Aguilar and Maxim Dounin.
*) Bugfix: a variable value was repeatedly encoded after each an "echo"
SSI-command output; the bug had appeared in 0.6.14.
*) Bugfix: a "stub" parameter of an "include" SSI directive was not
used, if empty response has 200 status code.
*) Bugfix: a block used in a "stub" parameter of an "include" SSI
directive was output with "text/plain" MIME type.
*) Bugfix: if a proxied or FastCGI request was internally redirected to
another proxied or FastCGI location, then a segmentation fault might
occur in a worker process; the bug had appeared in 0.7.65.
Thanks to Yichun Zhang.
*) Bugfix: IMAP connections may hang until they timed out while talking
to Zimbra server.
Thanks to Alan Batie.
*) Bugfix: nginx did not support chunked transfer encoding for 201
responses.
Thanks to Julian Reich.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 07 Jun 2010 00:00:00 +0400 |
parents | b246022ef454 |
children |
rev | line source |
---|---|
50 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
230 | 12 static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); |
50 | 13 |
14 | |
15 static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { | |
58 | 16 NULL, /* preconfiguration */ |
230 | 17 ngx_http_chunked_filter_init, /* postconfiguration */ |
50 | 18 |
19 NULL, /* create main configuration */ | |
20 NULL, /* init main configuration */ | |
21 | |
22 NULL, /* create server configuration */ | |
23 NULL, /* merge server configuration */ | |
24 | |
25 NULL, /* create location configuration */ | |
178 | 26 NULL /* merge location configuration */ |
50 | 27 }; |
28 | |
29 | |
30 ngx_module_t ngx_http_chunked_filter_module = { | |
58 | 31 NGX_MODULE_V1, |
50 | 32 &ngx_http_chunked_filter_module_ctx, /* module context */ |
33 NULL, /* module directives */ | |
34 NGX_HTTP_MODULE, /* module type */ | |
90 | 35 NULL, /* init master */ |
230 | 36 NULL, /* init module */ |
90 | 37 NULL, /* init process */ |
38 NULL, /* init thread */ | |
39 NULL, /* exit thread */ | |
40 NULL, /* exit process */ | |
41 NULL, /* exit master */ | |
42 NGX_MODULE_V1_PADDING | |
50 | 43 }; |
44 | |
45 | |
46 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
47 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
48 | |
49 | |
50 static ngx_int_t | |
51 ngx_http_chunked_header_filter(ngx_http_request_t *r) | |
52 { | |
508 | 53 ngx_http_core_loc_conf_t *clcf; |
54 | |
164 | 55 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED |
56 || r->headers_out.status == NGX_HTTP_NO_CONTENT | |
412 | 57 || r != r->main |
58 || (r->method & NGX_HTTP_HEAD)) | |
164 | 59 { |
50 | 60 return ngx_http_next_header_filter(r); |
61 } | |
62 | |
63 if (r->headers_out.content_length_n == -1) { | |
64 if (r->http_version < NGX_HTTP_VERSION_11) { | |
65 r->keepalive = 0; | |
66 | |
67 } else { | |
508 | 68 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
69 | |
70 if (clcf->chunked_transfer_encoding) { | |
71 r->chunked = 1; | |
72 | |
73 } else { | |
74 r->keepalive = 0; | |
75 } | |
50 | 76 } |
77 } | |
78 | |
79 return ngx_http_next_header_filter(r); | |
80 } | |
81 | |
82 | |
83 static ngx_int_t | |
84 ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
85 { | |
86 u_char *chunk; | |
87 off_t size; | |
88 ngx_buf_t *b; | |
89 ngx_chain_t out, tail, *cl, *tl, **ll; | |
90 | |
91 if (in == NULL || !r->chunked || r->header_only) { | |
92 return ngx_http_next_body_filter(r, in); | |
93 } | |
94 | |
95 out.buf = NULL; | |
96 ll = &out.next; | |
97 | |
98 size = 0; | |
99 cl = in; | |
100 | |
101 for ( ;; ) { | |
102 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
103 "http chunk: %d", ngx_buf_size(cl->buf)); | |
104 | |
105 size += ngx_buf_size(cl->buf); | |
106 | |
216 | 107 if (cl->buf->flush |
108 || cl->buf->sync | |
109 || ngx_buf_in_memory(cl->buf) | |
110 || cl->buf->in_file) | |
111 { | |
50 | 112 tl = ngx_alloc_chain_link(r->pool); |
113 if (tl == NULL) { | |
114 return NGX_ERROR; | |
115 } | |
116 | |
117 tl->buf = cl->buf; | |
118 *ll = tl; | |
119 ll = &tl->next; | |
120 } | |
121 | |
122 if (cl->next == NULL) { | |
123 break; | |
124 } | |
125 | |
126 cl = cl->next; | |
127 } | |
128 | |
129 if (size) { | |
130 b = ngx_calloc_buf(r->pool); | |
131 if (b == NULL) { | |
132 return NGX_ERROR; | |
133 } | |
134 | |
135 /* the "0000000000000000" is 64-bit hexadimal string */ | |
136 | |
137 chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1); | |
138 if (chunk == NULL) { | |
139 return NGX_ERROR; | |
140 } | |
141 | |
142 b->temporary = 1; | |
143 b->pos = chunk; | |
144 b->last = ngx_sprintf(chunk, "%xO" CRLF, size); | |
145 | |
146 out.buf = b; | |
147 } | |
148 | |
149 if (cl->buf->last_buf) { | |
150 b = ngx_calloc_buf(r->pool); | |
151 if (b == NULL) { | |
152 return NGX_ERROR; | |
153 } | |
154 | |
155 b->memory = 1; | |
156 b->last_buf = 1; | |
157 b->pos = (u_char *) CRLF "0" CRLF CRLF; | |
158 b->last = b->pos + 7; | |
159 | |
160 cl->buf->last_buf = 0; | |
161 | |
162 if (size == 0) { | |
163 b->pos += 2; | |
164 out.buf = b; | |
165 out.next = NULL; | |
166 | |
167 return ngx_http_next_body_filter(r, &out); | |
168 } | |
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; | |
179 } | |
180 | |
181 b->memory = 1; | |
182 b->pos = (u_char *) CRLF; | |
183 b->last = b->pos + 2; | |
184 } | |
185 | |
186 tail.buf = b; | |
187 tail.next = NULL; | |
188 *ll = &tail; | |
189 | |
190 return ngx_http_next_body_filter(r, &out); | |
191 } | |
192 | |
193 | |
194 static ngx_int_t | |
230 | 195 ngx_http_chunked_filter_init(ngx_conf_t *cf) |
50 | 196 { |
197 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
198 ngx_http_top_header_filter = ngx_http_chunked_header_filter; | |
199 | |
200 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
201 ngx_http_top_body_filter = ngx_http_chunked_body_filter; | |
202 | |
203 return NGX_OK; | |
204 } |