~cyphermox/ubuntu/lucid/nginx/merge_0.7.64-2_lp513099

« back to all changes in this revision

Viewing changes to src/http/ngx_http_special_response.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio Tranchitella
  • Date: 2008-02-10 17:57:57 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080210175757-n8uesiel5a7j2wma
Tags: 0.5.35-2
debian/init.d: do not break if start-stop-daemon exits with an error.
(Closes: #464453)

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include <nginx.h>
11
11
 
12
12
 
13
 
static u_char error_tail[] =
 
13
static ngx_int_t ngx_http_send_error_page(ngx_http_request_t *r,
 
14
    ngx_http_err_page_t *err_page);
 
15
static ngx_int_t ngx_http_send_special_response(ngx_http_request_t *r,
 
16
    ngx_http_core_loc_conf_t *clcf, ngx_uint_t err);
 
17
static ngx_int_t ngx_http_send_refresh(ngx_http_request_t *r);
 
18
 
 
19
 
 
20
static u_char ngx_http_error_full_tail[] =
14
21
"<hr><center>" NGINX_VER "</center>" CRLF
15
22
"</body>" CRLF
16
23
"</html>" CRLF
17
24
;
18
25
 
19
26
 
 
27
static u_char ngx_http_error_tail[] =
 
28
"<hr><center>nginx</center>" CRLF
 
29
"</body>" CRLF
 
30
"</html>" CRLF
 
31
;
 
32
 
 
33
 
20
34
static u_char ngx_http_msie_stub[] =
21
35
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
22
36
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
35
49
"\"></head><body></body></html>" CRLF;
36
50
 
37
51
 
38
 
static char error_301_page[] =
 
52
static char ngx_http_error_301_page[] =
39
53
"<html>" CRLF
40
54
"<head><title>301 Moved Permanently</title></head>" CRLF
41
55
"<body bgcolor=\"white\">" CRLF
43
57
;
44
58
 
45
59
 
46
 
static char error_302_page[] =
 
60
static char ngx_http_error_302_page[] =
47
61
"<html>" CRLF
48
62
"<head><title>302 Found</title></head>" CRLF
49
63
"<body bgcolor=\"white\">" CRLF
51
65
;
52
66
 
53
67
 
54
 
static char error_400_page[] =
 
68
static char ngx_http_error_400_page[] =
55
69
"<html>" CRLF
56
70
"<head><title>400 Bad Request</title></head>" CRLF
57
71
"<body bgcolor=\"white\">" CRLF
59
73
;
60
74
 
61
75
 
62
 
static char error_401_page[] =
 
76
static char ngx_http_error_401_page[] =
63
77
"<html>" CRLF
64
78
"<head><title>401 Authorization Required</title></head>" CRLF
65
79
"<body bgcolor=\"white\">" CRLF
67
81
;
68
82
 
69
83
 
70
 
static char error_402_page[] =
 
84
static char ngx_http_error_402_page[] =
71
85
"<html>" CRLF
72
86
"<head><title>402 Payment Required</title></head>" CRLF
73
87
"<body bgcolor=\"white\">" CRLF
75
89
;
76
90
 
77
91
 
78
 
static char error_403_page[] =
 
92
static char ngx_http_error_403_page[] =
79
93
"<html>" CRLF
80
94
"<head><title>403 Forbidden</title></head>" CRLF
81
95
"<body bgcolor=\"white\">" CRLF
83
97
;
84
98
 
85
99
 
86
 
static char error_404_page[] =
 
100
static char ngx_http_error_404_page[] =
87
101
"<html>" CRLF
88
102
"<head><title>404 Not Found</title></head>" CRLF
89
103
"<body bgcolor=\"white\">" CRLF
91
105
;
92
106
 
93
107
 
94
 
static char error_405_page[] =
 
108
static char ngx_http_error_405_page[] =
95
109
"<html>" CRLF
96
110
"<head><title>405 Not Allowed</title></head>" CRLF
97
111
"<body bgcolor=\"white\">" CRLF
99
113
;
100
114
 
101
115
 
102
 
static char error_406_page[] =
 
116
static char ngx_http_error_406_page[] =
103
117
"<html>" CRLF
104
118
"<head><title>406 Not Acceptable</title></head>" CRLF
105
119
"<body bgcolor=\"white\">" CRLF
107
121
;
108
122
 
109
123
 
110
 
static char error_408_page[] =
 
124
static char ngx_http_error_408_page[] =
111
125
"<html>" CRLF
112
126
"<head><title>408 Request Time-out</title></head>" CRLF
113
127
"<body bgcolor=\"white\">" CRLF
115
129
;
116
130
 
117
131
 
118
 
static char error_409_page[] =
 
132
static char ngx_http_error_409_page[] =
119
133
"<html>" CRLF
120
134
"<head><title>409 Conflict</title></head>" CRLF
121
135
"<body bgcolor=\"white\">" CRLF
123
137
;
124
138
 
125
139
 
126
 
static char error_410_page[] =
 
140
static char ngx_http_error_410_page[] =
127
141
"<html>" CRLF
128
142
"<head><title>410 Gone</title></head>" CRLF
129
143
"<body bgcolor=\"white\">" CRLF
131
145
;
132
146
 
133
147
 
134
 
static char error_411_page[] =
 
148
static char ngx_http_error_411_page[] =
135
149
"<html>" CRLF
136
150
"<head><title>411 Length Required</title></head>" CRLF
137
151
"<body bgcolor=\"white\">" CRLF
139
153
;
140
154
 
141
155
 
142
 
static char error_412_page[] =
 
156
static char ngx_http_error_412_page[] =
143
157
"<html>" CRLF
144
158
"<head><title>412 Precondition Failed</title></head>" CRLF
145
159
"<body bgcolor=\"white\">" CRLF
147
161
;
148
162
 
149
163
 
150
 
static char error_413_page[] =
 
164
static char ngx_http_error_413_page[] =
151
165
"<html>" CRLF
152
166
"<head><title>413 Request Entity Too Large</title></head>" CRLF
153
167
"<body bgcolor=\"white\">" CRLF
155
169
;
156
170
 
157
171
 
158
 
static char error_414_page[] =
 
172
static char ngx_http_error_414_page[] =
159
173
"<html>" CRLF
160
174
"<head><title>414 Request-URI Too Large</title></head>" CRLF
161
175
"<body bgcolor=\"white\">" CRLF
163
177
;
164
178
 
165
179
 
166
 
static char error_415_page[] =
 
180
static char ngx_http_error_415_page[] =
167
181
"<html>" CRLF
168
182
"<head><title>415 Unsupported Media Type</title></head>" CRLF
169
183
"<body bgcolor=\"white\">" CRLF
171
185
;
172
186
 
173
187
 
174
 
static char error_416_page[] =
 
188
static char ngx_http_error_416_page[] =
175
189
"<html>" CRLF
176
190
"<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
177
191
"<body bgcolor=\"white\">" CRLF
179
193
;
180
194
 
181
195
 
182
 
static char error_495_page[] =
 
196
static char ngx_http_error_495_page[] =
183
197
"<html>" CRLF
184
198
"<head><title>400 The SSL certificate error</title></head>"
185
199
CRLF
189
203
;
190
204
 
191
205
 
192
 
static char error_496_page[] =
 
206
static char ngx_http_error_496_page[] =
193
207
"<html>" CRLF
194
208
"<head><title>400 No required SSL certificate was sent</title></head>"
195
209
CRLF
199
213
;
200
214
 
201
215
 
202
 
static char error_497_page[] =
 
216
static char ngx_http_error_497_page[] =
203
217
"<html>" CRLF
204
218
"<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>"
205
219
CRLF
209
223
;
210
224
 
211
225
 
212
 
static char error_500_page[] =
 
226
static char ngx_http_error_500_page[] =
213
227
"<html>" CRLF
214
228
"<head><title>500 Internal Server Error</title></head>" CRLF
215
229
"<body bgcolor=\"white\">" CRLF
217
231
;
218
232
 
219
233
 
220
 
static char error_501_page[] =
 
234
static char ngx_http_error_501_page[] =
221
235
"<html>" CRLF
222
236
"<head><title>501 Method Not Implemented</title></head>" CRLF
223
237
"<body bgcolor=\"white\">" CRLF
225
239
;
226
240
 
227
241
 
228
 
static char error_502_page[] =
 
242
static char ngx_http_error_502_page[] =
229
243
"<html>" CRLF
230
244
"<head><title>502 Bad Gateway</title></head>" CRLF
231
245
"<body bgcolor=\"white\">" CRLF
233
247
;
234
248
 
235
249
 
236
 
static char error_503_page[] =
 
250
static char ngx_http_error_503_page[] =
237
251
"<html>" CRLF
238
252
"<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
239
253
"<body bgcolor=\"white\">" CRLF
241
255
;
242
256
 
243
257
 
244
 
static char error_504_page[] =
 
258
static char ngx_http_error_504_page[] =
245
259
"<html>" CRLF
246
260
"<head><title>504 Gateway Time-out</title></head>" CRLF
247
261
"<body bgcolor=\"white\">" CRLF
249
263
;
250
264
 
251
265
 
252
 
static char error_507_page[] =
 
266
static char ngx_http_error_507_page[] =
253
267
"<html>" CRLF
254
268
"<head><title>507 Insufficient Storage</title></head>" CRLF
255
269
"<body bgcolor=\"white\">" CRLF
257
271
;
258
272
 
259
273
 
260
 
static ngx_str_t error_pages[] = {
 
274
static ngx_str_t ngx_http_error_pages[] = {
261
275
 
262
 
    ngx_null_string,             /* 201, 204 */
 
276
    ngx_null_string,                     /* 201, 204 */
263
277
 
264
278
#define NGX_HTTP_LEVEL_200  1
265
279
 
266
 
    /* ngx_null_string, */       /* 300 */
267
 
    ngx_string(error_301_page),
268
 
    ngx_string(error_302_page),
269
 
    ngx_null_string,             /* 303 */
 
280
    /* ngx_null_string, */               /* 300 */
 
281
    ngx_string(ngx_http_error_301_page),
 
282
    ngx_string(ngx_http_error_302_page),
 
283
    ngx_null_string,                     /* 303 */
270
284
 
271
285
#define NGX_HTTP_LEVEL_300  3
272
286
 
273
 
    ngx_string(error_400_page),
274
 
    ngx_string(error_401_page),
275
 
    ngx_string(error_402_page),
276
 
    ngx_string(error_403_page),
277
 
    ngx_string(error_404_page),
278
 
    ngx_string(error_405_page),
279
 
    ngx_string(error_406_page),
280
 
    ngx_null_string,             /* 407 */
281
 
    ngx_string(error_408_page),
282
 
    ngx_string(error_409_page),
283
 
    ngx_string(error_410_page),
284
 
    ngx_string(error_411_page),
285
 
    ngx_string(error_412_page),
286
 
    ngx_string(error_413_page),
287
 
    ngx_string(error_414_page),
288
 
    ngx_string(error_415_page),
289
 
    ngx_string(error_416_page),
 
287
    ngx_string(ngx_http_error_400_page),
 
288
    ngx_string(ngx_http_error_401_page),
 
289
    ngx_string(ngx_http_error_402_page),
 
290
    ngx_string(ngx_http_error_403_page),
 
291
    ngx_string(ngx_http_error_404_page),
 
292
    ngx_string(ngx_http_error_405_page),
 
293
    ngx_string(ngx_http_error_406_page),
 
294
    ngx_null_string,                     /* 407 */
 
295
    ngx_string(ngx_http_error_408_page),
 
296
    ngx_string(ngx_http_error_409_page),
 
297
    ngx_string(ngx_http_error_410_page),
 
298
    ngx_string(ngx_http_error_411_page),
 
299
    ngx_string(ngx_http_error_412_page),
 
300
    ngx_string(ngx_http_error_413_page),
 
301
    ngx_string(ngx_http_error_414_page),
 
302
    ngx_string(ngx_http_error_415_page),
 
303
    ngx_string(ngx_http_error_416_page),
290
304
 
291
305
#define NGX_HTTP_LEVEL_400  17
292
306
 
293
 
    ngx_string(error_495_page),  /* 495, https certificate error */
294
 
    ngx_string(error_496_page),  /* 496, https no certificate */
295
 
    ngx_string(error_497_page),  /* 497, http to https */
296
 
    ngx_string(error_404_page),  /* 498, invalid host name */
297
 
    ngx_null_string,             /* 499, client had closed connection */
 
307
    ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
 
308
    ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
 
309
    ngx_string(ngx_http_error_497_page), /* 497, http to https */
 
310
    ngx_string(ngx_http_error_404_page), /* 498, canceled */
 
311
    ngx_null_string,                     /* 499, client has closed connection */
298
312
 
299
 
    ngx_string(error_500_page),
300
 
    ngx_string(error_501_page),
301
 
    ngx_string(error_502_page),
302
 
    ngx_string(error_503_page),
303
 
    ngx_string(error_504_page),
304
 
    ngx_null_string,             /* 505 */
305
 
    ngx_null_string,             /* 506 */
306
 
    ngx_string(error_507_page)
 
313
    ngx_string(ngx_http_error_500_page),
 
314
    ngx_string(ngx_http_error_501_page),
 
315
    ngx_string(ngx_http_error_502_page),
 
316
    ngx_string(ngx_http_error_503_page),
 
317
    ngx_string(ngx_http_error_504_page),
 
318
    ngx_null_string,                     /* 505 */
 
319
    ngx_null_string,                     /* 506 */
 
320
    ngx_string(ngx_http_error_507_page)
307
321
};
308
322
 
309
323
 
313
327
ngx_int_t
314
328
ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
315
329
{
316
 
    u_char                    *p;
317
 
    size_t                     msie_refresh;
318
 
    uintptr_t                  escape;
319
330
    ngx_int_t                  rc;
320
 
    ngx_buf_t                 *b;
321
 
    ngx_str_t                 *uri, *location;
322
 
    ngx_uint_t                 i, n, err, msie_padding;
323
 
    ngx_chain_t               *out, *cl;
 
331
    ngx_uint_t                 i, err;
324
332
    ngx_http_err_page_t       *err_page;
325
333
    ngx_http_core_loc_conf_t  *clcf;
326
334
 
371
379
        err_page = clcf->error_pages->elts;
372
380
 
373
381
        for (i = 0; i < clcf->error_pages->nelts; i++) {
374
 
 
375
382
            if (err_page[i].status == error) {
376
 
                r->err_status = err_page[i].overwrite;
377
 
 
378
 
                r->method = NGX_HTTP_GET;
379
 
                r->method_name = ngx_http_get_name;
380
 
 
381
 
                uri = &err_page[i].uri;
382
 
 
383
 
                if (err_page[i].uri_lengths) {
384
 
                    if (ngx_http_script_run(r, uri,
385
 
                                            err_page[i].uri_lengths->elts, 0,
386
 
                                            err_page[i].uri_values->elts)
387
 
                        == NULL)
388
 
                    {
389
 
                        return NGX_ERROR;
390
 
                    }
391
 
 
392
 
                    if (r->zero_in_uri) {
393
 
                        for (n = 0; n < uri->len; n++) {
394
 
                            if (uri->data[n] == '\0') {
395
 
                                goto zero;
396
 
                            }
397
 
                        }
398
 
 
399
 
                        r->zero_in_uri = 0;
400
 
                    }
401
 
 
402
 
                } else {
403
 
                    r->zero_in_uri = 0;
404
 
                }
405
 
 
406
 
            zero:
407
 
 
408
 
                if (uri->data[0] == '/') {
409
 
                    return ngx_http_internal_redirect(r, uri, NULL);
410
 
                }
411
 
 
412
 
                if (uri->data[0] == '@') {
413
 
                    return ngx_http_named_location(r, uri);
414
 
                }
415
 
 
416
 
                r->headers_out.location =
417
 
                                        ngx_list_push(&r->headers_out.headers);
418
 
 
419
 
                if (r->headers_out.location) {
420
 
                    error = NGX_HTTP_MOVED_TEMPORARILY;
421
 
 
422
 
                    r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
423
 
 
424
 
                    r->headers_out.location->hash = 1;
425
 
                    r->headers_out.location->key.len = sizeof("Location") - 1;
426
 
                    r->headers_out.location->key.data = (u_char *) "Location";
427
 
                    r->headers_out.location->value = *uri;
428
 
 
429
 
                } else {
430
 
                    return NGX_ERROR;
431
 
                }
 
383
                return ngx_http_send_error_page(r, &err_page[i]);
432
384
            }
433
385
        }
434
386
    }
435
387
 
 
388
    if (clcf->msie_refresh
 
389
        && r->headers_in.msie
 
390
        && (error == NGX_HTTP_MOVED_PERMANENTLY
 
391
            || error == NGX_HTTP_MOVED_TEMPORARILY))
 
392
    {
 
393
        return ngx_http_send_refresh(r);
 
394
    }
 
395
 
436
396
    if (error == NGX_HTTP_CREATED) {
437
397
        /* 201 */
438
398
        err = 0;
461
421
            case NGX_HTTPS_CERT_ERROR:
462
422
            case NGX_HTTPS_NO_CERT:
463
423
                r->err_status = NGX_HTTP_BAD_REQUEST;
464
 
                error = NGX_HTTP_BAD_REQUEST;
465
424
                break;
466
425
        }
467
426
    }
468
427
 
 
428
    return ngx_http_send_special_response(r, clcf, err);
 
429
}
 
