src/server/safs/cgi.c

Sun, 04 Jun 2023 20:09:18 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 04 Jun 2023 20:09:18 +0200
changeset 498
0d80f8a2b29f
parent 497
8827517054ec
child 499
ef77854a91f3
permissions
-rw-r--r--

fix net_http_write when used with chunked transfer encoding and non-blocking IO

118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2016 Olaf Wintermann. All rights reserved.
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include "cgi.h"
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <stdio.h>
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include <stdlib.h>
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33 #include <unistd.h>
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34
162
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
35 #include <sys/types.h>
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
36 #include <signal.h>
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
37 #include <sys/wait.h>
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
38
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
39 #include <cx/string.h>
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 171
diff changeset
40
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 #include "../util/util.h"
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
42 #include "../util/pblock.h"
171
af7e2d80dee6 adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 164
diff changeset
43 #include "../daemon/netsite.h"
450
d7b276de183b fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 433
diff changeset
44 #include "../daemon/vfs.h"
125
c913d515be1e adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 124
diff changeset
45 #include "../util/io.h"
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
46 #include "../daemon/event.h"
125
c913d515be1e adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 124
diff changeset
47
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 #include "cgiutils.h"
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 #define CGI_VARS 32
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 #define CGI_RESPONSE_PARSER_BUFLEN 2048
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 #define CGI_RESPONSE_MAX_LINE_LENGTH 512
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 int send_cgi(pblock *pb, Session *sn, Request *rq) {
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
56 char *path = pblock_findkeyval(pb_key_path, rq->vars);
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
57 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
58 int64_t content_length = 0;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
59
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
60 if(ctlen) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
61 if(!util_strtoint(ctlen, &content_length)) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
62 log_ereport(
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
63 LOG_FAILURE,
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
64 "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
65 protocol_status(sn, rq, 400, NULL);
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
66 return REQ_ABORTED;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
67 }
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
68 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69
450
d7b276de183b fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 433
diff changeset
70 // 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
71 // 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
72 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
73 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
74 }
d7b276de183b fix cgi pipes not closed in some error case + minor improvements
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 433
diff changeset
75
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 struct stat s;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 if(stat(path, &s)) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 int statuscode = util_errno2status(errno);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 protocol_status(sn, rq, statuscode, NULL);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 return REQ_ABORTED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 if(S_ISDIR(s.st_mode)) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 protocol_status(sn, rq, 403, NULL);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 return REQ_ABORTED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 param_free(pblock_remove("content-type", rq->srvhdrs));
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 const char *args = pblock_findval("query", rq->reqpb);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 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
91 if(!argv) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
92 return REQ_ABORTED;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
93 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 char **env = http_hdrs2env(rq->headers);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 env = cgi_common_vars(sn, rq, env);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 env = cgi_specific_vars(sn, rq, args, env, 1);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
99 // 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
100 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
101 if(!handler) {
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 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
104 ZERO(handler, sizeof(CGIHandler));
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
105 handler->path = path;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
106
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
107 int ret = cgi_start(&handler->process, path, argv, env);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 if(ret != REQ_PROCEED) {
145
1c93281ca4bf fixes memory leaks in request_stat_path and send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 144
diff changeset
109 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
110 cgi_free_argv(argv);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 return ret;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
114 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
115 cgi_free_argv(argv);
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
116
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
117 char buf[4096]; // I/O buffer
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
118 ssize_t r;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
120 if(content_length > 0) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
121 ssize_t n = 0;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
122 while(n < content_length) {
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
123 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
124 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
125 log_ereport(
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
126 LOG_FAILURE,
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
127 "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
128 path);
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
129 kill(handler->process.pid, SIGTERM);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
130 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
131 return REQ_ABORTED;
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
132 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
133 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
134 if(w <= 0) {
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
135 log_ereport(
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
136 LOG_FAILURE,
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
137 "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
138 path);
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
139 kill(handler->process.pid, SIGKILL);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
140 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
141 return REQ_ABORTED;
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
142 }
119
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
143 n += r;
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
144 }
155cbab9eefd adds support for CGI with request bodies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 118
diff changeset
145 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
146 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
147 handler->process.in[1] = -1;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
148
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
149 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
150
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
151 // 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
152 int flags;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
153 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
154 flags = 0;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
155 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
156 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
157 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
158 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
159 if ((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
160 flags = 0;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
161 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
162 if (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
163 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
164 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
165
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
166 // 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
167 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
168 ZERO(readev, sizeof(Event));
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
169 readev->cookie = handler;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
170 readev->fn = cgi_stdout_readevent;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
171 readev->finish = cgi_event_finish;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
172
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
173 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
174 ZERO(stderr_readev, sizeof(Event));
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
175 stderr_readev->cookie = handler;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
176 stderr_readev->fn = cgi_stderr_readevent;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
177 stderr_readev->finish = NULL;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
178
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
179 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
180 ZERO(writeev, sizeof(Event));
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
181 writeev->cookie = handler;
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
182
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
183
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
184 handler->writeev = writeev;
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
185 handler->stderrev = stderr_readev;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
187 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
188
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
189 // add poll events for cgi stdout/stderr
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
190 int error = 0;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
191 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
192 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
193 error = 1;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
194 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
195 if(ev_pollin(sn->ev, handler->process.out[0], readev)) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
196 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
197 error = 1;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
198 }
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 if(error) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
201 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", path);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
202 kill(handler->process.pid, SIGKILL);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
203 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
204 cgi_close(&handler->process);
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
205 return REQ_ABORTED;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
206 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
207
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
208 return REQ_PROCESSING;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
209 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
210
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
211 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
212 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
213 while(
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
214 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
215 (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
216 sn->csd,
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
217 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
218 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
219 > 0)
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
220 {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
221 handler->writebuf_pos += wr;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
222 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
223 if(wr < 0) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
224 if(errno != EWOULDBLOCK) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
225 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
226 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
227 return 1;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
228 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
229 return 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
230 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
231
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
232 static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
233 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
234 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
235 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
236 pos += wr;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
237 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
238 if(wr < 0) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
239 if(errno == EWOULDBLOCK) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
240 // 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
241 // 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
242 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
243 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
244 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
245 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
246 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
247 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
248 return 1;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
249 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
250 }
497
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
251 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
252 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
253 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
254
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
255 // initialize poll, if it isn't already active
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
256 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
257 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
258 handler->result = REQ_ABORTED;
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
259 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
260 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
261 handler->poll_out = TRUE;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
262 }
497
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
263 } else {
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
264 handler->result = REQ_ABORTED;
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
265 log_ereport(LOG_FAILURE, "cgi_try_write: %s", strerror(errno));
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
266 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
267 return 1;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
268 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
269
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
270 return 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
271 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
272
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
273 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
274 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
275
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
276 return cgi_read_output(handler, ev);
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
277 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
278
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
279 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
280 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
281
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
282 // cgi_read_output will try to flush the buffer
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
283 return cgi_read_output(handler, ev);
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
284 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
285
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
286
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
287
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
288 int cgi_read_output(CGIHandler *handler, EventHandler *ev) {
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
289 CGIResponseParser *parser = handler->parser;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
290 Session *sn = parser->sn;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
291 Request *rq = parser->rq;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
292
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
293 // 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
294 // 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
295 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
296 if(handler->result == REQ_ABORTED) {
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
297 log_ereport(LOG_DEBUG, "cgi-send: req: %p write failed: abort", rq);
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
298 return 0;
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
299 } else {
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
300 return 1;
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
301 }
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
302 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
303
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
304 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
305 ssize_t r;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
306
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
307 handler->result = REQ_PROCEED;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
308 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
309 if(parser->cgiheader) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 size_t pos;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
311 int ret = cgi_parse_response(parser, buf, r, &pos);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 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
313 log_ereport(
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
314 LOG_FAILURE,
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
315 "broken cgi script response: path: %s", handler->path);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 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
317 handler->result = REQ_ABORTED;
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
318 return 0;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 } 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
320 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
321
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
322 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
323
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
324 parser->cgiheader = FALSE;
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
325 if(parser->status > 0) {
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
326 protocol_status(sn, rq, parser->status, parser->msg);
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
327 }
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
328
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
329 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
330 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
331 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
332 return 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
333 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
334
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
335 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
336 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
337 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
338 break;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
339 } else if(send_response == 1) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
340 // EWOULDBLOCK
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
341 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
342 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
343 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
344 return 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
345 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
346 handler->poll_out = TRUE;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
347 return 1;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
348 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
349 } else {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
350 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
351 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
352
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
353 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
354 if(cgi_try_write(handler, ev, sn, &buf[pos], r-pos)) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
355 return handler->result == REQ_ABORTED ? 0 : 1;
125
c913d515be1e adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 124
diff changeset
356 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
357 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
358 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
359 } else {
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
360 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
361 if(cgi_try_write(handler, ev, sn, buf, r)) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
362 return handler->result == REQ_ABORTED ? 0 : 1;
125
c913d515be1e adds more error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 124
diff changeset
363 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
364 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
365 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
366 if(r < 0 && errno == EWOULDBLOCK) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
367 return 1;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
368 }
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
369
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
370 handler->read_output_finished = TRUE;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
371 return 0;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
372 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
373
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
374 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
375 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
376 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
377
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
378 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
379 char *line = buf;
451
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
380 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
381 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
382 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
383 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
384 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
385 // 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
386 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
387 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
388 log_ereport(
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
389 LOG_INFORM,
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
390 "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
391 (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
392 handler->path,
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
393 (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
394 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
395 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
396 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
397 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
398 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
399
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
400 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
401 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
402 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
403 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
404 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
405
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
406 // 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
407 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
408 int tmplen = r-pos;
451
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
409 if(handler->stderr_tmplen > 0) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
410 // 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
411 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
412 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
413 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
414 if(!handler->stderr_tmp) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
415 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
416 handler->stderr_tmpalloc = 0;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
417 handler->stderr_tmplen = 0;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
418 continue;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
419 }
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
420 }
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
421 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
422 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
423 } else {
451
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
424 if(handler->stderr_tmpalloc < tmplen) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
425 // 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
426 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
427 if(handler->stderr_tmp) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
428 // free old tmp buf
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
429 // 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
430 // 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
431 // 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
432 // 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
433 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
434 }
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
435 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
436 if(!handler->stderr_tmp) {
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
437 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
438 handler->stderr_tmpalloc = 0;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
439 handler->stderr_tmplen = 0;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
440 continue;
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
441 }
edbbb3000494 fix cgi stderr logger + reuse stderr tmp buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 450
diff changeset
442 }
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
443 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
444 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
445 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
446 } else {
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
447 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
448 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
449 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
450
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
451
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
452 if(r < 0 && errno == EWOULDBLOCK) {
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
453 return 1;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
454 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
455
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
456 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
457 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
458 }
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
459 handler->stderr_finished = TRUE;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
460 return 0;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
461 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
462
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
463 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
464 CGIHandler *handler = event->cookie;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
465 CGIResponseParser *parser = handler->parser;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
466 Session *sn = parser->sn;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
467 Request *rq = parser->rq;
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
468
497
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
469 log_ereport(LOG_DEBUG, "cgi-send: req: %p event-finish", rq);
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
470 if(handler->result == REQ_ABORTED && handler->process.pid != 0) {
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
471 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", handler->path);
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
472
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
473 killpg(handler->process.pid, SIGTERM);
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
474
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
475 handler->process.pid = 0;
162
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
476 }
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
477
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
478 if(!handler->stderr_finished) {
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
479 // stderr handler is still active
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
480 // set stderr event finish function, to run the finish code later
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
481 handler->stderrev->finish = cgi_event_finish;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
482 return 0;
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
483 }
433
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
484 if(handler->poll_out && !handler->send_response_finished) {
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
485 // send response is still active
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
486 handler->writeev->finish = cgi_event_finish;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
487 return 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
488 }
431
032b0ad35ee3 parse cgi stderr output for logging and use non-blocking pipes
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 430
diff changeset
489
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
490 int exit_code = cgi_close(&handler->process);
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
491 if(exit_code != 0) {
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
492 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
493 handler->result = REQ_ABORTED;
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
494 }
126
631aaa01b2b5 fixes chunked transfer encoding
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 125
diff changeset
495
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
496 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
497
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
498 // 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
499 // 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
500 // 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
501 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
502 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
503 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
504 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
505 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
506 log_ereport(
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
507 LOG_FAILURE,
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
508 "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
509 handler->path);
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
510 rq->rq_attr.keep_alive = 0;
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
511 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
512 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
513 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
514 }
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
515
39fe86ae4db0 use non-blocking IO for pipes and socket in send_cgi
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 431
diff changeset
516 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
517
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
518 // return to nsapi loop
497
8827517054ec fix cgi response could send an uninitialized buffer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 451
diff changeset
519 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
520 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
521 return 0;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
522 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
523
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
524 int cgi_start(CGIProcess *p, char *path, char *const argv[], char *const envp[]) {
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
525 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
526 log_ereport(
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
527 LOG_FAILURE,
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
528 "send-cgi: cannot create pipe: %s",
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
529 strerror(errno));
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
530 return REQ_ABORTED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
531 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
532
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
533 p->pid = fork();
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
534 if(p->pid == 0) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
535 // child
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
536
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
537 // get script directory and script name
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
538 cxstring script = cx_str(path);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
539 cxmutstr parent;
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
540 int len = strlen(path);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
541 for(int i=len-1;i>=0;i--) {
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
542 if(path[i] == '/') {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
543 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
544 parent = cx_strdup(cx_strn(path, i));
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
545 if(chdir(parent.ptr)) {
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
546 perror("cgi_start: chdir");
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
547 free(parent.ptr);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
548 exit(-1);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
549 }
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
550 free(parent.ptr);
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
551 break;
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
552 }
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
553 }
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
554
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
555 if(dup2(p->in[0], STDIN_FILENO) == -1) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
556 perror("cgi_start: dup2");
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
557 exit(EXIT_FAILURE);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
558 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
559 if(dup2(p->out[1], STDOUT_FILENO) == -1) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
560 perror("cgi_start: dup2");
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
561 exit(EXIT_FAILURE);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
562 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
563 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
564 perror("cgi_start: dup2");
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
565 exit(EXIT_FAILURE);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
566 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
567
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
568 // we need to close this unused pipe
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
569 // 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
570 system_close(p->in[1]);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
571
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
572 // execute program
120
d2eb5fd97df0 adds chdir before cgi execution
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 119
diff changeset
573 exit(execve(script.ptr, argv, envp));
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
574 } else {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
575 // parent
171
af7e2d80dee6 adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 164
diff changeset
576 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
577 system_close(p->err[1]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
578 p->out[1] = -1;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
579 p->err[1] = -1;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
580 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
581
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
582 return REQ_PROCEED;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
583 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
584
162
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
585 int cgi_close(CGIProcess *p) {
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
586 int status = -1;
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
587 waitpid(p->pid, &status, 0);
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
588
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
589 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
590 system_close(p->in[0]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
591 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
592 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
593 system_close(p->in[1]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
594 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
595 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
596 system_close(p->out[0]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
597 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
598 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
599 system_close(p->out[1]);
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
600 }
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
601 if(p->err[0] != -1) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
602 system_close(p->err[0]);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
603 }
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
604 if(p->err[1] != -1) {
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
605 system_close(p->err[1]);
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
606 }
162
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
607
359
79b28ae7bfbd check cgi exit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
608 return status;
144
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
609 }
4b546c4f25ed fixes cgi fd leak
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 133
diff changeset
610
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
611 CGIResponseParser* cgi_parser_new(Session *sn, Request *rq) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
612 CGIResponseParser* parser = pool_malloc(sn->pool, sizeof(CGIResponseParser));
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
613 parser->sn = sn;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
614 parser->rq = rq;
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
615 parser->status = 0;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
616 parser->msg = NULL;
430
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
617 parser->response_length = 0;
83560f32e7d5 refactor send_cgi into non-blocking SAF (wip)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
618 parser->cgiheader = TRUE;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
619 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
620 return parser;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
621 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
622
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
623 void cgi_parser_free(CGIResponseParser *parser) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
624 if(parser->tmp.space) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
625 cxBufferDestroy(&parser->tmp);
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
626 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
627 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
628 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
629
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
630 /*
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
631 * 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
632 * returns 0: incomplete line
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
633 * 1: successfully parsed lines
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
634 * 2: cgi response header complete (empty line)
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
635 * -1: error
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
636 */
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
637 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
638 CxAllocator *a = pool_allocator(parser->sn->pool);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
639 cxmutstr name;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
640 cxmutstr value;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
641 WSBool space = TRUE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
642 int i;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
643
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
644 int line_begin = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
645 int value_begin = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
646 for(i=0;i<len;i++) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
647 char c = buf[i];
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
648 if(value_begin == line_begin && c == ':') {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
649 name = cx_mutstrn(buf + line_begin, i - line_begin);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
650 value_begin = i + 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
651 } else if(c == '\n') {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
652 if(value_begin == line_begin) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
653 if(space) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
654 *pos = i + 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
655 return 2;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
656 } else {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
657 // line ends with content but without ':' -> error
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
658 return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
659 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
660 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
661 value = cx_mutstrn(buf + value_begin, i - value_begin);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
662
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
663 cx_strlower(name);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
664 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
665 value = cx_strtrim_m(value);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
666
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
667 if(name.length == 0 || value.length == 0) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
668 return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
669 }
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
670
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
671 if(!cx_strcmp((cxstring){name.ptr, name.length}, (cxstring)CX_STR("status"))) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
672 cxmutstr codestr = value;
133
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
673 int j;
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
674 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
675 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
676 break;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
677 }
133
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
678 if(j > 2) {
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
679 break;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
680 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
681 }
133
87b405d61f64 improves event handler and ssl error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 126
diff changeset
682 codestr.ptr[j] = '\0';
124
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
683
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
684 int64_t s = 0;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
685 util_strtoint(codestr.ptr, &s);
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
686 parser->status = (int)s;
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
687
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
688 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
689
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
690 if(msg.length > 0) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
691 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
692 }
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
693 } else {
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
694 pblock_nvlinsert(
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
695 name.ptr,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
696 name.length,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
697 value.ptr,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
698 value.length,
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
699 parser->rq->srvhdrs);
85985e88f63b using the status code from cgi output now
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 123
diff changeset
700 }
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
701
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
702 line_begin = i+1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
703 value_begin = line_begin;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
704 space = TRUE;
121
a881dc866e23 adds more CGI stuff
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 120
diff changeset
705 } else if(!isspace(c)) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
706 space = FALSE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
707 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
708 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
709
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
710 if(i < len) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
711 *pos = i;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
712 return 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
713 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
714 return 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
715 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
716
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
717 /*
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
718 * returns -1: error
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
719 * 0: response header incomplete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
720 * 1: complete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
721 */
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
722 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
723 *bpos = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
724 int pos = 0;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
725 if(parser->tmp.pos > 0) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
726 // the tmp buffer contains an unfinished line
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
727 // fill up the buffer until the line is complete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
728 WSBool nb = FALSE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
729 for(pos=0;pos<len;pos++) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
730 if(buf[pos] == '\n') {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
731 nb = TRUE;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
732 break;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
733 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
734 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
735 cxBufferWrite(buf, 1, pos, &parser->tmp);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
736
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
737 if(nb) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
738 // line complete
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
739 int npos;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
740 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
741 switch(r) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
742 case -1: return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
743 case 0: return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
744 case 1: break;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
745 case 2: {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
746 *bpos = pos + 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
747 return 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
748 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
749 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
750 // reset tmp buffer
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
751 parser->tmp.pos = 0;
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
752 } else {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
753 if(parser->tmp.pos > CGI_RESPONSE_MAX_LINE_LENGTH) {
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
754 return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
755 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
756 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
757 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
758
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
759 int npos = 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
760 int r = parse_lines(parser, buf + pos, len - pos, &npos);
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
761 switch(r) {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
762 default: return -1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
763 case 0:
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
764 case 1: {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
765 int newlen = len - npos;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
766 if(npos > 0) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 359
diff changeset
767 cxBufferWrite(buf + npos, 1, newlen, &parser->tmp);
118
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
768 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
769 return 0;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
770 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
771 case 2: {
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
772 *bpos = pos + npos;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
773 return 1;
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
774 }
38bf6dd8f4e7 adds minimal cgi implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
775 }
171
af7e2d80dee6 adds wrapper for close syscall with error handling
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 164
diff changeset
776 }

mercurial