annotate src/core/ngx_spinlock.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 3f8a2132b93d
children d620f497c50f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
441
da8c5707af39 nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents: 435
diff changeset
1
da8c5707af39 nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents: 435
diff changeset
2 /*
444
42d11f017717 nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents: 441
diff changeset
3 * Copyright (C) Igor Sysoev
441
da8c5707af39 nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents: 435
diff changeset
4 */
da8c5707af39 nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents: 435
diff changeset
5
373
018569a8f09c nginx-0.0.7-2004-06-30-19:30:41 import
Igor Sysoev <igor@sysoev.ru>
parents: 363
diff changeset
6
018569a8f09c nginx-0.0.7-2004-06-30-19:30:41 import
Igor Sysoev <igor@sysoev.ru>
parents: 363
diff changeset
7 #include <ngx_config.h>
018569a8f09c nginx-0.0.7-2004-06-30-19:30:41 import
Igor Sysoev <igor@sysoev.ru>
parents: 363
diff changeset
8 #include <ngx_core.h>
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10
563
9c2f3ed7a247 nginx-0.3.3-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 493
diff changeset
11 void
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
12 ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 {
435
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
14
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
15 #if (NGX_HAVE_ATOMIC_OPS)
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
16
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
17 ngx_uint_t i, n;
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19 for ( ;; ) {
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
21 if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
22 return;
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
23 }
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
24
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
25 if (ngx_ncpu > 1) {
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
26
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
27 for (n = 1; n < spin; n <<= 1) {
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
28
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
29 for (i = 0; i < n; i++) {
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
30 ngx_cpu_pause();
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
31 }
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
33 if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
34 return;
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
35 }
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36 }
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
37 }
611
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
38
3f8a2132b93d nginx-0.3.27-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 563
diff changeset
39 ngx_sched_yield();
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
40 }
435
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
41
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
42 #else
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
43
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
44 #if (NGX_THREADS)
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
45
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
46 #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
47
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
48 #endif
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
49
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
50 #endif
5cdc4838d4e8 nginx-0.0.11-2004-09-22-20:18:21 import
Igor Sysoev <igor@sysoev.ru>
parents: 373
diff changeset
51
363
f2755a2885c8 nginx-0.0.7-2004-06-21-23:22:53 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52 }