Update and clean Tomato RAF files
[tomato.git] / release / src / router / nginx / src / http / ngx_http_special_response.c
blob875c24d9c75518000c0cab3309ae792c1790a979
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 #include <ngx_http.h>
11 #include <nginx.h>
14 static ngx_int_t ngx_http_send_error_page(ngx_http_request_t *r,
15 ngx_http_err_page_t *err_page);
16 static ngx_int_t ngx_http_send_special_response(ngx_http_request_t *r,
17 ngx_http_core_loc_conf_t *clcf, ngx_uint_t err);
18 static ngx_int_t ngx_http_send_refresh(ngx_http_request_t *r);
21 static u_char ngx_http_error_full_tail[] =
22 "<hr><center>" NGINX_VER "</center>" CRLF
23 "</body>" CRLF
24 "</html>" CRLF
28 static u_char ngx_http_error_tail[] =
29 "<hr><center>nginx</center>" CRLF
30 "</body>" CRLF
31 "</html>" CRLF
35 static u_char ngx_http_msie_padding[] =
36 "<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
37 "<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
38 "<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
39 "<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
40 "<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
41 "<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
45 static u_char ngx_http_msie_refresh_head[] =
46 "<html><head><meta http-equiv=\"Refresh\" content=\"0; URL=";
49 static u_char ngx_http_msie_refresh_tail[] =
50 "\"></head><body></body></html>" CRLF;
53 static char ngx_http_error_301_page[] =
54 "<html>" CRLF
55 "<head><title>301 Moved Permanently</title></head>" CRLF
56 "<body bgcolor=\"white\">" CRLF
57 "<center><h1>301 Moved Permanently</h1></center>" CRLF
61 static char ngx_http_error_302_page[] =
62 "<html>" CRLF
63 "<head><title>302 Found</title></head>" CRLF
64 "<body bgcolor=\"white\">" CRLF
65 "<center><h1>302 Found</h1></center>" CRLF
69 static char ngx_http_error_303_page[] =
70 "<html>" CRLF
71 "<head><title>303 See Other</title></head>" CRLF
72 "<body bgcolor=\"white\">" CRLF
73 "<center><h1>303 See Other</h1></center>" CRLF
77 static char ngx_http_error_307_page[] =
78 "<html>" CRLF
79 "<head><title>307 Temporary Redirect</title></head>" CRLF
80 "<body bgcolor=\"white\">" CRLF
81 "<center><h1>307 Temporary Redirect</h1></center>" CRLF
85 static char ngx_http_error_400_page[] =
86 "<html>" CRLF
87 "<head><title>400 Bad Request</title></head>" CRLF
88 "<body bgcolor=\"white\">" CRLF
89 "<center><h1>400 Bad Request</h1></center>" CRLF
93 static char ngx_http_error_401_page[] =
94 "<html>" CRLF
95 "<head><title>401 Authorization Required</title></head>" CRLF
96 "<body bgcolor=\"white\">" CRLF
97 "<center><h1>401 Authorization Required</h1></center>" CRLF
101 static char ngx_http_error_402_page[] =
102 "<html>" CRLF
103 "<head><title>402 Payment Required</title></head>" CRLF
104 "<body bgcolor=\"white\">" CRLF
105 "<center><h1>402 Payment Required</h1></center>" CRLF
109 static char ngx_http_error_403_page[] =
110 "<html>" CRLF
111 "<head><title>403 Forbidden</title></head>" CRLF
112 "<body bgcolor=\"white\">" CRLF
113 "<center><h1>403 Forbidden</h1></center>" CRLF
117 static char ngx_http_error_404_page[] =
118 "<html>" CRLF
119 "<head><title>404 Not Found</title></head>" CRLF
120 "<body bgcolor=\"white\">" CRLF
121 "<center><h1>404 Not Found</h1></center>" CRLF
125 static char ngx_http_error_405_page[] =
126 "<html>" CRLF
127 "<head><title>405 Not Allowed</title></head>" CRLF
128 "<body bgcolor=\"white\">" CRLF
129 "<center><h1>405 Not Allowed</h1></center>" CRLF
133 static char ngx_http_error_406_page[] =
134 "<html>" CRLF
135 "<head><title>406 Not Acceptable</title></head>" CRLF
136 "<body bgcolor=\"white\">" CRLF
137 "<center><h1>406 Not Acceptable</h1></center>" CRLF
141 static char ngx_http_error_408_page[] =
142 "<html>" CRLF
143 "<head><title>408 Request Time-out</title></head>" CRLF
144 "<body bgcolor=\"white\">" CRLF
145 "<center><h1>408 Request Time-out</h1></center>" CRLF
149 static char ngx_http_error_409_page[] =
150 "<html>" CRLF
151 "<head><title>409 Conflict</title></head>" CRLF
152 "<body bgcolor=\"white\">" CRLF
153 "<center><h1>409 Conflict</h1></center>" CRLF
157 static char ngx_http_error_410_page[] =
158 "<html>" CRLF
159 "<head><title>410 Gone</title></head>" CRLF
160 "<body bgcolor=\"white\">" CRLF
161 "<center><h1>410 Gone</h1></center>" CRLF
165 static char ngx_http_error_411_page[] =
166 "<html>" CRLF
167 "<head><title>411 Length Required</title></head>" CRLF
168 "<body bgcolor=\"white\">" CRLF
169 "<center><h1>411 Length Required</h1></center>" CRLF
173 static char ngx_http_error_412_page[] =
174 "<html>" CRLF
175 "<head><title>412 Precondition Failed</title></head>" CRLF
176 "<body bgcolor=\"white\">" CRLF
177 "<center><h1>412 Precondition Failed</h1></center>" CRLF
181 static char ngx_http_error_413_page[] =
182 "<html>" CRLF
183 "<head><title>413 Request Entity Too Large</title></head>" CRLF
184 "<body bgcolor=\"white\">" CRLF
185 "<center><h1>413 Request Entity Too Large</h1></center>" CRLF
189 static char ngx_http_error_414_page[] =
190 "<html>" CRLF
191 "<head><title>414 Request-URI Too Large</title></head>" CRLF
192 "<body bgcolor=\"white\">" CRLF
193 "<center><h1>414 Request-URI Too Large</h1></center>" CRLF
197 static char ngx_http_error_415_page[] =
198 "<html>" CRLF
199 "<head><title>415 Unsupported Media Type</title></head>" CRLF
200 "<body bgcolor=\"white\">" CRLF
201 "<center><h1>415 Unsupported Media Type</h1></center>" CRLF
205 static char ngx_http_error_416_page[] =
206 "<html>" CRLF
207 "<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
208 "<body bgcolor=\"white\">" CRLF
209 "<center><h1>416 Requested Range Not Satisfiable</h1></center>" CRLF
213 static char ngx_http_error_494_page[] =
214 "<html>" CRLF
215 "<head><title>400 Request Header Or Cookie Too Large</title></head>"
216 CRLF
217 "<body bgcolor=\"white\">" CRLF
218 "<center><h1>400 Bad Request</h1></center>" CRLF
219 "<center>Request Header Or Cookie Too Large</center>" CRLF
223 static char ngx_http_error_495_page[] =
224 "<html>" CRLF
225 "<head><title>400 The SSL certificate error</title></head>"
226 CRLF
227 "<body bgcolor=\"white\">" CRLF
228 "<center><h1>400 Bad Request</h1></center>" CRLF
229 "<center>The SSL certificate error</center>" CRLF
233 static char ngx_http_error_496_page[] =
234 "<html>" CRLF
235 "<head><title>400 No required SSL certificate was sent</title></head>"
236 CRLF
237 "<body bgcolor=\"white\">" CRLF
238 "<center><h1>400 Bad Request</h1></center>" CRLF
239 "<center>No required SSL certificate was sent</center>" CRLF
243 static char ngx_http_error_497_page[] =
244 "<html>" CRLF
245 "<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>"
246 CRLF
247 "<body bgcolor=\"white\">" CRLF
248 "<center><h1>400 Bad Request</h1></center>" CRLF
249 "<center>The plain HTTP request was sent to HTTPS port</center>" CRLF
253 static char ngx_http_error_500_page[] =
254 "<html>" CRLF
255 "<head><title>500 Internal Server Error</title></head>" CRLF
256 "<body bgcolor=\"white\">" CRLF
257 "<center><h1>500 Internal Server Error</h1></center>" CRLF
261 static char ngx_http_error_501_page[] =
262 "<html>" CRLF
263 "<head><title>501 Not Implemented</title></head>" CRLF
264 "<body bgcolor=\"white\">" CRLF
265 "<center><h1>501 Not Implemented</h1></center>" CRLF
269 static char ngx_http_error_502_page[] =
270 "<html>" CRLF
271 "<head><title>502 Bad Gateway</title></head>" CRLF
272 "<body bgcolor=\"white\">" CRLF
273 "<center><h1>502 Bad Gateway</h1></center>" CRLF
277 static char ngx_http_error_503_page[] =
278 "<html>" CRLF
279 "<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
280 "<body bgcolor=\"white\">" CRLF
281 "<center><h1>503 Service Temporarily Unavailable</h1></center>" CRLF
285 static char ngx_http_error_504_page[] =
286 "<html>" CRLF
287 "<head><title>504 Gateway Time-out</title></head>" CRLF
288 "<body bgcolor=\"white\">" CRLF
289 "<center><h1>504 Gateway Time-out</h1></center>" CRLF
293 static char ngx_http_error_507_page[] =
294 "<html>" CRLF
295 "<head><title>507 Insufficient Storage</title></head>" CRLF
296 "<body bgcolor=\"white\">" CRLF
297 "<center><h1>507 Insufficient Storage</h1></center>" CRLF
301 static ngx_str_t ngx_http_error_pages[] = {
303 ngx_null_string, /* 201, 204 */
305 #define NGX_HTTP_LAST_2XX 202
306 #define NGX_HTTP_OFF_3XX (NGX_HTTP_LAST_2XX - 201)
308 /* ngx_null_string, */ /* 300 */
309 ngx_string(ngx_http_error_301_page),
310 ngx_string(ngx_http_error_302_page),
311 ngx_string(ngx_http_error_303_page),
312 ngx_null_string, /* 304 */
313 ngx_null_string, /* 305 */
314 ngx_null_string, /* 306 */
315 ngx_string(ngx_http_error_307_page),
317 #define NGX_HTTP_LAST_3XX 308
318 #define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX)
320 ngx_string(ngx_http_error_400_page),
321 ngx_string(ngx_http_error_401_page),
322 ngx_string(ngx_http_error_402_page),
323 ngx_string(ngx_http_error_403_page),
324 ngx_string(ngx_http_error_404_page),
325 ngx_string(ngx_http_error_405_page),
326 ngx_string(ngx_http_error_406_page),
327 ngx_null_string, /* 407 */
328 ngx_string(ngx_http_error_408_page),
329 ngx_string(ngx_http_error_409_page),
330 ngx_string(ngx_http_error_410_page),
331 ngx_string(ngx_http_error_411_page),
332 ngx_string(ngx_http_error_412_page),
333 ngx_string(ngx_http_error_413_page),
334 ngx_string(ngx_http_error_414_page),
335 ngx_string(ngx_http_error_415_page),
336 ngx_string(ngx_http_error_416_page),
338 #define NGX_HTTP_LAST_4XX 417
339 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
341 ngx_string(ngx_http_error_494_page), /* 494, request header too large */
342 ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
343 ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
344 ngx_string(ngx_http_error_497_page), /* 497, http to https */
345 ngx_string(ngx_http_error_404_page), /* 498, canceled */
346 ngx_null_string, /* 499, client has closed connection */
348 ngx_string(ngx_http_error_500_page),
349 ngx_string(ngx_http_error_501_page),
350 ngx_string(ngx_http_error_502_page),
351 ngx_string(ngx_http_error_503_page),
352 ngx_string(ngx_http_error_504_page),
353 ngx_null_string, /* 505 */
354 ngx_null_string, /* 506 */
355 ngx_string(ngx_http_error_507_page)
357 #define NGX_HTTP_LAST_5XX 508
362 static ngx_str_t ngx_http_get_name = { 3, (u_char *) "GET " };
365 ngx_int_t
366 ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
368 ngx_uint_t i, err;
369 ngx_http_err_page_t *err_page;
370 ngx_http_core_loc_conf_t *clcf;
372 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
373 "http special response: %d, \"%V?%V\"",
374 error, &r->uri, &r->args);
376 r->err_status = error;
378 if (r->keepalive) {
379 switch (error) {
380 case NGX_HTTP_BAD_REQUEST:
381 case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE:
382 case NGX_HTTP_REQUEST_URI_TOO_LARGE:
383 case NGX_HTTP_TO_HTTPS:
384 case NGX_HTTPS_CERT_ERROR:
385 case NGX_HTTPS_NO_CERT:
386 case NGX_HTTP_INTERNAL_SERVER_ERROR:
387 case NGX_HTTP_NOT_IMPLEMENTED:
388 r->keepalive = 0;
392 if (r->lingering_close) {
393 switch (error) {
394 case NGX_HTTP_BAD_REQUEST:
395 case NGX_HTTP_TO_HTTPS:
396 case NGX_HTTPS_CERT_ERROR:
397 case NGX_HTTPS_NO_CERT:
398 r->lingering_close = 0;
402 r->headers_out.content_type.len = 0;
404 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
406 if (!r->error_page && clcf->error_pages && r->uri_changes != 0) {
408 if (clcf->recursive_error_pages == 0) {
409 r->error_page = 1;
412 err_page = clcf->error_pages->elts;
414 for (i = 0; i < clcf->error_pages->nelts; i++) {
415 if (err_page[i].status == error) {
416 return ngx_http_send_error_page(r, &err_page[i]);
421 r->expect_tested = 1;
423 if (ngx_http_discard_request_body(r) != NGX_OK) {
424 r->keepalive = 0;
427 if (clcf->msie_refresh
428 && r->headers_in.msie
429 && (error == NGX_HTTP_MOVED_PERMANENTLY
430 || error == NGX_HTTP_MOVED_TEMPORARILY))
432 return ngx_http_send_refresh(r);
435 if (error == NGX_HTTP_CREATED) {
436 /* 201 */
437 err = 0;
439 } else if (error == NGX_HTTP_NO_CONTENT) {
440 /* 204 */
441 err = 0;
443 } else if (error >= NGX_HTTP_MOVED_PERMANENTLY
444 && error < NGX_HTTP_LAST_3XX)
446 /* 3XX */
447 err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_OFF_3XX;
449 } else if (error >= NGX_HTTP_BAD_REQUEST
450 && error < NGX_HTTP_LAST_4XX)
452 /* 4XX */
453 err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_OFF_4XX;
455 } else if (error >= NGX_HTTP_NGINX_CODES
456 && error < NGX_HTTP_LAST_5XX)
458 /* 49X, 5XX */
459 err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_OFF_5XX;
460 switch (error) {
461 case NGX_HTTP_TO_HTTPS:
462 case NGX_HTTPS_CERT_ERROR:
463 case NGX_HTTPS_NO_CERT:
464 case NGX_HTTP_REQUEST_HEADER_TOO_LARGE:
465 r->err_status = NGX_HTTP_BAD_REQUEST;
466 break;
469 } else {
470 /* unknown code, zero body */
471 err = 0;
474 return ngx_http_send_special_response(r, clcf, err);
478 ngx_int_t
479 ngx_http_filter_finalize_request(ngx_http_request_t *r, ngx_module_t *m,
480 ngx_int_t error)
482 void *ctx;
483 ngx_int_t rc;
485 ngx_http_clean_header(r);
487 ctx = NULL;
489 if (m) {
490 ctx = r->ctx[m->ctx_index];
493 /* clear the modules contexts */
494 ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
496 if (m) {
497 r->ctx[m->ctx_index] = ctx;
500 r->filter_finalize = 1;
502 rc = ngx_http_special_response_handler(r, error);
504 /* NGX_ERROR resets any pending data */
506 switch (rc) {
508 case NGX_OK:
509 case NGX_DONE:
510 return NGX_ERROR;
512 default:
513 return rc;
518 void
519 ngx_http_clean_header(ngx_http_request_t *r)
521 ngx_memzero(&r->headers_out.status,
522 sizeof(ngx_http_headers_out_t)
523 - offsetof(ngx_http_headers_out_t, status));
525 r->headers_out.headers.part.nelts = 0;
526 r->headers_out.headers.part.next = NULL;
527 r->headers_out.headers.last = &r->headers_out.headers.part;
529 r->headers_out.content_length_n = -1;
530 r->headers_out.last_modified_time = -1;
534 static ngx_int_t
535 ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
537 ngx_int_t overwrite;
538 ngx_str_t uri, args;
539 ngx_table_elt_t *location;
540 ngx_http_core_loc_conf_t *clcf;
542 overwrite = err_page->overwrite;
544 if (overwrite && overwrite != NGX_HTTP_OK) {
545 r->expect_tested = 1;
548 if (overwrite >= 0) {
549 r->err_status = overwrite;
552 if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) {
553 return NGX_ERROR;
556 if (uri.data[0] == '/') {
558 if (err_page->value.lengths) {
559 ngx_http_split_args(r, &uri, &args);
561 } else {
562 args = err_page->args;
565 if (r->method != NGX_HTTP_HEAD) {
566 r->method = NGX_HTTP_GET;
567 r->method_name = ngx_http_get_name;
570 return ngx_http_internal_redirect(r, &uri, &args);
573 if (uri.data[0] == '@') {
574 return ngx_http_named_location(r, &uri);
577 location = ngx_list_push(&r->headers_out.headers);
579 if (location == NULL) {
580 return NGX_ERROR;
583 if (overwrite != NGX_HTTP_MOVED_PERMANENTLY
584 && overwrite != NGX_HTTP_MOVED_TEMPORARILY
585 && overwrite != NGX_HTTP_SEE_OTHER
586 && overwrite != NGX_HTTP_TEMPORARY_REDIRECT)
588 r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
591 location->hash = 1;
592 ngx_str_set(&location->key, "Location");
593 location->value = uri;
595 ngx_http_clear_location(r);
597 r->headers_out.location = location;
599 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
601 if (clcf->msie_refresh && r->headers_in.msie) {
602 return ngx_http_send_refresh(r);
605 return ngx_http_send_special_response(r, clcf, r->err_status
606 - NGX_HTTP_MOVED_PERMANENTLY
607 + NGX_HTTP_OFF_3XX);
611 static ngx_int_t
612 ngx_http_send_special_response(ngx_http_request_t *r,
613 ngx_http_core_loc_conf_t *clcf, ngx_uint_t err)
615 u_char *tail;
616 size_t len;
617 ngx_int_t rc;
618 ngx_buf_t *b;
619 ngx_uint_t msie_padding;
620 ngx_chain_t out[3];
622 if (clcf->server_tokens) {
623 len = sizeof(ngx_http_error_full_tail) - 1;
624 tail = ngx_http_error_full_tail;
626 } else {
627 len = sizeof(ngx_http_error_tail) - 1;
628 tail = ngx_http_error_tail;
631 msie_padding = 0;
633 if (ngx_http_error_pages[err].len) {
634 r->headers_out.content_length_n = ngx_http_error_pages[err].len + len;
635 if (clcf->msie_padding
636 && (r->headers_in.msie || r->headers_in.chrome)
637 && r->http_version >= NGX_HTTP_VERSION_10
638 && err >= NGX_HTTP_OFF_4XX)
640 r->headers_out.content_length_n +=
641 sizeof(ngx_http_msie_padding) - 1;
642 msie_padding = 1;
645 r->headers_out.content_type_len = sizeof("text/html") - 1;
646 ngx_str_set(&r->headers_out.content_type, "text/html");
647 r->headers_out.content_type_lowcase = NULL;
649 } else {
650 r->headers_out.content_length_n = 0;
653 if (r->headers_out.content_length) {
654 r->headers_out.content_length->hash = 0;
655 r->headers_out.content_length = NULL;
658 ngx_http_clear_accept_ranges(r);
659 ngx_http_clear_last_modified(r);
660 ngx_http_clear_etag(r);
662 rc = ngx_http_send_header(r);
664 if (rc == NGX_ERROR || r->header_only) {
665 return rc;
668 if (ngx_http_error_pages[err].len == 0) {
669 return ngx_http_send_special(r, NGX_HTTP_LAST);
672 b = ngx_calloc_buf(r->pool);
673 if (b == NULL) {
674 return NGX_ERROR;
677 b->memory = 1;
678 b->pos = ngx_http_error_pages[err].data;
679 b->last = ngx_http_error_pages[err].data + ngx_http_error_pages[err].len;
681 out[0].buf = b;
682 out[0].next = &out[1];
684 b = ngx_calloc_buf(r->pool);
685 if (b == NULL) {
686 return NGX_ERROR;
689 b->memory = 1;
691 b->pos = tail;
692 b->last = tail + len;
694 out[1].buf = b;
695 out[1].next = NULL;
697 if (msie_padding) {
698 b = ngx_calloc_buf(r->pool);
699 if (b == NULL) {
700 return NGX_ERROR;
703 b->memory = 1;
704 b->pos = ngx_http_msie_padding;
705 b->last = ngx_http_msie_padding + sizeof(ngx_http_msie_padding) - 1;
707 out[1].next = &out[2];
708 out[2].buf = b;
709 out[2].next = NULL;
712 if (r == r->main) {
713 b->last_buf = 1;
716 b->last_in_chain = 1;
718 return ngx_http_output_filter(r, &out[0]);
722 static ngx_int_t
723 ngx_http_send_refresh(ngx_http_request_t *r)
725 u_char *p, *location;
726 size_t len, size;
727 uintptr_t escape;
728 ngx_int_t rc;
729 ngx_buf_t *b;
730 ngx_chain_t out;
732 len = r->headers_out.location->value.len;
733 location = r->headers_out.location->value.data;
735 escape = 2 * ngx_escape_uri(NULL, location, len, NGX_ESCAPE_REFRESH);
737 size = sizeof(ngx_http_msie_refresh_head) - 1
738 + escape + len
739 + sizeof(ngx_http_msie_refresh_tail) - 1;
741 r->err_status = NGX_HTTP_OK;
743 r->headers_out.content_type_len = sizeof("text/html") - 1;
744 ngx_str_set(&r->headers_out.content_type, "text/html");
745 r->headers_out.content_type_lowcase = NULL;
747 r->headers_out.location->hash = 0;
748 r->headers_out.location = NULL;
750 r->headers_out.content_length_n = size;
752 if (r->headers_out.content_length) {
753 r->headers_out.content_length->hash = 0;
754 r->headers_out.content_length = NULL;
757 ngx_http_clear_accept_ranges(r);
758 ngx_http_clear_last_modified(r);
759 ngx_http_clear_etag(r);
761 rc = ngx_http_send_header(r);
763 if (rc == NGX_ERROR || r->header_only) {
764 return rc;
767 b = ngx_create_temp_buf(r->pool, size);
768 if (b == NULL) {
769 return NGX_ERROR;
772 p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
773 sizeof(ngx_http_msie_refresh_head) - 1);
775 if (escape == 0) {
776 p = ngx_cpymem(p, location, len);
778 } else {
779 p = (u_char *) ngx_escape_uri(p, location, len, NGX_ESCAPE_REFRESH);
782 b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
783 sizeof(ngx_http_msie_refresh_tail) - 1);
785 b->last_buf = 1;
786 b->last_in_chain = 1;
788 out.buf = b;
789 out.next = NULL;
791 return ngx_http_output_filter(r, &out);