annotate src/core/ngx_queue.c @ 4147:7f64de1cc2c0

Fix for double content when return is used in error_page handler. Test case: location / { error_page 405 /nope; return 405; } location /nope { return 200; } This is expected to return 405 with empty body, but in 0.8.42+ will return builtin 405 error page as well (though not counted in Content-Length, thus breaking protocol). Fix is to use status provided by rewrite script execution in case it's less than NGX_HTTP_BAD_REQUEST even if r->error_status set. This check is in line with one in ngx_http_script_return_code(). Note that this patch also changes behaviour for "return 302 ..." and "rewrite ... redirect" used as error handler. E.g. location / { error_page 405 /redirect; return 405; } location /redirect { rewrite ^ http://example.com/; } will actually return redirect to "http://example.com/" instead of builtin 405 error page with meaningless Location header. This looks like correct change and it's in line with what happens on e.g. directory redirects in error handlers.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 27 Sep 2011 11:11:30 +0000
parents 72db8932f782
children d620f497c50f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2026
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
2 /*
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
4 */
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
5
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7 #include <ngx_config.h>
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #include <ngx_core.h>
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11 /*
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
12 * find the middle queue element if the queue has odd number of elements
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 * or the first element of the queue's second part otherwise
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
14 */
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
15
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
16 ngx_queue_t *
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
17 ngx_queue_middle(ngx_queue_t *queue)
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18 {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19 ngx_queue_t *middle, *next;
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
21 middle = ngx_queue_head(queue);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
23 if (middle == ngx_queue_last(queue)) {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24 return middle;
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
25 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
26
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
27 next = ngx_queue_head(queue);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
28
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
29 for ( ;; ) {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
30 middle = ngx_queue_next(middle);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32 next = ngx_queue_next(next);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
34 if (next == ngx_queue_last(queue)) {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
35 return middle;
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
37
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38 next = ngx_queue_next(next);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
40 if (next == ngx_queue_last(queue)) {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
41 return middle;
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
42 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
43 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
44 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
46
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
47 /* the stable insertion sort */
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
48
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
49 void
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
50 ngx_queue_sort(ngx_queue_t *queue,
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
51 ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *))
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52 {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
53 ngx_queue_t *q, *prev, *next;
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
55 q = ngx_queue_head(queue);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
56
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
57 if (q == ngx_queue_last(queue)) {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58 return;
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
61 for (q = ngx_queue_next(q); q != ngx_queue_sentinel(queue); q = next) {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
62
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
63 prev = ngx_queue_prev(q);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 next = ngx_queue_next(q);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66 ngx_queue_remove(q);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 do {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 if (cmp(prev, q) <= 0) {
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 break;
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
71 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
72
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
73 prev = ngx_queue_prev(prev);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
75 } while (prev != ngx_queue_sentinel(queue));
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77 ngx_queue_insert_after(prev, q);
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
78 }
72db8932f782 new ngx_queue functions
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
79 }