Sun, 27 Nov 2022 13:33:30 +0100
improve daemon startup
parent will wait until daemon is started and returns error code if startup failed
daemon startup log messages will be printed by parent
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" |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
44 | #include "../util/io.h" |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
45 | #include "../daemon/event.h" |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
46 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
47 | #include "cgiutils.h" |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
48 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
49 | #define CGI_VARS 32 |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
50 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
51 | #define CGI_RESPONSE_PARSER_BUFLEN 2048 |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
52 | #define CGI_RESPONSE_MAX_LINE_LENGTH 512 |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
53 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
54 | 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
|
55 | 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
|
56 | 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
|
57 | int64_t content_length = 0; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
58 | |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
59 | if(ctlen) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
60 | if(!util_strtoint(ctlen, &content_length)) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
61 | log_ereport( |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
62 | LOG_FAILURE, |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
63 | "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
|
64 | protocol_status(sn, rq, 400, NULL); |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
65 | return REQ_ABORTED; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
66 | } |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
67 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
68 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
69 | struct stat s; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
70 | if(stat(path, &s)) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
71 | int statuscode = util_errno2status(errno); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
72 | protocol_status(sn, rq, statuscode, NULL); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
73 | return REQ_ABORTED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
74 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
75 | if(S_ISDIR(s.st_mode)) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
76 | protocol_status(sn, rq, 403, NULL); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
77 | return REQ_ABORTED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
78 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
79 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
80 | param_free(pblock_remove("content-type", rq->srvhdrs)); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
81 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
82 | const char *args = pblock_findval("query", rq->reqpb); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
83 | 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
|
84 | if(!argv) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
85 | return REQ_ABORTED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
86 | } |
118
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 | char **env = http_hdrs2env(rq->headers); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
89 | env = cgi_common_vars(sn, rq, env); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
90 | env = cgi_specific_vars(sn, rq, args, env, 1); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
91 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
92 | // 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
|
93 | 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
|
94 | if(!handler) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
95 | return REQ_ABORTED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
96 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
97 | ZERO(handler, sizeof(CGIHandler)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
98 | handler->path = path; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
99 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
100 | int ret = cgi_start(&handler->process, path, argv, env); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
101 | 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
|
102 | 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
|
103 | cgi_free_argv(argv); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
104 | return ret; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
105 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
106 | |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
107 | 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
|
108 | cgi_free_argv(argv); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
109 | |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
110 | char buf[4096]; // I/O buffer |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
111 | ssize_t r; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
112 | |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
113 | if(content_length > 0) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
114 | ssize_t n = 0; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
115 | while(n < content_length) { |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
116 | 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
|
117 | 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
|
118 | // TODO: handle error |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
119 | log_ereport( |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
120 | LOG_FAILURE, |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
121 | "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
|
122 | path); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
123 | kill(handler->process.pid, SIGTERM); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
124 | 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
|
125 | return REQ_ABORTED; |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
126 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
127 | 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
|
128 | if(w <= 0) { |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
129 | // TODO: handle error |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
130 | log_ereport( |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
131 | LOG_FAILURE, |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
132 | "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
|
133 | path); |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
134 | kill(handler->process.pid, SIGKILL); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
135 | 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
|
136 | return REQ_ABORTED; |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
137 | } |
119
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
138 | n += r; |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
139 | } |
155cbab9eefd
adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
118
diff
changeset
|
140 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
141 | 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
|
142 | handler->process.in[1] = -1; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
143 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
144 | 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
|
145 | |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
146 | // 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
|
147 | int flags; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
148 | 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
|
149 | flags = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
150 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
151 | 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
|
152 | 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
|
153 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
154 | 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
|
155 | flags = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
156 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
157 | 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
|
158 | 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
|
159 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
160 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
161 | // 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
|
162 | 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
|
163 | ZERO(readev, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
164 | readev->cookie = handler; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
165 | readev->fn = cgi_stdout_readevent; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
166 | readev->finish = cgi_event_finish; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
167 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
168 | 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
|
169 | ZERO(stderr_readev, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
170 | stderr_readev->cookie = handler; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
171 | stderr_readev->fn = cgi_stderr_readevent; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
172 | stderr_readev->finish = NULL; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
173 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
174 | 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
|
175 | ZERO(writeev, sizeof(Event)); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
176 | writeev->cookie = handler; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
177 | // TODO: fn |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
178 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
179 | handler->writeev = writeev; |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
180 | handler->stderrev = stderr_readev; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
181 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
182 | 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
|
183 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
184 | // add poll events for cgi stdout/stderr |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
185 | int error = 0; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
186 | 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
|
187 | 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
|
188 | error = 1; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
189 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
190 | if(ev_pollin(sn->ev, handler->process.out[0], readev)) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
191 | 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
|
192 | error = 1; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
193 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
194 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
195 | if(error) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
196 | log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", path); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
197 | kill(handler->process.pid, SIGKILL); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
198 | cgi_parser_free(handler->parser); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
199 | return REQ_ABORTED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
200 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
201 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
202 | return REQ_PROCESSING; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
203 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
204 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
205 | 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
|
206 | 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
|
207 | while( |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
208 | 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
|
209 | (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
|
210 | sn->csd, |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
211 | 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
|
212 | 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
|
213 | > 0) |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
214 | { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
215 | handler->writebuf_pos += wr; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
216 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
217 | if(wr < 0) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
218 | if(errno != EWOULDBLOCK) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
219 | 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
|
220 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
221 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
222 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
223 | return 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
224 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
225 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
226 | static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
227 | 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
|
228 | 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
|
229 | 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
|
230 | pos += wr; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
231 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
232 | if(wr < 0) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
233 | if(errno == EWOULDBLOCK) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
234 | // 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
|
235 | // 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
|
236 | size_t remaining = size-pos; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
237 | if(remaining <= 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
|
238 | memcpy(handler->writebuf, buf+pos, remaining); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
239 | } else { |
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_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
|
241 | 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
|
242 | 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
|
243 | 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
|
244 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
245 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
246 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
247 | 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
|
248 | 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
|
249 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
250 | // initialize poll, if it isn't already active |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
251 | 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
|
252 | 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
|
253 | 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
|
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 | handler->poll_out = TRUE; |
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 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
259 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
260 | 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
|
261 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
262 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
263 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
264 | return 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
265 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
266 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
267 | 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
|
268 | 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
|
269 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
270 | return cgi_read_output(handler, ev); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
271 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
272 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
273 | 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
|
274 | 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
|
275 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
276 | // cgi_read_output will try to flush the buffer |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
277 | return cgi_read_output(handler, ev); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
278 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
279 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
280 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
281 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
282 | int cgi_read_output(CGIHandler *handler, EventHandler *ev) { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
283 | CGIResponseParser *parser = handler->parser; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
284 | Session *sn = parser->sn; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
285 | Request *rq = parser->rq; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
286 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
287 | // 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
|
288 | // 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
|
289 | if(cgi_try_write_flush(handler, sn)) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
290 | return handler->result == REQ_ABORTED ? 0 : 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
291 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
292 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
293 | 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
|
294 | ssize_t r; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
295 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
296 | handler->result = REQ_PROCEED; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
297 | 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
|
298 | if(parser->cgiheader) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
299 | size_t pos; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
300 | int ret = cgi_parse_response(parser, buf, r, &pos); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
301 | 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
|
302 | log_ereport( |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
303 | LOG_FAILURE, |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
304 | "broken cgi script response: path: %s", handler->path); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
305 | 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
|
306 | handler->result = REQ_ABORTED; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
307 | return 0; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
308 | } 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
|
309 | 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
|
310 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
311 | 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
|
312 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
313 | parser->cgiheader = FALSE; |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
314 | if(parser->status > 0) { |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
315 | 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
|
316 | } |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
317 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
318 | 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
|
319 | 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
|
320 | 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
|
321 | return 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
322 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
323 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
324 | 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
|
325 | 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
|
326 | 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
|
327 | break; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
328 | } 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
|
329 | // EWOULDBLOCK |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
330 | 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
|
331 | 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
|
332 | 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
|
333 | return 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
334 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
335 | handler->poll_out = TRUE; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
336 | return 1; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
337 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
338 | } else { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
339 | 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
|
340 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
341 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
342 | 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
|
343 | if(cgi_try_write(handler, ev, sn, &buf[pos], r-pos)) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
344 | return handler->result == REQ_ABORTED ? 0 : 1; |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
345 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
346 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
347 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
348 | } else { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
349 | 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
|
350 | if(cgi_try_write(handler, ev, sn, buf, r)) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
351 | return handler->result == REQ_ABORTED ? 0 : 1; |
125
c913d515be1e
adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
124
diff
changeset
|
352 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
353 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
354 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
355 | if(r < 0 && errno == EWOULDBLOCK) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
356 | return 1; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
357 | } |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
358 | |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
359 | handler->read_output_finished = TRUE; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
360 | return 0; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
361 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
362 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
363 | 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
|
364 | 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
|
365 | 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
|
366 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
367 | 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
|
368 | char *line = buf; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
369 | int line_start = 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
370 | 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
|
371 | while((r = read(handler->process.err[0], buf, 4096)) > 0) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
372 | 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
|
373 | // 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
|
374 | for(int i=0;i<r;i++) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
375 | if(buf[i] == '\n') { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
376 | log_ereport( |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
377 | LOG_INFORM, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
378 | "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
|
379 | (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
|
380 | handler->path, |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
381 | (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
|
382 | 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
|
383 | 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
|
384 | 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
|
385 | 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
|
386 | 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
|
387 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
388 | 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
|
389 | pool_free(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
|
390 | handler->stderr_tmp = NULL; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
391 | 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
|
392 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
393 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
394 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
395 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
396 | // 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
|
397 | 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
|
398 | int tmplen = r-pos; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
399 | 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
|
400 | handler->stderr_tmp = pool_realloc(pool, handler->stderr_tmp, 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
|
401 | 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
|
402 | 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
|
403 | } else { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
404 | handler->stderr_tmp = pool_malloc(pool, tmplen); |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
405 | 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
|
406 | 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
|
407 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
408 | } else { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
409 | pool_free(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
|
410 | handler->stderr_tmp = NULL; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
411 | 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
|
412 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
413 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
414 | |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
415 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
416 | 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
|
417 | return 1; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
418 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
419 | |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
420 | 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
|
421 | 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
|
422 | } |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
423 | handler->stderr_finished = TRUE; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
424 | return 0; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
425 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
426 | |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
427 | 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
|
428 | CGIHandler *handler = event->cookie; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
429 | CGIResponseParser *parser = handler->parser; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
430 | Session *sn = parser->sn; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
431 | Request *rq = parser->rq; |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
432 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
433 | if(handler->result == REQ_ABORTED) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
434 | log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", handler->path); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
435 | kill(handler->process.pid, SIGKILL); |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
436 | } |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
437 | |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
438 | if(!handler->stderr_finished) { |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
439 | // stderr handler is still active |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
440 | // set stderr event finish function, to run the finish code later |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
441 | handler->stderrev->finish = cgi_event_finish; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
442 | return 0; |
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
443 | } |
433
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
444 | if(handler->poll_out && !handler->send_response_finished) { |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
445 | // send response is still active |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
446 | handler->writeev->finish = cgi_event_finish; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
447 | return 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
448 | } |
431
032b0ad35ee3
parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
430
diff
changeset
|
449 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
450 | int exit_code = cgi_close(&handler->process); |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
451 | if(exit_code != 0) { |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
452 | 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
|
453 | handler->result = REQ_ABORTED; |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
454 | } |
126
631aaa01b2b5
fixes chunked transfer encoding
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
125
diff
changeset
|
455 | |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
456 | 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
|
457 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
458 | // 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
|
459 | // 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
|
460 | // 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
|
461 | 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
|
462 | 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
|
463 | 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
|
464 | 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
|
465 | 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
|
466 | log_ereport( |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
467 | LOG_FAILURE, |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
468 | "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
|
469 | handler->path); |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
470 | rq->rq_attr.keep_alive = 0; |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
471 | 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
|
472 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
473 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
474 | } |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
475 | |
39fe86ae4db0
use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
431
diff
changeset
|
476 | 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
|
477 | |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
478 | // return to nsapi loop |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
479 | 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
|
480 | return 0; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
481 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
482 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
483 | 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
|
484 | 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
|
485 | log_ereport( |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
486 | LOG_FAILURE, |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
487 | "send-cgi: cannot create pipe: %s", |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
488 | strerror(errno)); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
489 | return REQ_ABORTED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
490 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
491 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
492 | p->pid = fork(); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
493 | if(p->pid == 0) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
494 | // child |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
495 | |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
496 | // get script directory and script name |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
497 | cxstring script = cx_str(path); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
498 | cxmutstr parent; |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
499 | int len = strlen(path); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
500 | for(int i=len-1;i>=0;i--) { |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
501 | if(path[i] == '/') { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
502 | 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
|
503 | parent = cx_strdup(cx_strn(path, i)); |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
504 | if(chdir(parent.ptr)) { |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
505 | perror("cgi_start: chdir"); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
506 | free(parent.ptr); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
507 | exit(-1); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
508 | } |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
509 | free(parent.ptr); |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
510 | break; |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
511 | } |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
512 | } |
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
513 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
514 | if(dup2(p->in[0], STDIN_FILENO) == -1) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
515 | perror("cgi_start: dup2"); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
516 | exit(EXIT_FAILURE); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
517 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
518 | if(dup2(p->out[1], STDOUT_FILENO) == -1) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
519 | perror("cgi_start: dup2"); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
520 | exit(EXIT_FAILURE); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
521 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
522 | 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
|
523 | perror("cgi_start: dup2"); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
524 | exit(EXIT_FAILURE); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
525 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
526 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
527 | // we need to close this unused pipe |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
528 | // 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
|
529 | system_close(p->in[1]); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
530 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
531 | // execute program |
120
d2eb5fd97df0
adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
119
diff
changeset
|
532 | exit(execve(script.ptr, argv, envp)); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
533 | } else { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
534 | // parent |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
535 | 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
|
536 | system_close(p->err[1]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
537 | p->out[1] = -1; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
538 | p->err[1] = -1; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
539 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
540 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
541 | return REQ_PROCEED; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
542 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
543 | |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
544 | int cgi_close(CGIProcess *p) { |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
545 | int status = -1; |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
546 | waitpid(p->pid, &status, 0); |
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
547 | |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
548 | 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
|
549 | system_close(p->in[0]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
550 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
551 | 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
|
552 | system_close(p->in[1]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
553 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
554 | 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
|
555 | system_close(p->out[0]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
556 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
557 | 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
|
558 | system_close(p->out[1]); |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
559 | } |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
560 | if(p->err[0] != -1) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
561 | system_close(p->err[0]); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
562 | } |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
563 | if(p->err[1] != -1) { |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
564 | system_close(p->err[1]); |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
565 | } |
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
161
diff
changeset
|
566 | |
359
79b28ae7bfbd
check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
254
diff
changeset
|
567 | return status; |
144
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
568 | } |
4b546c4f25ed
fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
133
diff
changeset
|
569 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
570 | CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
571 | CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser)); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
572 | parser->sn = sn; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
573 | parser->rq = rq; |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
574 | parser->status = 0; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
575 | parser->msg = NULL; |
430
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
576 | parser->response_length = 0; |
83560f32e7d5
refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
415
diff
changeset
|
577 | parser->cgiheader = TRUE; |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
578 | 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
|
579 | return parser; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
580 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
581 | |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
582 | void cgi_parser_free(CGIResponseParser *parser) { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
583 | if(parser->tmp.space) { |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
584 | cxBufferDestroy(&parser->tmp); |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
585 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
586 | 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
|
587 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
588 | |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
589 | /* |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
590 | * 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
|
591 | * returns 0: incomplete line |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
592 | * 1: successfully parsed lines |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
593 | * 2: cgi response header complete (empty line) |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
594 | * -1: error |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
595 | */ |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
596 | 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
|
597 | CxAllocator *a = pool_allocator(parser->sn->pool); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
598 | cxmutstr name; |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
599 | cxmutstr value; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
600 | WSBool space = TRUE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
601 | int i; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
602 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
603 | int line_begin = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
604 | int value_begin = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
605 | for(i=0;i<len;i++) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
606 | char c = buf[i]; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
607 | if(value_begin == line_begin && c == ':') { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
608 | name = cx_mutstrn(buf + line_begin, i - line_begin); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
609 | value_begin = i + 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
610 | } else if(c == '\n') { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
611 | if(value_begin == line_begin) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
612 | if(space) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
613 | *pos = i + 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
614 | return 2; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
615 | } else { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
616 | // line ends with content but without ':' -> error |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
617 | return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
618 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
619 | } |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
620 | value = cx_mutstrn(buf + value_begin, i - value_begin); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
621 | |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
622 | cx_strlower(name); |
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
623 | 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
|
624 | value = cx_strtrim_m(value); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
625 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
626 | if(name.length == 0 || value.length == 0) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
627 | return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
628 | } |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
629 | |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
630 | 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
|
631 | cxmutstr codestr = value; |
133
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
632 | int j; |
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
633 | 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
|
634 | 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
|
635 | break; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
636 | } |
133
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
637 | if(j > 2) { |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
638 | break; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
639 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
640 | } |
133
87b405d61f64
improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
126
diff
changeset
|
641 | codestr.ptr[j] = '\0'; |
124
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
642 | |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
643 | int64_t s = 0; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
644 | util_strtoint(codestr.ptr, &s); |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
645 | parser->status = (int)s; |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
646 | |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
647 | 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
|
648 | |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
649 | if(msg.length > 0) { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
650 | 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
|
651 | } |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
652 | } else { |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
653 | pblock_nvlinsert( |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
654 | name.ptr, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
655 | name.length, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
656 | value.ptr, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
657 | value.length, |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
658 | parser->rq->srvhdrs); |
85985e88f63b
using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
123
diff
changeset
|
659 | } |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
660 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
661 | line_begin = i+1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
662 | value_begin = line_begin; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
663 | space = TRUE; |
121
a881dc866e23
adds more CGI stuff
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
120
diff
changeset
|
664 | } else if(!isspace(c)) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
665 | space = FALSE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
666 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
667 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
668 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
669 | if(i < len) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
670 | *pos = i; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
671 | return 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
672 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
673 | return 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
674 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
675 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
676 | /* |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
677 | * returns -1: error |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
678 | * 0: response header incomplete |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
679 | * 1: complete |
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 | 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
|
682 | *bpos = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
683 | int pos = 0; |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
684 | if(parser->tmp.pos > 0) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
685 | // the tmp buffer contains an unfinished line |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
686 | // fill up the buffer until the line is complete |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
687 | WSBool nb = FALSE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
688 | for(pos=0;pos<len;pos++) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
689 | if(buf[pos] == '\n') { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
690 | nb = TRUE; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
691 | break; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
692 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
693 | } |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
694 | cxBufferWrite(buf, 1, pos, &parser->tmp); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
695 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
696 | if(nb) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
697 | // line complete |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
698 | int npos; |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
699 | 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
|
700 | switch(r) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
701 | case -1: return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
702 | case 0: return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
703 | case 1: break; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
704 | case 2: { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
705 | *bpos = pos + 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
706 | return 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
707 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
708 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
709 | // reset tmp buffer |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
710 | parser->tmp.pos = 0; |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
711 | } else { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
712 | if(parser->tmp.pos > CGI_RESPONSE_MAX_LINE_LENGTH) { |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
713 | return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
714 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
715 | } |
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 | |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
718 | int npos = 0; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
719 | int r = parse_lines(parser, buf + pos, len - pos, &npos); |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
720 | switch(r) { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
721 | default: return -1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
722 | case 0: |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
723 | case 1: { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
724 | int newlen = len - npos; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
725 | if(npos > 0) { |
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
359
diff
changeset
|
726 | cxBufferWrite(buf + npos, 1, newlen, &parser->tmp); |
118
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
727 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
728 | return 0; |
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 | case 2: { |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
731 | *bpos = pos + npos; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
732 | return 1; |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
733 | } |
38bf6dd8f4e7
adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
734 | } |
171
af7e2d80dee6
adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
164
diff
changeset
|
735 | } |