src/server/safs/cgi.c

Wed, 05 Jun 2024 19:50:44 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 05 Jun 2024 19:50:44 +0200
changeset 537
ad44e72fbf50
parent 536
e95fa761db0c
child 538
f9a7b5c76208
permissions
-rw-r--r--

add extra nullptr check in the event loop to handle the case when the finish ptr is set to NULL after it was already scheduled

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

mercurial