Mercurial > hg > nginx-vendor-0-8
comparison src/http/ngx_http_special_response.c @ 228:9eebc1b2cdbb NGINX_0_3_61
nginx 0.3.61
*) Change: now the "tcp_nodelay" directive is turned on by default.
*) Feature: the "msie_refresh" directive.
*) Feature: the "recursive_error_pages" directive.
*) Bugfix: the "rewrite" directive returned incorrect redirect, if the
redirect had the captured escaped symbols from original URI.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 28 Aug 2006 00:00:00 +0400 |
parents | 21f2ace7c936 |
children | 38e7b94d63ac |
comparison
equal
deleted
inserted
replaced
227:f554f17a0fb7 | 228:9eebc1b2cdbb |
---|---|
23 "<!-- The padding to disable MSIE's friendly error page -->" CRLF | 23 "<!-- The padding to disable MSIE's friendly error page -->" CRLF |
24 "<!-- The padding to disable MSIE's friendly error page -->" CRLF | 24 "<!-- The padding to disable MSIE's friendly error page -->" CRLF |
25 "<!-- The padding to disable MSIE's friendly error page -->" CRLF | 25 "<!-- The padding to disable MSIE's friendly error page -->" CRLF |
26 "<!-- The padding to disable MSIE's friendly error page -->" CRLF | 26 "<!-- The padding to disable MSIE's friendly error page -->" CRLF |
27 ; | 27 ; |
28 | |
29 | |
30 static u_char ngx_http_msie_refresh_head[] = | |
31 "<html><head><meta http-equiv=\"Refresh\" content=\"0; URL="; | |
32 | |
33 | |
34 static u_char ngx_http_msie_refresh_tail[] = | |
35 "\"></head><body></body></html>" CRLF; | |
28 | 36 |
29 | 37 |
30 static char error_301_page[] = | 38 static char error_301_page[] = |
31 "<html>" CRLF | 39 "<html>" CRLF |
32 "<head><title>301 Moved Permanently</title></head>" CRLF | 40 "<head><title>301 Moved Permanently</title></head>" CRLF |
292 | 300 |
293 | 301 |
294 ngx_int_t | 302 ngx_int_t |
295 ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) | 303 ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) |
296 { | 304 { |
305 u_char *p; | |
306 size_t msie_refresh; | |
297 ngx_int_t rc; | 307 ngx_int_t rc; |
298 ngx_buf_t *b; | 308 ngx_buf_t *b; |
299 ngx_str_t *uri; | 309 ngx_str_t *uri, *location; |
300 ngx_uint_t i, err, msie_padding; | 310 ngx_uint_t i, err, msie_padding; |
301 ngx_chain_t *out, *cl; | 311 ngx_chain_t *out, *cl; |
302 ngx_http_err_page_t *err_page; | 312 ngx_http_err_page_t *err_page; |
303 ngx_http_core_loc_conf_t *clcf; | 313 ngx_http_core_loc_conf_t *clcf; |
304 | 314 |
309 | 319 |
310 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { | 320 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { |
311 error = NGX_HTTP_INTERNAL_SERVER_ERROR; | 321 error = NGX_HTTP_INTERNAL_SERVER_ERROR; |
312 } | 322 } |
313 | 323 |
314 r->headers_out.status = error; | |
315 r->err_status = error; | 324 r->err_status = error; |
316 | 325 |
317 if (r->keepalive != 0) { | 326 if (r->keepalive != 0) { |
318 switch (error) { | 327 switch (error) { |
319 case NGX_HTTP_BAD_REQUEST: | 328 case NGX_HTTP_BAD_REQUEST: |
339 | 348 |
340 r->headers_out.content_type.len = 0; | 349 r->headers_out.content_type.len = 0; |
341 | 350 |
342 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 351 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
343 | 352 |
344 if (r->uri_changes && clcf->error_pages) { | 353 if (!r->error_page && clcf->error_pages) { |
354 | |
355 if (clcf->recursive_error_pages == 0) { | |
356 r->error_page = 1; | |
357 } | |
345 | 358 |
346 err_page = clcf->error_pages->elts; | 359 err_page = clcf->error_pages->elts; |
347 | 360 |
348 for (i = 0; i < clcf->error_pages->nelts; i++) { | 361 for (i = 0; i < clcf->error_pages->nelts; i++) { |
349 | 362 |
413 + NGX_HTTP_LEVEL_400; | 426 + NGX_HTTP_LEVEL_400; |
414 switch (error) { | 427 switch (error) { |
415 case NGX_HTTP_TO_HTTPS: | 428 case NGX_HTTP_TO_HTTPS: |
416 case NGX_HTTPS_CERT_ERROR: | 429 case NGX_HTTPS_CERT_ERROR: |
417 case NGX_HTTPS_NO_CERT: | 430 case NGX_HTTPS_NO_CERT: |
418 r->headers_out.status = NGX_HTTP_BAD_REQUEST; | 431 r->err_status = NGX_HTTP_BAD_REQUEST; |
419 error = NGX_HTTP_BAD_REQUEST; | 432 error = NGX_HTTP_BAD_REQUEST; |
420 break; | 433 break; |
421 } | 434 } |
422 } | 435 } |
423 | 436 |
447 if (r->headers_out.content_length) { | 460 if (r->headers_out.content_length) { |
448 r->headers_out.content_length->hash = 0; | 461 r->headers_out.content_length->hash = 0; |
449 r->headers_out.content_length = NULL; | 462 r->headers_out.content_length = NULL; |
450 } | 463 } |
451 | 464 |
465 msie_refresh = 0; | |
466 location = NULL; | |
467 | |
468 if (clcf->msie_refresh | |
469 && r->headers_in.msie | |
470 && (error == NGX_HTTP_MOVED_PERMANENTLY | |
471 || error == NGX_HTTP_MOVED_TEMPORARILY)) | |
472 { | |
473 location = &r->headers_out.location->value; | |
474 msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1 | |
475 + location->len | |
476 + sizeof(ngx_http_msie_refresh_tail) - 1; | |
477 | |
478 r->err_status = NGX_HTTP_OK; | |
479 r->headers_out.content_type_len = sizeof("text/html") - 1; | |
480 r->headers_out.content_length_n = msie_refresh; | |
481 r->headers_out.location->hash = 0; | |
482 r->headers_out.location = NULL; | |
483 } | |
484 | |
452 ngx_http_clear_accept_ranges(r); | 485 ngx_http_clear_accept_ranges(r); |
453 ngx_http_clear_last_modified(r); | 486 ngx_http_clear_last_modified(r); |
454 | 487 |
455 rc = ngx_http_send_header(r); | 488 rc = ngx_http_send_header(r); |
456 | 489 |
457 if (rc == NGX_ERROR || r->header_only) { | 490 if (rc == NGX_ERROR || r->header_only) { |
458 return rc; | 491 return rc; |
459 } | 492 } |
460 | 493 |
461 if (error_pages[err].len == 0) { | 494 |
462 return NGX_OK; | 495 if (msie_refresh == 0) { |
463 } | 496 |
464 | 497 if (error_pages[err].len == 0) { |
465 | 498 return NGX_OK; |
466 b = ngx_calloc_buf(r->pool); | 499 } |
467 if (b == NULL) { | 500 |
468 return NGX_ERROR; | |
469 } | |
470 | |
471 b->memory = 1; | |
472 b->pos = error_pages[err].data; | |
473 b->last = error_pages[err].data + error_pages[err].len; | |
474 | |
475 cl = ngx_alloc_chain_link(r->pool); | |
476 if (cl == NULL) { | |
477 return NGX_ERROR; | |
478 } | |
479 | |
480 cl->buf = b; | |
481 out = cl; | |
482 | |
483 | |
484 b = ngx_calloc_buf(r->pool); | |
485 if (b == NULL) { | |
486 return NGX_ERROR; | |
487 } | |
488 | |
489 b->memory = 1; | |
490 b->pos = error_tail; | |
491 b->last = error_tail + sizeof(error_tail) - 1; | |
492 | |
493 cl->next = ngx_alloc_chain_link(r->pool); | |
494 if (cl->next == NULL) { | |
495 return NGX_ERROR; | |
496 } | |
497 | |
498 cl = cl->next; | |
499 cl->buf = b; | |
500 | |
501 if (msie_padding) { | |
502 b = ngx_calloc_buf(r->pool); | 501 b = ngx_calloc_buf(r->pool); |
503 if (b == NULL) { | 502 if (b == NULL) { |
504 return NGX_ERROR; | 503 return NGX_ERROR; |
505 } | 504 } |
506 | 505 |
507 b->memory = 1; | 506 b->memory = 1; |
508 b->pos = ngx_http_msie_stub; | 507 b->pos = error_pages[err].data; |
509 b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1; | 508 b->last = error_pages[err].data + error_pages[err].len; |
509 | |
510 cl = ngx_alloc_chain_link(r->pool); | |
511 if (cl == NULL) { | |
512 return NGX_ERROR; | |
513 } | |
514 | |
515 cl->buf = b; | |
516 out = cl; | |
517 | |
518 | |
519 b = ngx_calloc_buf(r->pool); | |
520 if (b == NULL) { | |
521 return NGX_ERROR; | |
522 } | |
523 | |
524 b->memory = 1; | |
525 b->pos = error_tail; | |
526 b->last = error_tail + sizeof(error_tail) - 1; | |
510 | 527 |
511 cl->next = ngx_alloc_chain_link(r->pool); | 528 cl->next = ngx_alloc_chain_link(r->pool); |
512 if (cl->next == NULL) { | 529 if (cl->next == NULL) { |
513 return NGX_ERROR; | 530 return NGX_ERROR; |
514 } | 531 } |
515 | 532 |
516 cl = cl->next; | 533 cl = cl->next; |
517 cl->buf = b; | 534 cl->buf = b; |
535 | |
536 if (msie_padding) { | |
537 b = ngx_calloc_buf(r->pool); | |
538 if (b == NULL) { | |
539 return NGX_ERROR; | |
540 } | |
541 | |
542 b->memory = 1; | |
543 b->pos = ngx_http_msie_stub; | |
544 b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1; | |
545 | |
546 cl->next = ngx_alloc_chain_link(r->pool); | |
547 if (cl->next == NULL) { | |
548 return NGX_ERROR; | |
549 } | |
550 | |
551 cl = cl->next; | |
552 cl->buf = b; | |
553 } | |
554 | |
555 } else { | |
556 b = ngx_create_temp_buf(r->pool, msie_refresh); | |
557 if (b == NULL) { | |
558 return NGX_ERROR; | |
559 } | |
560 | |
561 p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head, | |
562 sizeof(ngx_http_msie_refresh_head) - 1); | |
563 | |
564 p = ngx_cpymem(p, location->data, location->len); | |
565 | |
566 b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail, | |
567 sizeof(ngx_http_msie_refresh_tail) - 1); | |
568 | |
569 cl = ngx_alloc_chain_link(r->pool); | |
570 if (cl == NULL) { | |
571 return NGX_ERROR; | |
572 } | |
573 | |
574 cl->buf = b; | |
575 out = cl; | |
518 } | 576 } |
519 | 577 |
520 if (r == r->main) { | 578 if (r == r->main) { |
521 b->last_buf = 1; | 579 b->last_buf = 1; |
522 } | 580 } |