Mercurial > hg > nginx
comparison src/http/ngx_http_header_filter.c @ 164:84036764e215
nginx-0.0.1-2003-10-29-11:30:44 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 29 Oct 2003 08:30:44 +0000 |
parents | 46eb23d9471d |
children | 894a01c6aea3 |
comparison
equal
deleted
inserted
replaced
163:fb61ba77beba | 164:84036764e215 |
---|---|
100 | 100 |
101 if (r->method == NGX_HTTP_HEAD) { | 101 if (r->method == NGX_HTTP_HEAD) { |
102 r->header_only = 1; | 102 r->header_only = 1; |
103 } | 103 } |
104 | 104 |
105 /* 9 is for "HTTP/1.x ", 2 is for trailing "\r\n" | 105 /* 2 is for trailing "\r\n" and 2 is for "\r\n" in the end of header */ |
106 and 2 is for end of header */ | 106 len = sizeof("HTTP/1.x ") - 1 + 2 + 2; |
107 len = 9 + 2 + 2; | |
108 | 107 |
109 /* status line */ | 108 /* status line */ |
110 if (r->headers_out.status_line.len) { | 109 if (r->headers_out.status_line.len) { |
111 len += r->headers_out.status_line.len; | 110 len += r->headers_out.status_line.len; |
112 #if (NGX_SUPPRESS_WARN) | 111 #if (NGX_SUPPRESS_WARN) |
148 | 147 |
149 if (r->headers_out.date && r->headers_out.date->key.len) { | 148 if (r->headers_out.date && r->headers_out.date->key.len) { |
150 len += r->headers_out.date->key.len | 149 len += r->headers_out.date->key.len |
151 + r->headers_out.date->value.len + 2; | 150 + r->headers_out.date->value.len + 2; |
152 } else { | 151 } else { |
153 /* "Date: ... \r\n" */ | 152 len += sizeof("Date: Mon, 28 Sep 1970 00:00:00 GMT" CRLF) - 1; |
154 len += 37; | |
155 } | 153 } |
156 | 154 |
157 if (r->headers_out.content_range && r->headers_out.content_range->value.len) | 155 if (r->headers_out.content_range && r->headers_out.content_range->value.len) |
158 { | 156 { |
159 len += 15 + r->headers_out.content_range->value.len + 2; | 157 len += sizeof("Content-Range: ") - 1 |
158 + r->headers_out.content_range->value.len + 2; | |
160 } | 159 } |
161 | 160 |
162 if (r->headers_out.content_length == NULL) { | 161 if (r->headers_out.content_length == NULL) { |
163 if (r->headers_out.content_length_n >= 0) { | 162 if (r->headers_out.content_length_n >= 0) { |
164 /* "Content-Length: ... \r\n", 2^64 is 20 characters */ | 163 /* 2^64 */ |
165 len += 48; | 164 len += sizeof("Content-Length: 18446744073709551616" CRLF) - 1; |
166 } | 165 } |
167 } | 166 } |
168 | 167 |
169 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { | 168 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { |
170 r->headers_out.content_type->key.len = 0; | 169 r->headers_out.content_type->key.len = 0; |
171 len += 14 + r->headers_out.content_type->value.len + 2; | 170 len += sizeof("Content-Type: ") - 1 |
171 + r->headers_out.content_type->value.len + 2; | |
172 | 172 |
173 if (r->headers_out.charset.len) { | 173 if (r->headers_out.charset.len) { |
174 /* "; charset= ... " */ | 174 len += sizeof("; charset=") - 1 + r->headers_out.charset.len; |
175 len += 10 + r->headers_out.charset.len; | |
176 } | 175 } |
177 } | 176 } |
178 | 177 |
179 if (r->headers_out.content_encoding | 178 if (r->headers_out.content_encoding |
180 && r->headers_out.content_encoding->value.len) | 179 && r->headers_out.content_encoding->value.len) |
185 if (r->headers_out.location | 184 if (r->headers_out.location |
186 && r->headers_out.location->value.len | 185 && r->headers_out.location->value.len |
187 && r->headers_out.location->value.data[0] == '/') | 186 && r->headers_out.location->value.data[0] == '/') |
188 { | 187 { |
189 r->headers_out.location->key.len = 0; | 188 r->headers_out.location->key.len = 0; |
190 /* "Location: http:// ... \r\n" */ | 189 len += sizeof("Location: http://") - 1, |
191 len += 17 + r->server_name->len | 190 + r->server_name->len + r->headers_out.location->value.len + 2; |
192 + r->headers_out.location->value.len + 2; | |
193 | 191 |
194 if (r->port != 80) { | 192 if (r->port != 80) { |
195 len += r->port_name->len; | 193 len += r->port_name->len; |
196 } | 194 } |
197 } | 195 } |
199 if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) { | 197 if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) { |
200 len += r->headers_out.last_modified->key.len | 198 len += r->headers_out.last_modified->key.len |
201 + r->headers_out.last_modified->value.len + 2; | 199 + r->headers_out.last_modified->value.len + 2; |
202 | 200 |
203 } else if (r->headers_out.last_modified_time != -1) { | 201 } else if (r->headers_out.last_modified_time != -1) { |
204 /* "Last-Modified: ... \r\n" */ | 202 len += sizeof("Last-Modified: Mon, 28 Sep 1970 00:00:00 GMT" CRLF) - 1; |
205 len += 46; | |
206 } | 203 } |
207 | 204 |
208 if (r->chunked) { | 205 if (r->chunked) { |
209 /* "Transfer-Encoding: chunked\r\n" */ | 206 len += sizeof("Transfer-Encoding: chunked" CRLF) - 1; |
210 len += 28; | |
211 } | 207 } |
212 | 208 |
213 if (r->keepalive) { | 209 if (r->keepalive) { |
214 /* "Connection: keep-alive\r\n" */ | 210 len += sizeof("Connection: keep-alive" CRLF) - 1; |
215 len += 24; | 211 } else { |
216 } else { | 212 len += sizeof("Connection: closed" CRLF) - 1; |
217 /* "Connection: close\r\n" */ | 213 } |
218 len += 19; | 214 |
219 } | 215 header = r->headers_out.headers->elts; |
220 | |
221 header = (ngx_table_elt_t *) r->headers_out.headers->elts; | |
222 for (i = 0; i < r->headers_out.headers->nelts; i++) { | 216 for (i = 0; i < r->headers_out.headers->nelts; i++) { |
223 if (header[i].key.len == 0) { | 217 if (header[i].key.len == 0) { |
224 continue; | 218 continue; |
225 } | 219 } |
226 | 220 |
228 } | 222 } |
229 | 223 |
230 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR); | 224 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR); |
231 | 225 |
232 /* "HTTP/1.x " */ | 226 /* "HTTP/1.x " */ |
233 h->last = ngx_cpymem(h->last, "HTTP/1.1 ", 9); | 227 h->last = ngx_cpymem(h->last, "HTTP/1.1 ", sizeof("HTTP/1.x ") - 1); |
234 | 228 |
235 /* status line */ | 229 /* status line */ |
236 if (r->headers_out.status_line.len) { | 230 if (r->headers_out.status_line.len) { |
237 h->last = ngx_cpymem(h->last, r->headers_out.status_line.data, | 231 h->last = ngx_cpymem(h->last, r->headers_out.status_line.data, |
238 r->headers_out.status_line.len); | 232 r->headers_out.status_line.len); |
246 if (!(r->headers_out.server && r->headers_out.server->key.len)) { | 240 if (!(r->headers_out.server && r->headers_out.server->key.len)) { |
247 h->last = ngx_cpymem(h->last, server_string, sizeof(server_string) - 1); | 241 h->last = ngx_cpymem(h->last, server_string, sizeof(server_string) - 1); |
248 } | 242 } |
249 | 243 |
250 if (!(r->headers_out.date && r->headers_out.date->key.len)) { | 244 if (!(r->headers_out.date && r->headers_out.date->key.len)) { |
251 h->last = ngx_cpymem(h->last, "Date: ", 6); | 245 h->last = ngx_cpymem(h->last, "Date: ", sizeof("Date: ") - 1); |
252 h->last += ngx_http_get_time(h->last, time(NULL)); | 246 h->last += ngx_http_get_time(h->last, time(NULL)); |
253 *(h->last++) = CR; *(h->last++) = LF; | 247 *(h->last++) = CR; *(h->last++) = LF; |
254 } | 248 } |
255 | 249 |
256 | 250 |
257 if (r->headers_out.content_range && r->headers_out.content_range->value.len) | 251 if (r->headers_out.content_range && r->headers_out.content_range->value.len) |
258 { | 252 { |
259 h->last = ngx_cpymem(h->last, "Content-Range: ", 15); | 253 h->last = ngx_cpymem(h->last, "Content-Range: ", |
254 sizeof("Content-Range: ") - 1); | |
260 h->last = ngx_cpymem(h->last, r->headers_out.content_range->value.data, | 255 h->last = ngx_cpymem(h->last, r->headers_out.content_range->value.data, |
261 r->headers_out.content_range->value.len); | 256 r->headers_out.content_range->value.len); |
262 *(h->last++) = CR; *(h->last++) = LF; | 257 *(h->last++) = CR; *(h->last++) = LF; |
263 } | 258 } |
264 | 259 |
265 if (r->headers_out.content_length == NULL) { | 260 if (r->headers_out.content_length == NULL) { |
266 /* 2^64 is 20 characters */ | 261 /* 2^64 is 20 characters */ |
267 if (r->headers_out.content_length_n >= 0) { | 262 if (r->headers_out.content_length_n >= 0) { |
268 h->last += ngx_snprintf(h->last, 49, | 263 h->last += ngx_snprintf(h->last, |
269 "Content-Length: " OFF_FMT CRLF, | 264 sizeof("Content-Length: 18446744073709551616" CRLF), |
270 r->headers_out.content_length_n); | 265 "Content-Length: " OFF_FMT CRLF, |
266 r->headers_out.content_length_n); | |
271 } | 267 } |
272 } | 268 } |
273 | 269 |
274 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { | 270 if (r->headers_out.content_type && r->headers_out.content_type->value.len) { |
275 h->last = ngx_cpymem(h->last, "Content-Type: ", 14); | 271 h->last = ngx_cpymem(h->last, "Content-Type: ", |
272 sizeof("Content-Type: ") - 1); | |
276 h->last = ngx_cpymem(h->last, r->headers_out.content_type->value.data, | 273 h->last = ngx_cpymem(h->last, r->headers_out.content_type->value.data, |
277 r->headers_out.content_type->value.len); | 274 r->headers_out.content_type->value.len); |
278 | 275 |
279 if (r->headers_out.charset.len) { | 276 if (r->headers_out.charset.len) { |
280 h->last = ngx_cpymem(h->last, "; charset=", 10); | 277 h->last = ngx_cpymem(h->last, "; charset=", |
278 sizeof("; charset=") - 1); | |
281 h->last = ngx_cpymem(h->last, r->headers_out.charset.data, | 279 h->last = ngx_cpymem(h->last, r->headers_out.charset.data, |
282 r->headers_out.charset.len); | 280 r->headers_out.charset.len); |
283 } | 281 } |
284 | 282 |
285 *(h->last++) = CR; *(h->last++) = LF; | 283 *(h->last++) = CR; *(h->last++) = LF; |
286 } | 284 } |
287 | 285 |
288 if (r->headers_out.content_encoding | 286 if (r->headers_out.content_encoding |
289 && r->headers_out.content_encoding->value.len) | 287 && r->headers_out.content_encoding->value.len) |
290 { | 288 { |
291 h->last = ngx_cpymem(h->last, "Content-Encoding: ", 18); | 289 h->last = ngx_cpymem(h->last, "Content-Encoding: ", |
290 sizeof("Content-Encoding: ") - 1); | |
292 h->last = ngx_cpymem(h->last, | 291 h->last = ngx_cpymem(h->last, |
293 r->headers_out.content_encoding->value.data, | 292 r->headers_out.content_encoding->value.data, |
294 r->headers_out.content_encoding->value.len); | 293 r->headers_out.content_encoding->value.len); |
295 | 294 |
296 *(h->last++) = CR; *(h->last++) = LF; | 295 *(h->last++) = CR; *(h->last++) = LF; |
298 | 297 |
299 if (r->headers_out.location | 298 if (r->headers_out.location |
300 && r->headers_out.location->value.len | 299 && r->headers_out.location->value.len |
301 && r->headers_out.location->value.data[0] == '/') | 300 && r->headers_out.location->value.data[0] == '/') |
302 { | 301 { |
303 h->last = ngx_cpymem(h->last, "Location: http://", 17); | 302 h->last = ngx_cpymem(h->last, "Location: http://", |
303 sizeof("Location: http://") - 1); | |
304 h->last = ngx_cpymem(h->last, r->server_name->data, | 304 h->last = ngx_cpymem(h->last, r->server_name->data, |
305 r->server_name->len); | 305 r->server_name->len); |
306 if (r->port != 80) { | 306 if (r->port != 80) { |
307 h->last = ngx_cpymem(h->last, r->port_name->data, | 307 h->last = ngx_cpymem(h->last, r->port_name->data, |
308 r->port_name->len); | 308 r->port_name->len); |
315 } | 315 } |
316 | 316 |
317 if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len) | 317 if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len) |
318 && r->headers_out.last_modified_time != -1) | 318 && r->headers_out.last_modified_time != -1) |
319 { | 319 { |
320 h->last = ngx_cpymem(h->last, "Last-Modified: ", 15); | 320 h->last = ngx_cpymem(h->last, "Last-Modified: ", |
321 sizeof("Last-Modified: ") - 1); | |
321 h->last += ngx_http_get_time(h->last, | 322 h->last += ngx_http_get_time(h->last, |
322 r->headers_out.last_modified_time); | 323 r->headers_out.last_modified_time); |
323 *(h->last++) = CR; *(h->last++) = LF; | 324 *(h->last++) = CR; *(h->last++) = LF; |
324 } | 325 } |
325 | 326 |
326 if (r->chunked) { | 327 if (r->chunked) { |
327 h->last = ngx_cpymem(h->last, "Transfer-Encoding: chunked" CRLF, 28); | 328 h->last = ngx_cpymem(h->last, "Transfer-Encoding: chunked" CRLF, |
329 sizeof("Transfer-Encoding: chunked" CRLF) - 1); | |
328 } | 330 } |
329 | 331 |
330 if (r->keepalive) { | 332 if (r->keepalive) { |
331 h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, 24); | 333 h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, |
332 | 334 sizeof("Connection: keep-alive" CRLF) - 1); |
333 } else { | 335 |
334 h->last = ngx_cpymem(h->last, "Connection: close" CRLF, 19); | 336 } else { |
337 h->last = ngx_cpymem(h->last, "Connection: close" CRLF, | |
338 sizeof("Connection: close" CRLF) - 1); | |
335 } | 339 } |
336 | 340 |
337 for (i = 0; i < r->headers_out.headers->nelts; i++) { | 341 for (i = 0; i < r->headers_out.headers->nelts; i++) { |
338 if (header[i].key.len == 0) { | 342 if (header[i].key.len == 0) { |
339 continue; | 343 continue; |