Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_header_filter_module.c @ 517:8fbdd980b527
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 13 Jul 2009 23:56:24 +0400 |
parents | 98143f74eb3d |
children | e19e5f542878 |
comparison
equal
deleted
inserted
replaced
424:44a61c599bb2 | 517:8fbdd980b527 |
---|---|
59 ngx_null_string, /* "205 Reset Content" */ | 59 ngx_null_string, /* "205 Reset Content" */ |
60 ngx_string("206 Partial Content"), | 60 ngx_string("206 Partial Content"), |
61 | 61 |
62 /* ngx_null_string, */ /* "207 Multi-Status" */ | 62 /* ngx_null_string, */ /* "207 Multi-Status" */ |
63 | 63 |
64 #define NGX_HTTP_LEVEL_200 7 | 64 #define NGX_HTTP_LAST_LEVEL_200 207 |
65 #define NGX_HTTP_LEVEL_200 (NGX_HTTP_LAST_LEVEL_200 - 200) | |
65 | 66 |
66 /* ngx_null_string, */ /* "300 Multiple Choices" */ | 67 /* ngx_null_string, */ /* "300 Multiple Choices" */ |
67 | 68 |
68 ngx_string("301 Moved Permanently"), | 69 ngx_string("301 Moved Permanently"), |
69 ngx_string("302 Moved Temporarily"), | 70 ngx_string("302 Moved Temporarily"), |
72 | 73 |
73 /* ngx_null_string, */ /* "305 Use Proxy" */ | 74 /* ngx_null_string, */ /* "305 Use Proxy" */ |
74 /* ngx_null_string, */ /* "306 unused" */ | 75 /* ngx_null_string, */ /* "306 unused" */ |
75 /* ngx_null_string, */ /* "307 Temporary Redirect" */ | 76 /* ngx_null_string, */ /* "307 Temporary Redirect" */ |
76 | 77 |
77 #define NGX_HTTP_LEVEL_300 4 | 78 #define NGX_HTTP_LAST_LEVEL_300 305 |
79 #define NGX_HTTP_LEVEL_300 (NGX_HTTP_LAST_LEVEL_300 - 301) | |
78 | 80 |
79 ngx_string("400 Bad Request"), | 81 ngx_string("400 Bad Request"), |
80 ngx_string("401 Unauthorized"), | 82 ngx_string("401 Unauthorized"), |
81 ngx_string("402 Payment Required"), | 83 ngx_string("402 Payment Required"), |
82 ngx_string("403 Forbidden"), | 84 ngx_string("403 Forbidden"), |
104 /* ngx_null_string, */ /* "421 unused" */ | 106 /* ngx_null_string, */ /* "421 unused" */ |
105 /* ngx_null_string, */ /* "422 Unprocessable Entity" */ | 107 /* ngx_null_string, */ /* "422 Unprocessable Entity" */ |
106 /* ngx_null_string, */ /* "423 Locked" */ | 108 /* ngx_null_string, */ /* "423 Locked" */ |
107 /* ngx_null_string, */ /* "424 Failed Dependency" */ | 109 /* ngx_null_string, */ /* "424 Failed Dependency" */ |
108 | 110 |
109 #define NGX_HTTP_LEVEL_400 17 | 111 #define NGX_HTTP_LAST_LEVEL_400 417 |
112 #define NGX_HTTP_LEVEL_400 (NGX_HTTP_LAST_LEVEL_400 - 400) | |
110 | 113 |
111 ngx_string("500 Internal Server Error"), | 114 ngx_string("500 Internal Server Error"), |
112 ngx_string("501 Method Not Implemented"), | 115 ngx_string("501 Method Not Implemented"), |
113 ngx_string("502 Bad Gateway"), | 116 ngx_string("502 Bad Gateway"), |
114 ngx_string("503 Service Temporarily Unavailable"), | 117 ngx_string("503 Service Temporarily Unavailable"), |
118 ngx_null_string, /* "506 Variant Also Negotiates" */ | 121 ngx_null_string, /* "506 Variant Also Negotiates" */ |
119 ngx_string("507 Insufficient Storage"), | 122 ngx_string("507 Insufficient Storage"), |
120 /* ngx_null_string, */ /* "508 unused" */ | 123 /* ngx_null_string, */ /* "508 unused" */ |
121 /* ngx_null_string, */ /* "509 unused" */ | 124 /* ngx_null_string, */ /* "509 unused" */ |
122 /* ngx_null_string, */ /* "510 Not Extended" */ | 125 /* ngx_null_string, */ /* "510 Not Extended" */ |
126 | |
127 #define NGX_HTTP_LAST_LEVEL_500 508 | |
128 | |
123 }; | 129 }; |
124 | 130 |
125 | 131 |
126 ngx_http_header_out_t ngx_http_headers_out[] = { | 132 ngx_http_header_out_t ngx_http_headers_out[] = { |
127 { ngx_string("Server"), offsetof(ngx_http_headers_out_t, server) }, | 133 { ngx_string("Server"), offsetof(ngx_http_headers_out_t, server) }, |
151 static ngx_int_t | 157 static ngx_int_t |
152 ngx_http_header_filter(ngx_http_request_t *r) | 158 ngx_http_header_filter(ngx_http_request_t *r) |
153 { | 159 { |
154 u_char *p; | 160 u_char *p; |
155 size_t len; | 161 size_t len; |
156 ngx_str_t host; | 162 ngx_str_t host, *status_line; |
157 ngx_buf_t *b; | 163 ngx_buf_t *b; |
158 ngx_uint_t status, i; | 164 ngx_uint_t status, i, port; |
159 ngx_chain_t out; | 165 ngx_chain_t out; |
160 ngx_list_part_t *part; | 166 ngx_list_part_t *part; |
161 ngx_table_elt_t *header; | 167 ngx_table_elt_t *header; |
168 ngx_connection_t *c; | |
162 ngx_http_core_loc_conf_t *clcf; | 169 ngx_http_core_loc_conf_t *clcf; |
163 ngx_http_core_srv_conf_t *cscf; | 170 ngx_http_core_srv_conf_t *cscf; |
164 /* AF_INET only */ | 171 struct sockaddr_in *sin; |
165 u_char addr[NGX_INET_ADDRSTRLEN]; | 172 #if (NGX_HAVE_INET6) |
173 struct sockaddr_in6 *sin6; | |
174 #endif | |
175 u_char addr[NGX_SOCKADDR_STRLEN]; | |
166 | 176 |
167 r->header_sent = 1; | 177 r->header_sent = 1; |
168 | 178 |
169 if (r != r->main) { | 179 if (r != r->main) { |
170 return NGX_OK; | 180 return NGX_OK; |
194 | 204 |
195 /* status line */ | 205 /* status line */ |
196 | 206 |
197 if (r->headers_out.status_line.len) { | 207 if (r->headers_out.status_line.len) { |
198 len += r->headers_out.status_line.len; | 208 len += r->headers_out.status_line.len; |
209 status_line = &r->headers_out.status_line; | |
199 #if (NGX_SUPPRESS_WARN) | 210 #if (NGX_SUPPRESS_WARN) |
200 status = NGX_INVALID_ARRAY_INDEX; | 211 status = 0; |
201 #endif | 212 #endif |
202 | 213 |
203 } else { | 214 } else { |
204 | 215 |
205 if (r->headers_out.status < NGX_HTTP_MOVED_PERMANENTLY) { | 216 status = r->headers_out.status; |
217 | |
218 if (status >= NGX_HTTP_OK | |
219 && status < NGX_HTTP_LAST_LEVEL_200) | |
220 { | |
206 /* 2XX */ | 221 /* 2XX */ |
207 status = r->headers_out.status - NGX_HTTP_OK; | 222 |
208 | 223 if (status == NGX_HTTP_NO_CONTENT) { |
209 if (r->headers_out.status == NGX_HTTP_NO_CONTENT) { | |
210 r->header_only = 1; | 224 r->header_only = 1; |
211 r->headers_out.content_type.len = 0; | 225 r->headers_out.content_type.len = 0; |
212 r->headers_out.content_type.data = NULL; | 226 r->headers_out.content_type.data = NULL; |
213 r->headers_out.last_modified_time = -1; | 227 r->headers_out.last_modified_time = -1; |
214 r->headers_out.last_modified = NULL; | 228 r->headers_out.last_modified = NULL; |
215 r->headers_out.content_length = NULL; | 229 r->headers_out.content_length = NULL; |
216 r->headers_out.content_length_n = -1; | 230 r->headers_out.content_length_n = -1; |
217 } | 231 } |
218 | 232 |
219 } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { | 233 status -= NGX_HTTP_OK; |
234 status_line = &ngx_http_status_lines[status]; | |
235 len += ngx_http_status_lines[status].len; | |
236 | |
237 } else if (status >= NGX_HTTP_MOVED_PERMANENTLY | |
238 && status < NGX_HTTP_LAST_LEVEL_300) | |
239 { | |
220 /* 3XX */ | 240 /* 3XX */ |
221 status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY | 241 |
222 + NGX_HTTP_LEVEL_200; | 242 if (status == NGX_HTTP_NOT_MODIFIED) { |
223 | |
224 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) { | |
225 r->header_only = 1; | 243 r->header_only = 1; |
226 } | 244 } |
227 | 245 |
228 } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) { | 246 status = status - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_LEVEL_200; |
247 status_line = &ngx_http_status_lines[status]; | |
248 len += ngx_http_status_lines[status].len; | |
249 | |
250 } else if (status >= NGX_HTTP_BAD_REQUEST | |
251 && status < NGX_HTTP_LAST_LEVEL_400) | |
252 { | |
229 /* 4XX */ | 253 /* 4XX */ |
230 status = r->headers_out.status - NGX_HTTP_BAD_REQUEST | 254 status = status - NGX_HTTP_BAD_REQUEST |
231 + NGX_HTTP_LEVEL_200 | 255 + NGX_HTTP_LEVEL_200 |
232 + NGX_HTTP_LEVEL_300; | 256 + NGX_HTTP_LEVEL_300; |
257 | |
258 status_line = &ngx_http_status_lines[status]; | |
259 len += ngx_http_status_lines[status].len; | |
260 | |
261 } else if (status >= NGX_HTTP_INTERNAL_SERVER_ERROR | |
262 && status < NGX_HTTP_LAST_LEVEL_500) | |
263 { | |
264 /* 5XX */ | |
265 status = status - NGX_HTTP_INTERNAL_SERVER_ERROR | |
266 + NGX_HTTP_LEVEL_200 | |
267 + NGX_HTTP_LEVEL_300 | |
268 + NGX_HTTP_LEVEL_400; | |
269 | |
270 status_line = &ngx_http_status_lines[status]; | |
271 len += ngx_http_status_lines[status].len; | |
233 | 272 |
234 } else { | 273 } else { |
235 /* 5XX */ | 274 len += NGX_INT_T_LEN; |
236 status = r->headers_out.status - NGX_HTTP_INTERNAL_SERVER_ERROR | 275 status_line = NULL; |
237 + NGX_HTTP_LEVEL_200 | 276 } |
238 + NGX_HTTP_LEVEL_300 | |
239 + NGX_HTTP_LEVEL_400; | |
240 } | |
241 | |
242 len += ngx_http_status_lines[status].len; | |
243 } | 277 } |
244 | 278 |
245 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 279 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
246 | 280 |
247 if (r->headers_out.server == NULL) { | 281 if (r->headers_out.server == NULL) { |
273 if (r->headers_out.last_modified == NULL | 307 if (r->headers_out.last_modified == NULL |
274 && r->headers_out.last_modified_time != -1) | 308 && r->headers_out.last_modified_time != -1) |
275 { | 309 { |
276 len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; | 310 len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; |
277 } | 311 } |
312 | |
313 c = r->connection; | |
278 | 314 |
279 if (r->headers_out.location | 315 if (r->headers_out.location |
280 && r->headers_out.location->value.len | 316 && r->headers_out.location->value.len |
281 && r->headers_out.location->value.data[0] == '/') | 317 && r->headers_out.location->value.data[0] == '/') |
282 { | 318 { |
288 | 324 |
289 } else if (r->headers_in.server.len) { | 325 } else if (r->headers_in.server.len) { |
290 host = r->headers_in.server; | 326 host = r->headers_in.server; |
291 | 327 |
292 } else { | 328 } else { |
329 host.len = NGX_SOCKADDR_STRLEN; | |
293 host.data = addr; | 330 host.data = addr; |
294 | 331 |
295 if (ngx_http_server_addr(r, &host) != NGX_OK) { | 332 if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) { |
296 return NGX_ERROR; | 333 return NGX_ERROR; |
297 } | 334 } |
298 } | 335 } |
299 | 336 |
337 switch (c->local_sockaddr->sa_family) { | |
338 | |
339 #if (NGX_HAVE_INET6) | |
340 case AF_INET6: | |
341 sin6 = (struct sockaddr_in6 *) c->local_sockaddr; | |
342 port = ntohs(sin6->sin6_port); | |
343 break; | |
344 #endif | |
345 default: /* AF_INET */ | |
346 sin = (struct sockaddr_in *) c->local_sockaddr; | |
347 port = ntohs(sin->sin_port); | |
348 break; | |
349 } | |
350 | |
351 len += sizeof("Location: https://") - 1 | |
352 + host.len | |
353 + r->headers_out.location->value.len + 2; | |
354 | |
355 if (clcf->port_in_redirect) { | |
356 | |
300 #if (NGX_HTTP_SSL) | 357 #if (NGX_HTTP_SSL) |
301 if (r->connection->ssl) { | 358 if (c->ssl) |
302 len += sizeof("Location: https://") - 1 | 359 port = (port == 443) ? 0 : port; |
303 + host.len | 360 else |
304 + r->headers_out.location->value.len + 2; | 361 #endif |
305 | 362 port = (port == 80) ? 0 : port; |
306 if (clcf->port_in_redirect && r->port != 443) { | 363 |
307 len += r->port_text->len; | 364 } else { |
308 } | 365 port = 0; |
309 | 366 } |
310 } else | 367 |
311 #endif | 368 if (port) { |
312 { | 369 len += sizeof(":65535") - 1; |
313 len += sizeof("Location: http://") - 1 | |
314 + host.len | |
315 + r->headers_out.location->value.len + 2; | |
316 | |
317 if (clcf->port_in_redirect && r->port != 80) { | |
318 len += r->port_text->len; | |
319 } | |
320 } | 370 } |
321 | 371 |
322 } else { | 372 } else { |
323 host.len = 0; | 373 host.len = 0; |
324 host.data = NULL; | 374 host.data = NULL; |
375 port = 0; | |
325 } | 376 } |
326 | 377 |
327 if (r->chunked) { | 378 if (r->chunked) { |
328 len += sizeof("Transfer-Encoding: chunked" CRLF) - 1; | 379 len += sizeof("Transfer-Encoding: chunked" CRLF) - 1; |
329 } | 380 } |
383 | 434 |
384 /* "HTTP/1.x " */ | 435 /* "HTTP/1.x " */ |
385 b->last = ngx_cpymem(b->last, "HTTP/1.1 ", sizeof("HTTP/1.x ") - 1); | 436 b->last = ngx_cpymem(b->last, "HTTP/1.1 ", sizeof("HTTP/1.x ") - 1); |
386 | 437 |
387 /* status line */ | 438 /* status line */ |
388 if (r->headers_out.status_line.len) { | 439 if (status_line) { |
389 b->last = ngx_copy(b->last, r->headers_out.status_line.data, | 440 b->last = ngx_copy(b->last, status_line->data, status_line->len); |
390 r->headers_out.status_line.len); | |
391 | 441 |
392 } else { | 442 } else { |
393 b->last = ngx_copy(b->last, ngx_http_status_lines[status].data, | 443 b->last = ngx_sprintf(b->last, "%ui", status); |
394 ngx_http_status_lines[status].len); | |
395 } | 444 } |
396 *b->last++ = CR; *b->last++ = LF; | 445 *b->last++ = CR; *b->last++ = LF; |
397 | 446 |
398 if (r->headers_out.server == NULL) { | 447 if (r->headers_out.server == NULL) { |
399 if (clcf->server_tokens) { | 448 if (clcf->server_tokens) { |
463 | 512 |
464 b->last = ngx_cpymem(b->last, "Location: http", | 513 b->last = ngx_cpymem(b->last, "Location: http", |
465 sizeof("Location: http") - 1); | 514 sizeof("Location: http") - 1); |
466 | 515 |
467 #if (NGX_HTTP_SSL) | 516 #if (NGX_HTTP_SSL) |
468 if (r->connection->ssl) { | 517 if (c->ssl) { |
469 *b->last++ ='s'; | 518 *b->last++ ='s'; |
470 } | 519 } |
471 #endif | 520 #endif |
472 | 521 |
473 *b->last++ = ':'; *b->last++ = '/'; *b->last++ = '/'; | 522 *b->last++ = ':'; *b->last++ = '/'; *b->last++ = '/'; |
474 b->last = ngx_copy(b->last, host.data, host.len); | 523 b->last = ngx_copy(b->last, host.data, host.len); |
475 | 524 |
476 if (clcf->port_in_redirect) { | 525 if (port) { |
477 #if (NGX_HTTP_SSL) | 526 b->last = ngx_sprintf(b->last, ":%ui", port); |
478 if (r->connection->ssl) { | |
479 if (r->port != 443) { | |
480 b->last = ngx_copy(b->last, r->port_text->data, | |
481 r->port_text->len); | |
482 } | |
483 } else | |
484 #endif | |
485 { | |
486 if (r->port != 80) { | |
487 b->last = ngx_copy(b->last, r->port_text->data, | |
488 r->port_text->len); | |
489 } | |
490 } | |
491 } | 527 } |
492 | 528 |
493 b->last = ngx_copy(b->last, r->headers_out.location->value.data, | 529 b->last = ngx_copy(b->last, r->headers_out.location->value.data, |
494 r->headers_out.location->value.len); | 530 r->headers_out.location->value.len); |
495 | 531 |
553 | 589 |
554 b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); | 590 b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); |
555 *b->last++ = CR; *b->last++ = LF; | 591 *b->last++ = CR; *b->last++ = LF; |
556 } | 592 } |
557 | 593 |
558 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 594 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
559 "%*s\n", (size_t) (b->last - b->pos), b->pos); | 595 "%*s", (size_t) (b->last - b->pos), b->pos); |
560 | 596 |
561 /* the end of HTTP header */ | 597 /* the end of HTTP header */ |
562 *b->last++ = CR; *b->last++ = LF; | 598 *b->last++ = CR; *b->last++ = LF; |
563 | 599 |
564 r->header_size = b->last - b->pos; | 600 r->header_size = b->last - b->pos; |