Blame


1 b0a6bcf7 2022-09-13 op /*
2 b0a6bcf7 2022-09-13 op * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
3 b0a6bcf7 2022-09-13 op *
4 b0a6bcf7 2022-09-13 op * Permission to use, copy, modify, and distribute this software for any
5 b0a6bcf7 2022-09-13 op * purpose with or without fee is hereby granted, provided that the above
6 b0a6bcf7 2022-09-13 op * copyright notice and this permission notice appear in all copies.
7 b0a6bcf7 2022-09-13 op *
8 b0a6bcf7 2022-09-13 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 b0a6bcf7 2022-09-13 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 b0a6bcf7 2022-09-13 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 b0a6bcf7 2022-09-13 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 b0a6bcf7 2022-09-13 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 b0a6bcf7 2022-09-13 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 b0a6bcf7 2022-09-13 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 b0a6bcf7 2022-09-13 op */
16 b0a6bcf7 2022-09-13 op
17 b0a6bcf7 2022-09-13 op #include <sys/queue.h>
18 b0a6bcf7 2022-09-13 op #include <sys/tree.h>
19 b0a6bcf7 2022-09-13 op #include <sys/socket.h>
20 b0a6bcf7 2022-09-13 op
21 b0a6bcf7 2022-09-13 op #include <netinet/in.h>
22 b0a6bcf7 2022-09-13 op #include <arpa/inet.h>
23 b0a6bcf7 2022-09-13 op
24 b0a6bcf7 2022-09-13 op #include <errno.h>
25 b0a6bcf7 2022-09-13 op #include <event.h>
26 b0a6bcf7 2022-09-13 op #include <limits.h>
27 b0a6bcf7 2022-09-13 op #include <stdarg.h>
28 b0a6bcf7 2022-09-13 op #include <stdio.h>
29 b0a6bcf7 2022-09-13 op #include <stdlib.h>
30 b0a6bcf7 2022-09-13 op #include <stdint.h>
31 b0a6bcf7 2022-09-13 op #include <string.h>
32 b0a6bcf7 2022-09-13 op #include <unistd.h>
33 b0a6bcf7 2022-09-13 op
34 b0a6bcf7 2022-09-13 op #include "log.h"
35 b0a6bcf7 2022-09-13 op
36 b0a6bcf7 2022-09-13 op #include "galileo.h"
37 b0a6bcf7 2022-09-13 op
38 b0a6bcf7 2022-09-13 op #define MIN(a, b) ((a) < (b) ? (a) : (b))
39 b0a6bcf7 2022-09-13 op
40 b0a6bcf7 2022-09-13 op struct fcgi_header {
41 b0a6bcf7 2022-09-13 op unsigned char version;
42 b0a6bcf7 2022-09-13 op unsigned char type;
43 b0a6bcf7 2022-09-13 op unsigned char req_id1;
44 b0a6bcf7 2022-09-13 op unsigned char req_id0;
45 b0a6bcf7 2022-09-13 op unsigned char content_len1;
46 b0a6bcf7 2022-09-13 op unsigned char content_len0;
47 b0a6bcf7 2022-09-13 op unsigned char padding;
48 b0a6bcf7 2022-09-13 op unsigned char reserved;
49 b0a6bcf7 2022-09-13 op } __attribute__((packed));
50 b0a6bcf7 2022-09-13 op
51 b0a6bcf7 2022-09-13 op /*
52 b0a6bcf7 2022-09-13 op * number of bytes in a FCGI_HEADER. Future version of the protocol
53 b0a6bcf7 2022-09-13 op * will not reduce this number.
54 b0a6bcf7 2022-09-13 op */
55 b0a6bcf7 2022-09-13 op #define FCGI_HEADER_LEN 8
56 b0a6bcf7 2022-09-13 op
57 b0a6bcf7 2022-09-13 op /*
58 b0a6bcf7 2022-09-13 op * values for the version component
59 b0a6bcf7 2022-09-13 op */
60 b0a6bcf7 2022-09-13 op #define FCGI_VERSION_1 1
61 b0a6bcf7 2022-09-13 op
62 b0a6bcf7 2022-09-13 op /*
63 b0a6bcf7 2022-09-13 op * values for the type component
64 b0a6bcf7 2022-09-13 op */
65 b0a6bcf7 2022-09-13 op #define FCGI_BEGIN_REQUEST 1
66 b0a6bcf7 2022-09-13 op #define FCGI_ABORT_REQUEST 2
67 b0a6bcf7 2022-09-13 op #define FCGI_END_REQUEST 3
68 b0a6bcf7 2022-09-13 op #define FCGI_PARAMS 4
69 b0a6bcf7 2022-09-13 op #define FCGI_STDIN 5
70 b0a6bcf7 2022-09-13 op #define FCGI_STDOUT 6
71 b0a6bcf7 2022-09-13 op #define FCGI_STDERR 7
72 b0a6bcf7 2022-09-13 op #define FCGI_DATA 8
73 b0a6bcf7 2022-09-13 op #define FCGI_GET_VALUES 9
74 b0a6bcf7 2022-09-13 op #define FCGI_GET_VALUES_RESULT 10
75 b0a6bcf7 2022-09-13 op #define FCGI_UNKNOWN_TYPE 11
76 b0a6bcf7 2022-09-13 op #define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
77 b0a6bcf7 2022-09-13 op
78 b0a6bcf7 2022-09-13 op struct fcgi_begin_req {
79 b0a6bcf7 2022-09-13 op unsigned char role1;
80 b0a6bcf7 2022-09-13 op unsigned char role0;
81 b0a6bcf7 2022-09-13 op unsigned char flags;
82 b0a6bcf7 2022-09-13 op unsigned char reserved[5];
83 b0a6bcf7 2022-09-13 op };
84 b0a6bcf7 2022-09-13 op
85 b0a6bcf7 2022-09-13 op struct fcgi_begin_req_record {
86 b0a6bcf7 2022-09-13 op struct fcgi_header header;
87 b0a6bcf7 2022-09-13 op struct fcgi_begin_req body;
88 b0a6bcf7 2022-09-13 op };
89 b0a6bcf7 2022-09-13 op
90 b0a6bcf7 2022-09-13 op /*
91 b0a6bcf7 2022-09-13 op * mask for flags;
92 b0a6bcf7 2022-09-13 op */
93 b0a6bcf7 2022-09-13 op #define FCGI_KEEP_CONN 1
94 b0a6bcf7 2022-09-13 op
95 b0a6bcf7 2022-09-13 op /*
96 b0a6bcf7 2022-09-13 op * values for the role
97 b0a6bcf7 2022-09-13 op */
98 b0a6bcf7 2022-09-13 op #define FCGI_RESPONDER 1
99 b0a6bcf7 2022-09-13 op #define FCGI_AUTHORIZER 2
100 b0a6bcf7 2022-09-13 op #define FCGI_FILTER 3
101 b0a6bcf7 2022-09-13 op
102 b0a6bcf7 2022-09-13 op struct fcgi_end_req_body {
103 b0a6bcf7 2022-09-13 op unsigned char app_status3;
104 b0a6bcf7 2022-09-13 op unsigned char app_status2;
105 b0a6bcf7 2022-09-13 op unsigned char app_status1;
106 b0a6bcf7 2022-09-13 op unsigned char app_status0;
107 b0a6bcf7 2022-09-13 op unsigned char proto_status;
108 b0a6bcf7 2022-09-13 op unsigned char reserved[3];
109 b0a6bcf7 2022-09-13 op };
110 b0a6bcf7 2022-09-13 op
111 b0a6bcf7 2022-09-13 op /*
112 b0a6bcf7 2022-09-13 op * values for proto_status
113 b0a6bcf7 2022-09-13 op */
114 b0a6bcf7 2022-09-13 op #define FCGI_REQUEST_COMPLETE 0
115 b0a6bcf7 2022-09-13 op #define FCGI_CANT_MPX_CONN 1
116 b0a6bcf7 2022-09-13 op #define FCGI_OVERLOADED 2
117 b0a6bcf7 2022-09-13 op #define FCGI_UNKNOWN_ROLE 3
118 b0a6bcf7 2022-09-13 op
119 b0a6bcf7 2022-09-13 op /*
120 b0a6bcf7 2022-09-13 op * Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT
121 b0a6bcf7 2022-09-13 op * records.
122 b0a6bcf7 2022-09-13 op */
123 b0a6bcf7 2022-09-13 op #define FCGI_MAX_CONNS "FCGI_MAX_CONNS"
124 b0a6bcf7 2022-09-13 op #define FCGI_MAX_REQS "FCGI_MAX_REQS"
125 b0a6bcf7 2022-09-13 op #define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
126 b0a6bcf7 2022-09-13 op
127 b0a6bcf7 2022-09-13 op #define CAT(f0, f1) ((f0) + ((f1) << 8))
128 b0a6bcf7 2022-09-13 op
129 b0a6bcf7 2022-09-13 op enum {
130 b0a6bcf7 2022-09-13 op FCGI_RECORD_HEADER,
131 b0a6bcf7 2022-09-13 op FCGI_RECORD_BODY,
132 b0a6bcf7 2022-09-13 op };
133 b0a6bcf7 2022-09-13 op
134 b0a6bcf7 2022-09-13 op volatile int fcgi_inflight;
135 b0a6bcf7 2022-09-13 op
136 b0a6bcf7 2022-09-13 op static int
137 b0a6bcf7 2022-09-13 op fcgi_send_end_req(struct fcgi *fcgi, int id, int as, int ps)
138 b0a6bcf7 2022-09-13 op {
139 b0a6bcf7 2022-09-13 op struct bufferevent *bev = fcgi->fcg_bev;
140 b0a6bcf7 2022-09-13 op struct fcgi_header hdr;
141 b0a6bcf7 2022-09-13 op struct fcgi_end_req_body end;
142 b0a6bcf7 2022-09-13 op
143 b0a6bcf7 2022-09-13 op memset(&hdr, 0, sizeof(hdr));
144 b0a6bcf7 2022-09-13 op memset(&end, 0, sizeof(end));
145 b0a6bcf7 2022-09-13 op
146 b0a6bcf7 2022-09-13 op hdr.version = FCGI_VERSION_1;
147 b0a6bcf7 2022-09-13 op hdr.type = FCGI_END_REQUEST;
148 b0a6bcf7 2022-09-13 op hdr.req_id0 = (id & 0xFF);
149 b0a6bcf7 2022-09-13 op hdr.req_id1 = (id >> 8);
150 b0a6bcf7 2022-09-13 op hdr.content_len0 = sizeof(end);
151 b0a6bcf7 2022-09-13 op
152 b0a6bcf7 2022-09-13 op end.app_status0 = (unsigned char)as;
153 b0a6bcf7 2022-09-13 op end.proto_status = (unsigned char)ps;
154 b0a6bcf7 2022-09-13 op
155 b0a6bcf7 2022-09-13 op if (bufferevent_write(bev, &hdr, sizeof(hdr)) == -1)
156 b0a6bcf7 2022-09-13 op return (-1);
157 b0a6bcf7 2022-09-13 op if (bufferevent_write(bev, &end, sizeof(end)) == -1)
158 b0a6bcf7 2022-09-13 op return (-1);
159 b0a6bcf7 2022-09-13 op return (0);
160 b0a6bcf7 2022-09-13 op }
161 b0a6bcf7 2022-09-13 op
162 b0a6bcf7 2022-09-13 op static int
163 b0a6bcf7 2022-09-13 op end_request(struct client *clt, int status, int proto_status)
164 b0a6bcf7 2022-09-13 op {
165 b0a6bcf7 2022-09-13 op struct fcgi *fcgi = clt->clt_fcgi;
166 b0a6bcf7 2022-09-13 op int r;
167 b0a6bcf7 2022-09-13 op
168 b0a6bcf7 2022-09-13 op if (clt_flush(clt) == -1)
169 b0a6bcf7 2022-09-13 op return (-1);
170 b0a6bcf7 2022-09-13 op
171 b0a6bcf7 2022-09-13 op r = fcgi_send_end_req(fcgi, clt->clt_id, status,
172 b0a6bcf7 2022-09-13 op proto_status);
173 b0a6bcf7 2022-09-13 op if (r == -1) {
174 b0a6bcf7 2022-09-13 op fcgi_error(fcgi->fcg_bev, EV_WRITE, fcgi);
175 b0a6bcf7 2022-09-13 op return (-1);
176 b0a6bcf7 2022-09-13 op }
177 b0a6bcf7 2022-09-13 op
178 b0a6bcf7 2022-09-13 op SPLAY_REMOVE(client_tree, &fcgi->fcg_clients, clt);
179 b0a6bcf7 2022-09-13 op proxy_client_free(clt);
180 b0a6bcf7 2022-09-13 op return (0);
181 b0a6bcf7 2022-09-13 op }
182 b0a6bcf7 2022-09-13 op
183 b0a6bcf7 2022-09-13 op int
184 b0a6bcf7 2022-09-13 op fcgi_end_request(struct client *clt, int status)
185 b0a6bcf7 2022-09-13 op {
186 b0a6bcf7 2022-09-13 op return (end_request(clt, status, FCGI_REQUEST_COMPLETE));
187 b0a6bcf7 2022-09-13 op }
188 b0a6bcf7 2022-09-13 op
189 b0a6bcf7 2022-09-13 op int
190 b0a6bcf7 2022-09-13 op fcgi_abort_request(struct client *clt)
191 b0a6bcf7 2022-09-13 op {
192 b0a6bcf7 2022-09-13 op return (end_request(clt, 1, FCGI_OVERLOADED));
193 b0a6bcf7 2022-09-13 op }
194 b0a6bcf7 2022-09-13 op
195 b0a6bcf7 2022-09-13 op static void
196 b0a6bcf7 2022-09-13 op fcgi_inflight_dec(const char *why)
197 b0a6bcf7 2022-09-13 op {
198 b0a6bcf7 2022-09-13 op fcgi_inflight--;
199 b0a6bcf7 2022-09-13 op log_debug("%s: fcgi inflight decremented, now %d, %s",
200 b0a6bcf7 2022-09-13 op __func__, fcgi_inflight, why);
201 b0a6bcf7 2022-09-13 op }
202 b0a6bcf7 2022-09-13 op
203 b0a6bcf7 2022-09-13 op void
204 b0a6bcf7 2022-09-13 op fcgi_accept(struct galileo *env)
205 b0a6bcf7 2022-09-13 op {
206 b0a6bcf7 2022-09-13 op struct fcgi *fcgi = NULL;
207 b0a6bcf7 2022-09-13 op socklen_t slen;
208 b0a6bcf7 2022-09-13 op struct sockaddr_storage ss;
209 b0a6bcf7 2022-09-13 op int s = -1;
210 b0a6bcf7 2022-09-13 op
211 b0a6bcf7 2022-09-13 op slen = sizeof(ss);
212 b0a6bcf7 2022-09-13 op if ((s = accept_reserve(env->sc_sock_fd, (struct sockaddr *)&ss,
213 b0a6bcf7 2022-09-13 op &slen, FD_RESERVE, &fcgi_inflight)) == -1) {
214 b0a6bcf7 2022-09-13 op /*
215 b0a6bcf7 2022-09-13 op * Pause accept if we are out of file descriptors, or
216 b0a6bcf7 2022-09-13 op * libevent will haunt us here too.
217 b0a6bcf7 2022-09-13 op */
218 b0a6bcf7 2022-09-13 op if (errno == ENFILE || errno == EMFILE) {
219 b0a6bcf7 2022-09-13 op struct timeval evtpause = { 1, 0 };
220 b0a6bcf7 2022-09-13 op
221 b0a6bcf7 2022-09-13 op event_del(&env->sc_evsock);
222 b0a6bcf7 2022-09-13 op evtimer_add(&env->sc_evpause, &evtpause);
223 b0a6bcf7 2022-09-13 op log_debug("%s: deferring connections", __func__);
224 b0a6bcf7 2022-09-13 op }
225 b0a6bcf7 2022-09-13 op return;
226 b0a6bcf7 2022-09-13 op }
227 b0a6bcf7 2022-09-13 op
228 b0a6bcf7 2022-09-13 op if ((fcgi = calloc(1, sizeof(*fcgi))) == NULL)
229 b0a6bcf7 2022-09-13 op goto err;
230 b0a6bcf7 2022-09-13 op
231 b0a6bcf7 2022-09-13 op fcgi->fcg_id = ++proxy_fcg_id;
232 b0a6bcf7 2022-09-13 op fcgi->fcg_s = s;
233 b0a6bcf7 2022-09-13 op fcgi->fcg_env = env;
234 b0a6bcf7 2022-09-13 op fcgi->fcg_want = FCGI_RECORD_HEADER;
235 b0a6bcf7 2022-09-13 op fcgi->fcg_toread = sizeof(struct fcgi_header);
236 b0a6bcf7 2022-09-13 op SPLAY_INIT(&fcgi->fcg_clients);
237 b0a6bcf7 2022-09-13 op
238 b0a6bcf7 2022-09-13 op /* assume it's enabled until we get a FCGI_BEGIN_REQUEST */
239 b0a6bcf7 2022-09-13 op fcgi->fcg_keep_conn = 1;
240 b0a6bcf7 2022-09-13 op
241 b0a6bcf7 2022-09-13 op fcgi->fcg_bev = bufferevent_new(fcgi->fcg_s, fcgi_read, fcgi_write,
242 b0a6bcf7 2022-09-13 op fcgi_error, fcgi);
243 b0a6bcf7 2022-09-13 op if (fcgi->fcg_bev == NULL)
244 b0a6bcf7 2022-09-13 op goto err;
245 b0a6bcf7 2022-09-13 op
246 b0a6bcf7 2022-09-13 op bufferevent_enable(fcgi->fcg_bev, EV_READ | EV_WRITE);
247 b0a6bcf7 2022-09-13 op return;
248 b0a6bcf7 2022-09-13 op
249 b0a6bcf7 2022-09-13 op err:
250 b0a6bcf7 2022-09-13 op if (s != -1) {
251 b0a6bcf7 2022-09-13 op close(s);
252 b0a6bcf7 2022-09-13 op free(fcgi);
253 b0a6bcf7 2022-09-13 op fcgi_inflight_dec(__func__);
254 b0a6bcf7 2022-09-13 op }
255 b0a6bcf7 2022-09-13 op }
256 b0a6bcf7 2022-09-13 op
257 b0a6bcf7 2022-09-13 op static int
258 b0a6bcf7 2022-09-13 op parse_len(struct fcgi *fcgi, struct evbuffer *src)
259 b0a6bcf7 2022-09-13 op {
260 b0a6bcf7 2022-09-13 op unsigned char c, x[3];
261 b0a6bcf7 2022-09-13 op
262 b0a6bcf7 2022-09-13 op fcgi->fcg_toread--;
263 b0a6bcf7 2022-09-13 op evbuffer_remove(src, &c, 1);
264 b0a6bcf7 2022-09-13 op if (c >> 7 == 0)
265 b0a6bcf7 2022-09-13 op return (c);
266 b0a6bcf7 2022-09-13 op
267 b0a6bcf7 2022-09-13 op if (fcgi->fcg_toread < 3)
268 b0a6bcf7 2022-09-13 op return (-1);
269 b0a6bcf7 2022-09-13 op
270 b0a6bcf7 2022-09-13 op fcgi->fcg_toread -= 3;
271 b0a6bcf7 2022-09-13 op evbuffer_remove(src, x, sizeof(x));
272 b0a6bcf7 2022-09-13 op return (((c & 0x7F) << 24) | (x[0] << 16) | (x[1] << 8) | x[2]);
273 b0a6bcf7 2022-09-13 op }
274 b0a6bcf7 2022-09-13 op
275 b0a6bcf7 2022-09-13 op static int
276 b0a6bcf7 2022-09-13 op fcgi_parse_params(struct fcgi *fcgi, struct evbuffer *src, struct client *clt)
277 b0a6bcf7 2022-09-13 op {
278 b0a6bcf7 2022-09-13 op char pname[32];
279 b0a6bcf7 2022-09-13 op char server[HOST_NAME_MAX + 1];
280 b0a6bcf7 2022-09-13 op char path[PATH_MAX];
281 b0a6bcf7 2022-09-13 op int nlen, vlen;
282 b0a6bcf7 2022-09-13 op
283 b0a6bcf7 2022-09-13 op while (fcgi->fcg_toread > 0) {
284 b0a6bcf7 2022-09-13 op if ((nlen = parse_len(fcgi, src)) < 0 ||
285 b0a6bcf7 2022-09-13 op (vlen = parse_len(fcgi, src)) < 0)
286 b0a6bcf7 2022-09-13 op return (-1);
287 b0a6bcf7 2022-09-13 op
288 b0a6bcf7 2022-09-13 op if (fcgi->fcg_toread < nlen + vlen)
289 b0a6bcf7 2022-09-13 op return (-1);
290 b0a6bcf7 2022-09-13 op
291 b0a6bcf7 2022-09-13 op if ((size_t)nlen > sizeof(pname) - 1) {
292 b0a6bcf7 2022-09-13 op /* ignore this parameter */
293 b0a6bcf7 2022-09-13 op fcgi->fcg_toread -= nlen - vlen;
294 b0a6bcf7 2022-09-13 op evbuffer_drain(src, nlen + vlen);
295 b0a6bcf7 2022-09-13 op continue;
296 b0a6bcf7 2022-09-13 op }
297 b0a6bcf7 2022-09-13 op
298 b0a6bcf7 2022-09-13 op fcgi->fcg_toread -= nlen;
299 b0a6bcf7 2022-09-13 op evbuffer_remove(src, &pname, nlen);
300 b0a6bcf7 2022-09-13 op pname[nlen] = '\0';
301 b0a6bcf7 2022-09-13 op
302 b0a6bcf7 2022-09-13 op if (!strcmp(pname, "SERVER_NAME") &&
303 b0a6bcf7 2022-09-13 op (size_t)vlen < sizeof(server)) {
304 b0a6bcf7 2022-09-13 op fcgi->fcg_toread -= vlen;
305 b0a6bcf7 2022-09-13 op evbuffer_remove(src, &server, vlen);
306 b0a6bcf7 2022-09-13 op server[vlen] = '\0';
307 b0a6bcf7 2022-09-13 op
308 b0a6bcf7 2022-09-13 op if ((clt->clt_server_name = strdup(server)) == NULL)
309 b0a6bcf7 2022-09-13 op return (-1);
310 b0a6bcf7 2022-09-13 op log_debug("clt %d: server_name: %s", clt->clt_id,
311 b0a6bcf7 2022-09-13 op clt->clt_server_name);
312 b0a6bcf7 2022-09-13 op continue;
313 b0a6bcf7 2022-09-13 op }
314 b0a6bcf7 2022-09-13 op
315 b0a6bcf7 2022-09-13 op if (!strcmp(pname, "SCRIPT_NAME") &&
316 b0a6bcf7 2022-09-13 op (size_t)vlen < sizeof(path)) {
317 b0a6bcf7 2022-09-13 op fcgi->fcg_toread -= vlen;
318 b0a6bcf7 2022-09-13 op evbuffer_remove(src, &path, vlen);
319 b0a6bcf7 2022-09-13 op path[vlen] = '\0';
320 b0a6bcf7 2022-09-13 op
321 b0a6bcf7 2022-09-13 op if ((clt->clt_script_name = strdup(path)) == NULL)
322 b0a6bcf7 2022-09-13 op return (-1);
323 b0a6bcf7 2022-09-13 op log_debug("clt %d: script_name: %s", clt->clt_id,
324 b0a6bcf7 2022-09-13 op clt->clt_script_name);
325 b0a6bcf7 2022-09-13 op continue;
326 b0a6bcf7 2022-09-13 op }
327 b0a6bcf7 2022-09-13 op
328 b0a6bcf7 2022-09-13 op if (!strcmp(pname, "PATH_INFO") &&
329 b0a6bcf7 2022-09-13 op (size_t)vlen < sizeof(path)) {
330 b0a6bcf7 2022-09-13 op fcgi->fcg_toread -= vlen;
331 b0a6bcf7 2022-09-13 op evbuffer_remove(src, &path, vlen);
332 b0a6bcf7 2022-09-13 op path[vlen] = '\0';
333 b0a6bcf7 2022-09-13 op
334 b0a6bcf7 2022-09-13 op if ((clt->clt_path_info = strdup(path)) == NULL)
335 b0a6bcf7 2022-09-13 op return (-1);
336 b0a6bcf7 2022-09-13 op log_debug("clt %d: path_info: %s", clt->clt_id,
337 b0a6bcf7 2022-09-13 op clt->clt_path_info);
338 b0a6bcf7 2022-09-13 op continue;
339 b0a6bcf7 2022-09-13 op }
340 b0a6bcf7 2022-09-13 op
341 b0a6bcf7 2022-09-13 op fcgi->fcg_toread -= vlen;
342 b0a6bcf7 2022-09-13 op evbuffer_drain(src, vlen);
343 b0a6bcf7 2022-09-13 op }
344 b0a6bcf7 2022-09-13 op
345 b0a6bcf7 2022-09-13 op return (0);
346 b0a6bcf7 2022-09-13 op }
347 b0a6bcf7 2022-09-13 op
348 b0a6bcf7 2022-09-13 op void
349 b0a6bcf7 2022-09-13 op fcgi_read(struct bufferevent *bev, void *d)
350 b0a6bcf7 2022-09-13 op {
351 b0a6bcf7 2022-09-13 op struct fcgi *fcgi = d;
352 b0a6bcf7 2022-09-13 op struct galileo *env = fcgi->fcg_env;
353 b0a6bcf7 2022-09-13 op struct evbuffer *src = EVBUFFER_INPUT(bev);
354 b0a6bcf7 2022-09-13 op struct fcgi_header hdr;
355 b0a6bcf7 2022-09-13 op struct fcgi_begin_req breq;
356 b0a6bcf7 2022-09-13 op struct client *clt, q;
357 b0a6bcf7 2022-09-13 op int role;
358 b0a6bcf7 2022-09-13 op
359 b0a6bcf7 2022-09-13 op memset(&q, 0, sizeof(q));
360 b0a6bcf7 2022-09-13 op
361 b0a6bcf7 2022-09-13 op for (;;) {
362 b0a6bcf7 2022-09-13 op if (EVBUFFER_LENGTH(src) < (size_t)fcgi->fcg_toread)
363 b0a6bcf7 2022-09-13 op return;
364 b0a6bcf7 2022-09-13 op
365 b0a6bcf7 2022-09-13 op if (fcgi->fcg_want == FCGI_RECORD_HEADER) {
366 b0a6bcf7 2022-09-13 op fcgi->fcg_want = FCGI_RECORD_BODY;
367 b0a6bcf7 2022-09-13 op bufferevent_read(bev, &hdr, sizeof(hdr));
368 b0a6bcf7 2022-09-13 op
369 b0a6bcf7 2022-09-13 op #ifdef DEBUG
370 b0a6bcf7 2022-09-13 op log_warnx("header: v=%d t=%d id=%d len=%d p=%d",
371 b0a6bcf7 2022-09-13 op hdr.version, hdr.type,
372 b0a6bcf7 2022-09-13 op CAT(hdr.req_id0, hdr.req_id1),
373 b0a6bcf7 2022-09-13 op CAT(hdr.content_len0, hdr.content_len1),
374 b0a6bcf7 2022-09-13 op hdr.padding);
375 b0a6bcf7 2022-09-13 op #endif
376 b0a6bcf7 2022-09-13 op
377 b0a6bcf7 2022-09-13 op if (hdr.version != FCGI_VERSION_1) {
378 b0a6bcf7 2022-09-13 op log_warnx("unknown fastcgi version: %d",
379 b0a6bcf7 2022-09-13 op hdr.version);
380 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_READ, d);
381 b0a6bcf7 2022-09-13 op return;
382 b0a6bcf7 2022-09-13 op }
383 b0a6bcf7 2022-09-13 op
384 b0a6bcf7 2022-09-13 op fcgi->fcg_toread = CAT(hdr.content_len0,
385 b0a6bcf7 2022-09-13 op hdr.content_len1);
386 b0a6bcf7 2022-09-13 op if (fcgi->fcg_toread < 0) {
387 b0a6bcf7 2022-09-13 op log_warnx("invalid record length: %d",
388 b0a6bcf7 2022-09-13 op fcgi->fcg_toread);
389 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_READ, d);
390 b0a6bcf7 2022-09-13 op return;
391 b0a6bcf7 2022-09-13 op }
392 b0a6bcf7 2022-09-13 op
393 b0a6bcf7 2022-09-13 op fcgi->fcg_padding = hdr.padding;
394 b0a6bcf7 2022-09-13 op if (fcgi->fcg_padding < 0) {
395 b0a6bcf7 2022-09-13 op log_warnx("invalid padding: %d",
396 b0a6bcf7 2022-09-13 op fcgi->fcg_padding);
397 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_READ, d);
398 b0a6bcf7 2022-09-13 op return;
399 b0a6bcf7 2022-09-13 op }
400 b0a6bcf7 2022-09-13 op
401 b0a6bcf7 2022-09-13 op fcgi->fcg_type = hdr.type;
402 b0a6bcf7 2022-09-13 op fcgi->fcg_rec_id = CAT(hdr.req_id0, hdr.req_id1);
403 b0a6bcf7 2022-09-13 op continue;
404 b0a6bcf7 2022-09-13 op }
405 b0a6bcf7 2022-09-13 op
406 b0a6bcf7 2022-09-13 op q.clt_id = fcgi->fcg_rec_id;
407 b0a6bcf7 2022-09-13 op clt = SPLAY_FIND(client_tree, &fcgi->fcg_clients, &q);
408 b0a6bcf7 2022-09-13 op
409 b0a6bcf7 2022-09-13 op switch (fcgi->fcg_type) {
410 b0a6bcf7 2022-09-13 op case FCGI_BEGIN_REQUEST:
411 b0a6bcf7 2022-09-13 op if (sizeof(breq) != fcgi->fcg_toread) {
412 b0a6bcf7 2022-09-13 op log_warnx("unexpected size for "
413 b0a6bcf7 2022-09-13 op "FCGI_BEGIN_REQUEST");
414 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_READ, d);
415 b0a6bcf7 2022-09-13 op return;
416 b0a6bcf7 2022-09-13 op }
417 b0a6bcf7 2022-09-13 op
418 b0a6bcf7 2022-09-13 op evbuffer_remove(src, &breq, sizeof(breq));
419 b0a6bcf7 2022-09-13 op
420 b0a6bcf7 2022-09-13 op role = CAT(breq.role0, breq.role1);
421 b0a6bcf7 2022-09-13 op if (role != FCGI_RESPONDER) {
422 b0a6bcf7 2022-09-13 op log_warnx("unknown fastcgi role: %d",
423 b0a6bcf7 2022-09-13 op role);
424 b0a6bcf7 2022-09-13 op if (fcgi_send_end_req(fcgi, fcgi->fcg_rec_id,
425 b0a6bcf7 2022-09-13 op 1, FCGI_UNKNOWN_ROLE) == -1) {
426 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_READ, d);
427 b0a6bcf7 2022-09-13 op return;
428 b0a6bcf7 2022-09-13 op }
429 b0a6bcf7 2022-09-13 op break;
430 b0a6bcf7 2022-09-13 op }
431 b0a6bcf7 2022-09-13 op
432 b0a6bcf7 2022-09-13 op if (!fcgi->fcg_keep_conn) {
433 b0a6bcf7 2022-09-13 op log_warnx("trying to reuse the fastcgi "
434 b0a6bcf7 2022-09-13 op "socket without marking it as so.");
435 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_READ, d);
436 b0a6bcf7 2022-09-13 op return;
437 b0a6bcf7 2022-09-13 op }
438 b0a6bcf7 2022-09-13 op fcgi->fcg_keep_conn = breq.flags & FCGI_KEEP_CONN;
439 b0a6bcf7 2022-09-13 op
440 b0a6bcf7 2022-09-13 op if (clt != NULL) {
441 b0a6bcf7 2022-09-13 op log_warnx("ignoring attemp to re-use an "
442 b0a6bcf7 2022-09-13 op "active request id (%d)",
443 b0a6bcf7 2022-09-13 op fcgi->fcg_rec_id);
444 b0a6bcf7 2022-09-13 op break;
445 b0a6bcf7 2022-09-13 op }
446 b0a6bcf7 2022-09-13 op
447 b0a6bcf7 2022-09-13 op if ((clt = calloc(1, sizeof(*clt))) == NULL) {
448 b0a6bcf7 2022-09-13 op log_warnx("calloc");
449 b0a6bcf7 2022-09-13 op break;
450 b0a6bcf7 2022-09-13 op }
451 b0a6bcf7 2022-09-13 op
452 b0a6bcf7 2022-09-13 op clt->clt_id = fcgi->fcg_rec_id;
453 b0a6bcf7 2022-09-13 op clt->clt_fd = -1;
454 b0a6bcf7 2022-09-13 op clt->clt_fcgi = fcgi;
455 b0a6bcf7 2022-09-13 op SPLAY_INSERT(client_tree, &fcgi->fcg_clients, clt);
456 b0a6bcf7 2022-09-13 op break;
457 b0a6bcf7 2022-09-13 op case FCGI_PARAMS:
458 b0a6bcf7 2022-09-13 op if (clt == NULL) {
459 b0a6bcf7 2022-09-13 op log_warnx("got FCGI_PARAMS for inactive id "
460 b0a6bcf7 2022-09-13 op "(%d)", fcgi->fcg_rec_id);
461 b0a6bcf7 2022-09-13 op evbuffer_drain(src, fcgi->fcg_toread);
462 b0a6bcf7 2022-09-13 op break;
463 b0a6bcf7 2022-09-13 op }
464 b0a6bcf7 2022-09-13 op if (fcgi->fcg_toread == 0) {
465 b0a6bcf7 2022-09-13 op evbuffer_drain(src, fcgi->fcg_toread);
466 b0a6bcf7 2022-09-13 op proxy_start_request(env, clt);
467 b0a6bcf7 2022-09-13 op break;
468 b0a6bcf7 2022-09-13 op }
469 b0a6bcf7 2022-09-13 op if (fcgi_parse_params(fcgi, src, clt) == -1) {
470 b0a6bcf7 2022-09-13 op log_warnx("fcgi_parse_params failed");
471 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_READ, d);
472 b0a6bcf7 2022-09-13 op return;
473 b0a6bcf7 2022-09-13 op }
474 b0a6bcf7 2022-09-13 op break;
475 b0a6bcf7 2022-09-13 op case FCGI_STDIN:
476 b0a6bcf7 2022-09-13 op /* ignore */
477 b0a6bcf7 2022-09-13 op evbuffer_drain(src, fcgi->fcg_toread);
478 b0a6bcf7 2022-09-13 op break;
479 b0a6bcf7 2022-09-13 op case FCGI_ABORT_REQUEST:
480 b0a6bcf7 2022-09-13 op if (clt == NULL) {
481 b0a6bcf7 2022-09-13 op log_warnx("got FCGI_ABORT_REQUEST for inactive"
482 b0a6bcf7 2022-09-13 op " id (%d)", fcgi->fcg_rec_id);
483 b0a6bcf7 2022-09-13 op evbuffer_drain(src, fcgi->fcg_toread);
484 b0a6bcf7 2022-09-13 op break;
485 b0a6bcf7 2022-09-13 op }
486 b0a6bcf7 2022-09-13 op if (fcgi_end_request(clt, 1) == -1) {
487 b0a6bcf7 2022-09-13 op /* calls fcgi_error on failure */
488 b0a6bcf7 2022-09-13 op return;
489 b0a6bcf7 2022-09-13 op }
490 b0a6bcf7 2022-09-13 op break;
491 b0a6bcf7 2022-09-13 op default:
492 b0a6bcf7 2022-09-13 op log_warnx("unknown fastcgi record type %d",
493 b0a6bcf7 2022-09-13 op fcgi->fcg_type);
494 b0a6bcf7 2022-09-13 op evbuffer_drain(src, fcgi->fcg_toread);
495 b0a6bcf7 2022-09-13 op break;
496 b0a6bcf7 2022-09-13 op }
497 b0a6bcf7 2022-09-13 op
498 b0a6bcf7 2022-09-13 op /* Prepare for the next record. */
499 b0a6bcf7 2022-09-13 op evbuffer_drain(src, fcgi->fcg_padding);
500 b0a6bcf7 2022-09-13 op fcgi->fcg_want = FCGI_RECORD_HEADER;
501 b0a6bcf7 2022-09-13 op fcgi->fcg_toread = sizeof(struct fcgi_header);
502 b0a6bcf7 2022-09-13 op }
503 b0a6bcf7 2022-09-13 op }
504 b0a6bcf7 2022-09-13 op
505 b0a6bcf7 2022-09-13 op void
506 b0a6bcf7 2022-09-13 op fcgi_write(struct bufferevent *bev, void *d)
507 b0a6bcf7 2022-09-13 op {
508 b0a6bcf7 2022-09-13 op struct fcgi *fcgi = d;
509 b0a6bcf7 2022-09-13 op
510 b0a6bcf7 2022-09-13 op (void)fcgi;
511 b0a6bcf7 2022-09-13 op }
512 b0a6bcf7 2022-09-13 op
513 b0a6bcf7 2022-09-13 op void
514 b0a6bcf7 2022-09-13 op fcgi_error(struct bufferevent *bev, short event, void *d)
515 b0a6bcf7 2022-09-13 op {
516 b0a6bcf7 2022-09-13 op struct fcgi *fcgi = d;
517 b0a6bcf7 2022-09-13 op struct galileo *env = fcgi->fcg_env;
518 b0a6bcf7 2022-09-13 op struct client *clt;
519 b0a6bcf7 2022-09-13 op
520 b0a6bcf7 2022-09-13 op log_debug("fcgi failure, shutting down connection (ev: %x)",
521 b0a6bcf7 2022-09-13 op event);
522 b0a6bcf7 2022-09-13 op fcgi_inflight_dec(__func__);
523 b0a6bcf7 2022-09-13 op
524 b0a6bcf7 2022-09-13 op while ((clt = SPLAY_MIN(client_tree, &fcgi->fcg_clients)) != NULL) {
525 b0a6bcf7 2022-09-13 op SPLAY_REMOVE(client_tree, &fcgi->fcg_clients, clt);
526 b0a6bcf7 2022-09-13 op proxy_client_free(clt);
527 b0a6bcf7 2022-09-13 op }
528 b0a6bcf7 2022-09-13 op
529 b0a6bcf7 2022-09-13 op close(fcgi->fcg_s);
530 b0a6bcf7 2022-09-13 op bufferevent_free(fcgi->fcg_bev);
531 b0a6bcf7 2022-09-13 op SPLAY_REMOVE(fcgi_tree, &env->sc_fcgi_socks, fcgi);
532 b0a6bcf7 2022-09-13 op free(fcgi);
533 b0a6bcf7 2022-09-13 op
534 b0a6bcf7 2022-09-13 op return;
535 b0a6bcf7 2022-09-13 op }
536 b0a6bcf7 2022-09-13 op
537 b0a6bcf7 2022-09-13 op int
538 b0a6bcf7 2022-09-13 op clt_flush(struct client *clt)
539 b0a6bcf7 2022-09-13 op {
540 b0a6bcf7 2022-09-13 op struct fcgi *fcgi = clt->clt_fcgi;
541 b0a6bcf7 2022-09-13 op struct bufferevent *bev = fcgi->fcg_bev;
542 b0a6bcf7 2022-09-13 op struct fcgi_header hdr;
543 b0a6bcf7 2022-09-13 op
544 b0a6bcf7 2022-09-13 op if (clt->clt_buflen == 0)
545 b0a6bcf7 2022-09-13 op return (0);
546 b0a6bcf7 2022-09-13 op
547 b0a6bcf7 2022-09-13 op memset(&hdr, 0, sizeof(hdr));
548 b0a6bcf7 2022-09-13 op hdr.version = FCGI_VERSION_1;
549 b0a6bcf7 2022-09-13 op hdr.type = FCGI_STDOUT;
550 b0a6bcf7 2022-09-13 op hdr.req_id0 = (clt->clt_id & 0xFF);
551 b0a6bcf7 2022-09-13 op hdr.req_id1 = (clt->clt_id >> 8);
552 b0a6bcf7 2022-09-13 op hdr.content_len0 = (clt->clt_buflen & 0xFF);
553 b0a6bcf7 2022-09-13 op hdr.content_len1 = (clt->clt_buflen >> 8);
554 b0a6bcf7 2022-09-13 op
555 b0a6bcf7 2022-09-13 op if (bufferevent_write(bev, &hdr, sizeof(hdr)) == -1 ||
556 b0a6bcf7 2022-09-13 op bufferevent_write(bev, clt->clt_buf, clt->clt_buflen) == -1) {
557 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_WRITE, fcgi);
558 b0a6bcf7 2022-09-13 op return (-1);
559 b0a6bcf7 2022-09-13 op }
560 b0a6bcf7 2022-09-13 op
561 b0a6bcf7 2022-09-13 op clt->clt_buflen = 0;
562 b0a6bcf7 2022-09-13 op
563 b0a6bcf7 2022-09-13 op return (0);
564 b0a6bcf7 2022-09-13 op }
565 b0a6bcf7 2022-09-13 op
566 b0a6bcf7 2022-09-13 op int
567 b0a6bcf7 2022-09-13 op clt_write(struct client *clt, const uint8_t *buf, size_t len)
568 b0a6bcf7 2022-09-13 op {
569 b0a6bcf7 2022-09-13 op size_t left, copy;
570 b0a6bcf7 2022-09-13 op
571 b0a6bcf7 2022-09-13 op while (len > 0) {
572 b0a6bcf7 2022-09-13 op left = sizeof(clt->clt_buf) - clt->clt_buflen;
573 b0a6bcf7 2022-09-13 op if (left == 0) {
574 b0a6bcf7 2022-09-13 op if (clt_flush(clt) == -1)
575 b0a6bcf7 2022-09-13 op return (-1);
576 b0a6bcf7 2022-09-13 op left = sizeof(clt->clt_buf);
577 b0a6bcf7 2022-09-13 op }
578 b0a6bcf7 2022-09-13 op
579 b0a6bcf7 2022-09-13 op copy = MIN(left, len);
580 b0a6bcf7 2022-09-13 op
581 b0a6bcf7 2022-09-13 op memcpy(&clt->clt_buf[clt->clt_buflen], buf, copy);
582 b0a6bcf7 2022-09-13 op clt->clt_buflen += copy;
583 b0a6bcf7 2022-09-13 op buf += copy;
584 b0a6bcf7 2022-09-13 op len -= copy;
585 b0a6bcf7 2022-09-13 op }
586 b0a6bcf7 2022-09-13 op
587 b0a6bcf7 2022-09-13 op return (0);
588 b0a6bcf7 2022-09-13 op }
589 b0a6bcf7 2022-09-13 op
590 b0a6bcf7 2022-09-13 op int
591 b0a6bcf7 2022-09-13 op clt_write_bufferevent(struct client *clt, struct bufferevent *bev)
592 b0a6bcf7 2022-09-13 op {
593 b0a6bcf7 2022-09-13 op struct evbuffer *src = EVBUFFER_INPUT(bev);
594 b0a6bcf7 2022-09-13 op size_t len, left, copy;
595 b0a6bcf7 2022-09-13 op
596 b0a6bcf7 2022-09-13 op len = EVBUFFER_LENGTH(src);
597 b0a6bcf7 2022-09-13 op while (len > 0) {
598 b0a6bcf7 2022-09-13 op left = sizeof(clt->clt_buf) - clt->clt_buflen;
599 b0a6bcf7 2022-09-13 op if (left == 0) {
600 b0a6bcf7 2022-09-13 op if (clt_flush(clt) == -1)
601 b0a6bcf7 2022-09-13 op return (-1);
602 b0a6bcf7 2022-09-13 op left = sizeof(clt->clt_buf);
603 b0a6bcf7 2022-09-13 op }
604 b0a6bcf7 2022-09-13 op
605 b0a6bcf7 2022-09-13 op copy = bufferevent_read(bev, &clt->clt_buf[clt->clt_buflen],
606 b0a6bcf7 2022-09-13 op MIN(left, len));
607 b0a6bcf7 2022-09-13 op clt->clt_buflen += copy;
608 b0a6bcf7 2022-09-13 op
609 b0a6bcf7 2022-09-13 op len = EVBUFFER_LENGTH(src);
610 b0a6bcf7 2022-09-13 op }
611 b0a6bcf7 2022-09-13 op
612 b0a6bcf7 2022-09-13 op return (0);
613 b0a6bcf7 2022-09-13 op }
614 b0a6bcf7 2022-09-13 op
615 b0a6bcf7 2022-09-13 op int
616 b0a6bcf7 2022-09-13 op clt_printf(struct client *clt, const char *fmt, ...)
617 b0a6bcf7 2022-09-13 op {
618 b0a6bcf7 2022-09-13 op struct fcgi *fcgi = clt->clt_fcgi;
619 b0a6bcf7 2022-09-13 op struct bufferevent *bev = fcgi->fcg_bev;
620 b0a6bcf7 2022-09-13 op char *str;
621 b0a6bcf7 2022-09-13 op va_list ap;
622 b0a6bcf7 2022-09-13 op int r;
623 b0a6bcf7 2022-09-13 op
624 b0a6bcf7 2022-09-13 op va_start(ap, fmt);
625 b0a6bcf7 2022-09-13 op r = vasprintf(&str, fmt, ap);
626 b0a6bcf7 2022-09-13 op va_end(ap);
627 b0a6bcf7 2022-09-13 op if (r == -1) {
628 b0a6bcf7 2022-09-13 op fcgi_error(bev, EV_WRITE, fcgi);
629 b0a6bcf7 2022-09-13 op return (-1);
630 b0a6bcf7 2022-09-13 op }
631 b0a6bcf7 2022-09-13 op
632 b0a6bcf7 2022-09-13 op r = clt_write(clt, str, r);
633 b0a6bcf7 2022-09-13 op free(str);
634 b0a6bcf7 2022-09-13 op return (r);
635 b0a6bcf7 2022-09-13 op }
636 b0a6bcf7 2022-09-13 op
637 b0a6bcf7 2022-09-13 op int
638 b0a6bcf7 2022-09-13 op fcgi_cmp(struct fcgi *a, struct fcgi *b)
639 b0a6bcf7 2022-09-13 op {
640 b0a6bcf7 2022-09-13 op return ((int)a->fcg_id - b->fcg_id);
641 b0a6bcf7 2022-09-13 op }
642 b0a6bcf7 2022-09-13 op
643 b0a6bcf7 2022-09-13 op int
644 b0a6bcf7 2022-09-13 op fcgi_client_cmp(struct client *a, struct client *b)
645 b0a6bcf7 2022-09-13 op {
646 b0a6bcf7 2022-09-13 op return ((int)a->clt_id - b->clt_id);
647 b0a6bcf7 2022-09-13 op }
648 b0a6bcf7 2022-09-13 op
649 b0a6bcf7 2022-09-13 op SPLAY_GENERATE(fcgi_tree, fcgi, fcg_nodes, fcgi_cmp);
650 b0a6bcf7 2022-09-13 op SPLAY_GENERATE(client_tree, client, clt_nodes, fcgi_client_cmp);
651 b0a6bcf7 2022-09-13 op