src/server/safs/cgi.c

Wed, 05 Jun 2024 19:49:17 +0200

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

fix cgi_writeevent not returning immediately when cgi IO is already done

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