430
 
 
431
 
 
432
static ngx_int_t
 
433
ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
 
434
{
 
435
    u_char                     ch, *p, *last;
 
436
    ngx_str_t                 *uri, *args, u, a;
 
437
    ngx_table_elt_t           *location;
 
438
    ngx_http_core_loc_conf_t  *clcf;
 
439
 
 
440
    r->err_status = err_page->overwrite;
 
441
 
 
442
    r->method = NGX_HTTP_GET;
 
443
    r->method_name = ngx_http_get_name;
 
444
 
 
445
    r->zero_in_uri = 0;
 
446
 
 
447
    args = NULL;
 
448
 
 
449
    if (err_page->uri_lengths) {
 
450
        if (ngx_http_script_run(r, &u, err_page->uri_lengths->elts, 0,
 
451
                                err_page->uri_values->elts)
 
452
            == NULL)
 
453
        {
 
454
            return NGX_ERROR;
 
455
        }
 
456
 
 
457
        p = u.data;
 
458
        uri = &u;
 
459
 
 
460
        if (*p == '/') {
 
461
 
 
462
            last = p + uri->len;
 
463
 
 
464
            while (p < last) {
 
465
 
 
466
                ch = *p++;
 
467
 
 
468
                if (ch == '?') {
 
469
                    a.len = last - p;
 
470
                    a.data = p;
 
471
                    args = &a;
 
472
 
 
473
                    u.len = p - 1 - u.data;
 
474
 
 
475
                    while (p < last) {
 
476
                        if (*p++ == '\0') {
 
477
                            r->zero_in_uri = 1;
 
478
                            break;
 
479
                        }
 
480
                    }
 
481
 
 
482
                    break;
 
483
                }
 
484
 
 
485
                if (ch == '\0') {
 
486
                    r->zero_in_uri = 1;
 
487
                    continue;
 
488
                }
 
489
            }
 
490
        }
 
491
 
 
492
    } else {
 
493
        uri = &err_page->uri;
 
494
    }
 
495
 
 
496
    if (uri->data[0] == '/') {
 
497
        return ngx_http_internal_redirect(r, uri, args);
 
498
    }
 
499
 
 
500
    if (uri->data[0] == '@') {
 
501
        return ngx_http_named_location(r, uri);
 
502
    }
 
503
 
 
504
    location = ngx_list_push(&r->headers_out.headers);
 
505
 
 
506
    if (location == NULL) {
 
507
        return NGX_ERROR;
 
508
    }
 
509
 
 
510
    r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
 
511
 
 
512
    location->hash = 1;
 
513
    location->key.len = sizeof("Location") - 1;
 
514
    location->key.data = (u_char *) "Location";
 
515
    location->value = *uri;
 
516
 
 
517
    r->headers_out.location = location;
 
518
 
 
519
    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
520
 
 
521
    if (clcf->msie_refresh && r->headers_in.msie) {
 
522
        return ngx_http_send_refresh(r);
 
523
    }
 
524
 
 
525
    return ngx_http_send_special_response(r, clcf, NGX_HTTP_MOVED_TEMPORARILY
 
526
                                                   - NGX_HTTP_MOVED_PERMANENTLY
 
527
                                                   + NGX_HTTP_LEVEL_200);
 
528
}
 
