1 /*	$Id$ */
2 /*
3  * Copyright (c) 2015--2016, 2018 Kristaps Dzonsons <kristaps@bsd.lv>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include "config.h"
18 
19 #include <sys/ioctl.h>
20 #include <sys/socket.h>
21 
22 #include <assert.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <inttypes.h>
26 #include <limits.h>
27 #include <poll.h>
28 #include <signal.h>
29 #include <stdarg.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #include <stdio.h> /* BUFSIZ */
33 #include <string.h>
34 #include <unistd.h>
35 
36 #include "kcgi.h"
37 #include "extern.h"
38 
39 struct	kfcgi {
40 	const struct kvalid	 *keys;
41 	size_t			  keysz;
42 	const char *const	 *mimes;
43 	size_t			  mimesz;
44 	size_t			  defmime;
45 	unsigned int		  debugging;
46 	const char *const	 *pages;
47 	size_t			  pagesz;
48 	size_t			  defpage;
49 	const struct kmimemap 	 *mimemap;
50 	pid_t			  work_pid;
51 	pid_t			  sock_pid;
52 	int			  work_dat;
53 	int			  sock_ctl;
54 	struct kopts		  opts;
55 	void			 *arg;
56 };
57 
58 static	volatile sig_atomic_t sig = 0;
59 
60 static void
dosignal(int arg)61 dosignal(int arg)
62 {
63 
64 	sig = 1;
65 }
66 
67 /*
68  * This is our control process.
69  * It listens for FastCGI connections on the manager connection in
70  * traditional mode ("fdaccept") xor extended mode ("fdfiled").
71  * When it has one, it reads and passes to the worker (sibling) process,
72  * which will be parsing the data.
73  * When the worker has finished, it passes back the request identifier,
74  * which this passes to the main application for output.
75  * If the current FastCGI connection closes, abandon it and wait for the
76  * next.
77  * This exits with the manager connection closes.
78  * On exit, it will close the fdaccept or fdfiled descriptor.
79  */
80 static int
kfcgi_control(int work,int ctrl,int fdaccept,int fdfiled,pid_t worker)81 kfcgi_control(int work, int ctrl,
82 	int fdaccept, int fdfiled, pid_t worker)
83 {
84 	struct sockaddr_storage ss;
85 	socklen_t	 sslen;
86 	int		 fd = -1, rc, ourfd, erc = EXIT_FAILURE;
87 	uint64_t	 magic;
88 	uint32_t	 cookie, test;
89 	struct pollfd	 pfd[2];
90 	char		 buf[BUFSIZ];
91 	ssize_t		 ssz;
92 	enum kcgi_err	 kerr;
93 	uint16_t	 rid, rtest;
94 
95 	ourfd = fdaccept == -1 ? fdfiled : fdaccept;
96 	assert(ourfd != -1);
97 
98 	if (kxsocketprep(ourfd) != KCGI_OK)
99 		goto out;
100 
101 	for (;;) {
102 		pfd[0].fd = ourfd;
103 		pfd[0].events = POLLIN;
104 		pfd[0].revents = 0;
105 		pfd[1].fd = ctrl;
106 		pfd[1].events = POLLIN;
107 		pfd[1].revents = 0;
108 
109 		/*
110 		 * If either the worker or manager disconnect, then exit
111 		 * cleanly.
112 		 * The calling application will check the worker's exit
113 		 * code, which will say whether it did something bad, so
114 		 * we don't really care.
115 		 */
116 
117 		if ((rc = poll(pfd, 2, INFTIM)) < 0) {
118 			kutil_warn(NULL, NULL, "poll");
119 			goto out;
120 		} else if (rc == 0) {
121 			kutil_warnx(NULL, NULL, "poll: timeout!?");
122 			continue;
123 		}
124 
125 		if ((pfd[1].revents & POLLHUP) ||
126 		    !(pfd[0].revents & POLLIN))
127 			break;
128 
129 		/*
130 		 * Accept a new connection.
131 		 * In the old way, a blocking accept from FastCGI
132 		 * socket.
133 		 * This will be round-robined by the kernel so that
134 		 * other control processes are fairly notified.
135 		 * In the new one, accepting a descriptor from the
136 		 * caller.
137 		 */
138 
139 		if (fdaccept != -1) {
140 			assert(fdfiled == -1);
141 			sslen = sizeof(ss);
142 			fd = accept(fdaccept,
143 				(struct sockaddr *)&ss, &sslen);
144 			if (fd < 0) {
145 				if (errno == EAGAIN ||
146 				    errno == EWOULDBLOCK)
147 					continue;
148 				kutil_warn(NULL, NULL, "accept");
149 				goto out;
150 			}
151 		} else {
152 			assert(fdfiled != -1);
153 			rc = fullreadfd(fdfiled,
154 				&fd, &magic, sizeof(uint64_t));
155 			if (rc < 0)
156 				goto out;
157 			else if (rc == 0)
158 				break;
159 		}
160 
161 		/*
162 		 * We then set that the FastCGI socket is non-blocking,
163 		 * making it consistent with the behaviour of the CGI
164 		 * socket, which is also set as such.
165 		 */
166 
167 		if (kxsocketprep(fd) != KCGI_OK)
168 			goto out;
169 
170 		/* This doesn't need to be crypto quality. */
171 
172 #if HAVE_ARC4RANDOM
173 		cookie = arc4random();
174 #else
175 		cookie = random();
176 #endif
177 
178 		/* Write a header cookie to the work. */
179 
180 		fullwrite(work, &cookie, sizeof(uint32_t));
181 
182 		/*
183 		 * Keep pushing data into the worker til it has read it
184 		 * all, at which point it will write to us.
185 		 * If at any point we have errors (e.g., the connection
186 		 * closes), then write a zero-length frame.
187 		 * Write a zero-length frame at the end anyway.
188 		 */
189 
190 		pfd[0].fd = fd;
191 		pfd[0].events = POLLIN;
192 		pfd[1].fd = work;
193 		pfd[1].events = POLLIN;
194 
195 		for (;;) {
196 			if ((rc = poll(pfd, 2, INFTIM)) < 0) {
197 				kutil_warn(NULL, NULL, "poll");
198 				goto out;
199 			} else if (rc == 0) {
200 				kutil_warnx(NULL, NULL, "poll: timeout!?");
201 				continue;
202 			}
203 
204 			/*
205 			 * If the child responds, that means that the
206 			 * full request has been read and processed.
207 			 * If not, we probably still have data to write
208 			 * to it from the connection.
209 			 */
210 
211 			if (pfd[1].revents & POLLIN) {
212 				ssz = 0;
213 				kerr = fullwritenoerr
214 					(pfd[1].fd, &ssz, sizeof(size_t));
215 				if (kerr != KCGI_OK)
216 					goto out;
217 				break;
218 			}
219 
220 			if (!(pfd[0].revents & POLLIN)) {
221 				kutil_warnx(NULL, NULL, "poll: no input");
222 				goto out;
223 			} else if ((ssz = read(fd, buf, BUFSIZ)) < 0) {
224 				kutil_warn(NULL, NULL, "read");
225 				goto out;
226 			}
227 
228 			/*
229 			 * Send the child the amount of data we've read.
230 			 * This will let the child see if the connection
231 			 * abruptly closes, at which point we'll have a
232 			 * read size of zero, and error out.
233 			 */
234 
235 			kerr = fullwritenoerr
236 				(pfd[1].fd, &ssz, sizeof(size_t));
237 			if (KCGI_OK != kerr)
238 				goto out;
239 
240 			kerr = fullwritenoerr(pfd[1].fd, buf, ssz);
241 			if (KCGI_OK != kerr)
242 				goto out;
243 
244 			/*
245 			 * If we wrote a zero-sized buffer, it means
246 			 * that the connection has unexpectedly closed.
247 			 * The child will stop all processing for the
248 			 * request and will not return to the parsing
249 			 * routine for the given session.
250 			 */
251 
252 			if (ssz == 0) {
253 				kutil_warnx(NULL, NULL, "read: "
254 					"connection closed");
255 				break;
256 			}
257 		}
258 
259 		/* Now verify that the worker is sane. */
260 
261 		if (fullread(pfd[1].fd, &rc,
262 		    sizeof(int), 0, &kerr) < 0)
263 			goto out;
264 
265 		if (rc == 0) {
266 			kutil_warnx(NULL, NULL, "FastCGI: bad code");
267 			goto recover;
268 		}
269 
270 		/*
271 		 * We have a non-zero return code.
272 		 * Check our cookie and responseId values.
273 		 */
274 
275 		if (fullread(pfd[1].fd, &test,
276 		    sizeof(uint32_t), 0, &kerr) < 0)
277 			goto out;
278 
279 		if (cookie != test) {
280 			kutil_warnx(NULL, NULL, "FastCGI: bad cookie");
281 			goto out;
282 		}
283 
284 		if (fullread(pfd[1].fd, &rid,
285 		    sizeof(uint16_t), 0, &kerr) < 0)
286 			goto out;
287 
288 		/*
289 		 * Pass the file descriptor, which has had its data
290 		 * sucked dry, to the main application.
291 		 * It will do output, so it also needs the FastCGI
292 		 * socket request identifier.
293 		 */
294 
295 		if (!fullwritefd(ctrl, fd, &rid, sizeof(uint16_t)))
296 			goto out;
297 
298 		/*
299 		 * This will wait til the application is finished.
300 		 * It will then double-check the requestId.
301 		 */
302 
303 		if (fullread(ctrl, &rtest,
304 		    sizeof(uint16_t), 0, &kerr) < 0)
305 			goto out;
306 
307 		if (rid != rtest) {
308 			kutil_warnx(NULL, NULL, "FastCGI: bad cookie");
309 			goto out;
310 		}
311 
312 recover:
313 		/*
314 		 * If we are being passed descriptors (instead of
315 		 * waiting on the accept()), then notify the manager
316 		 * that we've finished processing this request.
317 		 * We also jump to here if the connection fails in any
318 		 * way whilst being transcribed to the worker.
319 		 */
320 
321 		if (fdfiled != -1) {
322 			kerr = fullwritenoerr(fdfiled,
323 				&magic, sizeof(uint64_t));
324 			if (KCGI_OK != kerr)
325 				goto out;
326 		}
327 
328 		close(fd);
329 		fd = -1;
330 	}
331 
332 	erc = EXIT_SUCCESS;
333 out:
334 	if (fd != -1)
335 		close(fd);
336 	close(ourfd);
337 	return erc;
338 }
339 
340 void
khttp_fcgi_child_free(struct kfcgi * fcgi)341 khttp_fcgi_child_free(struct kfcgi *fcgi)
342 {
343 
344 	close(fcgi->sock_ctl);
345 	close(fcgi->work_dat);
346 	free(fcgi);
347 }
348 
349 enum kcgi_err
khttp_fcgi_free(struct kfcgi * fcgi)350 khttp_fcgi_free(struct kfcgi *fcgi)
351 {
352 
353 	if (fcgi == NULL)
354 		return KCGI_OK;
355 
356 	close(fcgi->sock_ctl);
357 	close(fcgi->work_dat);
358 	kxwaitpid(fcgi->work_pid);
359 	kxwaitpid(fcgi->sock_pid);
360 	free(fcgi);
361 	return KCGI_OK;
362 }
363 
364 enum kcgi_err
khttp_fcgi_initx(struct kfcgi ** fcgip,const char * const * mimes,size_t mimesz,const struct kvalid * keys,size_t keysz,const struct kmimemap * mimemap,size_t defmime,const char * const * pages,size_t pagesz,size_t defpage,void * arg,void (* argfree)(void *),unsigned int debugging,const struct kopts * opts)365 khttp_fcgi_initx(struct kfcgi **fcgip,
366 	const char *const *mimes, size_t mimesz,
367 	const struct kvalid *keys, size_t keysz,
368 	const struct kmimemap *mimemap, size_t defmime,
369 	const char *const *pages, size_t pagesz,
370 	size_t defpage, void *arg, void (*argfree)(void *),
371 	unsigned int debugging, const struct kopts *opts)
372 {
373 	struct kfcgi	*fcgi;
374 	int 		 er, fdaccept, fdfiled;
375 	int		 work_ctl[2], work_dat[2], sock_ctl[2];
376 	pid_t		 work_pid, sock_pid;
377 	const char	*cp, *ercp;
378 	sigset_t	 mask;
379 	enum sandtype	 st;
380 
381 	/*
382 	 * Determine whether we're supposed to accept() on a socket or,
383 	 * rather, we're supposed to receive file descriptors from a
384 	 * kfcgi-like manager.
385 	 */
386 
387 	st = SAND_CONTROL_OLD;
388 	fdaccept = fdfiled = -1;
389 
390 	if ((cp = getenv("FCGI_LISTENSOCK_DESCRIPTORS")) != NULL) {
391 		fdfiled = strtonum(cp, 0, INT_MAX, &ercp);
392 		if (ercp != NULL) {
393 			fdaccept = STDIN_FILENO;
394 			fdfiled = -1;
395 		} else
396 			st = SAND_CONTROL_NEW;
397 	} else
398 		fdaccept = STDIN_FILENO;
399 
400 	/*
401 	 * Block this signal unless we're right at the fullreadfd
402 	 * function, at which point unblock and let it interrupt us.
403 	 * We don't save the signal mask because we're allowed free
404 	 * reign on the SIGTERM value.
405 	 */
406 
407 	if (signal(SIGTERM, dosignal) == SIG_ERR) {
408 		kutil_warn(NULL, NULL, "signal");
409 		return KCGI_SYSTEM;
410 	}
411 
412 	sigemptyset(&mask);
413 	sigaddset(&mask, SIGTERM);
414 	sigprocmask(SIG_BLOCK, &mask, NULL);
415 	sig = 0;
416 
417 	if (kxsocketpair(work_ctl) != KCGI_OK)
418 		return KCGI_SYSTEM;
419 
420 	if (kxsocketpair(work_dat) != KCGI_OK) {
421 		close(work_ctl[KWORKER_PARENT]);
422 		close(work_ctl[KWORKER_CHILD]);
423 		return KCGI_SYSTEM;
424 	}
425 
426 	if ((work_pid = fork()) == -1) {
427 		er = errno;
428 		kutil_warn(NULL, NULL, "fork");
429 		close(work_ctl[KWORKER_PARENT]);
430 		close(work_ctl[KWORKER_CHILD]);
431 		close(work_dat[KWORKER_PARENT]);
432 		close(work_dat[KWORKER_CHILD]);
433 		return (er == EAGAIN) ? KCGI_EAGAIN : KCGI_ENOMEM;
434 	} else if (work_pid == 0) {
435 		if (signal(SIGTERM, SIG_IGN) == SIG_ERR) {
436 			kutil_warn(NULL, NULL, "signal");
437 			_exit(EXIT_FAILURE);
438 		}
439 
440 		if (argfree != NULL)
441 			argfree(arg);
442 
443 		/*
444 		 * STDIN_FILENO isn't really stdin, it's the control
445 		 * socket used to pass input sockets to us.
446 		 * Thus, close the parent's control socket.
447 		 */
448 
449 		if (fdaccept != -1)
450 			close(fdaccept);
451 		if (fdfiled != -1)
452 			close(fdfiled);
453 
454 		close(STDOUT_FILENO);
455 		close(work_dat[KWORKER_PARENT]);
456 		close(work_ctl[KWORKER_PARENT]);
457 
458 		/*
459 		 * Prep child sandbox and run worker process.
460 		 * The worker code will exit on failure, so no need to
461 		 * check any return codes on it.
462 		 */
463 
464 		er = EXIT_SUCCESS;
465 		if (!ksandbox_init_child(SAND_WORKER,
466 		    work_dat[KWORKER_CHILD],
467 		    work_ctl[KWORKER_CHILD], -1, -1))
468 			er = EXIT_FAILURE;
469 		else
470 			kworker_fcgi_child
471 				(work_dat[KWORKER_CHILD],
472 				 work_ctl[KWORKER_CHILD],
473 				 keys, keysz, mimes, mimesz,
474 				 debugging);
475 
476 		close(work_dat[KWORKER_CHILD]);
477 		close(work_ctl[KWORKER_CHILD]);
478 		_exit(er);
479 		/* NOTREACHED */
480 	}
481 
482 	close(work_dat[KWORKER_CHILD]);
483 	close(work_ctl[KWORKER_CHILD]);
484 
485 	if (kxsocketpair(sock_ctl) != KCGI_OK) {
486 		close(work_dat[KWORKER_PARENT]);
487 		close(work_ctl[KWORKER_PARENT]);
488 		kxwaitpid(work_pid);
489 		return KCGI_SYSTEM;
490 	}
491 
492 	if ((sock_pid = fork()) == -1) {
493 		er = errno;
494 		kutil_warn(NULL, NULL, "fork");
495 		close(work_dat[KWORKER_PARENT]);
496 		close(work_ctl[KWORKER_PARENT]);
497 		close(sock_ctl[KWORKER_CHILD]);
498 		close(sock_ctl[KWORKER_PARENT]);
499 		kxwaitpid(work_pid);
500 		return (er == EAGAIN) ? KCGI_EAGAIN : KCGI_ENOMEM;
501 	} else if (sock_pid == 0) {
502 		if (signal(SIGTERM, SIG_IGN) == SIG_ERR) {
503 			kutil_warn(NULL, NULL, "signal");
504 			_exit(EXIT_FAILURE);
505 		}
506 
507 		if (argfree != NULL)
508 			argfree(arg);
509 
510 		close(STDOUT_FILENO);
511 		close(work_dat[KWORKER_PARENT]);
512 		close(sock_ctl[KWORKER_PARENT]);
513 
514 		if (!ksandbox_init_child(st,
515 		    sock_ctl[KWORKER_CHILD], -1, fdfiled, fdaccept))
516 			er = EXIT_FAILURE;
517 		else
518 			er = kfcgi_control
519 				(work_ctl[KWORKER_PARENT],
520 				 sock_ctl[KWORKER_CHILD],
521 				 fdaccept, fdfiled, work_pid);
522 
523 		close(work_ctl[KWORKER_PARENT]);
524 		close(sock_ctl[KWORKER_CHILD]);
525 		_exit(er);
526 		/* NOTREACHED */
527 	}
528 
529 	close(sock_ctl[KWORKER_CHILD]);
530 	close(work_ctl[KWORKER_PARENT]);
531 
532 	if (fdaccept != -1)
533 		close(fdaccept);
534 	if (fdfiled != -1)
535 		close(fdfiled);
536 
537 	/* Now allocate our device. */
538 
539 	*fcgip = fcgi = kxcalloc(1, sizeof(struct kfcgi));
540 	if (fcgi == NULL) {
541 		close(sock_ctl[KWORKER_PARENT]);
542 		close(work_dat[KWORKER_PARENT]);
543 		kxwaitpid(work_pid);
544 		kxwaitpid(sock_pid);
545 		return KCGI_ENOMEM;
546 	}
547 
548 	if (opts == NULL)
549 		fcgi->opts.sndbufsz = -1;
550 	else
551 		memcpy(&fcgi->opts, opts, sizeof(struct kopts));
552 
553 	if (fcgi->opts.sndbufsz < 0)
554 		fcgi->opts.sndbufsz = UINT16_MAX;
555 
556 	fcgi->work_pid = work_pid;
557 	fcgi->work_dat = work_dat[KWORKER_PARENT];
558 	fcgi->sock_pid = sock_pid;
559 	fcgi->sock_ctl = sock_ctl[KWORKER_PARENT];
560 	fcgi->arg = arg;
561 	fcgi->mimes = mimes;
562 	fcgi->mimesz = mimesz;
563 	fcgi->defmime = defmime;
564 	fcgi->keys = keys;
565 	fcgi->keysz = keysz;
566 	fcgi->mimemap = mimemap;
567 	fcgi->pages = pages;
568 	fcgi->pagesz = pagesz;
569 	fcgi->defpage = defpage;
570 	fcgi->debugging = debugging;
571 	return KCGI_OK;
572 }
573 
574 enum kcgi_err
khttp_fcgi_init(struct kfcgi ** fcgi,const struct kvalid * keys,size_t keysz,const char * const * pages,size_t pagesz,size_t defpage)575 khttp_fcgi_init(struct kfcgi **fcgi,
576 	const struct kvalid *keys, size_t keysz,
577 	const char *const *pages, size_t pagesz,
578 	size_t defpage)
579 {
580 
581 	return khttp_fcgi_initx(fcgi, kmimetypes,
582 		KMIME__MAX, keys, keysz, ksuffixmap,
583 		KMIME_TEXT_HTML, pages, pagesz, defpage,
584 		NULL, NULL, 0, NULL);
585 }
586 
587 /*
588  * Here we wait for the next FastCGI connection in such a way that, if
589  * we're notified that we must exit via a SIGTERM, we'll properly close
590  * down without spurious warnings.
591  */
592 static enum kcgi_err
fcgi_waitread(int fd)593 fcgi_waitread(int fd)
594 {
595 	int		 rc;
596 	struct pollfd	 pfd;
597 	sigset_t	 mask;
598 
599 again:
600 	pfd.fd = fd;
601 	pfd.events = POLLIN;
602 
603 	/*
604 	 * Unblock SIGTERM around the poll().
605 	 * XXX: this could be drastically simplified with ppoll(), but
606 	 * it's not available on many systems.
607 	 * TODO: provide a shim in wrappers.c.
608 	 */
609 
610 	sigemptyset(&mask);
611 	sigaddset(&mask, SIGTERM);
612 	sigprocmask(SIG_UNBLOCK, &mask, NULL);
613 	rc = poll(&pfd, 1, 1000);
614 	sigprocmask(SIG_BLOCK, &mask, NULL);
615 
616 	/* Exit signal has been set. */
617 
618 	if (sig)
619 		return KCGI_EXIT;
620 
621 	/* Problems?  Exit.  Timeout?  Retry. */
622 
623 	if (rc < 0) {
624 		kutil_warn(NULL, NULL, "poll");
625 		return KCGI_SYSTEM;
626 	} else if (rc == 0)
627 		goto again;
628 
629 	/* Only POLLIN is a "good" exit from this. */
630 
631 	if (pfd.revents & POLLIN)
632 		return KCGI_OK;
633 	else if (pfd.revents & POLLHUP)
634 		return KCGI_EXIT;
635 
636 	kutil_warnx(NULL, NULL, "poll: error");
637 	return KCGI_SYSTEM;
638 }
639 
640 enum kcgi_err
khttp_fcgi_parse(struct kfcgi * fcgi,struct kreq * req)641 khttp_fcgi_parse(struct kfcgi *fcgi, struct kreq *req)
642 {
643 	enum kcgi_err	 kerr;
644 	const struct kmimemap *mm;
645 	int		 c, fd = -1;
646 	uint16_t	 rid;
647 
648 	memset(req, 0, sizeof(struct kreq));
649 
650 	/*
651 	 * Blocking wait until our control process sends us the file
652 	 * descriptor and requestId of the current sequence.
653 	 * It may also decide to exit, which we note by seeing that
654 	 * "sig" has been set (inheriting the SIGTERM) or the channel
655 	 * closed gracefully.
656 	 */
657 
658 	if ((kerr = fcgi_waitread(fcgi->sock_ctl)) != KCGI_OK)
659 		return kerr;
660 
661 	c = fullreadfd(fcgi->sock_ctl, &fd, &rid, sizeof(uint16_t));
662 	if (c < 0)
663 		return KCGI_SYSTEM;
664 	else if (c == 0)
665 		return KCGI_EXIT;
666 
667 	/* Now get ready to receive data from the child. */
668 
669 	req->arg = fcgi->arg;
670 	req->keys = fcgi->keys;
671 	req->keysz = fcgi->keysz;
672 	req->kdata = kdata_alloc(fcgi->sock_ctl,
673 		fd, rid, fcgi->debugging, &fcgi->opts);
674 
675 	if (req->kdata == NULL) {
676 		close(fd);
677 		goto err;
678 	}
679 
680 	if (fcgi->keysz) {
681 		req->cookiemap = kxcalloc
682 			(fcgi->keysz, sizeof(struct kpair *));
683 		if (req->cookiemap == NULL)
684 			goto err;
685 		req->cookienmap = kxcalloc
686 			(fcgi->keysz, sizeof(struct kpair *));
687 		if (req->cookienmap == NULL)
688 			goto err;
689 		req->fieldmap = kxcalloc
690 			(fcgi->keysz, sizeof(struct kpair *));
691 		if (req->fieldmap == NULL)
692 			goto err;
693 		req->fieldnmap = kxcalloc
694 			(fcgi->keysz, sizeof(struct kpair *));
695 		if (req->fieldnmap == NULL)
696 			goto err;
697 	}
698 
699 	/*
700 	 * Read the request itself from the worker child.
701 	 * We'll wait perpetually on data until the channel closes or
702 	 * until we're interrupted during a read by the parent.
703 	 */
704 
705 	kerr = kworker_parent(fcgi->work_dat, req, 0, fcgi->mimesz);
706 	if (KCGI_OK != kerr)
707 		goto err;
708 
709 	/* Look up page type from component. */
710 
711 	req->page = fcgi->defpage;
712 	if (*req->pagename != '\0')
713 		for (req->page = 0; req->page < fcgi->pagesz; req->page++)
714 			if (strcasecmp(fcgi->pages[req->page], req->pagename) == 0)
715 				break;
716 
717 	/* Start with the default. */
718 
719 	req->mime = fcgi->defmime;
720 	if (*req->suffix != '\0') {
721 		for (mm = fcgi->mimemap; NULL != mm->name; mm++)
722 			if (strcasecmp(mm->name, req->suffix) == 0) {
723 				req->mime = mm->mime;
724 				break;
725 			}
726 		 /* Could not find this mime type! */
727 		if (mm->name == NULL)
728 			req->mime = fcgi->mimesz;
729 	}
730 
731 	return kerr;
732 err:
733 	kdata_free(req->kdata, 0);
734 	req->kdata = NULL;
735 	kreq_free(req);
736 	return kerr;
737 }
738 
739 int
khttp_fcgi_test(void)740 khttp_fcgi_test(void)
741 {
742 	socklen_t	 len = 0;
743 	const char	*cp, *ercp = NULL;
744 
745 	if ((cp = getenv("FCGI_LISTENSOCK_DESCRIPTORS")) != NULL) {
746 		strtonum(cp, 0, INT_MAX, &ercp);
747 		if (ercp == NULL)
748 			return 1;
749 	}
750 
751 	if (getpeername(STDIN_FILENO, NULL, &len) != -1)
752 		return 0;
753 	return errno == ENOTCONN;
754 }
755