src/server/safs/cgi.c

Tue, 27 May 2025 18:41:23 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 27 May 2025 18:41:23 +0200
changeset 585
bae488d2b3c2
parent 579
e10457d74fe1
child 617
01228719b3ce
permissions
-rw-r--r--

make cgi response status header check case insensitive

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
567
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
55 static void close_std_pipes(int fds[static 6]) {
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
56 for(int i=0;i<6;i++) {
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
57 if(fds[i] >= 0) {
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
58 close(fds[i]);
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
59 }
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
60 }
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
61 }
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
62
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 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
64 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
65 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
66 int64_t content_length = 0;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
67
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
68 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
69
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
70 if(ctlen) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
71 if(!util_strtoint(ctlen, &content_length)) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
72 log_ereport(
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
73 LOG_FAILURE,
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
74 "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
75 protocol_status(sn, rq, 400, NULL);
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
76 return REQ_ABORTED;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
77 }
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
78 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79
450
d7b276de183b fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 433
diff changeset
80 // 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
81 // 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
82 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
83 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
84 }
d7b276de183b fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 433
diff changeset
85
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 struct stat s;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 if(stat(path, &s)) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 int statuscode = util_errno2status(errno);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 protocol_status(sn, rq, statuscode, NULL);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 return REQ_ABORTED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 if(S_ISDIR(s.st_mode)) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 protocol_status(sn, rq, 403, NULL);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 return REQ_ABORTED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 }
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 param_free(pblock_remove("content-type", rq->srvhdrs));
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 const char *args = pblock_findval("query", rq->reqpb);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 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
101 if(!argv) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
102 return REQ_ABORTED;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
103 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 char **env = http_hdrs2env(rq->headers);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 env = cgi_common_vars(sn, rq, env);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 env = cgi_specific_vars(sn, rq, args, env, 1);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
109 // 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
110 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
111 if(!handler) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
112 return REQ_ABORTED;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
113 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
114 ZERO(handler, sizeof(CGIHandler));
567
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
115 handler->process.out[0] = -1;
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
116 handler->process.out[1] = -1;
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
117 handler->process.err[0] = -1;
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
118 handler->process.err[0] = -1;
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
119 handler->process.in[0] = -1;
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
120 handler->process.in[0] = -1;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
121 handler->path = path;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
122
566
963edce64e6e log all cgi pipe fds
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 565
diff changeset
123 int ret = cgi_start(rq, &handler->process, path, argv, env);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 if(ret != REQ_PROCEED) {
567
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
125 close_std_pipes((int[6]){
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
126 handler->process.out[0], handler->process.out[1],
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
127 handler->process.err[0], handler->process.err[1],
fed45fc71e7c check and close pipes if cgi_start fails
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 566
diff changeset
128 handler->process.in[0], handler->process.in[1]});
145
1c93281ca4bf fixes memory leaks in request_stat_path and send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 144
diff changeset
129 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
130 cgi_free_argv(argv);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 return ret;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 }
566
963edce64e6e log all cgi pipe fds
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 565
diff changeset
133 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
134
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
135 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
136 cgi_free_argv(argv);
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
137
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
138 char buf[4096]; // I/O buffer
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
139 ssize_t r;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
140
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
141 if(content_length > 0) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
142 ssize_t n = 0;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
143 while(n < content_length) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
144 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
145 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
146 log_ereport(
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
147 LOG_FAILURE,
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
148 "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
149 path);
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
150 kill(handler->process.pid, SIGTERM);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
151 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
152 return REQ_ABORTED;
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
153 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
154 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
155 if(w <= 0) {
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
156 log_ereport(
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
157 LOG_FAILURE,
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
158 "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
159 path);
528
8206bfafb7a6 use sigterm to kill cgi scripts
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 527
diff changeset
160 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
161 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
162 return REQ_ABORTED;
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
163 }
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
164 n += r;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
165 }
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
166 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
167 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
168 handler->process.in[1] = -1;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
169
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
170 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
171
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
172 // 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
173 int flags;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
174 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
175 flags = 0;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
176 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
177 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
178 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
179 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
180 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
181 flags = 0;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
182 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
183 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
184 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
185 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
186
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
187 // 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
188 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
189 ZERO(readev, sizeof(Event));
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
190 readev->cookie = handler;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
191 readev->fn = cgi_stdout_readevent;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
192 readev->finish = cgi_event_finish;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
193
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
194 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
195 ZERO(stderr_readev, sizeof(Event));
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
196 stderr_readev->cookie = handler;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
197 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
198 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
199
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
200 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
201 ZERO(writeev, sizeof(Event));
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
202 writeev->cookie = handler;
499
ef77854a91f3 fix cgi event handling, pipes were not always closed
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 498
diff changeset
203 writeev->fn = cgi_writeevent;
ef77854a91f3 fix cgi event handling, pipes were not always closed
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 498
diff changeset
204 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
205
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
206 handler->readev = readev;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
207 handler->writeev = writeev;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
209 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
210
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
211 // 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
212 int error = 0;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
213 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
214 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
215 error = 1;
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
216 } else {
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
217 handler->wait_read = TRUE;
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
218 handler->events++;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
219 }
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
220 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
221 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
222 error = 1;
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
223 } else {
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
224 handler->events++;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
225 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
226
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
227 // 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
228
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
229 if(error) {
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
230 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
231 kill(handler->process.pid, SIGKILL);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
232 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
233 cgi_close(&handler->process);
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
234 return REQ_ABORTED;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
235 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
236
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
237 return REQ_PROCESSING;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
238 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
239
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
240 /*
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
241 * Try to flush the CGIHandler write buffer
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
242 *
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
243 * 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
244 * 1 is returned.
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
245 *
538
f9a7b5c76208 replace EWOULDBLOCK with EAGAIN
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 536
diff changeset
246 * If the error is not EAGAIN, handler->result is set to REQ_ABORTED.
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
247 */
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
248 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
249 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
250 while(
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
251 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
252 (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
253 sn->csd,
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
254 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
255 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
256 > 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 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
259 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
260 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
261 if(handler->writebuf_size - handler->writebuf_pos > 0) {
538
f9a7b5c76208 replace EWOULDBLOCK with EAGAIN
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 536
diff changeset
262 if(net_errno(sn->csd) != EAGAIN) {
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
263 handler->result = REQ_ABORTED;
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
264 log_ereport(
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
265 LOG_FAILURE,
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
266 "cgi pid %d %s: network error: %s",
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
267 (int)handler->process.pid,
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
268 handler->path,
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
269 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
270 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
271
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
272 return 1;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
273 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
274 return 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
275 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
276
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
277 /*
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
278 * Try to write the buffer to sn->csd
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
279 * 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
280 * 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
281 *
538
f9a7b5c76208 replace EWOULDBLOCK with EAGAIN
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 536
diff changeset
282 * If an error occurs that is not EAGAIN, handler->result is set to
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
283 * REQ_ABORTED.
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
284 *
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
285 * 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
286 */
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
287 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
288
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
289 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
290 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
291 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
292 pos += wr;
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
293 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
294 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
295
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
296 if(pos < size) {
538
f9a7b5c76208 replace EWOULDBLOCK with EAGAIN
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 536
diff changeset
297 if(net_errno(sn->csd) == EAGAIN) {
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
298 // 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
299 // 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
300 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
301 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
302 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
303 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
304 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
305 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
306 return 1;
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 }
497
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
309 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
310 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
311 handler->writebuf_pos = 0;
497
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
312 } else {
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
313 handler->result = REQ_ABORTED;
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
314 log_ereport(
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
315 LOG_FAILURE,
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
316 "cgi pid %d %s: network error: %s",
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
317 (int)handler->process.pid,
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
318 handler->path,
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
319 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
320 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
321 return 1;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
322 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
323
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
324 return 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
325 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
326
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
327 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
328 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
329
521
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
330 if(handler->debug_finished) {
522
317cd83fa3df fix build
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 521
diff changeset
331 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
332 }
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
333
532
d8212d4f24f2 stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 530
diff changeset
334 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
335 // 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
336 // 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
337 // 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
338 // 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
339 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
340 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
341 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
342 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
343 }
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
344
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
345 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
346 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
347 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
348 switch(ret) {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
349 case CGI_IO_COMPLETE: {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
350 break;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
351 }
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
352 case CGI_IO_NEED_READ: {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
353 return 1;
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 case CGI_IO_NEED_WRITE: {
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
356 // 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
357 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
358 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
359 }
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
360 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
361 handler->result = REQ_ABORTED;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
362 } else {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
363 handler->poll_out = TRUE;
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
364 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
365 return 1; // keep readevent active
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
366 }
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
367 }
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
368 case CGI_IO_ERROR: {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
369 break;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
370 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
371 }
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
372
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
373 handler->wait_read = FALSE;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
374 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
375 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
376
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
377 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
378 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
379
532
d8212d4f24f2 stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 530
diff changeset
380 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
381 // 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
382 // 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
383 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
384 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
385 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
386 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
387 }
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
388
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
389 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
390 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
391 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
392 switch(ret) {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
393 case CGI_IO_COMPLETE: {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
394 break;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
395 }
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
396 case CGI_IO_NEED_READ: {
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
397 return 1;
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
398 }
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
399 case CGI_IO_NEED_WRITE: {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
400 return 1;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
401 }
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
402 case CGI_IO_ERROR: {
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
403 break;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
404 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
405 }
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
406
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
407 handler->poll_out = FALSE;
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
408 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
409 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
410
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
411
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
412
534
bf62eddbdb9b add more cgi logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 532
diff changeset
413 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
414 CGIResponseParser *parser = handler->parser;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
415 Session *sn = parser->sn;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
416 Request *rq = parser->rq;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
417
517
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
418 if(handler->result == REQ_ABORTED) {
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
419 return CGI_IO_ERROR;
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
420 }
be62c9604377 improve cgi io event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 516
diff changeset
421
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
422 // 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
423 // 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
424 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
425 if(handler->result == REQ_ABORTED) {
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
426 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
427 } else {
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
428 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
429 }
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
430 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
431
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
432 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
433 ssize_t r;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
434
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
435 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
436 handler->result = REQ_PROCEED;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
437 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
438 if(parser->cgiheader) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
439 size_t pos;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
440 int ret = cgi_parse_response(parser, buf, r, &pos);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
441 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
442 log_ereport(
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
443 LOG_FAILURE,
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
444 "broken cgi script response: path: %s", handler->path);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 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
446 handler->result = REQ_ABORTED;
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
447 return CGI_IO_ERROR;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
448 } 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
449 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
450
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
451 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
452
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
453 parser->cgiheader = FALSE;
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
454 if(parser->status > 0) {
585
bae488d2b3c2 make cgi response status header check case insensitive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
455 log_ereport(LOG_DEBUG, "cgi-send: req: %p pid: %d response status code: %d", rq, handler->process.pid, parser->status);
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
456 protocol_status(sn, rq, parser->status, parser->msg);
585
bae488d2b3c2 make cgi response status header check case insensitive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
457 } else {
bae488d2b3c2 make cgi response status header check case insensitive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
458 log_ereport(LOG_DEBUG, "cgi-send: req: %p pid: %d no status code", rq, handler->process.pid);
bae488d2b3c2 make cgi response status header check case insensitive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
459 protocol_status(sn, rq, 200, NULL); // default 200 ok
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
460 }
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
461
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 = 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
463 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
464 handler->result = REQ_ABORTED;
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
465 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
466 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
467
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
468 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
469 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
470 handler->result = REQ_ABORTED;
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
471 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
472 break;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
473 } else if(send_response == 1) {
538
f9a7b5c76208 replace EWOULDBLOCK with EAGAIN
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 536
diff changeset
474 // EAGAIN
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
475 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
476 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
477 handler->result = REQ_ABORTED;
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
478 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
479 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
480 handler->poll_out = TRUE;
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
481 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
482 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
483 } else {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
484 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
485 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
486
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
487 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
488 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
489 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
490 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
491 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
492 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
493 } else {
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
494 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
495 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
496 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
497 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
498 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
499 }
538
f9a7b5c76208 replace EWOULDBLOCK with EAGAIN
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 536
diff changeset
500 if(r < 0 && errno == EAGAIN) {
516
ec22d4ccd081 fix cgi poll event handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 503
diff changeset
501 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
502 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
503 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
504 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
505 return ret;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
506 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
507
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
508 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
509 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
510 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
511
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
512 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
513 char *line = buf;
451
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
514 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
515 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
516 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
517 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
518 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
519 // 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
520 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
521 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
522 log_ereport(
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
523 LOG_INFORM,
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
524 "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
525 (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
526 handler->path,
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
527 (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
528 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
529 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
530 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
531 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
532 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
533
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
534 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
535 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
536 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
537 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
538 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
539
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
540 // 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
541 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
542 int tmplen = r-pos;
451
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
543 if(handler->stderr_tmplen > 0) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
544 // 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
545 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
546 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
547 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
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 + 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
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 } else {
451
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
558 if(handler->stderr_tmpalloc < tmplen) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
559 // 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
560 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
561 if(handler->stderr_tmp) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
562 // free old tmp buf
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
563 // 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
564 // 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
565 // 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
566 // 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
567 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
568 }
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
569 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
570 if(!handler->stderr_tmp) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
571 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
572 handler->stderr_tmpalloc = 0;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
573 handler->stderr_tmplen = 0;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
574 continue;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
575 }
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
576 }
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
577 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
578 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
579 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
580 } else {
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
581 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
582 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
583 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
584
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
585
538
f9a7b5c76208 replace EWOULDBLOCK with EAGAIN
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 536
diff changeset
586 if(r < 0 && errno == EAGAIN) {
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
587 return 1;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
588 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
589
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
590 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
591 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
592 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
593 return 0;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
594 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
595
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
596 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
597 CGIHandler *handler = event->cookie;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
598 CGIResponseParser *parser = handler->parser;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
599 Session *sn = parser->sn;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
600 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
601
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
602 char *event_fn = "";
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
603 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
604 event_fn = "stdout";
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
605 } 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
606 event_fn = "stderr";
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
607 } 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
608 event_fn = "httpout";
521
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
609 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
610 }
520
0b09f0cb6098 add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 519
diff changeset
611 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
612
521
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
613 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
614 if(event->fn != cgi_stderr_readevent) {
534
bf62eddbdb9b add more cgi logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 532
diff changeset
615 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
616 handler->cgi_eof = TRUE;
d8212d4f24f2 stop cgi read-event processing if an error occured
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 530
diff changeset
617 }
521
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
618
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
619 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
620 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
621 if(kill(handler->process.pid, SIGTERM)) {
526
6c06b845701a handle killpg error
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 525
diff changeset
622 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
623 } else {
8206bfafb7a6 use sigterm to kill cgi scripts
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 527
diff changeset
624 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
625 handler->cgi_kill = SIGTERM;
526
6c06b845701a handle killpg error
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 525
diff changeset
626 }
524
9f1d30988231 kill broken cgi processes as soon as possible
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 523
diff changeset
627 }
9f1d30988231 kill broken cgi processes as soon as possible
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 523
diff changeset
628
521
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
629 if(--handler->events > 0) {
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
630 return 0;
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
631 }
536a2305f3fa add more cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 520
diff changeset
632
520
0b09f0cb6098 add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 519
diff changeset
633 if(handler->poll_out) {
0b09f0cb6098 add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 519
diff changeset
634 // 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
635 // we can safely remove the event
0b09f0cb6098 add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 519
diff changeset
636 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
637 if(event_removepoll(ev, sn->csd)) {
0b09f0cb6098 add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 519
diff changeset
638 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
639 }
0b09f0cb6098 add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 519
diff changeset
640 handler->poll_out = FALSE;
0b09f0cb6098 add wait_read to cgi debug logging
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 519
diff changeset
641 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
642
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
643 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
644 // 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
645 // (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
646 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
647 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
648 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
649 }
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
650 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
651 }
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
652
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
653 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
654
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
655 int exit_code = cgi_close(&handler->process);
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
656 if(exit_code != 0) {
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
657 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
658 handler->result = REQ_ABORTED;
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
659 }
126
631aaa01b2b5 fixes chunked transfer encoding
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 125
diff changeset
660
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
661 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
662
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
663 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
664 // 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
665 // 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
666 // 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
667 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
668 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
669 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
670 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
671 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
672 log_ereport(
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
673 LOG_FAILURE,
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
674 "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
675 handler->path);
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
676 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
677 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
678 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
679 }
502
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
680 // 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
681 // 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
682 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
683 log_ereport(
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
684 LOG_FAILURE,
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
685 "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
686 handler->path);
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
687 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
688 }
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
689
11ac3761c0e3 fix non-blocking CGI handler and non-blocking SSL-IO
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 501
diff changeset
690 // 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
691 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
692 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
693 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
694 }
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
695
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
696 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
697
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
698 // return to nsapi loop
497
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
699 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
700 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
701 return 0;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
702 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
703
566
963edce64e6e log all cgi pipe fds
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 565
diff changeset
704 int cgi_start(Request *rq, 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
705 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
706 log_ereport(
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
707 LOG_FAILURE,
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
708 "send-cgi: cannot create pipe: %s",
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
709 strerror(errno));
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
710 return REQ_ABORTED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
711 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
712
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
713 p->pid = fork();
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
714 if(p->pid == 0) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
715 // child
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
716
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
717 // get script directory and script name
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
718 cxstring script = cx_str(path);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
719 cxmutstr parent;
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
720 int len = strlen(path);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
721 for(int i=len-1;i>=0;i--) {
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
722 if(path[i] == '/') {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
723 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
724 parent = cx_strdup(cx_strn(path, i));
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
725 if(chdir(parent.ptr)) {
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
726 perror("cgi_start: chdir");
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
727 free(parent.ptr);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
728 exit(-1);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
729 }
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
730 free(parent.ptr);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
731 break;
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
732 }
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
733 }
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
734
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
735 if(dup2(p->in[0], STDIN_FILENO) == -1) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
736 perror("cgi_start: dup2");
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
737 exit(EXIT_FAILURE);
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 if(dup2(p->out[1], STDOUT_FILENO) == -1) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
740 perror("cgi_start: dup2");
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
741 exit(EXIT_FAILURE);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
742 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
743 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
744 perror("cgi_start: dup2");
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
745 exit(EXIT_FAILURE);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
746 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
747
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
748 // we need to close this unused pipe
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
749 // 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
750 system_close(p->in[1]);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
751
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
752 // execute program
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
753 exit(execve(script.ptr, argv, envp));
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
754 } else {
566
963edce64e6e log all cgi pipe fds
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 565
diff changeset
755 log_ereport(LOG_DEBUG, "send-cgi: start-cgi: req: %p pid: %d pipes: [%d, %d][%d, %d][%d, %d]", rq, (int)p->pid, p->out[0], p->out[1], p->err[0], p->err[1], p->in[0], p->in[1]);
963edce64e6e log all cgi pipe fds
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 565
diff changeset
756 // parent
171
af7e2d80dee6 adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 164
diff changeset
757 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
758 system_close(p->err[1]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
759 p->out[1] = -1;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
760 p->err[1] = -1;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
761 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
762
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
763 return REQ_PROCEED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
764 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
765
519
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
766 int cgi_close(CGIProcess *p) {
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
767 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
768 system_close(p->in[0]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
769 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
770 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
771 system_close(p->in[1]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
772 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
773 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
774 system_close(p->out[0]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
775 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
776 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
777 system_close(p->out[1]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
778 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
779 if(p->err[0] != -1) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
780 system_close(p->err[0]);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
781 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
782 if(p->err[1] != -1) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
783 system_close(p->err[1]);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
784 }
162
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
785
519
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
786 // 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
787 // 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
788 // be done later somewhere.
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
789 int status = -1;
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
790 if(waitpid(p->pid, &status, WNOHANG) == 0) {
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
791 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
792 // cgi process still running
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
793 // 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
794 sleep(1);
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
795 if(waitpid(p->pid, &status, WNOHANG) == 0) {
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
796 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
797 }
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
798 }
857e5b92828b add workaround for blocking cgi waitpid
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 518
diff changeset
799
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
800 return status;
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
801 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
802
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
803 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
804 CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser));
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
805 parser->sn = sn;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
806 parser->rq = rq;
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
807 parser->status = 0;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
808 parser->msg = NULL;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
809 parser->response_length = 0;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
810 parser->cgiheader = TRUE;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
811 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
812 return parser;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
813 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
814
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
815 void cgi_parser_free(CGIResponseParser *parser) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
816 if(parser->tmp.space) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
817 cxBufferDestroy(&parser->tmp);
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
818 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
819 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
820 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
821
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
822 /*
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
823 * 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
824 * returns 0: incomplete line
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
825 * 1: successfully parsed lines
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
826 * 2: cgi response header complete (empty line)
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
827 * -1: error
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 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
830 CxAllocator *a = pool_allocator(parser->sn->pool);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
831 cxmutstr name;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
832 cxmutstr value;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
833 WSBool space = TRUE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
834 int i;
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 int line_begin = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
837 int value_begin = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
838 for(i=0;i<len;i++) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
839 char c = buf[i];
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
840 if(value_begin == line_begin && c == ':') {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
841 name = cx_mutstrn(buf + line_begin, i - line_begin);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
842 value_begin = i + 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
843 } else if(c == '\n') {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
844 if(value_begin == line_begin) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
845 if(space) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
846 *pos = i + 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
847 return 2;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
848 } else {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
849 // line ends with content but without ':' -> error
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
850 return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
851 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
852 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
853 value = cx_mutstrn(buf + value_begin, i - value_begin);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
854
579
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 567
diff changeset
855 for(int l=0;i<name.length;l++) {
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 567
diff changeset
856 name.ptr[l] = tolower(name.ptr[l]);
e10457d74fe1 update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 567
diff changeset
857 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
858 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
859 value = cx_strtrim_m(value);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
860
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
861 if(name.length == 0 || value.length == 0) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
862 return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
863 }
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
864
585
bae488d2b3c2 make cgi response status header check case insensitive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 579
diff changeset
865 if(!cx_strcasecmp((cxstring){name.ptr, name.length}, (cxstring)CX_STR("status"))) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
866 cxmutstr codestr = value;
133
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
867 int j;
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
868 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
869 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
870 break;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
871 }
133
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
872 if(j > 2) {
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
873 break;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
874 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
875 }
133
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
876 codestr.ptr[j] = '\0';
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
877
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
878 int64_t s = 0;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
879 util_strtoint(codestr.ptr, &s);
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
880 parser->status = (int)s;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
881
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
882 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
883
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
884 if(msg.length > 0) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
885 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
886 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
887 } else {
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
888 pblock_nvlinsert(
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
889 name.ptr,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
890 name.length,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
891 value.ptr,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
892 value.length,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
893 parser->rq->srvhdrs);
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
894 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
895
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
896 line_begin = i+1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
897 value_begin = line_begin;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
898 space = TRUE;
121
a881dc866e23 adds more CGI stuff
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 120
diff changeset
899 } else if(!isspace(c)) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
900 space = FALSE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
901 }
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
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
904 if(i < len) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
905 *pos = i;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
906 return 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
907 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
908 return 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
909 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
910
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
911 /*
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
912 * returns -1: error
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
913 * 0: response header incomplete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
914 * 1: complete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
915 */
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
916 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
917 *bpos = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
918 int pos = 0;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
919 if(parser->tmp.pos > 0) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
920 // the tmp buffer contains an unfinished line
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
921 // fill up the buffer until the line is complete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
922 WSBool nb = FALSE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
923 for(pos=0;pos<len;pos++) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
924 if(buf[pos] == '\n') {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
925 nb = TRUE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
926 break;
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 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
929 cxBufferWrite(buf, 1, pos, &parser->tmp);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
930
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
931 if(nb) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
932 // line complete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
933 int npos;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
934 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
935 switch(r) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
936 case -1: return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
937 case 0: return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
938 case 1: break;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
939 case 2: {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
940 *bpos = pos + 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
941 return 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
942 }
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 // reset tmp buffer
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
945 parser->tmp.pos = 0;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
946 } else {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
947 if(parser->tmp.pos > CGI_RESPONSE_MAX_LINE_LENGTH) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
948 return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
949 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
950 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
951 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
952
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
953 int npos = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
954 int r = parse_lines(parser, buf + pos, len - pos, &npos);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
955 switch(r) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
956 default: return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
957 case 0:
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
958 case 1: {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
959 int newlen = len - npos;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
960 if(npos > 0) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
961 cxBufferWrite(buf + npos, 1, newlen, &parser->tmp);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
962 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
963 return 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
964 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
965 case 2: {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
966 *bpos = pos + npos;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
967 return 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
968 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
969 }
171
af7e2d80dee6 adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 164
diff changeset
970 }

mercurial