529
 
 
530
 
 
531
static ngx_int_t
 
532
ngx_http_send_special_response(ngx_http_request_t *r,
 
533
    ngx_http_core_loc_conf_t *clcf, ngx_uint_t err)
 
534
{
 
535
    u_char       *tail;
 
536
    size_t        len;
 
537
    ngx_int_t     rc;
 
538
    ngx_buf_t    *b;
 
539
    ngx_uint_t    msie_padding;
 
540
    ngx_chain_t   out[3];
 
541
 
 
542
    if (clcf->server_tokens) {
 
543
        len = sizeof(ngx_http_error_full_tail) - 1;
 
544
        tail = ngx_http_error_full_tail;
 
545
 
 
546
    } else {
 
547
        len = sizeof(ngx_http_error_tail) - 1;
 
548
        tail = ngx_http_error_tail;
 
549
    }
 
550
 
469
551
    msie_padding = 0;
470
552
 
471
553
    if (!r->zero_body) {
472
 
        if (error_pages[err].len) {
473
 
            r->headers_out.content_length_n = error_pages[err].len
474
 
                                              + sizeof(error_tail) - 1;
475
 
 
 
554
        if (ngx_http_error_pages[err].len) {
 
555
            r->headers_out.content_length_n = ngx_http_error_pages[err].len
 
556
                                              + len;
476
557
            if (clcf->msie_padding
477
558
                && r->headers_in.msie
478
559
                && r->http_version >= NGX_HTTP_VERSION_10
479
 
                && error >= NGX_HTTP_BAD_REQUEST
480
 
                && error != NGX_HTTP_REQUEST_URI_TOO_LARGE)
 
560
                && err >= NGX_HTTP_LEVEL_300)
481
561
            {
482
562
                r->headers_out.content_length_n +=
483
563
                                                sizeof(ngx_http_msie_stub) - 1;
484
564
                msie_padding = 1;
485
565
            }
486
566
 
 
567
            r->headers_out.content_type_len = sizeof("text/html") - 1;
487
568
            r->headers_out.content_type.len = sizeof("text/html") - 1;
488
569
            r->headers_out.content_type.data = (u_char *) "text/html";
489
570
 
501
582
        r->headers_out.content_length = NULL;
502
583
    }
503
584
 
504
 
    if (clcf->msie_refresh
505
 
        && r->headers_in.msie
506
 
        && (error == NGX_HTTP_MOVED_PERMANENTLY
507
 
            || error == NGX_HTTP_MOVED_TEMPORARILY))
508
 
    {
509
 
 
510
 
        location = &r->headers_out.location->value;
511
 
 
512
 
        escape = 2 * ngx_escape_uri(NULL, location->data, location->len,
513
 
                                    NGX_ESCAPE_REFRESH);
514
 
 
515
 
        msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
516
 
                       + escape + location->len
517
 
                       + sizeof(ngx_http_msie_refresh_tail) - 1;
518
 
 
519
 
        r->err_status = NGX_HTTP_OK;
520
 
        r->headers_out.content_type_len = sizeof("text/html") - 1;
521
 
        r->headers_out.content_length_n = msie_refresh;
522
 
        r->headers_out.location->hash = 0;
523
 
        r->headers_out.location = NULL;
524
 
 
525
 
    } else {
526
 
        location = NULL;
527
 
        escape = 0;
528
 
        msie_refresh = 0;
529
 
    }
530
 
 
531
585
    ngx_http_clear_accept_ranges(r);
532
586
    ngx_http_clear_last_modified(r);
533
587
 
537
591
        return rc;
538
592
    }
539
593
 
540
 
 
541
 
    if (msie_refresh == 0) {
542
 
 
543
 
        if (error_pages[err].len == 0) {
544
 
            return NGX_OK;
545
 
        }
546
 
 
547
 
        b = ngx_calloc_buf(r->pool);
548
 
        if (b == NULL) {
549
 
            return NGX_ERROR;
550
 
        }
551
 
 
552
 
        b->memory = 1;
553
 
        b->pos = error_pages[err].data;
554
 
        b->last = error_pages[err].data + error_pages[err].len;
555
 
 
556
 
        cl = ngx_alloc_chain_link(r->pool);
557
 
        if (cl == NULL) {
558
 
            return NGX_ERROR;
559
 
        }
560
 
 
561
 
        cl->buf = b;
562
 
        out = cl;
563
 
 
564
 
 
565
 
        b = ngx_calloc_buf(r->pool);
566
 
        if (b == NULL) {
567
 
            return NGX_ERROR;
568
 
        }
569
 
 
570
 
        b->memory = 1;
571
 
        b->pos = error_tail;
572
 
        b->last = error_tail + sizeof(error_tail) - 1;
573
 
 
574
 
        cl->next = ngx_alloc_chain_link(r->pool);
575
 
        if (cl->next == NULL) {
576
 
            return NGX_ERROR;
577
 
        }
578
 
 
579
 
        cl = cl->next;
580
 
        cl->buf = b;
581
 
 
582
 
        if (msie_padding) {
583
 
            b = ngx_calloc_buf(r->pool);
584
 
            if (b == NULL) {
585
 
                return NGX_ERROR;
586
 
            }
587
 
 
588
 
            b->memory = 1;
589
 
            b->pos = ngx_http_msie_stub;
590
 
            b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
591
 
 
592
 
            cl->next = ngx_alloc_chain_link(r->pool);
593
 
            if (cl->next == NULL) {
594
 
                return NGX_ERROR;
595
 
            }
596
 
 
597
 
            cl = cl->next;
598
 
            cl->buf = b;
599
 
        }
600
 
 
601
 
    } else {
602
 
        b = ngx_create_temp_buf(r->pool, msie_refresh);
603
 
        if (b == NULL) {
604
 
            return NGX_ERROR;
605
 
        }
606
 
 
607
 
        p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
608
 
                       sizeof(ngx_http_msie_refresh_head) - 1);
609
 
 
610
 
        if (escape == 0) {
611
 
            p = ngx_cpymem(p, location->data, location->len);
612
 
 
613
 
        } else {
614
 
            p = (u_char *) ngx_escape_uri(p, location->data, location->len,
615
 
                                          NGX_ESCAPE_REFRESH);
616
 
        }
617
 
 
618
 
        b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
619
 
                             sizeof(ngx_http_msie_refresh_tail) - 1);
