Mercurial > hg > nginx-vendor-0-7
comparison src/http/ngx_http_special_response.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | 45fe5b98a9de |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0b350454894 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 #include <nginx.h> | |
11 | |
12 | |
13 static u_char error_tail[] = | |
14 "<hr><center>" NGINX_VER "</center>" CRLF | |
15 "</body>" CRLF | |
16 "</html>" CRLF | |
17 ; | |
18 | |
19 | |
20 static u_char msie_stub[] = | |
21 "<!-- The padding to disable MSIE's friendly error page -->" CRLF | |
22 "<!-- 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 | |
25 "<!-- The padding to disable MSIE's friendly error page -->" CRLF | |
26 "<!-- The padding to disable MSIE's friendly error page -->" CRLF | |
27 ; | |
28 | |
29 | |
30 static char error_301_page[] = | |
31 "<html>" CRLF | |
32 "<head><title>301 Moved Permanently</title></head>" CRLF | |
33 "<body bgcolor=\"white\">" CRLF | |
34 "<center><h1>301 Moved Permanently</h1></center>" CRLF | |
35 ; | |
36 | |
37 | |
38 static char error_302_page[] = | |
39 "<html>" CRLF | |
40 "<head><title>302 Found</title></head>" CRLF | |
41 "<body bgcolor=\"white\">" CRLF | |
42 "<center><h1>302 Found</h1></center>" CRLF | |
43 ; | |
44 | |
45 | |
46 static char error_400_page[] = | |
47 "<html>" CRLF | |
48 "<head><title>400 Bad Request</title></head>" CRLF | |
49 "<body bgcolor=\"white\">" CRLF | |
50 "<center><h1>400 Bad Request</h1></center>" CRLF | |
51 ; | |
52 | |
53 | |
54 static char error_403_page[] = | |
55 "<html>" CRLF | |
56 "<head><title>403 Forbidden</title></head>" CRLF | |
57 "<body bgcolor=\"white\">" CRLF | |
58 "<center><h1>403 Forbidden</h1></center>" CRLF | |
59 ; | |
60 | |
61 | |
62 static char error_404_page[] = | |
63 "<html>" CRLF | |
64 "<head><title>404 Not Found</title></head>" CRLF | |
65 "<body bgcolor=\"white\">" CRLF | |
66 "<center><h1>404 Not Found</h1></center>" CRLF | |
67 ; | |
68 | |
69 | |
70 static char error_405_page[] = | |
71 "<html>" CRLF | |
72 "<head><title>405 Not Allowed</title></head>" CRLF | |
73 "<body bgcolor=\"white\">" CRLF | |
74 "<center><h1>405 Not Allowed</h1></center>" CRLF | |
75 ; | |
76 | |
77 | |
78 static char error_408_page[] = | |
79 "<html>" CRLF | |
80 "<head><title>408 Request Time-out</title></head>" CRLF | |
81 "<body bgcolor=\"white\">" CRLF | |
82 "<center><h1>408 Request Time-out</h1></center>" CRLF | |
83 ; | |
84 | |
85 | |
86 static char error_413_page[] = | |
87 "<html>" CRLF | |
88 "<head><title>413 Request Entity Too Large</title></head>" CRLF | |
89 "<body bgcolor=\"white\">" CRLF | |
90 "<center><h1>413 Request Entity Too Large</h1></center>" CRLF | |
91 ; | |
92 | |
93 | |
94 static char error_414_page[] = | |
95 "<html>" CRLF | |
96 "<head><title>414 Request-URI Too Large</title></head>" CRLF | |
97 "<body bgcolor=\"white\">" CRLF | |
98 "<center><h1>414 Request-URI Too Large</h1></center>" CRLF | |
99 ; | |
100 | |
101 | |
102 static char error_416_page[] = | |
103 "<html>" CRLF | |
104 "<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF | |
105 "<body bgcolor=\"white\">" CRLF | |
106 "<center><h1>416 Requested Range Not Satisfiable</h1></center>" CRLF | |
107 ; | |
108 | |
109 | |
110 static char error_497_page[] = | |
111 "<html>" CRLF | |
112 "<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>" | |
113 CRLF | |
114 "<body bgcolor=\"white\">" CRLF | |
115 "<center><h1>400 Bad Request</h1></center>" CRLF | |
116 "<center>The plain HTTP request was sent to HTTPS port</center>" CRLF | |
117 ; | |
118 | |
119 | |
120 static char error_500_page[] = | |
121 "<html>" CRLF | |
122 "<head><title>500 Internal Server Error</title></head>" CRLF | |
123 "<body bgcolor=\"white\">" CRLF | |
124 "<center><h1>500 Internal Server Error</h1></center>" CRLF | |
125 ; | |
126 | |
127 | |
128 static char error_501_page[] = | |
129 "<html>" CRLF | |
130 "<head><title>501 Method Not Implemented</title></head>" CRLF | |
131 "<body bgcolor=\"white\">" CRLF | |
132 "<center><h1>500 Method Not Implemented</h1></center>" CRLF | |
133 ; | |
134 | |
135 | |
136 static char error_502_page[] = | |
137 "<html>" CRLF | |
138 "<head><title>502 Bad Gateway</title></head>" CRLF | |
139 "<body bgcolor=\"white\">" CRLF | |
140 "<center><h1>502 Bad Gateway</h1></center>" CRLF | |
141 ; | |
142 | |
143 | |
144 static char error_503_page[] = | |
145 "<html>" CRLF | |
146 "<head><title>503 Service Temporarily Unavailable</title></head>" CRLF | |
147 "<body bgcolor=\"white\">" CRLF | |
148 "<center><h1>503 Service Temporarily Unavailable</h1></center>" CRLF | |
149 ; | |
150 | |
151 | |
152 static char error_504_page[] = | |
153 "<html>" CRLF | |
154 "<head><title>504 Gateway Time-out</title></head>" CRLF | |
155 "<body bgcolor=\"white\">" CRLF | |
156 "<center><h1>504 Gateway Time-out</h1></center>" CRLF | |
157 ; | |
158 | |
159 | |
160 static ngx_str_t error_pages[] = { | |
161 /* ngx_null_string, */ /* 300 */ | |
162 ngx_string(error_301_page), | |
163 ngx_string(error_302_page), | |
164 ngx_null_string, /* 303 */ | |
165 | |
166 ngx_string(error_400_page), | |
167 ngx_null_string, /* 401 */ | |
168 ngx_null_string, /* 402 */ | |
169 ngx_string(error_403_page), | |
170 ngx_string(error_404_page), | |
171 ngx_string(error_405_page), | |
172 ngx_null_string, /* 406 */ | |
173 ngx_null_string, /* 407 */ | |
174 ngx_string(error_408_page), | |
175 ngx_null_string, /* 409 */ | |
176 ngx_null_string, /* 410 */ | |
177 ngx_null_string, /* 411 */ | |
178 ngx_null_string, /* 412 */ | |
179 ngx_string(error_413_page), | |
180 ngx_string(error_414_page), | |
181 ngx_null_string, /* 415 */ | |
182 ngx_string(error_416_page), | |
183 | |
184 ngx_string(error_497_page), /* 497, http to https */ | |
185 ngx_string(error_404_page), /* 498, invalid host name */ | |
186 ngx_null_string, /* 499, client closed connection */ | |
187 | |
188 ngx_string(error_500_page), | |
189 ngx_string(error_501_page), | |
190 ngx_string(error_502_page), | |
191 ngx_string(error_503_page), | |
192 ngx_string(error_504_page) | |
193 }; | |
194 | |
195 | |
196 ngx_int_t ngx_http_special_response_handler(ngx_http_request_t *r, int error) | |
197 { | |
198 ngx_int_t rc; | |
199 ngx_uint_t err, i, msie_padding; | |
200 ngx_buf_t *b; | |
201 ngx_chain_t *out, **ll, *cl; | |
202 ngx_http_err_page_t *err_page; | |
203 ngx_http_core_loc_conf_t *clcf; | |
204 | |
205 rc = ngx_http_discard_body(r); | |
206 | |
207 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { | |
208 error = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
209 } | |
210 | |
211 r->headers_out.status = error; | |
212 | |
213 if (r->keepalive != 0) { | |
214 switch (error) { | |
215 case NGX_HTTP_BAD_REQUEST: | |
216 case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE: | |
217 case NGX_HTTP_REQUEST_URI_TOO_LARGE: | |
218 case NGX_HTTP_TO_HTTPS: | |
219 case NGX_HTTP_INTERNAL_SERVER_ERROR: | |
220 r->keepalive = 0; | |
221 } | |
222 } | |
223 | |
224 if (r->lingering_close == 1) { | |
225 switch (error) { | |
226 case NGX_HTTP_BAD_REQUEST: | |
227 case NGX_HTTP_TO_HTTPS: | |
228 r->lingering_close = 0; | |
229 } | |
230 } | |
231 | |
232 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
233 | |
234 if (r->err_ctx == NULL && clcf->error_pages) { | |
235 err_page = clcf->error_pages->elts; | |
236 for (i = 0; i < clcf->error_pages->nelts; i++) { | |
237 if (err_page[i].status == error) { | |
238 if (err_page[i].overwrite) { | |
239 r->err_status = err_page[i].overwrite; | |
240 } else { | |
241 r->err_status = error; | |
242 } | |
243 r->err_ctx = r->ctx; | |
244 return ngx_http_internal_redirect(r, &err_page[i].uri, NULL); | |
245 } | |
246 } | |
247 } | |
248 | |
249 if (error < NGX_HTTP_BAD_REQUEST) { | |
250 /* 3XX */ | |
251 err = error - NGX_HTTP_MOVED_PERMANENTLY; | |
252 | |
253 } else if (error < NGX_HTTP_NGX_CODES) { | |
254 /* 4XX */ | |
255 err = error - NGX_HTTP_BAD_REQUEST + 3; | |
256 | |
257 } else { | |
258 /* 49X, 5XX */ | |
259 err = error - NGX_HTTP_NGX_CODES + 3 + 17; | |
260 | |
261 switch (error) { | |
262 case NGX_HTTP_TO_HTTPS: | |
263 r->headers_out.status = NGX_HTTP_BAD_REQUEST; | |
264 error = NGX_HTTP_BAD_REQUEST; | |
265 break; | |
266 | |
267 case NGX_HTTP_INVALID_HOST: | |
268 r->headers_out.status = NGX_HTTP_NOT_FOUND; | |
269 error = NGX_HTTP_NOT_FOUND; | |
270 break; | |
271 } | |
272 } | |
273 | |
274 msie_padding = 0; | |
275 | |
276 if (error_pages[err].len) { | |
277 r->headers_out.content_length_n = error_pages[err].len | |
278 + sizeof(error_tail) - 1; | |
279 | |
280 if (clcf->msie_padding | |
281 && r->headers_in.msie | |
282 && r->http_version >= NGX_HTTP_VERSION_10 | |
283 && error >= NGX_HTTP_BAD_REQUEST | |
284 && error != NGX_HTTP_REQUEST_URI_TOO_LARGE) | |
285 { | |
286 r->headers_out.content_length_n += sizeof(msie_stub) - 1; | |
287 msie_padding = 1; | |
288 } | |
289 | |
290 r->headers_out.content_type = ngx_list_push(&r->headers_out.headers); | |
291 if (r->headers_out.content_type == NULL) { | |
292 return NGX_ERROR; | |
293 } | |
294 | |
295 r->headers_out.content_type->key.len = sizeof("Content-Type") - 1; | |
296 r->headers_out.content_type->key.data = (u_char *) "Content-Type"; | |
297 r->headers_out.content_type->value.len = sizeof("text/html") - 1; | |
298 r->headers_out.content_type->value.data = (u_char *) "text/html"; | |
299 | |
300 } else { | |
301 r->headers_out.content_length_n = -1; | |
302 } | |
303 | |
304 if (r->headers_out.content_length) { | |
305 r->headers_out.content_length->key.len = 0; | |
306 r->headers_out.content_length = NULL; | |
307 } | |
308 | |
309 rc = ngx_http_send_header(r); | |
310 | |
311 if (rc == NGX_ERROR || r->header_only) { | |
312 return rc; | |
313 } | |
314 | |
315 if (error_pages[err].len == 0) { | |
316 return NGX_OK; | |
317 } | |
318 | |
319 out = NULL; | |
320 ll = NULL; | |
321 | |
322 if (!(b = ngx_calloc_buf(r->pool))) { | |
323 return NGX_ERROR; | |
324 } | |
325 b->memory = 1; | |
326 b->pos = error_pages[err].data; | |
327 b->last = error_pages[err].data + error_pages[err].len; | |
328 | |
329 ngx_alloc_link_and_set_buf(cl, b, r->pool, NGX_ERROR); | |
330 ngx_chain_add_link(out, ll, cl); | |
331 | |
332 | |
333 if (!(b = ngx_calloc_buf(r->pool))) { | |
334 return NGX_ERROR; | |
335 } | |
336 b->memory = 1; | |
337 b->pos = error_tail; | |
338 b->last = error_tail + sizeof(error_tail) - 1; | |
339 | |
340 ngx_alloc_link_and_set_buf(cl, b, r->pool, NGX_ERROR); | |
341 ngx_chain_add_link(out, ll, cl); | |
342 | |
343 if (msie_padding) { | |
344 if (!(b = ngx_calloc_buf(r->pool))) { | |
345 return NGX_ERROR; | |
346 } | |
347 b->memory = 1; | |
348 b->pos = msie_stub; | |
349 b->last = msie_stub + sizeof(msie_stub) - 1; | |
350 | |
351 ngx_alloc_link_and_set_buf(cl, b, r->pool, NGX_ERROR); | |
352 ngx_chain_add_link(out, ll, cl); | |
353 } | |
354 | |
355 b->last_buf = 1; | |
356 | |
357 return ngx_http_output_filter(r, out); | |
358 } |