Wed, 05 Jun 2024 19:50:44 +0200
add extra nullptr check in the event loop to handle the case when the finish ptr is set to NULL after it was already scheduled
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
1 | /* |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
3 | * |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
4 | * Copyright 2016 Olaf Wintermann. All rights reserved. |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
5 | * |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
8 | * |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
11 | * |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
15 | * |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
27 | */ |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
28 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
29 | #include "cgi.h" |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
30 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
31 | #include <stdio.h> |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
32 | #include <stdlib.h> |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
33 | #include <unistd.h> |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
34 | |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
35 | #include <sys/types.h> |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
36 | #include <signal.h> |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
37 | #include <sys/wait.h> |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
38 | |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
39 | #include <cx/string.h> |
254 | 40 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
41 | #include "../util/util.h" |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
42 | #include "../util/pblock.h" |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
43 | #include "../daemon/netsite.h" |
450
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
44 | #include "../daemon/vfs.h" |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
45 | #include "../util/io.h" |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
46 | #include "../daemon/event.h" |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
47 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
48 | #include "cgiutils.h" |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
49 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
50 | #define CGI_VARS 32 |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
51 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
52 | #define CGI_RESPONSE_PARSER_BUFLEN 2048 |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
53 | #define CGI_RESPONSE_MAX_LINE_LENGTH 512 |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
54 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
55 | int send_cgi(pblock *pb, Session *sn, Request *rq) { |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
56 | char *path = pblock_findkeyval(pb_key_path, rq->vars); |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
57 | char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers); |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
58 | int64_t content_length = 0; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
59 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
60 | log_ereport(LOG_DEBUG, "cgi-send: path: %s req: %p content-length: %s", path, rq, ctlen); |
503
aeaf7db26fac
fix webdav mkcol error status codes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
502
diff
changeset
|
61 | |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
62 | if(ctlen) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
63 | if(!util_strtoint(ctlen, &content_length)) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
64 | log_ereport( |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
65 | LOG_FAILURE, |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
66 | "send-cgi: content-length header is not an integer"); |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
67 | protocol_status(sn, rq, 400, NULL); |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
68 | return REQ_ABORTED; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
69 | } |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
70 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
71 | |
450
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
72 | // using stat, not vfs_stat, because running scripts/executables works only |
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
73 | // with the sys fs |
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
74 | if(!vfs_is_sys(rq->vfs)) { |
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
75 | log_ereport(LOG_WARN, "send-cgi: VFS setting ignored"); |
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
76 | } |
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
77 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
78 | struct stat s; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
79 | if(stat(path, &s)) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
80 | int statuscode = util_errno2status(errno); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
81 | protocol_status(sn, rq, statuscode, NULL); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
82 | return REQ_ABORTED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
83 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
84 | if(S_ISDIR(s.st_mode)) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
85 | protocol_status(sn, rq, 403, NULL); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
86 | return REQ_ABORTED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
87 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
88 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
89 | param_free(pblock_remove("content-type", rq->srvhdrs)); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
90 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
91 | const char *args = pblock_findval("query", rq->reqpb); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
92 | char **argv = cgi_create_argv(path, NULL, args); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
93 | if(!argv) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
94 | return REQ_ABORTED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
95 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
96 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
97 | char **env = http_hdrs2env(rq->headers); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
98 | env = cgi_common_vars(sn, rq, env); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
99 | env = cgi_specific_vars(sn, rq, args, env, 1); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
100 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
101 | // event handler object for non-blocking io event handler |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
102 | CGIHandler *handler = pool_malloc(sn->pool, sizeof(CGIHandler)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
103 | if(!handler) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
104 | return REQ_ABORTED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
105 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
106 | ZERO(handler, sizeof(CGIHandler)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
107 | handler->path = path; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
108 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
109 | int ret = cgi_start(&handler->process, path, argv, env); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
110 | if(ret != REQ_PROCEED) { |
145
1c93281ca4bf
fixes memory leaks in request_stat_path and send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
144
diff
changeset
|
111 | util_env_free(env); |
1c93281ca4bf
fixes memory leaks in request_stat_path and send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
144
diff
changeset
|
112 | cgi_free_argv(argv); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
113 | return ret; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
114 | } |
523 | 115 | log_ereport(LOG_DEBUG, "send-cgi: req: %p pid: %d", rq, (int)handler->process.pid); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
116 | |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
117 | util_env_free(env); |
145
1c93281ca4bf
fixes memory leaks in request_stat_path and send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
144
diff
changeset
|
118 | cgi_free_argv(argv); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
119 | |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
120 | char buf[4096]; // I/O buffer |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
121 | ssize_t r; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
122 | |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
123 | if(content_length > 0) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
124 | ssize_t n = 0; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
125 | while(n < content_length) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
126 | r = netbuf_getbytes(sn->inbuf, buf, 4096); |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
127 | if(r <= 0) { |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
128 | log_ereport( |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
129 | LOG_FAILURE, |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
130 | "send-cgi: script: %s: cannot read request body", |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
131 | path); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
132 | kill(handler->process.pid, SIGTERM); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
133 | cgi_close(&handler->process); |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
134 | return REQ_ABORTED; |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
135 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
136 | ssize_t w = write(handler->process.in[1], buf, r); |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
137 | if(w <= 0) { |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
138 | log_ereport( |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
139 | LOG_FAILURE, |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
140 | "send-cgi: script: %s: cannot send request body to cgi process", |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
141 | path); |
528
8206bfafb7a6
use sigterm to kill cgi scripts
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
527
diff
changeset
|
142 | kill(handler->process.pid, SIGTERM); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
143 | cgi_close(&handler->process); |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
144 | return REQ_ABORTED; |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
145 | } |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
146 | n += r; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
147 | } |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
148 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
149 | system_close(handler->process.in[1]); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
150 | handler->process.in[1] = -1; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
151 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
152 | handler->parser = cgi_parser_new(sn, rq); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
153 | |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
154 | // set pipes non-blocking |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
155 | int flags; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
156 | if ((flags = fcntl(handler->process.err[0], F_GETFL, 0)) == -1) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
157 | flags = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
158 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
159 | if (fcntl(handler->process.err[0], F_SETFL, flags | O_NONBLOCK) != 0) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
160 | log_ereport(LOG_FAILURE, "cgi-bin: fcntl err[0] failed: %s", strerror(errno)); |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
161 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
162 | if ((flags = fcntl(handler->process.out[0], F_GETFL, 0)) == -1) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
163 | flags = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
164 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
165 | if (fcntl(handler->process.out[0], F_SETFL, flags | O_NONBLOCK) != 0) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
166 | log_ereport(LOG_FAILURE, "cgi-bin: fcntl out[0] failed: %s", strerror(errno)); |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
167 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
168 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
169 | // create events for reading cgi's stdout/stderr |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
170 | Event *readev = pool_malloc(sn->pool, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
171 | ZERO(readev, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
172 | readev->cookie = handler; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
173 | readev->fn = cgi_stdout_readevent; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
174 | readev->finish = cgi_event_finish; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
175 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
176 | Event *stderr_readev = pool_malloc(sn->pool, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
177 | ZERO(stderr_readev, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
178 | stderr_readev->cookie = handler; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
179 | stderr_readev->fn = cgi_stderr_readevent; |
499
ef77854a91f3
fix cgi event handling, pipes were not always closed
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
498
diff
changeset
|
180 | stderr_readev->finish = cgi_event_finish; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
181 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
182 | Event *writeev = pool_malloc(sn->pool, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
183 | ZERO(writeev, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
184 | writeev->cookie = handler; |
499
ef77854a91f3
fix cgi event handling, pipes were not always closed
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
498
diff
changeset
|
185 | writeev->fn = cgi_writeevent; |
ef77854a91f3
fix cgi event handling, pipes were not always closed
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
498
diff
changeset
|
186 | writeev->finish = cgi_event_finish; |
498
0d80f8a2b29f
fix net_http_write when used with chunked transfer encoding and non-blocking IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
497
diff
changeset
|
187 | |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
188 | handler->readev = readev; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
189 | handler->writeev = writeev; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
190 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
191 | net_setnonblock(sn->csd, 1); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
192 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
193 | // add poll events for cgi stdout/stderr and netout |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
194 | int error = 0; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
195 | if(ev_pollin(sn->ev, handler->process.err[0], stderr_readev)) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
196 | log_ereport(LOG_FAILURE, "send-cgi: stderr ev_pollin failed"); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
197 | error = 1; |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
198 | } else { |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
199 | handler->wait_read = TRUE; |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
200 | handler->events++; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
201 | } |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
202 | if(!error && ev_pollin(sn->ev, handler->process.out[0], readev)) { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
203 | log_ereport(LOG_FAILURE, "send-cgi: stdout ev_pollin failed"); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
204 | error = 1; |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
205 | } else { |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
206 | handler->events++; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
207 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
208 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
209 | // don't poll sn->csd yet, we wait until the first net_write fails |
499
ef77854a91f3
fix cgi event handling, pipes were not always closed
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
498
diff
changeset
|
210 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
211 | if(error) { |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
212 | log_ereport(LOG_FAILURE, "cgi-send: initialization error: kill script: %s", path); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
213 | kill(handler->process.pid, SIGKILL); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
214 | cgi_parser_free(handler->parser); |
450
d7b276de183b
fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
433
diff
changeset
|
215 | cgi_close(&handler->process); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
216 | return REQ_ABORTED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
217 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
218 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
219 | return REQ_PROCESSING; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
220 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
221 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
222 | /* |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
223 | * Try to flush the CGIHandler write buffer |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
224 | * |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
225 | * When successful, cgi_try_write_flush() returns 0. If an error occurs, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
226 | * 1 is returned. |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
227 | * |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
228 | * If the error is not EWOULDBLOCK, handler->result is set to REQ_ABORTED. |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
229 | */ |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
230 | static int cgi_try_write_flush(CGIHandler *handler, Session *sn) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
231 | ssize_t wr = 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
232 | while( |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
233 | handler->writebuf_size - handler->writebuf_pos > 0 && |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
234 | (wr = net_write( |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
235 | sn->csd, |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
236 | handler->writebuf + handler->writebuf_pos, |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
237 | handler->writebuf_size - handler->writebuf_pos)) |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
238 | > 0) |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
239 | { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
240 | handler->writebuf_pos += wr; |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
241 | handler->count_write += wr; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
242 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
243 | if(handler->writebuf_size - handler->writebuf_pos > 0) { |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
244 | if(net_errno(sn->csd) != EWOULDBLOCK) { |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
245 | handler->result = REQ_ABORTED; |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
246 | log_ereport( |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
247 | LOG_FAILURE, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
248 | "cgi pid %d %s: network error: %s", |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
249 | (int)handler->process.pid, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
250 | handler->path, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
251 | strerror(net_errno(sn->csd))); |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
252 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
253 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
254 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
255 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
256 | return 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
257 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
258 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
259 | /* |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
260 | * Try to write the buffer to sn->csd |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
261 | * In case the socket is non-blocking and not all bytes could be written, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
262 | * the remaining bytes are copied to the CGIHandler write buffer. |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
263 | * |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
264 | * If an error occurs that is not EWOULDBLOCK, handler->result is set to |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
265 | * REQ_ABORTED. |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
266 | * |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
267 | * Returns 0 if all bytes are successfully written, otherwise 1 |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
268 | */ |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
269 | static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) { |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
270 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
271 | size_t pos = 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
272 | ssize_t wr = 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
273 | while(size - pos > 0 && (wr = net_write(sn->csd, buf + pos, size - pos)) > 0) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
274 | pos += wr; |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
275 | handler->count_write += wr; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
276 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
277 | |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
278 | if(pos < size) { |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
279 | if(net_errno(sn->csd) == EWOULDBLOCK) { |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
280 | // copy remaining bytes to the write buffer |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
281 | // we assume there are no remaining bytes in writebuf |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
282 | size_t remaining = size-pos; |
497
8827517054ec
fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
451
diff
changeset
|
283 | if(remaining > handler->writebuf_alloc) { |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
284 | handler->writebuf_alloc = size > 4096 ? size : 4096; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
285 | handler->writebuf = pool_realloc(sn->pool, handler->writebuf, handler->writebuf_alloc); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
286 | if(!handler->writebuf) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
287 | handler->result = REQ_ABORTED; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
288 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
289 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
290 | } |
497
8827517054ec
fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
451
diff
changeset
|
291 | memcpy(handler->writebuf, buf+pos, remaining); |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
292 | handler->writebuf_size = remaining; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
293 | handler->writebuf_pos = 0; |
497
8827517054ec
fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
451
diff
changeset
|
294 | } else { |
8827517054ec
fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
451
diff
changeset
|
295 | handler->result = REQ_ABORTED; |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
296 | log_ereport( |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
297 | LOG_FAILURE, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
298 | "cgi pid %d %s: network error: %s", |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
299 | (int)handler->process.pid, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
300 | handler->path, |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
301 | strerror(net_errno(sn->csd))); |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
302 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
303 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
304 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
305 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
306 | return 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
307 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
308 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
309 | int cgi_stdout_readevent(EventHandler *ev, Event *event) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
310 | CGIHandler *handler = event->cookie; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
311 | |
521
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
312 | if(handler->debug_finished) { |
522 | 313 | log_ereport(LOG_DEBUG, "cgi-send: req: %p debug_finished: 1 cgi_stdout_readevent events: %d", handler->parser->rq, handler->events); |
521
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
314 | } |
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
315 | |
532
d8212d4f24f2
stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
530
diff
changeset
|
316 | if(handler->cgi_eof || handler->result == REQ_ABORTED) { |
530
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
317 | // cgi_eof will be set to true by cgi_read_output |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
318 | // if it is true here, the cgi handling was finished by cgi_writeevent |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
319 | // in that case, cgi_writeevent will finish the request processing |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
320 | // and nothing needs to be done here |
535
bf07abfe7f0a
add more debug logging to cgi_stdout_readevent
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
534
diff
changeset
|
321 | log_ereport(LOG_DEBUG, "cgi-send: req: %p readevent cgi_eof = TRUE result: %d", handler->parser->rq, handler->result); |
530
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
322 | handler->wait_read = FALSE; |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
323 | event->finish = NULL; |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
324 | return 0; |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
325 | } |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
326 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
327 | event->finish = cgi_event_finish; |
536
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
328 | handler->writeev->finish = NULL; // TODO: maybe this can be removed |
534
bf62eddbdb9b
add more cgi logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
532
diff
changeset
|
329 | CgiIOResult ret = cgi_read_output(handler, ev, "readevent"); |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
330 | switch(ret) { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
331 | case CGI_IO_COMPLETE: { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
332 | break; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
333 | } |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
334 | case CGI_IO_NEED_READ: { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
335 | return 1; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
336 | } |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
337 | case CGI_IO_NEED_WRITE: { |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
338 | // writeev is only enabled, if needed |
518
538a8a22f622
fix don't try to enable pollout if it is already active (cgi)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
517
diff
changeset
|
339 | if(handler->poll_out) { |
538a8a22f622
fix don't try to enable pollout if it is already active (cgi)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
517
diff
changeset
|
340 | return 1; |
538a8a22f622
fix don't try to enable pollout if it is already active (cgi)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
517
diff
changeset
|
341 | } |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
342 | if(event_pollout(ev, handler->parser->sn->csd, handler->writeev)) { |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
343 | handler->result = REQ_ABORTED; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
344 | } else { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
345 | handler->poll_out = TRUE; |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
346 | log_ereport(LOG_DEBUG, "cgi-send: req: %p enable poll out", handler->parser->rq); |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
347 | return 1; // keep readevent active |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
348 | } |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
349 | } |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
350 | case CGI_IO_ERROR: { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
351 | break; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
352 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
353 | } |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
354 | |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
355 | handler->wait_read = FALSE; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
356 | return 0; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
357 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
358 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
359 | int cgi_writeevent(EventHandler *ev, Event *event) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
360 | CGIHandler *handler = event->cookie; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
361 | |
532
d8212d4f24f2
stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
530
diff
changeset
|
362 | if(handler->cgi_eof || handler->result == REQ_ABORTED) { |
536
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
363 | // same as in cgi_stdout_readevent |
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
364 | // request processing will be finished by the read event |
532
d8212d4f24f2
stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
530
diff
changeset
|
365 | log_ereport(LOG_DEBUG, "cgi-send: req: %p writeevent cgi_eof = TRUE result: %d", handler->parser->rq, handler->result); |
536
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
366 | handler->poll_out = FALSE; |
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
367 | event->finish = NULL; |
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
368 | return 0; |
530
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
369 | } |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
370 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
371 | event->finish = cgi_event_finish; |
536
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
372 | handler->readev->finish = NULL; // TODO: maybe this can be removed |
534
bf62eddbdb9b
add more cgi logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
532
diff
changeset
|
373 | CgiIOResult ret = cgi_read_output(handler, ev, "writeevent"); |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
374 | switch(ret) { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
375 | case CGI_IO_COMPLETE: { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
376 | break; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
377 | } |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
378 | case CGI_IO_NEED_READ: { |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
379 | return 1; |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
380 | } |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
381 | case CGI_IO_NEED_WRITE: { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
382 | return 1; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
383 | } |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
384 | case CGI_IO_ERROR: { |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
385 | break; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
386 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
387 | } |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
388 | |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
389 | handler->poll_out = FALSE; |
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
390 | return 0; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
391 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
392 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
393 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
394 | |
534
bf62eddbdb9b
add more cgi logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
532
diff
changeset
|
395 | CgiIOResult cgi_read_output(CGIHandler *handler, EventHandler *ev, const char *debug_log) { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
396 | CGIResponseParser *parser = handler->parser; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
397 | Session *sn = parser->sn; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
398 | Request *rq = parser->rq; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
399 | |
517
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
400 | if(handler->result == REQ_ABORTED) { |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
401 | return CGI_IO_ERROR; |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
402 | } |
be62c9604377
improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
516
diff
changeset
|
403 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
404 | // try to flush handler->writebuf |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
405 | // if writebuf is empty, this does nothing and returns 0 |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
406 | if(cgi_try_write_flush(handler, sn)) { |
498
0d80f8a2b29f
fix net_http_write when used with chunked transfer encoding and non-blocking IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
497
diff
changeset
|
407 | if(handler->result == REQ_ABORTED) { |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
408 | return CGI_IO_ERROR; |
498
0d80f8a2b29f
fix net_http_write when used with chunked transfer encoding and non-blocking IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
497
diff
changeset
|
409 | } else { |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
410 | return CGI_IO_NEED_WRITE; |
498
0d80f8a2b29f
fix net_http_write when used with chunked transfer encoding and non-blocking IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
497
diff
changeset
|
411 | } |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
412 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
413 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
414 | char buf[4096]; // I/O buffer |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
415 | ssize_t r; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
416 | |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
417 | int ret = CGI_IO_COMPLETE; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
418 | handler->result = REQ_PROCEED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
419 | while((r = read(handler->process.out[0], buf, 4096)) > 0) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
420 | if(parser->cgiheader) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
421 | size_t pos; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
422 | int ret = cgi_parse_response(parser, buf, r, &pos); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
423 | if(ret == -1) { |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
424 | log_ereport( |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
425 | LOG_FAILURE, |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
426 | "broken cgi script response: path: %s", handler->path); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
427 | protocol_status(sn, rq, 500, NULL); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
428 | handler->result = REQ_ABORTED; |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
429 | return CGI_IO_ERROR; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
430 | } else if(ret == 1) { |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
431 | WS_ASSERT(pos <= r); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
432 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
433 | parser->response_length += r-pos; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
434 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
435 | parser->cgiheader = FALSE; |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
436 | if(parser->status > 0) { |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
437 | protocol_status(sn, rq, parser->status, parser->msg); |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
438 | } |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
439 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
440 | handler->response = http_create_response(sn, rq); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
441 | if(!handler->response) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
442 | handler->result = REQ_ABORTED; |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
443 | return CGI_IO_ERROR; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
444 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
445 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
446 | int send_response = http_send_response(handler->response); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
447 | if(send_response < 0) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
448 | handler->result = REQ_ABORTED; |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
449 | ret = CGI_IO_ERROR; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
450 | break; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
451 | } else if(send_response == 1) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
452 | // EWOULDBLOCK |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
453 | if(!handler->poll_out) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
454 | if(event_pollout(ev, sn->csd, handler->writeev)) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
455 | handler->result = REQ_ABORTED; |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
456 | return CGI_IO_ERROR; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
457 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
458 | handler->poll_out = TRUE; |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
459 | return CGI_IO_NEED_WRITE; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
460 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
461 | } else { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
462 | handler->response = NULL; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
463 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
464 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
465 | if(pos < r) { |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
466 | if(cgi_try_write(handler, ev, sn, &buf[pos], r-pos)) { |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
467 | return handler->result == REQ_ABORTED ? CGI_IO_ERROR : CGI_IO_NEED_WRITE; |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
468 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
469 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
470 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
471 | } else { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
472 | parser->response_length += r; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
473 | if(cgi_try_write(handler, ev, sn, buf, r)) { |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
474 | return handler->result == REQ_ABORTED ? CGI_IO_ERROR : CGI_IO_NEED_WRITE; |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
475 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
476 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
477 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
478 | if(r < 0 && errno == EWOULDBLOCK) { |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
479 | return CGI_IO_NEED_READ; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
480 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
481 | handler->cgi_eof = TRUE; |
536
e95fa761db0c
fix cgi_writeevent not returning immediately when cgi IO is already done
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
535
diff
changeset
|
482 | log_ereport(LOG_DEBUG, "cgi-send: req: %p pid: %d set cgi_eof : %s", rq, handler->process.pid, debug_log); |
516
ec22d4ccd081
fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
503
diff
changeset
|
483 | return ret; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
484 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
485 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
486 | int cgi_stderr_readevent(EventHandler *ev, Event *event) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
487 | CGIHandler *handler = event->cookie; |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
488 | pool_handle_t *pool = handler->parser->sn->pool; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
489 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
490 | char buf[4096]; |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
491 | char *line = buf; |
451
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
492 | int line_start; |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
493 | ssize_t r; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
494 | while((r = read(handler->process.err[0], buf, 4096)) > 0) { |
451
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
495 | line_start = 0; |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
496 | int pos = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
497 | // log stderr output lines |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
498 | for(int i=0;i<r;i++) { |
451
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
499 | if(buf[i] == '\n') { |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
500 | log_ereport( |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
501 | LOG_INFORM, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
502 | "cgi pid %d %s stderr: %.*s%.*s", |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
503 | (int)handler->process.pid, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
504 | handler->path, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
505 | (int)handler->stderr_tmplen, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
506 | handler->stderr_tmp, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
507 | i - line_start, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
508 | line + line_start); |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
509 | line_start = i+1; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
510 | pos = i+1; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
511 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
512 | if(handler->stderr_tmp) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
513 | handler->stderr_tmplen = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
514 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
515 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
516 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
517 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
518 | // check for incomplete line |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
519 | if(pos < r) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
520 | int tmplen = r-pos; |
451
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
521 | if(handler->stderr_tmplen > 0) { |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
522 | // append new text to the temp buffer |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
523 | if(handler->stderr_tmplen + tmplen > handler->stderr_tmpalloc) { |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
524 | handler->stderr_tmpalloc = handler->stderr_tmplen + tmplen; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
525 | handler->stderr_tmp = pool_realloc(pool, handler->stderr_tmp, handler->stderr_tmpalloc); |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
526 | if(!handler->stderr_tmp) { |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
527 | log_ereport(LOG_FAILURE, "send-cgi: cannot create tmp buffer for parsing stderr"); |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
528 | handler->stderr_tmpalloc = 0; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
529 | handler->stderr_tmplen = 0; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
530 | continue; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
531 | } |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
532 | } |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
533 | memcpy(handler->stderr_tmp + handler->stderr_tmplen, line + line_start, tmplen); |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
534 | handler->stderr_tmplen += tmplen; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
535 | } else { |
451
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
536 | if(handler->stderr_tmpalloc < tmplen) { |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
537 | // tmp buffer too small or not allocated |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
538 | handler->stderr_tmpalloc = tmplen < 256 ? 256 : tmplen; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
539 | if(handler->stderr_tmp) { |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
540 | // free old tmp buf |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
541 | // pool_realloc doesn't make sense here, because it |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
542 | // is just free+malloc+memcpy and we don't need the |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
543 | // memcpy part, because we are just reusing the buffer |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
544 | // and the previous content doesn't matter |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
545 | pool_free(pool, handler->stderr_tmp); |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
546 | } |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
547 | handler->stderr_tmp = pool_malloc(pool, handler->stderr_tmpalloc); |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
548 | if(!handler->stderr_tmp) { |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
549 | log_ereport(LOG_FAILURE, "send-cgi: cannot create tmp buffer for parsing stderr"); |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
550 | handler->stderr_tmpalloc = 0; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
551 | handler->stderr_tmplen = 0; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
552 | continue; |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
553 | } |
edbbb3000494
fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
450
diff
changeset
|
554 | } |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
555 | memcpy(handler->stderr_tmp, line + line_start, tmplen); |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
556 | handler->stderr_tmplen = tmplen; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
557 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
558 | } else { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
559 | handler->stderr_tmplen = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
560 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
561 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
562 | |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
563 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
564 | if(r < 0 && errno == EWOULDBLOCK) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
565 | return 1; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
566 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
567 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
568 | if(handler->stderr_tmp) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
569 | pool_free(handler->parser->sn->pool, handler->stderr_tmp); |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
570 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
571 | return 0; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
572 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
573 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
574 | int cgi_event_finish(EventHandler *ev, Event *event) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
575 | CGIHandler *handler = event->cookie; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
576 | CGIResponseParser *parser = handler->parser; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
577 | Session *sn = parser->sn; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
578 | Request *rq = parser->rq; |
501
2aa6bd9f166f
fix cgi-send inactive write event blocking request termination
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
499
diff
changeset
|
579 | |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
580 | char *event_fn = ""; |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
581 | if(event->fn == cgi_stdout_readevent) { |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
582 | event_fn = "stdout"; |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
583 | } else if(event->fn == cgi_stderr_readevent) { |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
584 | event_fn = "stderr"; |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
585 | } else if(event->fn == cgi_writeevent) { |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
586 | event_fn = "httpout"; |
521
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
587 | log_ereport(LOG_DEBUG, "cgi-send: req: %p finish: pid: %d", rq, handler->process.pid); |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
588 | } |
520
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
589 | log_ereport(LOG_DEBUG, "cgi-send: req: %p finish: event: %d pollout: %d wait_read: %d cgi_eof: %d fn: %s", rq, handler->events, handler->poll_out, handler->wait_read, handler->cgi_eof, event_fn); |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
590 | |
521
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
591 | handler->debug_finished = TRUE; |
532
d8212d4f24f2
stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
530
diff
changeset
|
592 | if(event->fn != cgi_stderr_readevent) { |
534
bf62eddbdb9b
add more cgi logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
532
diff
changeset
|
593 | log_ereport(LOG_DEBUG, "cgi-send: req: %p finish set cgi_eof: %s", rq, event_fn); |
532
d8212d4f24f2
stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
530
diff
changeset
|
594 | handler->cgi_eof = TRUE; |
d8212d4f24f2
stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
530
diff
changeset
|
595 | } |
521
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
596 | |
530
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
597 | if(handler->result == REQ_ABORTED && handler->process.pid != 0 && handler->cgi_kill == 0) { |
525
072d7794bcca
use SIGKILL instead of SIGTERM to cgi scripts in case of errors
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
524
diff
changeset
|
598 | log_ereport(LOG_FAILURE, "cgi-send: kill script: %s pid: %d", handler->path, (int)handler->process.pid); |
528
8206bfafb7a6
use sigterm to kill cgi scripts
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
527
diff
changeset
|
599 | if(kill(handler->process.pid, SIGTERM)) { |
526
6c06b845701a
handle killpg error
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
525
diff
changeset
|
600 | log_ereport(LOG_FAILURE, "cgi-send: pid: %d kill failed: %s", (int)handler->process.pid, strerror(errno)); |
528
8206bfafb7a6
use sigterm to kill cgi scripts
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
527
diff
changeset
|
601 | } else { |
8206bfafb7a6
use sigterm to kill cgi scripts
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
527
diff
changeset
|
602 | log_ereport(LOG_DEBUG, "cgi-send: finish: req: %p kill %d successful", rq, (int)handler->process.pid); |
530
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
603 | handler->cgi_kill = SIGTERM; |
526
6c06b845701a
handle killpg error
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
525
diff
changeset
|
604 | } |
524
9f1d30988231
kill broken cgi processes as soon as possible
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
523
diff
changeset
|
605 | } |
9f1d30988231
kill broken cgi processes as soon as possible
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
523
diff
changeset
|
606 | |
521
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
607 | if(--handler->events > 0) { |
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
608 | return 0; |
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
609 | } |
536a2305f3fa
add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
520
diff
changeset
|
610 | |
520
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
611 | if(handler->poll_out) { |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
612 | // write event registered, however it will not be activated anymore |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
613 | // we can safely remove the event |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
614 | log_ereport(LOG_DEBUG, "cgi-send: req: %p finish: remove-poll write", rq); |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
615 | if(event_removepoll(ev, sn->csd)) { |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
616 | log_ereport(LOG_FAILURE, "cgi_event_finish: event_removepoll: %s", strerror(errno)); |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
617 | } |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
618 | handler->poll_out = FALSE; |
0b09f0cb6098
add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
519
diff
changeset
|
619 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
620 | |
530
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
621 | if(handler->wait_read) { |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
622 | // read event registered, however it will not be activated anymore |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
623 | // (currently unsure if this can happen) |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
624 | log_ereport(LOG_DEBUG, "cgi-send: req: %p finish: remove-poll read", rq); |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
625 | if(ev_remove_poll(ev, handler->process.out[0])) { |
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
626 | log_ereport(LOG_FAILURE, "cgi_event_finish: req: %p ev_remove_poll: %s", rq, strerror(errno)); |
501
2aa6bd9f166f
fix cgi-send inactive write event blocking request termination
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
499
diff
changeset
|
627 | } |
530
1e117b5d6710
handle eof in cgi_stdout_readevent to fix potential double free in cgi_event_finish
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
528
diff
changeset
|
628 | handler->wait_read = FALSE; |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
629 | } |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
630 | |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
631 | log_ereport(LOG_DEBUG, "cgi-send: req: %p cgi_close", rq); |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
632 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
633 | int exit_code = cgi_close(&handler->process); |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
634 | if(exit_code != 0) { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
635 | log_ereport(LOG_FAILURE, "send-cgi: script: %s exited with code %d", handler->path, exit_code); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
636 | handler->result = REQ_ABORTED; |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
637 | } |
126
631aaa01b2b5
fixes chunked transfer encoding
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
125
diff
changeset
|
638 | |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
639 | cgi_parser_free(parser); |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
640 | |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
641 | WSBool response_length_error = FALSE; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
642 | // check if content-length set by the cgi script matches the number |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
643 | // of writes, that were written to the stream |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
644 | // this ensures, that broken cgi scripts don't break the connection |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
645 | char *ctlen_header = pblock_findkeyval(pb_key_content_length, rq->srvhdrs); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
646 | if(ctlen_header) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
647 | int64_t ctlenhdr; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
648 | if(util_strtoint(ctlen_header, &ctlenhdr)) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
649 | if(ctlenhdr != parser->response_length) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
650 | log_ereport( |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
651 | LOG_FAILURE, |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
652 | "cgi-send: script: %s: content length mismatch", |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
653 | handler->path); |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
654 | response_length_error = TRUE; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
655 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
656 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
657 | } |
502
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
658 | // make sure we haven't lost any bytes |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
659 | // should not happen unless the non-blocking IO code is buggy |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
660 | if(handler->result != REQ_ABORTED && handler->parser->response_length != handler->count_write) { |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
661 | log_ereport( |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
662 | LOG_FAILURE, |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
663 | "cgi-send: script: %s: IO error: cgi response length != http response length", |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
664 | handler->path); |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
665 | response_length_error = TRUE; |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
666 | } |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
667 | |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
668 | // if the response length is broken, we must close the connection |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
669 | if(response_length_error) { |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
670 | rq->rq_attr.keep_alive = 0; |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
671 | handler->result = REQ_ABORTED; |
11ac3761c0e3
fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
501
diff
changeset
|
672 | } |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
673 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
674 | net_setnonblock(sn->csd, 0); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
675 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
676 | // return to nsapi loop |
497
8827517054ec
fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
451
diff
changeset
|
677 | log_ereport(LOG_DEBUG, "cgi-send: req: %p event-finish nsapi return", rq); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
678 | nsapi_function_return(sn, rq, handler->result); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
679 | return 0; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
680 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
681 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
682 | int cgi_start(CGIProcess *p, char *path, char *const argv[], char *const envp[]) { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
683 | if(pipe(p->in) || pipe(p->out) || pipe(p->err)) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
684 | log_ereport( |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
685 | LOG_FAILURE, |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
686 | "send-cgi: cannot create pipe: %s", |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
687 | strerror(errno)); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
688 | return REQ_ABORTED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
689 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
690 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
691 | p->pid = fork(); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
692 | if(p->pid == 0) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
693 | // child |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
694 | |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
695 | // get script directory and script name |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
696 | cxstring script = cx_str(path); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
697 | cxmutstr parent; |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
698 | int len = strlen(path); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
699 | for(int i=len-1;i>=0;i--) { |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
700 | if(path[i] == '/') { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
701 | script = cx_strn(path + i + 1, len - i); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
702 | parent = cx_strdup(cx_strn(path, i)); |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
703 | if(chdir(parent.ptr)) { |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
704 | perror("cgi_start: chdir"); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
705 | free(parent.ptr); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
706 | exit(-1); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
707 | } |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
708 | free(parent.ptr); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
709 | break; |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
710 | } |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
711 | } |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
712 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
713 | if(dup2(p->in[0], STDIN_FILENO) == -1) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
714 | perror("cgi_start: dup2"); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
715 | exit(EXIT_FAILURE); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
716 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
717 | if(dup2(p->out[1], STDOUT_FILENO) == -1) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
718 | perror("cgi_start: dup2"); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
719 | exit(EXIT_FAILURE); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
720 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
721 | if(dup2(p->err[1], STDERR_FILENO) == -1) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
722 | perror("cgi_start: dup2"); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
723 | exit(EXIT_FAILURE); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
724 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
725 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
726 | // we need to close this unused pipe |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
727 | // otherwise stdin cannot reach EOF |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
728 | system_close(p->in[1]); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
729 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
730 | // execute program |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
731 | exit(execve(script.ptr, argv, envp)); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
732 | } else { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
733 | // parent |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
734 | system_close(p->out[1]); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
735 | system_close(p->err[1]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
736 | p->out[1] = -1; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
737 | p->err[1] = -1; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
738 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
739 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
740 | return REQ_PROCEED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
741 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
742 | |
519
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
743 | int cgi_close(CGIProcess *p) { |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
744 | if(p->in[0] != -1) { |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
745 | system_close(p->in[0]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
746 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
747 | if(p->in[1] != -1) { |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
748 | system_close(p->in[1]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
749 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
750 | if(p->out[0] != -1) { |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
751 | system_close(p->out[0]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
752 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
753 | if(p->out[1] != -1) { |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
754 | system_close(p->out[1]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
755 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
756 | if(p->err[0] != -1) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
757 | system_close(p->err[0]); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
758 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
759 | if(p->err[1] != -1) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
760 | system_close(p->err[1]); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
761 | } |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
762 | |
519
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
763 | // TODO: Because of WNOHANG, waitpid could fail and the process |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
764 | // is still running. In that case, another waitpid call should |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
765 | // be done later somewhere. |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
766 | int status = -1; |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
767 | if(waitpid(p->pid, &status, WNOHANG) == 0) { |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
768 | log_ereport(LOG_DEBUG, "cgi_close: waitpid returned 0: pid: %d", (int)p->pid); |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
769 | // cgi process still running |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
770 | // workaround: sleep 1 sec and try again, if that fails again |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
771 | sleep(1); |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
772 | if(waitpid(p->pid, &status, WNOHANG) == 0) { |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
773 | log_ereport(LOG_DEBUG, "cgi_close: waitpid returned 0 again: pid: %d", (int)p->pid); |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
774 | } |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
775 | } |
857e5b92828b
add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
518
diff
changeset
|
776 | |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
777 | return status; |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
778 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
779 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
780 | CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
781 | CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser)); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
782 | parser->sn = sn; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
783 | parser->rq = rq; |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
784 | parser->status = 0; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
785 | parser->msg = NULL; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
786 | parser->response_length = 0; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
787 | parser->cgiheader = TRUE; |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
788 | cxBufferInit(&parser->tmp, NULL, 64, pool_allocator(sn->pool), CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
789 | return parser; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
790 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
791 | |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
792 | void cgi_parser_free(CGIResponseParser *parser) { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
793 | if(parser->tmp.space) { |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
794 | cxBufferDestroy(&parser->tmp); |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
795 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
796 | pool_free(parser->sn->pool, parser); |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
797 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
798 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
799 | /* |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
800 | * parses a cgi response line and adds the response header to rq->srvhdrs |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
801 | * returns 0: incomplete line |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
802 | * 1: successfully parsed lines |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
803 | * 2: cgi response header complete (empty line) |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
804 | * -1: error |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
805 | */ |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
806 | static int parse_lines(CGIResponseParser *parser, char *buf, size_t len, int *pos) { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
807 | CxAllocator *a = pool_allocator(parser->sn->pool); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
808 | cxmutstr name; |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
809 | cxmutstr value; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
810 | WSBool space = TRUE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
811 | int i; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
812 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
813 | int line_begin = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
814 | int value_begin = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
815 | for(i=0;i<len;i++) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
816 | char c = buf[i]; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
817 | if(value_begin == line_begin && c == ':') { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
818 | name = cx_mutstrn(buf + line_begin, i - line_begin); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
819 | value_begin = i + 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
820 | } else if(c == '\n') { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
821 | if(value_begin == line_begin) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
822 | if(space) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
823 | *pos = i + 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
824 | return 2; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
825 | } else { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
826 | // line ends with content but without ':' -> error |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
827 | return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
828 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
829 | } |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
830 | value = cx_mutstrn(buf + value_begin, i - value_begin); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
831 | |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
832 | cx_strlower(name); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
833 | name = cx_strdup_a(a, cx_strtrim((cxstring){name.ptr, name.length})); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
834 | value = cx_strtrim_m(value); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
835 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
836 | if(name.length == 0 || value.length == 0) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
837 | return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
838 | } |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
839 | |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
840 | if(!cx_strcmp((cxstring){name.ptr, name.length}, (cxstring)CX_STR("status"))) { |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
841 | cxmutstr codestr = value; |
133
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
842 | int j; |
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
843 | for(j=0;j<codestr.length;j++) { |
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
844 | if(!isdigit(codestr.ptr[j])) { |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
845 | break; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
846 | } |
133
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
847 | if(j > 2) { |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
848 | break; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
849 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
850 | } |
133
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
851 | codestr.ptr[j] = '\0'; |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
852 | |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
853 | int64_t s = 0; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
854 | util_strtoint(codestr.ptr, &s); |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
855 | parser->status = (int)s; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
856 | |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
857 | cxmutstr msg = cx_strtrim_m(cx_strsubs_m(value, j + 1)); |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
858 | |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
859 | if(msg.length > 0) { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
860 | parser->msg = cx_strdup_pool(parser->sn->pool, msg).ptr; |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
861 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
862 | } else { |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
863 | pblock_nvlinsert( |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
864 | name.ptr, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
865 | name.length, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
866 | value.ptr, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
867 | value.length, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
868 | parser->rq->srvhdrs); |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
869 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
870 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
871 | line_begin = i+1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
872 | value_begin = line_begin; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
873 | space = TRUE; |
121
a881dc866e23
adds more CGI stuff
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
120
diff
changeset
|
874 | } else if(!isspace(c)) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
875 | space = FALSE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
876 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
877 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
878 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
879 | if(i < len) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
880 | *pos = i; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
881 | return 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
882 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
883 | return 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
884 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
885 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
886 | /* |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
887 | * returns -1: error |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
888 | * 0: response header incomplete |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
889 | * 1: complete |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
890 | */ |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
891 | int cgi_parse_response(CGIResponseParser *parser, char *buf, size_t len, size_t *bpos) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
892 | *bpos = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
893 | int pos = 0; |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
894 | if(parser->tmp.pos > 0) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
895 | // the tmp buffer contains an unfinished line |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
896 | // fill up the buffer until the line is complete |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
897 | WSBool nb = FALSE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
898 | for(pos=0;pos<len;pos++) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
899 | if(buf[pos] == '\n') { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
900 | nb = TRUE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
901 | break; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
902 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
903 | } |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
904 | cxBufferWrite(buf, 1, pos, &parser->tmp); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
905 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
906 | if(nb) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
907 | // line complete |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
908 | int npos; |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
909 | int r = parse_lines(parser, parser->tmp.space, parser->tmp.pos, &npos); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
910 | switch(r) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
911 | case -1: return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
912 | case 0: return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
913 | case 1: break; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
914 | case 2: { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
915 | *bpos = pos + 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
916 | return 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
917 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
918 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
919 | // reset tmp buffer |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
920 | parser->tmp.pos = 0; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
921 | } else { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
922 | if(parser->tmp.pos > CGI_RESPONSE_MAX_LINE_LENGTH) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
923 | return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
924 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
925 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
926 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
927 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
928 | int npos = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
929 | int r = parse_lines(parser, buf + pos, len - pos, &npos); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
930 | switch(r) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
931 | default: return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
932 | case 0: |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
933 | case 1: { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
934 | int newlen = len - npos; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
935 | if(npos > 0) { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
936 | cxBufferWrite(buf + npos, 1, newlen, &parser->tmp); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
937 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
938 | return 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
939 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
940 | case 2: { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
941 | *bpos = pos + npos; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
942 | return 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
943 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
944 | } |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
945 | } |