blob: 9a5dea1f85f276095059563845c12b700fa2b1ea [file] [log] [blame]
Igor Sysoevb0869052002-12-10 18:05:12 +00001
Igor Sysoevb0869052002-12-10 18:05:12 +00002#include <ngx_config.h>
Igor Sysoevb0869052002-12-10 18:05:12 +00003#include <ngx_core.h>
Igor Sysoevb0869052002-12-10 18:05:12 +00004#include <ngx_http.h>
Igor Sysoev7578ec92003-06-02 15:24:30 +00005#include <nginx.h>
Igor Sysoev73009772003-02-06 17:21:13 +00006
Igor Sysoevb0869052002-12-10 18:05:12 +00007
Igor Sysoev42feecb2002-12-15 06:25:09 +00008static char error_tail[] =
9"<hr><center>" NGINX_VER "</center>" CRLF
10"</body>" CRLF
11"</html>" CRLF
12;
13
Igor Sysoev73009772003-02-06 17:21:13 +000014
Igor Sysoev7578ec92003-06-02 15:24:30 +000015static char error_302_page[] =
16"<html>" CRLF
17"<head><title>302 Found</title></head>" CRLF
18"<body bgcolor=\"white\">" CRLF
19"<center><h1>302 Found</h1></center>" CRLF
20;
21
22
Igor Sysoev42feecb2002-12-15 06:25:09 +000023static char error_400_page[] =
24"<html>" CRLF
25"<head><title>400 Bad Request</title></head>" CRLF
26"<body bgcolor=\"white\">" CRLF
27"<center><h1>400 Bad Request</h1></center>" CRLF
28;
29
Igor Sysoev73009772003-02-06 17:21:13 +000030
Igor Sysoevb2620632003-01-10 06:09:20 +000031static char error_403_page[] =
32"<html>" CRLF
33"<head><title>403 Forbidden</title></head>" CRLF
34"<body bgcolor=\"white\">" CRLF
35"<center><h1>403 Forbidden</h1></center>" CRLF
36;
37
Igor Sysoev73009772003-02-06 17:21:13 +000038
Igor Sysoev42feecb2002-12-15 06:25:09 +000039static char error_404_page[] =
40"<html>" CRLF
41"<head><title>404 Not Found</title></head>" CRLF
42"<body bgcolor=\"white\">" CRLF
43"<center><h1>404 Not Found</h1></center>" CRLF
44;
45
Igor Sysoev73009772003-02-06 17:21:13 +000046
Igor Sysoev6253ca12003-05-27 12:18:54 +000047static char error_405_page[] =
48"<html>" CRLF
49"<head><title>405 Not Allowed</title></head>" CRLF
50"<body bgcolor=\"white\">" CRLF
51"<center><h1>405 Not Allowed</h1></center>" CRLF
52;
53
54
Igor Sysoevdc479b42003-03-20 16:09:44 +000055static char error_408_page[] =
56"<html>" CRLF
57"<head><title>408 Request Time-out</title></head>" CRLF
58"<body bgcolor=\"white\">" CRLF
59"<center><h1>408 Request Time-out</h1></center>" CRLF
60;
61
62
Igor Sysoevb7387572003-03-11 20:38:13 +000063static char error_414_page[] =
64"<html>" CRLF
65"<head><title>414 Request-URI Too Large</title></head>" CRLF
66"<body bgcolor=\"white\">" CRLF
67"<center><h1>414 Request-URI Too Large</h1></center>" CRLF
68;
69
70
Igor Sysoev7578ec92003-06-02 15:24:30 +000071static char error_416_page[] =
72"<html>" CRLF
73"<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
74"<body bgcolor=\"white\">" CRLF
75"<center><h1>416 Requested Range Not Satisfiable</h1></center>" CRLF
76;
77
78
Igor Sysoevad22e012003-01-15 07:02:27 +000079static char error_500_page[] =
80"<html>" CRLF
81"<head><title>500 Internal Server Error</title></head>" CRLF
82"<body bgcolor=\"white\">" CRLF
83"<center><h1>500 Internal Server Error</h1></center>" CRLF
84;
85
Igor Sysoev42feecb2002-12-15 06:25:09 +000086
Igor Sysoevdc479b42003-03-20 16:09:44 +000087static char error_502_page[] =
88"<html>" CRLF
89"<head><title>502 Bad Gateway</title></head>" CRLF
90"<body bgcolor=\"white\">" CRLF
91"<center><h1>502 Bad Gateway</h1></center>" CRLF
92;
93
94
95static char error_504_page[] =
96"<html>" CRLF
97"<head><title>504 Gateway Time-out</title></head>" CRLF
98"<body bgcolor=\"white\">" CRLF
99"<center><h1>504 Gateway Time-out</h1></center>" CRLF
100;
101
102
Igor Sysoev42feecb2002-12-15 06:25:09 +0000103static ngx_str_t error_pages[] = {
Igor Sysoev7578ec92003-06-02 15:24:30 +0000104 ngx_null_string, /* 300 */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000105 ngx_null_string, /* 301 */
Igor Sysoev7578ec92003-06-02 15:24:30 +0000106 ngx_string(error_302_page),
Igor Sysoevdc479b42003-03-20 16:09:44 +0000107 ngx_null_string, /* 303 */
Igor Sysoev42feecb2002-12-15 06:25:09 +0000108
Igor Sysoevdc479b42003-03-20 16:09:44 +0000109 ngx_string(error_400_page),
110 ngx_null_string, /* 401 */
111 ngx_null_string, /* 402 */
112 ngx_string(error_403_page),
113 ngx_string(error_404_page),
Igor Sysoev6253ca12003-05-27 12:18:54 +0000114 ngx_string(error_405_page),
Igor Sysoevdc479b42003-03-20 16:09:44 +0000115 ngx_null_string, /* 406 */
116 ngx_null_string, /* 407 */
117 ngx_string(error_408_page),
118 ngx_null_string, /* 409 */
119 ngx_null_string, /* 410 */
120 ngx_null_string, /* 411 */
121 ngx_null_string, /* 412 */
122 ngx_null_string, /* 413 */
123 ngx_string(error_414_page),
124 ngx_null_string, /* 415 */
Igor Sysoev7578ec92003-06-02 15:24:30 +0000125 ngx_string(error_416_page),
Igor Sysoev42feecb2002-12-15 06:25:09 +0000126
Igor Sysoevdc479b42003-03-20 16:09:44 +0000127 ngx_string(error_500_page),
128 ngx_null_string, /* 501 */
129 ngx_string(error_502_page),
130 ngx_null_string, /* 503 */
131 ngx_string(error_504_page)
Igor Sysoev42feecb2002-12-15 06:25:09 +0000132};
Igor Sysoevb0869052002-12-10 18:05:12 +0000133
Igor Sysoev73009772003-02-06 17:21:13 +0000134
Igor Sysoevdc479b42003-03-20 16:09:44 +0000135int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
Igor Sysoevb0869052002-12-10 18:05:12 +0000136{
Igor Sysoev7578ec92003-06-02 15:24:30 +0000137 int err;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000138 ngx_hunk_t *message, *tail;
Igor Sysoevb0869052002-12-10 18:05:12 +0000139
Igor Sysoev42feecb2002-12-15 06:25:09 +0000140 r->headers_out.status = error;
Igor Sysoevb0869052002-12-10 18:05:12 +0000141
Igor Sysoev90ace682003-03-12 17:32:22 +0000142 if (error < NGX_HTTP_BAD_REQUEST) {
Igor Sysoev79a80482003-05-14 17:13:13 +0000143 /* 3XX */
Igor Sysoev42feecb2002-12-15 06:25:09 +0000144 err = error - NGX_HTTP_MOVED_PERMANENTLY;
145
Igor Sysoev7578ec92003-06-02 15:24:30 +0000146 } else if (error < NGX_HTTP_INTERNAL_SERVER_ERROR) {
147 /* 4XX */
148 err = error - NGX_HTTP_BAD_REQUEST + 4;
149
Igor Sysoev90ace682003-03-12 17:32:22 +0000150 } else {
Igor Sysoev7578ec92003-06-02 15:24:30 +0000151 /* 5XX */
152 err = error - NGX_HTTP_INTERNAL_SERVER_ERROR + 4 + 17;
Igor Sysoev90ace682003-03-12 17:32:22 +0000153 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000154
Igor Sysoev90ace682003-03-12 17:32:22 +0000155 if (r->keepalive != 0) {
156 switch (error) {
157 case NGX_HTTP_BAD_REQUEST:
158 case NGX_HTTP_REQUEST_URI_TOO_LARGE:
159 case NGX_HTTP_INTERNAL_SERVER_ERROR:
160 r->keepalive = 0;
161 }
162 }
163
Igor Sysoev79a80482003-05-14 17:13:13 +0000164 if (r->lingering_close == 1) {
165 switch (error) {
166 case NGX_HTTP_BAD_REQUEST:
167 case NGX_HTTP_REQUEST_URI_TOO_LARGE:
168 case NGX_HTTP_INTERNAL_SERVER_ERROR:
169 r->lingering_close = 0;
170 }
171 }
172
Igor Sysoev7578ec92003-06-02 15:24:30 +0000173 if (error_pages[err].len) {
Igor Sysoev42feecb2002-12-15 06:25:09 +0000174 r->headers_out.content_length = error_pages[err].len
Igor Sysoev7578ec92003-06-02 15:24:30 +0000175 + sizeof(error_tail);
176
177 ngx_test_null(r->headers_out.content_type,
178 ngx_push_table(r->headers_out.headers),
179 NGX_HTTP_INTERNAL_SERVER_ERROR);
180
181 r->headers_out.content_type->key.len = 12;
182 r->headers_out.content_type->key.data = "Content-Type";
183 r->headers_out.content_type->value.len = 9;
184 r->headers_out.content_type->value.data = "text/html";
185
186 } else {
187 r->headers_out.content_length = -1;
Igor Sysoev90ace682003-03-12 17:32:22 +0000188 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000189
Igor Sysoev73009772003-02-06 17:21:13 +0000190 if (ngx_http_send_header(r) == NGX_ERROR) {
191 return NGX_ERROR;
192 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000193
Igor Sysoev73009772003-02-06 17:21:13 +0000194 if (error_pages[err].len == 0) {
Igor Sysoev42feecb2002-12-15 06:25:09 +0000195 return NGX_OK;
Igor Sysoev73009772003-02-06 17:21:13 +0000196 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000197
Igor Sysoev73009772003-02-06 17:21:13 +0000198 ngx_test_null(message, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), NGX_ERROR);
Igor Sysoev42feecb2002-12-15 06:25:09 +0000199
Igor Sysoevb7387572003-03-11 20:38:13 +0000200 message->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
201 message->pos = error_pages[err].data;
202 message->last = error_pages[err].data + error_pages[err].len;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000203
Igor Sysoev73009772003-02-06 17:21:13 +0000204 if (ngx_http_output_filter(r, message) == NGX_ERROR) {
205 return NGX_ERROR;
206 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000207
Igor Sysoev73009772003-02-06 17:21:13 +0000208 ngx_test_null(tail, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), NGX_ERROR);
Igor Sysoev42feecb2002-12-15 06:25:09 +0000209
Igor Sysoevb7387572003-03-11 20:38:13 +0000210 tail->type = NGX_HUNK_MEMORY|NGX_HUNK_LAST|NGX_HUNK_IN_MEMORY;
211 tail->pos = error_tail;
212 tail->last = error_tail + sizeof(error_tail);
Igor Sysoev42feecb2002-12-15 06:25:09 +0000213
Igor Sysoev73009772003-02-06 17:21:13 +0000214 return ngx_http_output_filter(r, tail);
Igor Sysoevb0869052002-12-10 18:05:12 +0000215}