620
 
 
621
 
        cl = ngx_alloc_chain_link(r->pool);
622
 
        if (cl == NULL) {
623
 
            return NGX_ERROR;
624
 
        }
625
 
 
626
 
        cl->buf = b;
627
 
        out = cl;
 
594
    if (ngx_http_error_pages[err].len == 0) {
 
595
        return NGX_OK;
 
596
    }
 
597
 
 
598
    b = ngx_calloc_buf(r->pool);
 
599
    if (b == NULL) {
 
600
        return NGX_ERROR;
 
601
    }
 
602
 
 
603
    b->memory = 1;
 
604
    b->pos = ngx_http_error_pages[err].data;
 
605
    b->last = ngx_http_error_pages[err].data + ngx_http_error_pages[err].len;
 
606
 
 
607
    out[0].buf = b;
 
608
    out[0].next = &out[1];
 
609
 
 
610
    b = ngx_calloc_buf(r->pool);
 
611
    if (b == NULL) {
 
612
        return NGX_ERROR;
 
613
    }
 
614
 
 
615
    b->memory = 1;
 
616
 
 
617
    b->pos = tail;
 
618
    b->last = tail + len;
 
619
 
 
620
    out[1].buf = b;
 
621
    out[1].next = NULL;;
 
622
 
 
623
    if (msie_padding) {
 
624
        b = ngx_calloc_buf(r->pool);
 
625
        if (b == NULL) {
 
626
            return NGX_ERROR;
 
627
        }
 
628
 
 
629
        b->memory = 1;
 
630
        b->pos = ngx_http_msie_stub;
 
631
        b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
 
632
 
 
633
        out[1].next = &out[2];
 
634
        out[2].buf = b;
 
635
        out[2].next = NULL;;
628
636
    }
