1 /* $Id$ */
2 /*
3 * Copyright (c) 2015, 2016, 2020 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 <arpa/inet.h>
20
21 #include <assert.h>
22 #include <ctype.h>
23 #include <inttypes.h>
24 #include <stdarg.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <zlib.h>
31
32 #include "kcgi.h"
33 #include "extern.h"
34
35 /*
36 * The state of our HTTP response.
37 * We can be in KSTATE_HEAD, where we're printing HTTP headers; or
38 * KSTATE_BODY, where we're printing the body parts.
39 * So if we try to print a header when we're supposed to be in the body,
40 * this will be caught.
41 */
42 enum kstate {
43 KSTATE_HEAD = 0,
44 KSTATE_BODY
45 };
46
47 /*
48 * Interior data.
49 * This is used for managing HTTP compression.
50 */
51 struct kdata {
52 int debugging; /* debugging flags */
53 int fcgi; /* file descriptor or -1 */
54 int control; /* control socket or -1 */
55 char linebuf[80]; /* debugging output line buffer */
56 size_t linebufpos; /* position in line buffer */
57 uint64_t bytes; /* total bytes written */
58 uint16_t requestId; /* current requestId or 0 */
59 enum kstate state;
60 gzFile gz;
61 char *outbuf;
62 size_t outbufpos;
63 size_t outbufsz;
64 int disabled;
65 };
66
67 /*
68 * A writer is allocated for use by a front-end formatter.
69 * It is basically the bridge between the back-end writer (currently
70 * operated by kdata_write) and the front-ends like kcgijson.
71 */
72 struct kcgi_writer {
73 struct kdata *kdata; /* the back-end writer context */
74 int type; /* currently unused */
75 };
76
77 static char *
fcgi_header(uint8_t type,uint16_t requestId,uint16_t contentLength,uint8_t paddingLength)78 fcgi_header(uint8_t type, uint16_t requestId,
79 uint16_t contentLength, uint8_t paddingLength)
80 {
81 static uint8_t header[8];
82
83 /* Masking probably not necessary: truncation. */
84
85 header[0] = 1;
86 header[1] = type;
87 header[2] = (requestId >> 8) & 0xff;
88 header[3] = requestId & 0xff;
89 header[4] = (contentLength >> 8) & 0xff;
90 header[5] = contentLength & 0xff;
91 header[6] = paddingLength;
92 header[7] = 0;
93 return((char *)header);
94 }
95
96 /*
97 * Write a `stdout' FastCGI packet.
98 * This involves writing the header, then the data itself, then padding.
99 * Returns KCGI_OK, KCGI_SYSTEM, or KCGI_HUP.
100 */
101 static enum kcgi_err
fcgi_write(uint8_t type,const struct kdata * p,const char * buf,size_t sz)102 fcgi_write(uint8_t type, const struct kdata *p, const char *buf, size_t sz)
103 {
104 const char *pad = "\0\0\0\0\0\0\0\0";
105 char *head;
106 size_t rsz, padlen;
107 enum kcgi_err er = KCGI_OK;
108
109 /*
110 * Break up the data stream into FastCGI-capable chunks of at
111 * most UINT16_MAX bytes.
112 * Send each of these in its own FastCGI frame.
113 * Pad to 8-byte boundary.
114 */
115
116 do {
117 rsz = sz > UINT16_MAX ? UINT16_MAX : sz;
118 padlen = -rsz % 8;
119 head = fcgi_header(type, p->requestId, rsz, padlen);
120 if ((er = fullwritenoerr(p->fcgi, head, 8)) != KCGI_OK)
121 break;
122 if ((er = fullwritenoerr(p->fcgi, buf, rsz)) != KCGI_OK)
123 break;
124 if ((er = fullwritenoerr(p->fcgi, pad, padlen)) != KCGI_OK)
125 break;
126 sz -= rsz;
127 buf += rsz;
128 } while (sz > 0);
129
130 return er;
131 }
132
133 /*
134 * Flushes a buffer "buf" of size "sz" to the wire (stdout in the case
135 * of CGI, the socket for FastCGI, and a gz stream for compression IFF
136 * in body parts).
137 * If sz is zero or buf is NULL, this is a no-op.
138 * Return zero on failure (system error writing to output) or non-zero
139 * on success.
140 */
141 static enum kcgi_err
kdata_flush(struct kdata * p,const char * buf,size_t sz)142 kdata_flush(struct kdata *p, const char *buf, size_t sz)
143 {
144
145 if (sz == 0 || buf == NULL)
146 return KCGI_OK;
147
148 /*
149 * FIXME: make this work properly on all systems.
150 * This is known (?) to break on FreeBSD: we may need to break
151 * the uncompressed buffer into chunks that will not cause
152 * EAGAIN to be raised.
153 */
154
155 if (p->gz != NULL && p->state != KSTATE_HEAD) {
156 if (gzwrite(p->gz, buf, sz) == 0) {
157 kutil_warnx(NULL, NULL, "gzwrite");
158 return KCGI_SYSTEM;
159 }
160 return KCGI_OK;
161 }
162
163 return (p->fcgi == -1) ?
164 fullwritenoerr(STDOUT_FILENO, buf, sz) :
165 fcgi_write(6, p, buf, sz);
166 }
167
168 /*
169 * Drain the output buffer with kdata_flush().
170 * Returns KCGI_OK, KCGI_SYSTEM, or KCGI_HUP.
171 * XXX: if errors occur, outbufpos is zeroed as if we wrote the data.
172 */
173 static enum kcgi_err
kdata_drain(struct kdata * p)174 kdata_drain(struct kdata *p)
175 {
176 enum kcgi_err er;
177
178 er = kdata_flush(p, p->outbuf, p->outbufpos);
179 p->outbufpos = 0;
180 return er;
181 }
182
183 /*
184 * In this function, we handle arbitrary writes of data to the output.
185 * In the event of CGI, this will be to stdout; in the event of FastCGI,
186 * this is to the wire.
187 * We want to handle buffering of output, so we maintain an output
188 * buffer that we fill and drain as needed.
189 * This will end up calling kdata_flush(), directly or indirectly.
190 * This will also handle debugging.
191 * Returns KCGI_ENOMEM if any allocation failures occur during the
192 * sequence, KCGI_SYSTEM if any errors occur writing to the output
193 * channel, KCGI_HUP on channel hangup, or KCGI_OK on success.
194 */
195 static enum kcgi_err
kdata_write(struct kdata * p,const char * buf,size_t sz)196 kdata_write(struct kdata *p, const char *buf, size_t sz)
197 {
198 size_t i, max;
199 int newln;
200 enum kcgi_err er = KCGI_OK;
201
202 assert(p != NULL);
203
204 if (sz == 0 || buf == NULL)
205 return er;
206
207 /*
208 * If we're debugging writes, first copy as many bytes as
209 * possible into the output line buffer, stopping when it's full
210 * or when we have a newline. Keep flushing in these cases til
211 * we have nothing left to add. We'll flush any stray bytes
212 * when we get back here or close the connection.
213 */
214
215 if (sz && (p->debugging & KREQ_DEBUG_WRITE))
216 for (i = 0, max = sizeof(p->linebuf); i < sz; ) {
217 newln = 0;
218 while (i < sz && p->linebufpos < max) {
219 p->linebuf[p->linebufpos] = buf[i++];
220 p->bytes++;
221 if (p->linebuf[p->linebufpos] == '\n') {
222 newln = 1;
223 break;
224 }
225 p->linebufpos++;
226 }
227 if (newln) {
228 kutil_info(NULL, NULL, "%lu-tx: %.*s",
229 (unsigned long)getpid(),
230 (int)p->linebufpos, p->linebuf);
231 p->linebufpos = 0;
232 } else if (p->linebufpos == max) {
233 kutil_info(NULL, NULL, "%lu-tx: %.*s...",
234 (unsigned long)getpid(),
235 (int)p->linebufpos, p->linebuf);
236 p->linebufpos = 0;
237 }
238 }
239
240 /*
241 * Short-circuit: if we have no output buffer, flush directly to
242 * the wire.
243 */
244
245 if (p->outbufsz == 0)
246 return kdata_flush(p, buf, sz);
247
248 /*
249 * If we want to accept new data and it exceeds the buffer size,
250 * push out the entire existing buffer to start.
251 * Then re-check if we exceed our buffer size.
252 * If we do, then instead of filling into the temporary buffer
253 * and looping until the new buffer is exhausted, just push the
254 * whole thing out.
255 * If we don't, then copy it into the buffer.
256 */
257
258 if (p->outbufpos + sz > p->outbufsz) {
259 if ((er = kdata_drain(p)) != KCGI_OK)
260 return er;
261 if (sz > p->outbufsz)
262 return kdata_flush(p, buf, sz);
263 }
264
265 assert(p->outbufpos + sz <= p->outbufsz);
266 assert(p->outbuf != NULL);
267 memcpy(p->outbuf + p->outbufpos, buf, sz);
268 p->outbufpos += sz;
269 return er;
270 }
271
272 enum kcgi_err
khttp_write(struct kreq * req,const char * buf,size_t sz)273 khttp_write(struct kreq *req, const char *buf, size_t sz)
274 {
275
276 assert(req->kdata != NULL);
277 if (req->kdata->state != KSTATE_BODY)
278 return KCGI_FORM;
279 assert(!req->kdata->disabled);
280
281 /* This protects against buf == NULL or sz == 0. */
282
283 return kdata_write(req->kdata, buf, sz);
284 }
285
286 enum kcgi_err
khttp_printf(struct kreq * req,const char * fmt,...)287 khttp_printf(struct kreq *req, const char *fmt, ...)
288 {
289 char *buf;
290 int len;
291 va_list ap;
292 enum kcgi_err er;
293
294 if (fmt == NULL)
295 return KCGI_OK;
296
297 va_start(ap, fmt);
298 len = kxvasprintf(&buf, fmt, ap);
299 va_end(ap);
300
301 if (len == -1)
302 return KCGI_ENOMEM;
303
304 er = khttp_write(req, buf, (size_t)len);
305 free(buf);
306 return er;
307 }
308
309 enum kcgi_err
khttp_puts(struct kreq * req,const char * cp)310 khttp_puts(struct kreq *req, const char *cp)
311 {
312
313 if (cp == NULL)
314 return KCGI_OK;
315 return khttp_write(req, cp, strlen(cp));
316 }
317
318 enum kcgi_err
khttp_putc(struct kreq * req,int c)319 khttp_putc(struct kreq *req, int c)
320 {
321 unsigned char cc = c;
322
323 return khttp_write(req, (char *)&cc, 1);
324 }
325
326 enum kcgi_err
khttp_head(struct kreq * req,const char * key,const char * fmt,...)327 khttp_head(struct kreq *req, const char *key, const char *fmt, ...)
328 {
329 va_list ap;
330 char *buf;
331 size_t ksz;
332 int len;
333 enum kcgi_err er;
334
335 assert(req->kdata != NULL);
336 assert(req->kdata->state == KSTATE_HEAD);
337
338 va_start(ap, fmt);
339 len = kxvasprintf(&buf, fmt, ap);
340 va_end(ap);
341
342 if (len == -1)
343 return KCGI_ENOMEM;
344
345 ksz = strlen(key);
346 if ((er = kdata_write(req->kdata, key, ksz)) != KCGI_OK)
347 goto out;
348 if ((er = kdata_write(req->kdata, ": ", 2)) != KCGI_OK)
349 goto out;
350 if ((er = kdata_write(req->kdata, buf, len)) != KCGI_OK)
351 goto out;
352 if ((er = kdata_write(req->kdata, "\r\n", 2)) != KCGI_OK)
353 goto out;
354 out:
355 free(buf);
356 return er;
357 }
358
359 /*
360 * Allocate our output data.
361 * We accept the file descriptor for the FastCGI stream, if there's any.
362 */
363 struct kdata *
kdata_alloc(int control,int fcgi,uint16_t requestId,unsigned int debugging,const struct kopts * opts)364 kdata_alloc(int control, int fcgi, uint16_t requestId,
365 unsigned int debugging, const struct kopts *opts)
366 {
367 struct kdata *p;
368
369 if ((p = kxcalloc(1, sizeof(struct kdata))) == NULL)
370 return NULL;
371
372 p->debugging = debugging;
373 p->fcgi = fcgi;
374 p->control = control;
375 p->requestId = requestId;
376
377 if (opts->sndbufsz > 0) {
378 p->outbufsz = opts->sndbufsz;
379 if ((p->outbuf = kxmalloc(p->outbufsz)) == NULL) {
380 free(p);
381 return NULL;
382 }
383 }
384
385 return p;
386 }
387
388 /*
389 * Two ways of doing this: with or without "flush".
390 * If we're flushing, then we drain our output buffers to the output.
391 * Either way, we then release all of our internal memory.
392 */
393 void
kdata_free(struct kdata * p,int flush)394 kdata_free(struct kdata *p, int flush)
395 {
396 char buf[8];
397 uint32_t appStatus;
398
399 if (p == NULL)
400 return;
401
402 /* Debugging messages. */
403
404 if (flush && (p->debugging & KREQ_DEBUG_WRITE)) {
405 if (p->linebufpos)
406 kutil_info(NULL, NULL, "%lu-tx: %.*s",
407 (unsigned long)getpid(),
408 (int)p->linebufpos, p->linebuf);
409 p->linebufpos = 0;
410 kutil_info(NULL, NULL, "%lu-tx: %" PRIu64 " B",
411 (unsigned long)getpid(), p->bytes);
412 }
413
414 /* Remaining buffered data. */
415
416 if (flush)
417 kdata_drain(p);
418
419 free(p->outbuf);
420
421 /*
422 * If we're not FastCGI and we're not going to flush, then close
423 * the file descriptors outright: we don't want gzclose()
424 * flushing anything to the wire.
425 */
426
427 if (!flush && p->fcgi == -1) {
428 close(STDOUT_FILENO);
429 close(STDIN_FILENO);
430 }
431
432 if (p->gz != NULL)
433 gzclose(p->gz);
434
435 if (p->fcgi == -1) {
436 free(p);
437 return;
438 }
439
440 /*
441 * If flushing, end the stream.
442 * Note that we've already flushed our last FastCGI record to
443 * the stream, but the standard implies that we need a blank
444 * record to really shut this thing down.
445 */
446
447 if (flush) {
448 fcgi_write(6, p, "", 0);
449 appStatus = htonl(EXIT_SUCCESS);
450 memset(buf, 0, 8);
451 memcpy(buf, &appStatus, sizeof(uint32_t));
452
453 /* End of request. */
454
455 fcgi_write(3, p, buf, 8);
456
457 /* Close out. */
458
459 close(p->fcgi);
460 fullwrite(p->control, &p->requestId, sizeof(uint16_t));
461 } else
462 close(p->fcgi);
463
464 free(p);
465 }
466
467 /*
468 * Try to enable compression on the output stream itself.
469 * This function is only available with zlib.
470 * We disallow compression on FastCGI streams because I don't yet have
471 * the structure in place to copy the compressed data into a buffer then
472 * write that out.
473 * Set "ret" to zero if compression is not enabled, non-zero if enabled.
474 * Returns zero if allocation errors occured (via gzdopen(3)), non-zero
475 * otherwise.
476 * On failure, "ret" is always zero.
477 */
478 static int
kdata_compress(struct kdata * p,int * ret)479 kdata_compress(struct kdata *p, int *ret)
480 {
481
482 *ret = 0;
483 assert(p->state == KSTATE_HEAD);
484
485 if (p->fcgi != -1)
486 return 1;
487
488 assert(p->gz == NULL);
489 if ((p->gz = gzdopen(STDOUT_FILENO, "w")) == NULL) {
490 kutil_warn(NULL, NULL, "gzdopen");
491 return 0;
492 }
493 *ret = 1;
494 return 1;
495 }
496
497 /*
498 * Begin the body sequence by draining the headers to the wire and
499 * marking that the body has begun.
500 * Returns KCGI_OK on success, KCGI_ENOMEM on memory exhaustion, and
501 * KCGI_SYSTEM on wire-writing failure.
502 */
503 static enum kcgi_err
kdata_body(struct kdata * p)504 kdata_body(struct kdata *p)
505 {
506 enum kcgi_err er;
507
508 assert(p->state == KSTATE_HEAD);
509
510 if ((er = kdata_write(p, "\r\n", 2)) != KCGI_OK)
511 return er;
512
513 /*
514 * XXX: we always drain our buffer after the headers have been
515 * written.
516 * This incurs more chat on the wire, but also ensures that our
517 * response gets to the server as quickly as possible.
518 * Should an option be added to disable this?
519 */
520
521 if ((er = kdata_drain(p)) != KCGI_OK)
522 return er;
523
524 if (p->fcgi == -1)
525 if (fflush(stdout) != 0) {
526 kutil_warn(NULL, NULL, "fflush");
527 return KCGI_SYSTEM;
528 }
529
530 p->state = KSTATE_BODY;
531 return KCGI_OK;
532 }
533
534 enum kcgi_err
khttp_body(struct kreq * req)535 khttp_body(struct kreq *req)
536 {
537 int hasreq = 0;
538 enum kcgi_err er;
539 const char *cp;
540
541 /*
542 * First determine if the request wants HTTP compression.
543 * Use RFC 2616 14.3 as a guide for checking this: if we have
544 * the "gzip" accept encoding and a non-zero quality, then use
545 * compression.
546 */
547
548 if (req->reqmap[KREQU_ACCEPT_ENCODING] != NULL) {
549 cp = req->reqmap[KREQU_ACCEPT_ENCODING]->val;
550 if ((cp = strstr(cp, "gzip")) != NULL) {
551 hasreq = 1;
552 cp += 4;
553 if (strncmp(cp, ";q=0", 4) == 0)
554 hasreq = '.' == cp[4];
555 }
556 }
557
558 /*
559 * Note: the underlying writing functions will not do any
560 * compression even if we have compression enabled when in
561 * header mode, so the order of these operations (enable
562 * compression then write headers) is ok.
563 */
564
565 if (hasreq) {
566 /*
567 * We could just ignore this error, which means gzdopen
568 * failed, and just continue with hasreq=0.
569 * However, if gzdopen fails (memory allocation), it
570 * probably means other things are going to fail, so we
571 * might as well just die now.
572 */
573
574 if (!kdata_compress(req->kdata, &hasreq))
575 return KCGI_ENOMEM;
576 if (hasreq) {
577 er = khttp_head(req,
578 kresps[KRESP_CONTENT_ENCODING], "gzip");
579 if (er != KCGI_OK)
580 return er;
581 }
582 }
583
584 return kdata_body(req->kdata);
585 }
586
587 enum kcgi_err
khttp_body_compress(struct kreq * req,int comp)588 khttp_body_compress(struct kreq *req, int comp)
589 {
590 int didcomp;
591
592 /*
593 * First, if we didn't request compression, go directly into the
594 * body of the document.
595 */
596
597 if (!comp)
598 return kdata_body(req->kdata);
599
600 /*
601 * If we do have compression requested, try enabling it on the
602 * output stream.
603 */
604
605 if (!kdata_compress(req->kdata, &didcomp))
606 return KCGI_ENOMEM;
607 else if (!didcomp)
608 return KCGI_FORM;
609
610 return kdata_body(req->kdata);
611 }
612
613 /*
614 * Allocate a writer.
615 * This only works if we haven't disabled allocation of writers yet via
616 * kcgi_writer_disable(), otherwise we abort().
617 * Returns the writer or NULL on allocation (memory) failure.
618 */
619 struct kcgi_writer *
kcgi_writer_get(struct kreq * r,int type)620 kcgi_writer_get(struct kreq *r, int type)
621 {
622 struct kcgi_writer *p;
623
624 if (r->kdata->disabled) {
625 kutil_warnx(NULL, NULL,
626 "kcgi_writer_get after kcgi_writer_disable");
627 abort();
628 }
629
630 if ((p = kxmalloc(sizeof(struct kcgi_writer))) != NULL)
631 p->kdata = r->kdata;
632
633 return p;
634 }
635
636 /*
637 * Disable further allocation of writers with kcgi_writer_get().
638 * Following this, kcgi_writer_get() will abort.
639 * This may be called as many times as desired: only the first time
640 * makes a difference.
641 */
642 void
kcgi_writer_disable(struct kreq * r)643 kcgi_writer_disable(struct kreq *r)
644 {
645
646 r->kdata->disabled = 1;
647 }
648
649 /*
650 * Release an allocation by kcgi_writer_get().
651 * May be called with a NULL-valued "p".
652 */
653 void
kcgi_writer_free(struct kcgi_writer * p)654 kcgi_writer_free(struct kcgi_writer *p)
655 {
656
657 free(p);
658 }
659
660 /*
661 * Write "sz" bytes of "buf" into the output.
662 * This doesn't necessarily mean that the output has been written: it
663 * may be further buffered.
664 * Returns KCGI_OK, KCGI_ENOMEM, or KCGI_SYSTEM.
665 */
666 enum kcgi_err
kcgi_writer_write(struct kcgi_writer * p,const void * buf,size_t sz)667 kcgi_writer_write(struct kcgi_writer *p, const void *buf, size_t sz)
668 {
669
670 if (p->kdata->state != KSTATE_BODY)
671 return KCGI_FORM;
672 return kdata_write(p->kdata, buf, sz);
673 }
674
675 /*
676 * Like kcgi_writer_write but for the NUL-terminated string.
677 */
678 enum kcgi_err
kcgi_writer_puts(struct kcgi_writer * p,const char * cp)679 kcgi_writer_puts(struct kcgi_writer *p, const char *cp)
680 {
681
682 return kcgi_writer_write(p, cp, strlen(cp));
683 }
684
685 /*
686 * Like kcgi_writer_write but for a single character.
687 */
688 enum kcgi_err
kcgi_writer_putc(struct kcgi_writer * p,char c)689 kcgi_writer_putc(struct kcgi_writer *p, char c)
690 {
691
692 return kcgi_writer_write(p, &c, 1);
693 }
694