annotate src/os/win32/ngx_wsarecv_chain.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 4d9ea73a627a
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: 343
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: 343
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: 343
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: 343
diff changeset
5
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7 #include <ngx_config.h>
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #include <ngx_core.h>
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #include <ngx_event.h>
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11
577
4d9ea73a627a nginx-0.3.10-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 501
diff changeset
12 #define NGX_WSABUFS 8
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
13
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
14
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
15 ssize_t
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
16 ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain)
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
17 {
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18 int rc;
292
a472bfb778b3 nginx-0.0.3-2004-03-17-00:26:01 import
Igor Sysoev <igor@sysoev.ru>
parents: 280
diff changeset
19 u_char *prev;
280
7c7183b3ea8b nginx-0.0.2-2004-03-05-11:34:24 import
Igor Sysoev <igor@sysoev.ru>
parents: 278
diff changeset
20 u_long bytes, flags;
7c7183b3ea8b nginx-0.0.2-2004-03-05-11:34:24 import
Igor Sysoev <igor@sysoev.ru>
parents: 278
diff changeset
21 size_t size;
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22 ngx_err_t err;
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
23 ngx_array_t vec;
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24 ngx_event_t *rev;
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
25 LPWSABUF wsabuf;
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
26 WSABUF wsabufs[NGX_WSABUFS];
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
27
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
28 prev = NULL;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
29 wsabuf = NULL;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
30 flags = 0;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31 size = 0;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32 bytes = 0;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
34 vec.elts = wsabufs;
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
35 vec.nelts = 0;
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
36 vec.size = sizeof(WSABUF);
577
4d9ea73a627a nginx-0.3.10-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 501
diff changeset
37 vec.nalloc = NGX_WSABUFS;
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
38 vec.pool = c->pool;
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39
343
6bdf858bff8c nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents: 292
diff changeset
40 /* coalesce the neighbouring bufs */
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
41
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
42 while (chain) {
343
6bdf858bff8c nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents: 292
diff changeset
43 if (prev == chain->buf->last) {
6bdf858bff8c nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents: 292
diff changeset
44 wsabuf->len += chain->buf->end - chain->buf->last;
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
46 } else {
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
47 wsabuf = ngx_array_push(&vec);
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
48 if (wsabuf == NULL) {
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
49 return NGX_ERROR;
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
50 }
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
51
343
6bdf858bff8c nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents: 292
diff changeset
52 wsabuf->buf = (char *) chain->buf->last;
6bdf858bff8c nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents: 292
diff changeset
53 wsabuf->len = chain->buf->end - chain->buf->last;
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54 }
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
55
343
6bdf858bff8c nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents: 292
diff changeset
56 size += chain->buf->end - chain->buf->last;
6bdf858bff8c nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents: 292
diff changeset
57 prev = chain->buf->end;
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58 chain = chain->next;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59 }
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60
278
0ba4821f4460 nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents: 186
diff changeset
61 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
62 "WSARecv: %d:%d", vec.nelts, wsabuf->len);
278
0ba4821f4460 nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents: 186
diff changeset
63
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64
501
d4ea69372b94 nginx-0.1.25-RELEASE import
Igor Sysoev <igor@sysoev.ru>
parents: 444
diff changeset
65 rc = WSARecv(c->fd, vec.elts, vec.nelts, &bytes, &flags, NULL, NULL);
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67 rev = c->read;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 if (rc == -1) {
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 rev->ready = 0;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
71 err = ngx_socket_errno;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
72
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
73 if (err == WSAEWOULDBLOCK) {
278
0ba4821f4460 nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents: 186
diff changeset
74 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
0ba4821f4460 nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents: 186
diff changeset
75 "WSARecv() not ready");
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76 return NGX_AGAIN;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77 }
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
78
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
79 rev->error = 1;
278
0ba4821f4460 nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents: 186
diff changeset
80 ngx_connection_error(c, err, "WSARecv() failed");
186
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
81 return NGX_ERROR;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
82 }
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
83
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84 if (bytes < size) {
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
85 rev->ready = 0;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
86 }
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88 if (bytes == 0) {
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
89 rev->eof = 1;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
90 }
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
91
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
92 return bytes;
c1f3a3c7c5db nginx-0.0.1-2003-11-17-00:49:42 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93 }