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 }