629
637
 
630
638
    if (r == r->main) {
633
641
 
634
642
    b->last_in_chain = 1;
635
643
 
636
 
    cl->next = NULL;
637
 
 
638
 
    return ngx_http_output_filter(r, out);
 
644
    return ngx_http_output_filter(r, &out[0]);
 
645
}
 
646
 
 
647
 
 
648
static ngx_int_t
 
649
ngx_http_send_refresh(ngx_http_request_t *r)
 
650
{
 
651
    u_char       *p, *location;
 
652
    size_t        len, size;
 
653
    uintptr_t     escape;
 
654
    ngx_int_t     rc;
 
655
    ngx_buf_t    *b;
 
656
    ngx_chain_t   out;
 
657
 
 
658
    len = r->headers_out.location->value.len;
 
659
    location = r->headers_out.location->value.data;
 
660
 
 
661
    escape = 2 * ngx_escape_uri(NULL, location, len, NGX_ESCAPE_REFRESH);
 
662
 
 
663
    size = sizeof(ngx_http_msie_refresh_head) - 1
 
664
           + escape + len
 
665
           + sizeof(ngx_http_msie_refresh_tail) - 1;
 
666
 
 
667
    r->err_status = NGX_HTTP_OK;
 
668
 
 
669
    r->headers_out.content_type_len = sizeof("text/html") - 1;
 
670
    r->headers_out.content_type.len = sizeof("text/html") - 1;
 
671
    r->headers_out.content_type.data = (u_char *) "text/html";
 
672
 
 
673
    r->headers_out.location->hash = 0;
 
674
    r->headers_out.location = NULL;
 
675
 
 
676
    r->headers_out.content_length_n = size;
 
677
 
 
678
    if (r->headers_out.content_length) {
 
679
        r->headers_out.content_length->hash = 0;
 
680
        r->headers_out.content_length = NULL;
 
681
    }
 
682
 
 
683
    ngx_http_clear_accept_ranges(r);
 
684
    ngx_http_clear_last_modified(r);
 
685
 
 
686
    rc = ngx_http_send_header(r);
 
687
 
 
688
    if (rc == NGX_ERROR || r->header_only) {
 
689
        return rc;
 
690
    }
 
691
 
 
692
    b = ngx_create_temp_buf(r->pool, size);
 
693
    if (b == NULL) {
 
694
        return NGX_ERROR;
 
695
    }
 
696
 
 
697
    p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
 
698
                   sizeof(ngx_http_msie_refresh_head) - 1);
 
699
 
 
700
    if (escape == 0) {
 
701
        p = ngx_cpymem(p, location, len);
 
702
 
 
703
    } else {
 
704
        p = (u_char *) ngx_escape_uri(p, location, len, NGX_ESCAPE_REFRESH);
 
705
    }
 
706
 
 
707
    b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
 
708
                         sizeof(ngx_http_msie_refresh_tail) - 1);
 
709
 
 
710
    b->last_buf = 1;
 
711
    b->last_in_chain = 1;
 
712
 
 
713
    out.buf = b;
 
714
    out.next = NULL;
 
715
 
 
716
    return ngx_http_output_filter(r, &out);
639
717
}