http.c (59581B)
1 /*
2 * Copyright (c) 2013-2022 Joris Vink <joris@coders.se>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <sys/param.h>
18 #include <sys/types.h>
19
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22
23 #include <ctype.h>
24 #include <fcntl.h>
25 #include <inttypes.h>
26 #include <float.h>
27 #include <time.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "kore.h"
32 #include "http.h"
33
34 #if defined(KORE_USE_PYTHON)
35 #include "python_api.h"
36 #endif
37
38 #if defined(KORE_USE_PGSQL)
39 #include "pgsql.h"
40 #endif
41
42 #if defined(KORE_USE_TASKS)
43 #include "tasks.h"
44 #endif
45
46 #if defined(KORE_USE_CURL)
47 #include "curl.h"
48 #endif
49
50 static struct {
51 const char *ext;
52 const char *type;
53 } builtin_media[] = {
54 { "gif", "image/gif" },
55 { "png", "image/png" },
56 { "jpeg", "image/jpeg" },
57 { "jpg", "image/jpeg" },
58 { "zip", "application/zip" },
59 { "pdf", "application/pdf" },
60 { "json", "application/json" },
61 { "js", "application/javascript" },
62 { "htm", "text/html" },
63 { "txt", "text/plain" },
64 { "css", "text/css" },
65 { "html", "text/html" },
66 { NULL, NULL },
67 };
68
69 #define HTTP_MAP_LIMIT 127
70
71 /*
72 * token = 1*<any CHAR except CTLs or separators>
73 * separators = "(" | ")" | "<" | ">" | "@"
74 * | "," | ";" | ":" | "\" | <">
75 * | "/" | "[" | "]" | "?" | "="
76 * | "{" | "}" | SP | HT
77 */
78 static const char http_token[] = {
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, '!' , 0x00, '#' , '$' , '%' , '&' , '\'',
84 0x00, 0x00, '*' , '+' , 0x00, '-' , '.' , 0x00,
85 '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' ,
86 '8' , '9' , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' ,
88 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' ,
89 'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' ,
90 'X' , 'Y' , 'Z' , 0x00, 0x00, 0x00, '^' , '_' ,
91 '`' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' ,
92 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' ,
93 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' ,
94 'x' , 'y' , 'z' , 0x00, '|' , 0x00, '~' , 0x00
95 };
96
97 /*
98 * field-content = <the OCTETs making up the field-value
99 * and consisting of either *TEXT or combinations
100 * of token, separators, and quoted-string>
101 */
102 static const char http_field_content[] = {
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 ' ' , '!' , '"' , '#' , '$' , '%' , '&' , '\'',
108 '(' , ')' , '*' , '+' , ',' , '-' , '.' , '/' ,
109 '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' ,
110 '8' , '9' , ':' , ';' , '<' , '=' , '>' , '?' ,
111 '@' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' ,
112 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' ,
113 'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' ,
114 'X' , 'Y' , 'Z' , '[' , '\\', ']' , '^' , '_' ,
115 '`' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' ,
116 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' ,
117 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' ,
118 'x' , 'y' , 'z' , '{' , '|' , '}' , '~' , 0x00
119 };
120
121 /*
122 * Fixed "pretty" HTTP error HTML page.
123 */
124 static const char *pretty_error_fmt =
125 "<html>\n<head>\n\t<title>%d %s</title>"
126 "</head>\n<body>\n\t"
127 "<h1>%d %s</h1>\n"
128 "</body>\n</html>\n";
129
130 static int http_body_recv(struct netbuf *);
131 static int http_release_buffer(struct netbuf *);
132 static void http_error_response(struct connection *, int);
133 static int http_data_convert(void *, void **, void *, int);
134 static void http_write_response_cookie(struct http_cookie *);
135 static int http_body_update(struct http_request *, const void *, size_t);
136 static void http_argument_add(struct http_request *, char *, char *,
137 int, int);
138 static int http_check_redirect(struct http_request *,
139 struct kore_domain *);
140 static void http_response_normal(struct http_request *,
141 struct connection *, int, const void *, size_t);
142 static void multipart_add_field(struct http_request *, struct kore_buf *,
143 char *, const char *, const int);
144 static void multipart_file_add(struct http_request *, struct kore_buf *,
145 const char *, const char *, const char *, const int);
146 static int multipart_find_data(struct kore_buf *, struct kore_buf *,
147 size_t *, struct http_request *, const void *, size_t);
148 static int multipart_parse_headers(struct http_request *,
149 struct kore_buf *, struct kore_buf *,
150 const char *, const int);
151
152 static struct http_request *http_request_new(struct connection *,
153 const char *, const char *, char *,
154 const char *);
155
156 static struct kore_buf *header_buf;
157 static struct kore_buf *ckhdr_buf;
158 static char http_version[64];
159 static u_int16_t http_version_len;
160 static TAILQ_HEAD(, http_request) http_requests;
161 static TAILQ_HEAD(, http_request) http_requests_sleeping;
162 static LIST_HEAD(, http_media_type) http_media_types;
163 static struct kore_pool http_request_pool;
164 static struct kore_pool http_cookie_pool;
165 static struct kore_pool http_body_path;
166 static struct kore_pool http_rlq_pool;
167
168 struct kore_pool http_header_pool;
169
170 int http_pretty_error = 0;
171 u_int32_t http_request_count = 0;
172 u_int32_t http_request_ms = HTTP_REQUEST_MS;
173 u_int16_t http_body_timeout = HTTP_BODY_TIMEOUT;
174 u_int32_t http_request_limit = HTTP_REQUEST_LIMIT;
175 u_int64_t http_hsts_enable = HTTP_HSTS_ENABLE;
176 u_int16_t http_header_max = HTTP_HEADER_MAX_LEN;
177 u_int16_t http_keepalive_time = HTTP_KEEPALIVE_TIME;
178 u_int16_t http_header_timeout = HTTP_HEADER_TIMEOUT;
179
180 size_t http_body_max = HTTP_BODY_MAX_LEN;
181 char *http_body_disk_path = HTTP_BODY_DISK_PATH;
182 u_int64_t http_body_disk_offload = HTTP_BODY_DISK_OFFLOAD;
183
184 void
185 http_parent_init(void)
186 {
187 LIST_INIT(&http_media_types);
188 }
189
190 void
191 http_init(void)
192 {
193 int prealloc, l, i;
194
195 TAILQ_INIT(&http_requests);
196 TAILQ_INIT(&http_requests_sleeping);
197
198 header_buf = kore_buf_alloc(HTTP_HEADER_BUFSIZE);
199 ckhdr_buf = kore_buf_alloc(HTTP_COOKIE_BUFSIZE);
200
201 if (!http_version_len) {
202 l = snprintf(http_version, sizeof(http_version),
203 "server: kore (%s)\r\n", kore_version);
204 if (l == -1 || (size_t)l >= sizeof(http_version))
205 fatal("http_init(): http_version buffer too small");
206
207 http_version_len = l;
208 }
209
210 prealloc = MIN((worker_max_connections / 10), 1000);
211 kore_pool_init(&http_request_pool, "http_request_pool",
212 sizeof(struct http_request), http_request_limit);
213 kore_pool_init(&http_header_pool, "http_header_pool",
214 sizeof(struct http_header), prealloc * HTTP_REQ_HEADER_MAX);
215 kore_pool_init(&http_cookie_pool, "http_cookie_pool",
216 sizeof(struct http_cookie), prealloc * HTTP_MAX_COOKIES);
217 kore_pool_init(&http_rlq_pool, "http_rlq_pool",
218 sizeof(struct http_runlock_queue), http_request_limit);
219
220 kore_pool_init(&http_body_path,
221 "http_body_path", HTTP_BODY_PATH_MAX, prealloc);
222
223 for (i = 0; builtin_media[i].ext != NULL; i++) {
224 if (!http_media_register(builtin_media[i].ext,
225 builtin_media[i].type)) {
226 fatal("duplicate media type for %s",
227 builtin_media[i].ext);
228 }
229 }
230 }
231
232 void
233 http_cleanup(void)
234 {
235 if (header_buf != NULL) {
236 kore_buf_free(header_buf);
237 header_buf = NULL;
238 }
239
240 if (ckhdr_buf != NULL) {
241 kore_buf_free(ckhdr_buf);
242 ckhdr_buf = NULL;
243 }
244
245 kore_pool_cleanup(&http_request_pool);
246 kore_pool_cleanup(&http_header_pool);
247 kore_pool_cleanup(&http_body_path);
248 }
249
250 void
251 http_server_version(const char *version)
252 {
253 int l;
254
255 l = snprintf(http_version, sizeof(http_version),
256 "server: %s\r\n", version);
257 if (l == -1 || (size_t)l >= sizeof(http_version))
258 fatal("http_server_version(): http_version buffer too small");
259
260 http_version_len = l;
261 }
262
263 int
264 http_check_timeout(struct connection *c, u_int64_t now)
265 {
266 u_int64_t d;
267
268 if (c->http_timeout == 0)
269 return (KORE_RESULT_OK);
270
271 if (now > c->http_start)
272 d = now - c->http_start;
273 else
274 d = 0;
275
276 if (d >= c->http_timeout) {
277 http_error_response(c, HTTP_STATUS_REQUEST_TIMEOUT);
278 kore_connection_disconnect(c);
279 return (KORE_RESULT_ERROR);
280 }
281
282 return (KORE_RESULT_OK);
283 }
284
285 void
286 http_request_sleep(struct http_request *req)
287 {
288 if (!(req->flags & HTTP_REQUEST_SLEEPING)) {
289 req->flags |= HTTP_REQUEST_SLEEPING;
290 TAILQ_REMOVE(&http_requests, req, list);
291 TAILQ_INSERT_TAIL(&http_requests_sleeping, req, list);
292 }
293 }
294
295 void
296 http_request_wakeup(struct http_request *req)
297 {
298 if (req->flags & HTTP_REQUEST_SLEEPING) {
299 req->flags &= ~HTTP_REQUEST_SLEEPING;
300 TAILQ_REMOVE(&http_requests_sleeping, req, list);
301 TAILQ_INSERT_TAIL(&http_requests, req, list);
302 }
303 }
304
305 void
306 http_process(void)
307 {
308 u_int64_t total;
309 struct http_request *req, *next;
310
311 total = 0;
312
313 for (req = TAILQ_FIRST(&http_requests); req != NULL; req = next) {
314 if (total >= http_request_ms)
315 break;
316
317 next = TAILQ_NEXT(req, list);
318 if (req->flags & HTTP_REQUEST_DELETE) {
319 http_request_free(req);
320 continue;
321 }
322
323 /* Sleeping requests should be in http_requests_sleeping. */
324 if (req->flags & HTTP_REQUEST_SLEEPING)
325 fatal("http_process: sleeping request on list");
326
327 if (!(req->flags & HTTP_REQUEST_COMPLETE))
328 continue;
329
330 http_process_request(req);
331 total += req->ms;
332
333 if (req->flags & HTTP_REQUEST_DELETE)
334 http_request_free(req);
335 }
336 }
337
338 void
339 http_process_request(struct http_request *req)
340 {
341 int r;
342
343 if (req->flags & HTTP_REQUEST_DELETE || req->rt == NULL)
344 return;
345
346 req->start = kore_time_ms();
347 if (req->rt->auth != NULL && !(req->flags & HTTP_REQUEST_AUTHED))
348 r = kore_auth_run(req, req->rt->auth);
349 else
350 r = KORE_RESULT_OK;
351
352 switch (r) {
353 case KORE_RESULT_OK:
354 r = kore_runtime_http_request(req->rt->rcall, req);
355 break;
356 case KORE_RESULT_RETRY:
357 break;
358 case KORE_RESULT_ERROR:
359 /*
360 * Set r to KORE_RESULT_OK so we can properly
361 * flush the result from kore_auth_run().
362 */
363 r = KORE_RESULT_OK;
364 break;
365 default:
366 fatal("kore_auth() returned unknown %d", r);
367 }
368 req->end = kore_time_ms();
369 req->ms = req->end - req->start;
370 req->total += req->ms;
371
372 switch (r) {
373 case KORE_RESULT_OK:
374 r = net_send_flush(req->owner);
375 if (r == KORE_RESULT_ERROR)
376 kore_connection_disconnect(req->owner);
377 break;
378 case KORE_RESULT_ERROR:
379 kore_connection_disconnect(req->owner);
380 break;
381 case KORE_RESULT_RETRY:
382 return;
383 default:
384 fatal("A page handler returned an unknown result: %d", r);
385 }
386
387 if (req->rt->dom->accesslog)
388 kore_accesslog(req);
389
390 req->flags |= HTTP_REQUEST_DELETE;
391 }
392
393 void
394 http_response_header(struct http_request *req,
395 const char *header, const char *value)
396 {
397 struct http_header *hdr;
398
399 hdr = NULL;
400
401 TAILQ_FOREACH(hdr, &req->resp_headers, list) {
402 if (!strcasecmp(hdr->header, header)) {
403 TAILQ_REMOVE(&req->resp_headers, hdr, list);
404 kore_free(hdr->header);
405 kore_free(hdr->value);
406 break;
407 }
408 }
409
410 if (hdr == NULL)
411 hdr = kore_pool_get(&http_header_pool);
412
413 hdr->header = kore_strdup(header);
414 hdr->value = kore_strdup(value);
415
416 TAILQ_INSERT_TAIL(&(req->resp_headers), hdr, list);
417 }
418
419 void
420 http_request_free(struct http_request *req)
421 {
422 #if defined(KORE_USE_TASKS)
423 struct kore_task *t, *nt;
424 int pending_tasks;
425 #endif
426 #if defined(KORE_USE_PGSQL)
427 struct kore_pgsql *pgsql;
428 #endif
429 #if defined(KORE_USE_CURL)
430 struct kore_curl *client;
431 #endif
432 struct http_file *f, *fnext;
433 struct http_arg *q, *qnext;
434 struct http_header *hdr, *next;
435 struct http_cookie *ck, *cknext;
436
437 if (req->rt != NULL && req->rt->on_free != NULL)
438 kore_runtime_http_request_free(req->rt->on_free, req);
439
440 if (req->runlock != NULL) {
441 LIST_REMOVE(req->runlock, list);
442 req->runlock = NULL;
443 }
444
445 #if defined(KORE_USE_TASKS)
446 pending_tasks = 0;
447 for (t = LIST_FIRST(&(req->tasks)); t != NULL; t = nt) {
448 nt = LIST_NEXT(t, rlist);
449 if (!kore_task_finished(t)) {
450 pending_tasks++;
451 } else {
452 kore_task_destroy(t);
453 }
454 }
455
456 if (pending_tasks)
457 return;
458 #endif
459
460 #if defined(KORE_USE_PYTHON)
461 if (req->py_coro != NULL) {
462 kore_python_coro_delete(req->py_coro);
463 req->py_coro = NULL;
464 }
465 if (req->py_validator != NULL) {
466 kore_python_coro_delete(req->py_validator);
467 req->py_validator = NULL;
468 }
469 Py_XDECREF(req->py_req);
470 #endif
471 #if defined(KORE_USE_PGSQL)
472 while (!LIST_EMPTY(&(req->pgsqls))) {
473 pgsql = LIST_FIRST(&(req->pgsqls));
474 kore_pgsql_cleanup(pgsql);
475 }
476 #endif
477 #if defined(KORE_USE_CURL)
478 while (!LIST_EMPTY(&req->chandles)) {
479 client = LIST_FIRST(&req->chandles);
480 kore_curl_cleanup(client);
481 }
482 #endif
483 kore_free(req->headers);
484
485 req->host = NULL;
486 req->path = NULL;
487 req->headers = NULL;
488
489 TAILQ_REMOVE(&http_requests, req, list);
490 if (req->owner != NULL)
491 TAILQ_REMOVE(&(req->owner->http_requests), req, olist);
492
493 for (hdr = TAILQ_FIRST(&(req->resp_headers)); hdr != NULL; hdr = next) {
494 next = TAILQ_NEXT(hdr, list);
495 TAILQ_REMOVE(&(req->resp_headers), hdr, list);
496 kore_free(hdr->header);
497 kore_free(hdr->value);
498 kore_pool_put(&http_header_pool, hdr);
499 }
500
501 for (hdr = TAILQ_FIRST(&(req->req_headers)); hdr != NULL; hdr = next) {
502 next = TAILQ_NEXT(hdr, list);
503 TAILQ_REMOVE(&(req->req_headers), hdr, list);
504 kore_pool_put(&http_header_pool, hdr);
505 }
506
507 for (ck = TAILQ_FIRST(&(req->resp_cookies)); ck != NULL; ck = cknext) {
508 cknext = TAILQ_NEXT(ck, list);
509 TAILQ_REMOVE(&(req->resp_cookies), ck, list);
510 kore_free(ck->name);
511 kore_free(ck->value);
512 kore_free(ck->path);
513 kore_free(ck->domain);
514 kore_pool_put(&http_cookie_pool, ck);
515 }
516
517 for (ck = TAILQ_FIRST(&(req->req_cookies)); ck != NULL; ck = cknext) {
518 cknext = TAILQ_NEXT(ck, list);
519 TAILQ_REMOVE(&(req->req_cookies), ck, list);
520 kore_free(ck->name);
521 kore_free(ck->value);
522 kore_pool_put(&http_cookie_pool, ck);
523 }
524
525 for (q = TAILQ_FIRST(&(req->arguments)); q != NULL; q = qnext) {
526 qnext = TAILQ_NEXT(q, list);
527 TAILQ_REMOVE(&(req->arguments), q, list);
528 kore_free(q->name);
529 kore_free(q->s_value);
530 kore_free(q);
531 }
532
533 for (f = TAILQ_FIRST(&(req->files)); f != NULL; f = fnext) {
534 fnext = TAILQ_NEXT(f, list);
535 TAILQ_REMOVE(&(req->files), f, list);
536 kore_free(f->filename);
537 kore_free(f->name);
538 kore_free(f);
539 }
540
541 if (req->http_body != NULL)
542 kore_buf_free(req->http_body);
543
544 if (req->http_body_fd != -1)
545 (void)close(req->http_body_fd);
546
547 if (req->http_body_path != NULL) {
548 if (unlink(req->http_body_path) == -1 && errno != ENOENT) {
549 kore_log(LOG_NOTICE, "failed to unlink %s: %s",
550 req->http_body_path, errno_s);
551 }
552 kore_pool_put(&http_body_path, req->http_body_path);
553 }
554
555 if (req->hdlr_extra != NULL &&
556 !(req->flags & HTTP_REQUEST_RETAIN_EXTRA))
557 kore_free(req->hdlr_extra);
558
559 kore_pool_put(&http_request_pool, req);
560 http_request_count--;
561 }
562
563 void
564 http_serveable(struct http_request *req, const void *data, size_t len,
565 const char *etag, const char *type)
566 {
567 const char *match;
568
569 if (req->method != HTTP_METHOD_GET) {
570 http_response_header(req, "allow", "get");
571 http_response(req, HTTP_STATUS_BAD_REQUEST, NULL, 0);
572 return;
573 }
574
575 if (http_request_header(req, "if-none-match", &match)) {
576 if (!strcmp(match, etag)) {
577 http_response(req, HTTP_STATUS_NOT_MODIFIED, NULL, 0);
578 return;
579 }
580 }
581
582 http_response_header(req, "etag", etag);
583 http_response_header(req, "content-type", type);
584 http_response(req, HTTP_STATUS_OK, data, len);
585 }
586
587 void
588 http_response(struct http_request *req, int code, const void *d, size_t l)
589 {
590 if (req->owner == NULL)
591 return;
592
593 req->status = code;
594
595 switch (req->owner->proto) {
596 case CONN_PROTO_HTTP:
597 case CONN_PROTO_WEBSOCKET:
598 http_response_normal(req, req->owner, code, d, l);
599 break;
600 default:
601 fatal("%s: bad proto %d", __func__, req->owner->proto);
602 /* NOTREACHED. */
603 }
604 }
605
606 void
607 http_response_close(struct http_request *req, int code, const void *d, size_t l)
608 {
609 if (req->owner == NULL)
610 return;
611
612 req->status = code;
613 req->owner->flags |= CONN_CLOSE_EMPTY;
614
615 switch (req->owner->proto) {
616 case CONN_PROTO_HTTP:
617 case CONN_PROTO_WEBSOCKET:
618 http_response_normal(req, req->owner, code, d, l);
619 break;
620 default:
621 fatal("%s: bad proto %d", __func__, req->owner->proto);
622 /* NOTREACHED. */
623 }
624 }
625
626 void
627 http_response_json(struct http_request *req, int status,
628 struct kore_json_item *json)
629 {
630 struct kore_buf *buf;
631
632 if (req->owner == NULL)
633 return;
634
635 buf = kore_buf_alloc(1024);
636 kore_json_item_tobuf(json, buf);
637 kore_json_item_free(json);
638
639 req->status = status;
640 http_response_header(req, "content-type", "application/json");
641
642 switch (req->owner->proto) {
643 case CONN_PROTO_HTTP:
644 http_response_stream(req, status, buf->data, buf->offset,
645 http_release_buffer, buf);
646 break;
647 default:
648 fatal("%s: bad proto %d", __func__, req->owner->proto);
649 /* NOTREACHED. */
650 }
651 }
652
653 void
654 http_response_stream(struct http_request *req, int status, void *base,
655 size_t len, int (*cb)(struct netbuf *), void *arg)
656 {
657 struct netbuf *nb;
658
659 if (req->owner == NULL)
660 return;
661
662 req->status = status;
663
664 switch (req->owner->proto) {
665 case CONN_PROTO_HTTP:
666 http_response_normal(req, req->owner, status, NULL, len);
667 break;
668 default:
669 fatal("%s: bad proto %d", __func__, req->owner->proto);
670 /* NOTREACHED. */
671 }
672
673 net_send_stream(req->owner, base, len, cb, &nb);
674 nb->extra = arg;
675
676 if (req->method == HTTP_METHOD_HEAD) {
677 nb->s_off = nb->b_len;
678 net_remove_netbuf(req->owner, nb);
679 }
680 }
681
682 void
683 http_response_fileref(struct http_request *req, int status,
684 struct kore_fileref *ref)
685 {
686 struct tm *tm;
687 time_t mtime;
688 char tbuf[128];
689 const char *media_type, *modified;
690
691 if (req->owner == NULL)
692 return;
693
694 media_type = http_media_type(ref->path);
695 if (media_type != NULL)
696 http_response_header(req, "content-type", media_type);
697
698 if (http_request_header(req, "if-modified-since", &modified)) {
699 mtime = kore_date_to_time(modified);
700 if (mtime == ref->mtime_sec) {
701 kore_fileref_release(ref);
702 http_response(req, HTTP_STATUS_NOT_MODIFIED, NULL, 0);
703 return;
704 }
705 }
706
707 if ((tm = gmtime(&ref->mtime_sec)) != NULL) {
708 if (strftime(tbuf, sizeof(tbuf),
709 "%a, %d %b %Y %H:%M:%S GMT", tm) > 0) {
710 http_response_header(req, "last-modified", tbuf);
711 }
712 }
713
714 req->status = status;
715 switch (req->owner->proto) {
716 case CONN_PROTO_HTTP:
717 http_response_normal(req, req->owner, status, NULL, ref->size);
718 break;
719 default:
720 fatal("http_response_fd() bad proto %d", req->owner->proto);
721 /* NOTREACHED. */
722 }
723
724 if (req->method != HTTP_METHOD_HEAD)
725 net_send_fileref(req->owner, ref);
726 else
727 kore_fileref_release(ref);
728 }
729
730 int
731 http_request_header(struct http_request *req, const char *header,
732 const char **out)
733 {
734 struct http_header *hdr;
735
736 TAILQ_FOREACH(hdr, &(req->req_headers), list) {
737 if (!strcasecmp(hdr->header, header)) {
738 *out = hdr->value;
739 return (KORE_RESULT_OK);
740 }
741 }
742
743 if (!strcasecmp(header, "host")) {
744 *out = req->host;
745 return (KORE_RESULT_OK);
746 }
747
748 return (KORE_RESULT_ERROR);
749 }
750
751 int
752 http_request_header_get(struct http_request *req, const char *header,
753 void **out, void *nout, int type)
754 {
755 struct http_header *hdr;
756
757 if (type == HTTP_ARG_TYPE_STRING)
758 fatal("%s: cannot be called with type string", __func__);
759
760 TAILQ_FOREACH(hdr, &req->req_headers, list) {
761 if (strcasecmp(hdr->header, header))
762 continue;
763
764 if (http_data_convert(hdr->value, out, nout, type))
765 return (KORE_RESULT_OK);
766
767 return (KORE_RESULT_ERROR);
768 }
769
770 return (KORE_RESULT_ERROR);
771 }
772
773 int
774 http_request_cookie(struct http_request *req, const char *cookie, char **out)
775 {
776 struct http_cookie *ck;
777
778 TAILQ_FOREACH(ck, &(req->req_cookies), list) {
779 if (!strcasecmp(ck->name, cookie)) {
780 *out = ck->value;
781 return (KORE_RESULT_OK);
782 }
783 }
784
785 return (KORE_RESULT_ERROR);
786 }
787
788 int
789 http_header_recv(struct netbuf *nb)
790 {
791 struct connection *c;
792 size_t len;
793 struct http_header *hdr;
794 struct http_request *req;
795 u_int8_t *end_headers;
796 int h, i, v, skip, l;
797 char *headers[HTTP_REQ_HEADER_MAX];
798 char *value, *host, *request[4], *hbuf;
799
800 c = nb->owner;
801
802 if (nb->s_off < 4)
803 return (KORE_RESULT_OK);
804
805 if (!isalpha(nb->buf[0])) {
806 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
807 return (KORE_RESULT_ERROR);
808 }
809
810 skip = 4;
811 end_headers = kore_mem_find(nb->buf, nb->s_off, "\r\n\r\n", 4);
812 if (end_headers == NULL) {
813 end_headers = kore_mem_find(nb->buf, nb->s_off, "\n\n", 2);
814 if (end_headers == NULL) {
815 if (nb->s_off == http_header_max) {
816 http_error_response(c,
817 HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE);
818 return (KORE_RESULT_ERROR);
819 }
820 return (KORE_RESULT_OK);
821 }
822 skip = 2;
823 }
824
825 *end_headers = '\0';
826 end_headers += skip;
827 len = end_headers - nb->buf;
828 hbuf = (char *)nb->buf;
829
830 h = kore_split_string(hbuf, "\r\n", headers, HTTP_REQ_HEADER_MAX);
831 if (h < 2) {
832 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
833 return (KORE_RESULT_OK);
834 }
835
836 v = kore_split_string(headers[0], " ", request, 4);
837 if (v != 3) {
838 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
839 return (KORE_RESULT_OK);
840 }
841
842 skip = 0;
843 host = NULL;
844 for (i = 0; i < h; i++) {
845 if (strncasecmp(headers[i], "host", 4))
846 continue;
847
848 if ((host = http_validate_header(headers[i])) == NULL) {
849 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
850 return (KORE_RESULT_OK);
851 }
852
853 if (*host == '\0') {
854 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
855 return (KORE_RESULT_OK);
856 }
857
858 skip = i;
859 break;
860 }
861
862 if (host == NULL) {
863 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
864 return (KORE_RESULT_OK);
865 }
866
867 req = http_request_new(c, host, request[0], request[1], request[2]);
868 if (req == NULL)
869 return (KORE_RESULT_OK);
870
871 /* take full ownership of the buffer. */
872 req->headers = nb->buf;
873 nb->buf = NULL;
874 nb->m_len = 0;
875
876 for (i = 1; i < h; i++) {
877 if (i == skip)
878 continue;
879
880 if ((value = http_validate_header(headers[i])) == NULL) {
881 req->flags |= HTTP_REQUEST_DELETE;
882 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
883 return (KORE_RESULT_OK);
884 }
885
886 if (*value == '\0') {
887 req->flags |= HTTP_REQUEST_DELETE;
888 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
889 return (KORE_RESULT_OK);
890 }
891
892 hdr = kore_pool_get(&http_header_pool);
893 hdr->header = headers[i];
894 hdr->value = value;
895 TAILQ_INSERT_TAIL(&(req->req_headers), hdr, list);
896
897 if (req->agent == NULL &&
898 !strcasecmp(hdr->header, "user-agent"))
899 req->agent = hdr->value;
900
901 if (req->referer == NULL &&
902 !strcasecmp(hdr->header, "referer"))
903 req->referer = hdr->value;
904 }
905
906 if (req->flags & HTTP_REQUEST_EXPECT_BODY) {
907 if (http_body_max == 0) {
908 req->flags |= HTTP_REQUEST_DELETE;
909 http_error_response(req->owner,
910 HTTP_STATUS_METHOD_NOT_ALLOWED);
911 return (KORE_RESULT_OK);
912 }
913
914 if (!http_request_header_uint64(req, "content-length",
915 &req->content_length)) {
916 if (req->method == HTTP_METHOD_DELETE) {
917 req->flags |= HTTP_REQUEST_COMPLETE;
918 return (KORE_RESULT_OK);
919 }
920
921 req->flags |= HTTP_REQUEST_DELETE;
922 http_error_response(req->owner,
923 HTTP_STATUS_LENGTH_REQUIRED);
924 return (KORE_RESULT_OK);
925 }
926
927 if (req->content_length == 0) {
928 c->http_timeout = 0;
929 req->flags |= HTTP_REQUEST_COMPLETE;
930 req->flags &= ~HTTP_REQUEST_EXPECT_BODY;
931 return (KORE_RESULT_OK);
932 }
933
934 if (req->content_length > http_body_max) {
935 req->flags |= HTTP_REQUEST_DELETE;
936 http_error_response(req->owner,
937 HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE);
938 return (KORE_RESULT_OK);
939 }
940
941 req->http_body_length = req->content_length;
942
943 if (http_body_disk_offload > 0 &&
944 req->content_length > http_body_disk_offload) {
945 req->http_body_path = kore_pool_get(&http_body_path);
946 l = snprintf(req->http_body_path, HTTP_BODY_PATH_MAX,
947 "%s/http_body.XXXXXX", http_body_disk_path);
948 if (l == -1 || (size_t)l >= HTTP_BODY_PATH_MAX) {
949 req->flags |= HTTP_REQUEST_DELETE;
950 http_error_response(req->owner,
951 HTTP_STATUS_INTERNAL_ERROR);
952 return (KORE_RESULT_ERROR);
953 }
954
955 req->http_body = NULL;
956 req->http_body_fd = mkstemp(req->http_body_path);
957 if (req->http_body_fd == -1) {
958 req->flags |= HTTP_REQUEST_DELETE;
959 http_error_response(req->owner,
960 HTTP_STATUS_INTERNAL_ERROR);
961 return (KORE_RESULT_OK);
962 }
963 } else {
964 req->http_body_fd = -1;
965 req->http_body = kore_buf_alloc(req->content_length);
966 }
967
968 SHA256Init(&req->hashctx);
969 c->http_timeout = http_body_timeout * 1000;
970
971 if (!http_body_update(req, end_headers, nb->s_off - len)) {
972 req->flags |= HTTP_REQUEST_DELETE;
973 http_error_response(req->owner,
974 HTTP_STATUS_INTERNAL_ERROR);
975 return (KORE_RESULT_OK);
976 }
977 } else {
978 c->http_timeout = 0;
979 }
980
981 if (req->rt->on_headers != NULL) {
982 if (!kore_runtime_http_request(req->rt->on_headers, req)) {
983 req->flags |= HTTP_REQUEST_DELETE;
984 return (KORE_RESULT_OK);
985 }
986 }
987
988 return (KORE_RESULT_OK);
989 }
990
991 int
992 http_argument_get(struct http_request *req, const char *name,
993 void **out, void *nout, int type)
994 {
995 struct http_arg *q;
996
997 TAILQ_FOREACH(q, &(req->arguments), list) {
998 if (strcmp(q->name, name))
999 continue;
1000
1001 if (http_data_convert(q->s_value, out, nout, type))
1002 return (KORE_RESULT_OK);
1003
1004 break;
1005 }
1006
1007 return (KORE_RESULT_ERROR);
1008 }
1009
1010 int
1011 http_argument_urldecode(char *arg, int url)
1012 {
1013 u_int8_t v;
1014 int err;
1015 size_t len;
1016 char *p, *in, h[5];
1017
1018 p = arg;
1019 in = arg;
1020 len = strlen(arg);
1021
1022 while (*p != '\0' && p < (arg + len)) {
1023 if (*p == '+')
1024 *p = ' ';
1025 if (*p != '%') {
1026 *in++ = *p++;
1027 continue;
1028 }
1029
1030 if ((p + 2) >= (arg + len))
1031 return (KORE_RESULT_ERROR);
1032
1033 if (!isxdigit((unsigned char)*(p + 1)) ||
1034 !isxdigit((unsigned char)*(p + 2))) {
1035 *in++ = *p++;
1036 continue;
1037 }
1038
1039 h[0] = '0';
1040 h[1] = 'x';
1041 h[2] = *(p + 1);
1042 h[3] = *(p + 2);
1043 h[4] = '\0';
1044
1045 v = kore_strtonum(h, 16, 0x0, 0xff, &err);
1046 if (err != KORE_RESULT_OK)
1047 return (err);
1048
1049 if (url) {
1050 if (v <= 0x1f || v == 0x7f)
1051 return (KORE_RESULT_ERROR);
1052 } else {
1053 if ((v <= 0x1f || v == 0x7f) &&
1054 (v != '\n' && v != '\r' && v != '\t'))
1055 return (KORE_RESULT_ERROR);
1056 }
1057
1058 *in++ = (char)v;
1059 p += 3;
1060 }
1061
1062 *in = '\0';
1063 return (KORE_RESULT_OK);
1064 }
1065
1066 struct http_file *
1067 http_file_lookup(struct http_request *req, const char *name)
1068 {
1069 struct http_file *f;
1070
1071 TAILQ_FOREACH(f, &(req->files), list) {
1072 if (!strcmp(f->name, name))
1073 return (f);
1074 }
1075
1076 return (NULL);
1077 }
1078
1079 ssize_t
1080 http_file_read(struct http_file *file, void *buf, size_t len)
1081 {
1082 ssize_t ret;
1083 size_t toread, off;
1084
1085 if (file->length < file->offset)
1086 return (-1);
1087 if ((file->offset + len) < file->offset)
1088 return (-1);
1089 if ((file->position + file->offset) < file->position)
1090 return (-1);
1091
1092 off = file->position + file->offset;
1093 toread = MIN(len, (file->length - file->offset));
1094 if (toread == 0)
1095 return (0);
1096
1097 if (file->req->http_body_fd != -1) {
1098 if (lseek(file->req->http_body_fd, off, SEEK_SET) == -1) {
1099 kore_log(LOG_ERR, "http_file_read: lseek(%s): %s",
1100 file->req->http_body_path, errno_s);
1101 return (-1);
1102 }
1103
1104 for (;;) {
1105 ret = read(file->req->http_body_fd, buf, toread);
1106 if (ret == -1) {
1107 if (errno == EINTR)
1108 continue;
1109 kore_log(LOG_ERR, "failed to read %s: %s",
1110 file->req->http_body_path, errno_s);
1111 return (-1);
1112 }
1113 if (ret == 0)
1114 return (0);
1115 break;
1116 }
1117 } else if (file->req->http_body != NULL) {
1118 if (off > file->req->http_body->length)
1119 return (0);
1120 memcpy(buf, file->req->http_body->data + off, toread);
1121 ret = toread;
1122 } else {
1123 kore_log(LOG_ERR, "http_file_read: called without body");
1124 return (-1);
1125 }
1126
1127 file->offset += (size_t)ret;
1128 return (ret);
1129 }
1130
1131 void
1132 http_file_rewind(struct http_file *file)
1133 {
1134 file->offset = 0;
1135 }
1136
1137 void
1138 http_response_cookie(struct http_request *req, const char *name,
1139 const char *val, const char *path, time_t expires, u_int32_t maxage,
1140 struct http_cookie **out)
1141 {
1142 char *p;
1143 struct http_cookie *ck;
1144
1145 if (name == NULL || val == NULL)
1146 fatal("http_response_cookie: invalid parameters");
1147
1148 ck = kore_pool_get(&http_cookie_pool);
1149
1150 ck->maxage = maxage;
1151 ck->expires = expires;
1152 ck->name = kore_strdup(name);
1153 ck->value = kore_strdup(val);
1154 ck->domain = kore_strdup(req->host);
1155 ck->flags = HTTP_COOKIE_HTTPONLY | HTTP_COOKIE_SECURE;
1156
1157 if ((p = strrchr(ck->domain, ':')) != NULL)
1158 *p = '\0';
1159
1160 if (path != NULL)
1161 ck->path = kore_strdup(path);
1162 else
1163 ck->path = NULL;
1164
1165 TAILQ_INSERT_TAIL(&(req->resp_cookies), ck, list);
1166
1167 if (out != NULL)
1168 *out = ck;
1169 }
1170
1171 void
1172 http_populate_cookies(struct http_request *req)
1173 {
1174 struct http_cookie *ck;
1175 const char *hdr;
1176 int i, v, n;
1177 char *c, *header, *pair[3];
1178 char *cookies[HTTP_MAX_COOKIES];
1179
1180 if (!http_request_header(req, "cookie", &hdr))
1181 return;
1182
1183 header = kore_strdup(hdr);
1184 v = kore_split_string(header, ";", cookies, HTTP_MAX_COOKIES);
1185 for (i = 0; i < v; i++) {
1186 for (c = cookies[i]; isspace(*(unsigned char *)c); c++)
1187 ;
1188
1189 n = kore_split_string(c, "=", pair, 3);
1190 if (n != 2)
1191 continue;
1192
1193 ck = kore_pool_get(&http_cookie_pool);
1194 ck->name = kore_strdup(pair[0]);
1195 ck->value = kore_strdup(pair[1]);
1196 TAILQ_INSERT_TAIL(&(req->req_cookies), ck, list);
1197 }
1198
1199 kore_free(header);
1200 }
1201
1202 void
1203 http_populate_post(struct http_request *req)
1204 {
1205 ssize_t ret;
1206 int i, v;
1207 struct kore_buf *body;
1208 char data[BUFSIZ];
1209 char *args[HTTP_MAX_QUERY_ARGS], *val[3], *string;
1210
1211 if (req->method != HTTP_METHOD_POST)
1212 return;
1213
1214 if (req->http_body != NULL) {
1215 body = NULL;
1216 req->http_body->offset = req->content_length;
1217 string = kore_buf_stringify(req->http_body, NULL);
1218 req->http_body_length = 0;
1219 req->http_body_offset = 0;
1220 } else {
1221 body = kore_buf_alloc(128);
1222 for (;;) {
1223 ret = http_body_read(req, data, sizeof(data));
1224 if (ret == -1)
1225 goto out;
1226 if (ret == 0)
1227 break;
1228 kore_buf_append(body, data, ret);
1229 }
1230 string = kore_buf_stringify(body, NULL);
1231 }
1232
1233 v = kore_split_string(string, "&", args, HTTP_MAX_QUERY_ARGS);
1234 for (i = 0; i < v; i++) {
1235 kore_split_string(args[i], "=", val, 3);
1236 if (val[0] != NULL && val[1] != NULL)
1237 http_argument_add(req, val[0], val[1], 0, 1);
1238 }
1239
1240 out:
1241 if (body != NULL)
1242 kore_buf_free(body);
1243 }
1244
1245 void
1246 http_populate_qs(struct http_request *req)
1247 {
1248 int i, v;
1249 char *query, *args[HTTP_MAX_QUERY_ARGS], *val[3];
1250
1251 if (req->query_string == NULL)
1252 return;
1253
1254 query = kore_strdup(req->query_string);
1255 v = kore_split_string(query, "&", args, HTTP_MAX_QUERY_ARGS);
1256 for (i = 0; i < v; i++) {
1257 kore_split_string(args[i], "=", val, 3);
1258 if (val[0] != NULL && val[1] != NULL)
1259 http_argument_add(req, val[0], val[1], 1, 1);
1260 }
1261
1262 kore_free(query);
1263 }
1264
1265 void
1266 http_populate_multipart_form(struct http_request *req)
1267 {
1268 const char *hdr;
1269 int h, blen;
1270 struct kore_buf in, out;
1271 char *type, *val, *args[3];
1272 char boundary[HTTP_BOUNDARY_MAX];
1273
1274 if (req->method != HTTP_METHOD_POST)
1275 return;
1276
1277 if (!http_request_header(req, "content-type", &hdr))
1278 return;
1279
1280 kore_buf_init(&in, 128);
1281 kore_buf_init(&out, 128);
1282
1283 type = kore_strdup(hdr);
1284 h = kore_split_string(type, ";", args, 3);
1285 if (h != 2)
1286 goto cleanup;
1287
1288 if (strcasecmp(args[0], "multipart/form-data"))
1289 goto cleanup;
1290
1291 if ((val = strchr(args[1], '=')) == NULL)
1292 goto cleanup;
1293
1294 val++;
1295 blen = snprintf(boundary, sizeof(boundary), "--%s", val);
1296 if (blen == -1 || (size_t)blen >= sizeof(boundary))
1297 goto cleanup;
1298
1299 if (!multipart_find_data(&in, NULL, NULL, req, boundary, blen))
1300 goto cleanup;
1301
1302 for (;;) {
1303 if (!multipart_find_data(&in, NULL, NULL, req, "\r\n", 2))
1304 break;
1305 if (in.offset < 4 && req->http_body_length == 0)
1306 break;
1307 if (!multipart_find_data(&in, &out, NULL, req, "\r\n\r\n", 4))
1308 break;
1309 if (!multipart_parse_headers(req, &in, &out, boundary, blen))
1310 break;
1311
1312 kore_buf_reset(&out);
1313 }
1314
1315 cleanup:
1316 kore_free(type);
1317 kore_buf_cleanup(&in);
1318 kore_buf_cleanup(&out);
1319 }
1320
1321 int
1322 http_body_rewind(struct http_request *req)
1323 {
1324 if (req->http_body_fd != -1) {
1325 if (lseek(req->http_body_fd, 0, SEEK_SET) == -1) {
1326 kore_log(LOG_ERR, "lseek(%s) failed: %s",
1327 req->http_body_path, errno_s);
1328 return (KORE_RESULT_ERROR);
1329 }
1330 } else if (req->http_body != NULL) {
1331 kore_buf_reset(req->http_body);
1332 }
1333
1334 req->http_body_offset = 0;
1335 req->http_body_length = req->content_length;
1336
1337 return (KORE_RESULT_OK);
1338 }
1339
1340 int
1341 http_body_digest(struct http_request *req, char *out, size_t len)
1342 {
1343 size_t idx;
1344 int slen;
1345
1346 if (len != HTTP_BODY_DIGEST_STRLEN) {
1347 fatal("http_body_digest: bad len:%zu wanted:%u",
1348 len, HTTP_BODY_DIGEST_STRLEN);
1349 }
1350
1351 if (!(req->flags & HTTP_REQUEST_COMPLETE))
1352 return (KORE_RESULT_ERROR);
1353
1354 for (idx = 0; idx < sizeof(req->http_body_digest); idx++) {
1355 slen = snprintf(out + (idx * 2), len - (idx * 2), "%02x",
1356 req->http_body_digest[idx]);
1357 if (slen == -1 || (size_t)slen >= len)
1358 fatal("failed to create hex string");
1359 }
1360
1361 return (KORE_RESULT_OK);
1362 }
1363
1364 ssize_t
1365 http_body_read(struct http_request *req, void *out, size_t len)
1366 {
1367 ssize_t ret;
1368 size_t toread;
1369
1370 toread = MIN(req->http_body_length, len);
1371 if (toread == 0)
1372 return (0);
1373
1374 if (req->http_body_fd != -1) {
1375 for (;;) {
1376 ret = read(req->http_body_fd, out, toread);
1377 if (ret == -1) {
1378 if (errno == EINTR)
1379 continue;
1380 kore_log(LOG_ERR, "failed to read %s: %s",
1381 req->http_body_path, errno_s);
1382 return (-1);
1383 }
1384 if (ret == 0)
1385 return (0);
1386 break;
1387 }
1388 } else if (req->http_body != NULL) {
1389 memcpy(out,
1390 (req->http_body->data + req->http_body->offset), toread);
1391 req->http_body->offset += toread;
1392 ret = toread;
1393 } else {
1394 kore_log(LOG_ERR, "http_body_read: called without body");
1395 return (-1);
1396 }
1397
1398 req->http_body_length -= (size_t)ret;
1399 req->http_body_offset += (size_t)ret;
1400
1401 return (ret);
1402 }
1403
1404 int
1405 http_state_run(struct http_state *states, u_int8_t elm,
1406 struct http_request *req)
1407 {
1408 int r, done;
1409
1410 done = 0;
1411
1412 while (!done) {
1413 if (req->fsm_state >= elm) {
1414 fatal("http_state_run: fsm_state > elm (%d/%d)",
1415 req->fsm_state, elm);
1416 }
1417
1418 r = states[req->fsm_state].cb(req);
1419 switch (r) {
1420 case HTTP_STATE_ERROR:
1421 return (KORE_RESULT_OK);
1422 case HTTP_STATE_RETRY:
1423 return (KORE_RESULT_RETRY);
1424 case HTTP_STATE_CONTINUE:
1425 break;
1426 case HTTP_STATE_COMPLETE:
1427 done = 1;
1428 break;
1429 default:
1430 fatal("http_state_run: unknown return value %d", r);
1431 }
1432 }
1433
1434 req->fsm_state = 0;
1435
1436 return (KORE_RESULT_OK);
1437 }
1438
1439 int
1440 http_state_exists(struct http_request *req)
1441 {
1442 return (req->hdlr_extra != NULL);
1443 }
1444
1445 void *
1446 http_state_create(struct http_request *req, size_t len)
1447 {
1448 if (req->hdlr_extra != NULL)
1449 fatal("http_state_create: state already exists");
1450
1451 req->state_len = len;
1452 req->hdlr_extra = kore_calloc(1, len);
1453
1454 return (req->hdlr_extra);
1455 }
1456
1457 void *
1458 http_state_get(struct http_request *req)
1459 {
1460 return (req->hdlr_extra);
1461 }
1462
1463 void
1464 http_state_cleanup(struct http_request *req)
1465 {
1466 kore_free(req->hdlr_extra);
1467 req->hdlr_extra = NULL;
1468 }
1469
1470 void
1471 http_start_recv(struct connection *c)
1472 {
1473 c->http_start = kore_time_ms();
1474 c->http_timeout = http_header_timeout * 1000;
1475 net_recv_reset(c, http_header_max, http_header_recv);
1476 }
1477
1478 void
1479 http_runlock_init(struct http_runlock *lock)
1480 {
1481 lock->owner = NULL;
1482 LIST_INIT(&lock->queue);
1483 }
1484
1485 int
1486 http_runlock_acquire(struct http_runlock *lock, struct http_request *req)
1487 {
1488 if (lock->owner != NULL) {
1489 if (req->runlock != NULL)
1490 fatal("%s: request already waiting on lock", __func__);
1491
1492 req->runlock = kore_pool_get(&http_rlq_pool);
1493 req->runlock->req = req;
1494 LIST_INSERT_HEAD(&lock->queue, req->runlock, list);
1495
1496 http_request_sleep(req);
1497 return (KORE_RESULT_ERROR);
1498 }
1499
1500 lock->owner = req;
1501
1502 return (KORE_RESULT_OK);
1503 }
1504
1505 void
1506 http_runlock_release(struct http_runlock *lock, struct http_request *req)
1507 {
1508 struct http_runlock_queue *next;
1509 struct http_request *nextreq;
1510
1511 if (lock->owner != req)
1512 fatal("%s: calling request != owner of runlock", __func__);
1513
1514 lock->owner = NULL;
1515
1516 if ((next = LIST_FIRST(&lock->queue)) != NULL) {
1517 LIST_REMOVE(next, list);
1518
1519 nextreq = next->req;
1520 nextreq->runlock = NULL;
1521
1522 http_request_wakeup(nextreq);
1523 kore_pool_put(&http_rlq_pool, next);
1524 }
1525 }
1526
1527 int
1528 http_redirect_add(struct kore_domain *dom, const char *path, int status,
1529 const char *target)
1530 {
1531 struct http_redirect *rdr;
1532
1533 rdr = kore_calloc(1, sizeof(*rdr));
1534
1535 if (regcomp(&(rdr->rctx), path, REG_EXTENDED)) {
1536 kore_free(rdr);
1537 return (KORE_RESULT_ERROR);
1538 }
1539
1540 rdr->status = status;
1541
1542 if (target != NULL)
1543 rdr->target = kore_strdup(target);
1544 else
1545 rdr->target = NULL;
1546
1547 TAILQ_INSERT_TAIL(&dom->redirects, rdr, list);
1548
1549 return (KORE_RESULT_OK);
1550 }
1551
1552 const char *
1553 http_status_text(int status)
1554 {
1555 const char *r;
1556
1557 switch (status) {
1558 case HTTP_STATUS_CONTINUE:
1559 r = "Continue";
1560 break;
1561 case HTTP_STATUS_SWITCHING_PROTOCOLS:
1562 r = "Switching Protocols";
1563 break;
1564 case HTTP_STATUS_OK:
1565 r = "OK";
1566 break;
1567 case HTTP_STATUS_CREATED:
1568 r = "Created";
1569 break;
1570 case HTTP_STATUS_ACCEPTED:
1571 r = "Accepted";
1572 break;
1573 case HTTP_STATUS_NON_AUTHORITATIVE:
1574 r = "Non-Authoritative Information";
1575 break;
1576 case HTTP_STATUS_NO_CONTENT:
1577 r = "No Content";
1578 break;
1579 case HTTP_STATUS_RESET_CONTENT:
1580 r = "Reset Content";
1581 break;
1582 case HTTP_STATUS_PARTIAL_CONTENT:
1583 r = "Partial Content";
1584 break;
1585 case HTTP_STATUS_MULTIPLE_CHOICES:
1586 r = "Multiple Choices";
1587 break;
1588 case HTTP_STATUS_MOVED_PERMANENTLY:
1589 r = "Moved Permanently";
1590 break;
1591 case HTTP_STATUS_FOUND:
1592 r = "Found";
1593 break;
1594 case HTTP_STATUS_SEE_OTHER:
1595 r = "See Other";
1596 break;
1597 case HTTP_STATUS_NOT_MODIFIED:
1598 r = "Not Modified";
1599 break;
1600 case HTTP_STATUS_USE_PROXY:
1601 r = "Use Proxy";
1602 break;
1603 case HTTP_STATUS_TEMPORARY_REDIRECT:
1604 r = "Temporary Redirect";
1605 break;
1606 case HTTP_STATUS_BAD_REQUEST:
1607 r = "Bad Request";
1608 break;
1609 case HTTP_STATUS_UNAUTHORIZED:
1610 r = "Unauthorized";
1611 break;
1612 case HTTP_STATUS_PAYMENT_REQUIRED:
1613 r = "Payment Required";
1614 break;
1615 case HTTP_STATUS_FORBIDDEN:
1616 r = "Forbidden";
1617 break;
1618 case HTTP_STATUS_NOT_FOUND:
1619 r = "Not Found";
1620 break;
1621 case HTTP_STATUS_METHOD_NOT_ALLOWED:
1622 r = "Method Not Allowed";
1623 break;
1624 case HTTP_STATUS_NOT_ACCEPTABLE:
1625 r = "Not Acceptable";
1626 break;
1627 case HTTP_STATUS_PROXY_AUTH_REQUIRED:
1628 r = "Proxy Authentication Required";
1629 break;
1630 case HTTP_STATUS_REQUEST_TIMEOUT:
1631 r = "Request Time-out";
1632 break;
1633 case HTTP_STATUS_CONFLICT:
1634 r = "Conflict";
1635 break;
1636 case HTTP_STATUS_GONE:
1637 r = "Gone";
1638 break;
1639 case HTTP_STATUS_LENGTH_REQUIRED:
1640 r = "Length Required";
1641 break;
1642 case HTTP_STATUS_PRECONDITION_FAILED:
1643 r = "Precondition Failed";
1644 break;
1645 case HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE:
1646 r = "Request Entity Too Large";
1647 break;
1648 case HTTP_STATUS_REQUEST_URI_TOO_LARGE:
1649 r = "Request-URI Too Large";
1650 break;
1651 case HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE:
1652 r = "Unsupported Media Type";
1653 break;
1654 case HTTP_STATUS_REQUEST_RANGE_INVALID:
1655 r = "Requested range not satisfiable";
1656 break;
1657 case HTTP_STATUS_EXPECTATION_FAILED:
1658 r = "Expectation Failed";
1659 break;
1660 case HTTP_STATUS_MISDIRECTED_REQUEST:
1661 r = "Misdirected Request";
1662 break;
1663 case HTTP_STATUS_INTERNAL_ERROR:
1664 r = "Internal Server Error";
1665 break;
1666 case HTTP_STATUS_NOT_IMPLEMENTED:
1667 r = "Not Implemented";
1668 break;
1669 case HTTP_STATUS_BAD_GATEWAY:
1670 r = "Bad Gateway";
1671 break;
1672 case HTTP_STATUS_SERVICE_UNAVAILABLE:
1673 r = "Service Unavailable";
1674 break;
1675 case HTTP_STATUS_GATEWAY_TIMEOUT:
1676 r = "Gateway Time-out";
1677 break;
1678 case HTTP_STATUS_BAD_VERSION:
1679 r = "HTTP Version not supported";
1680 break;
1681 default:
1682 r = "";
1683 break;
1684 }
1685
1686 return (r);
1687 }
1688
1689 const char *
1690 http_method_text(int method)
1691 {
1692 char *r;
1693
1694 switch(method) {
1695 case HTTP_METHOD_GET:
1696 r = "GET";
1697 break;
1698 case HTTP_METHOD_POST:
1699 r = "POST";
1700 break;
1701 case HTTP_METHOD_PUT:
1702 r = "PUT";
1703 break;
1704 case HTTP_METHOD_DELETE:
1705 r = "DELETE";
1706 break;
1707 case HTTP_METHOD_HEAD:
1708 r = "HEAD";
1709 break;
1710 case HTTP_METHOD_OPTIONS:
1711 r = "OPTIONS";
1712 break;
1713 case HTTP_METHOD_PATCH:
1714 r = "PATCH";
1715 break;
1716 default:
1717 r = "";
1718 break;
1719 }
1720
1721 return (r);
1722 }
1723
1724 int
1725 http_method_value(const char *method)
1726 {
1727 if (!strcasecmp(method, "GET"))
1728 return (HTTP_METHOD_GET);
1729
1730 if (!strcasecmp(method, "POST"))
1731 return (HTTP_METHOD_POST);
1732
1733 if (!strcasecmp(method, "PUT"))
1734 return (HTTP_METHOD_PUT);
1735
1736 if (!strcasecmp(method, "DELETE"))
1737 return (HTTP_METHOD_DELETE);
1738
1739 if (!strcasecmp(method, "HEAD"))
1740 return (HTTP_METHOD_HEAD);
1741
1742 if (!strcasecmp(method, "OPTIONS"))
1743 return (HTTP_METHOD_OPTIONS);
1744
1745 if (!strcasecmp(method, "PATCH"))
1746 return (HTTP_METHOD_PATCH);
1747
1748 return (0);
1749 }
1750
1751 int
1752 http_media_register(const char *ext, const char *type)
1753 {
1754 struct http_media_type *media;
1755
1756 LIST_FOREACH(media, &http_media_types, list) {
1757 if (!strcasecmp(media->ext, ext))
1758 return (KORE_RESULT_ERROR);
1759 }
1760
1761 media = kore_calloc(1, sizeof(*media));
1762 media->ext = kore_strdup(ext);
1763 media->type = kore_strdup(type);
1764
1765 LIST_INSERT_HEAD(&http_media_types, media, list);
1766
1767 return (KORE_RESULT_OK);
1768 }
1769
1770 const char *
1771 http_media_type(const char *path)
1772 {
1773 const char *p;
1774 struct http_media_type *media;
1775
1776 if ((p = strrchr(path, '.')) == NULL)
1777 return (NULL);
1778
1779 p++;
1780 if (*p == '\0')
1781 return (NULL);
1782
1783 LIST_FOREACH(media, &http_media_types, list) {
1784 if (!strcasecmp(media->ext, p))
1785 return (media->type);
1786 }
1787
1788 return (NULL);
1789 }
1790
1791 char *
1792 http_validate_header(char *header)
1793 {
1794 u_int8_t idx;
1795 char *p, *value;
1796
1797 for (p = header; *p != '\0'; p++) {
1798 idx = *p;
1799 if (idx > HTTP_MAP_LIMIT)
1800 return (NULL);
1801
1802 if (*p == ':') {
1803 *(p)++ = '\0';
1804 break;
1805 }
1806
1807 if (*p >= 'A' && *p <= 'Z')
1808 *p += 32;
1809
1810 if (http_token[idx] == 0x00)
1811 return (NULL);
1812 }
1813
1814 while (isspace(*(unsigned char *)p))
1815 p++;
1816
1817 if (*p == '\0')
1818 return (NULL);
1819
1820 value = p;
1821 while (*p != '\0') {
1822 idx = *p;
1823 if (idx > HTTP_MAP_LIMIT)
1824 return (NULL);
1825 if (http_field_content[idx] == 0x00)
1826 return (NULL);
1827 p++;
1828 }
1829
1830 return (value);
1831 }
1832
1833 static int
1834 http_release_buffer(struct netbuf *nb)
1835 {
1836 kore_buf_free(nb->extra);
1837
1838 return (KORE_RESULT_OK);
1839 }
1840
1841 static int
1842 http_check_redirect(struct http_request *req, struct kore_domain *dom)
1843 {
1844 int idx;
1845 struct http_redirect *rdr;
1846 const char *uri;
1847 char key[4];
1848 struct kore_buf location;
1849
1850 TAILQ_FOREACH(rdr, &dom->redirects, list) {
1851 if (!regexec(&(rdr->rctx), req->path,
1852 HTTP_CAPTURE_GROUPS, req->cgroups, 0))
1853 break;
1854 }
1855
1856 if (rdr == NULL)
1857 return (KORE_RESULT_ERROR);
1858
1859 uri = NULL;
1860 kore_buf_init(&location, 128);
1861
1862 if (rdr->target) {
1863 kore_buf_appendf(&location, "%s", rdr->target);
1864
1865 if (req->query_string != NULL) {
1866 kore_buf_replace_string(&location, "$qs",
1867 req->query_string, strlen(req->query_string));
1868 }
1869
1870 /* Starts at 1 to skip the full path. */
1871 for (idx = 1; idx < HTTP_CAPTURE_GROUPS - 1; idx++) {
1872 if (req->cgroups[idx].rm_so == -1 ||
1873 req->cgroups[idx].rm_eo == -1)
1874 break;
1875
1876 (void)snprintf(key, sizeof(key), "$%d", idx);
1877
1878 kore_buf_replace_string(&location, key,
1879 req->path + req->cgroups[idx].rm_so,
1880 req->cgroups[idx].rm_eo - req->cgroups[idx].rm_so);
1881 }
1882
1883 uri = kore_buf_stringify(&location, NULL);
1884 }
1885
1886 if (uri)
1887 http_response_header(req, "location", uri);
1888
1889 http_response(req, rdr->status, NULL, 0);
1890 kore_buf_cleanup(&location);
1891
1892 if (dom->accesslog)
1893 kore_accesslog(req);
1894
1895 return (KORE_RESULT_OK);
1896 }
1897
1898 static struct http_request *
1899 http_request_new(struct connection *c, const char *host,
1900 const char *method, char *path, const char *version)
1901 {
1902 struct kore_domain *dom;
1903 struct http_request *req;
1904 size_t qsoff;
1905 char *p, *hp;
1906 int m, flags, exists;
1907
1908 if (http_request_count >= http_request_limit) {
1909 http_error_response(c, HTTP_STATUS_SERVICE_UNAVAILABLE);
1910 return (NULL);
1911 }
1912
1913 if (strlen(host) >= KORE_DOMAINNAME_LEN - 1) {
1914 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
1915 return (NULL);
1916 }
1917
1918 if (strlen(path) >= HTTP_URI_LEN - 1) {
1919 http_error_response(c, HTTP_STATUS_REQUEST_URI_TOO_LARGE);
1920 return (NULL);
1921 }
1922
1923 if (strcasecmp(version, "http/1.1")) {
1924 if (strcasecmp(version, "http/1.0")) {
1925 http_error_response(c, HTTP_STATUS_BAD_VERSION);
1926 return (NULL);
1927 }
1928
1929 flags = HTTP_VERSION_1_0;
1930 } else {
1931 flags = HTTP_VERSION_1_1;
1932 }
1933
1934 if ((p = strchr(path, '?')) != NULL) {
1935 qsoff = p - path;
1936 } else {
1937 qsoff = 0;
1938 }
1939
1940 hp = NULL;
1941
1942 switch (c->family) {
1943 case AF_INET6:
1944 if (*host == '[') {
1945 if ((hp = strrchr(host, ']')) == NULL) {
1946 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
1947 return (NULL);
1948 }
1949 hp++;
1950 if (*hp == ':')
1951 *hp = '\0';
1952 else
1953 hp = NULL;
1954 }
1955 break;
1956 default:
1957 if ((hp = strrchr(host, ':')) != NULL)
1958 *hp = '\0';
1959 break;
1960 }
1961
1962 if (c->owner->server->tls && c->tls_sni != NULL) {
1963 if (strcasecmp(c->tls_sni, host)) {
1964 http_error_response(c, HTTP_STATUS_MISDIRECTED_REQUEST);
1965 return (NULL);
1966 }
1967 }
1968
1969 if ((dom = kore_domain_lookup(c->owner->server, host)) == NULL) {
1970 http_error_response(c, HTTP_STATUS_NOT_FOUND);
1971 return (NULL);
1972 }
1973
1974 if (dom->cafile != NULL && c->tls_cert == NULL) {
1975 http_error_response(c, HTTP_STATUS_FORBIDDEN);
1976 return (NULL);
1977 }
1978
1979 if (hp != NULL)
1980 *hp = ':';
1981
1982 if (!strcasecmp(method, "get")) {
1983 m = HTTP_METHOD_GET;
1984 flags |= HTTP_REQUEST_COMPLETE;
1985 } else if (!strcasecmp(method, "delete")) {
1986 m = HTTP_METHOD_DELETE;
1987 flags |= HTTP_REQUEST_EXPECT_BODY;
1988 } else if (!strcasecmp(method, "post")) {
1989 m = HTTP_METHOD_POST;
1990 flags |= HTTP_REQUEST_EXPECT_BODY;
1991 } else if (!strcasecmp(method, "put")) {
1992 m = HTTP_METHOD_PUT;
1993 flags |= HTTP_REQUEST_EXPECT_BODY;
1994 } else if (!strcasecmp(method, "head")) {
1995 m = HTTP_METHOD_HEAD;
1996 flags |= HTTP_REQUEST_COMPLETE;
1997 } else if (!strcasecmp(method, "options")) {
1998 m = HTTP_METHOD_OPTIONS;
1999 flags |= HTTP_REQUEST_COMPLETE;
2000 } else if (!strcasecmp(method, "patch")) {
2001 m = HTTP_METHOD_PATCH;
2002 flags |= HTTP_REQUEST_EXPECT_BODY;
2003 } else {
2004 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
2005 return (NULL);
2006 }
2007
2008 if (flags & HTTP_VERSION_1_0) {
2009 if (m != HTTP_METHOD_GET && m != HTTP_METHOD_POST &&
2010 m != HTTP_METHOD_HEAD) {
2011 http_error_response(c, HTTP_STATUS_METHOD_NOT_ALLOWED);
2012 return (NULL);
2013 }
2014 }
2015
2016 req = kore_pool_get(&http_request_pool);
2017
2018 req->end = 0;
2019 req->total = 0;
2020 req->start = 0;
2021 req->owner = c;
2022 req->status = 0;
2023 req->method = m;
2024 req->agent = NULL;
2025 req->referer = NULL;
2026 req->runlock = NULL;
2027 req->flags = flags;
2028 req->fsm_state = 0;
2029 req->http_body = NULL;
2030 req->http_body_fd = -1;
2031 req->hdlr_extra = NULL;
2032 req->content_length = 0;
2033 req->query_string = NULL;
2034 req->http_body_length = 0;
2035 req->http_body_offset = 0;
2036 req->http_body_path = NULL;
2037
2038 req->host = host;
2039 req->path = path;
2040
2041 #if defined(KORE_USE_PYTHON)
2042 req->py_req = NULL;
2043 req->py_coro = NULL;
2044 req->py_rqnext = NULL;
2045 req->py_validator = NULL;
2046 #endif
2047
2048 if (qsoff > 0) {
2049 req->query_string = path + qsoff;
2050 *(req->query_string)++ = '\0';
2051 } else {
2052 req->query_string = NULL;
2053 }
2054
2055 /* Checked further down below if we need to 404. */
2056 exists = kore_route_lookup(req, dom, m, &req->rt);
2057
2058 TAILQ_INIT(&(req->resp_headers));
2059 TAILQ_INIT(&(req->req_headers));
2060 TAILQ_INIT(&(req->resp_cookies));
2061 TAILQ_INIT(&(req->req_cookies));
2062 TAILQ_INIT(&(req->arguments));
2063 TAILQ_INIT(&(req->files));
2064
2065 #if defined(KORE_USE_TASKS)
2066 LIST_INIT(&(req->tasks));
2067 #endif
2068
2069 #if defined(KORE_USE_PGSQL)
2070 LIST_INIT(&(req->pgsqls));
2071 #endif
2072
2073 http_request_count++;
2074 TAILQ_INSERT_HEAD(&http_requests, req, list);
2075 TAILQ_INSERT_TAIL(&(c->http_requests), req, olist);
2076
2077 if (http_check_redirect(req, dom)) {
2078 http_request_free(req);
2079 return (NULL);
2080 }
2081
2082 if (exists == 0) {
2083 http_request_free(req);
2084 http_error_response(c, HTTP_STATUS_NOT_FOUND);
2085 return (NULL);
2086 }
2087
2088 if (req->rt == NULL) {
2089 http_request_free(req);
2090 http_error_response(c, HTTP_STATUS_METHOD_NOT_ALLOWED);
2091 return (NULL);
2092 }
2093
2094 return (req);
2095 }
2096
2097 static int
2098 multipart_find_data(struct kore_buf *in, struct kore_buf *out,
2099 size_t *olen, struct http_request *req, const void *needle, size_t len)
2100 {
2101 ssize_t ret;
2102 size_t left;
2103 u_int8_t *p, first, data[4096];
2104
2105 if (olen != NULL)
2106 *olen = 0;
2107
2108 first = *(const u_int8_t *)needle;
2109 for (;;) {
2110 if (in->offset < len) {
2111 ret = http_body_read(req, data, sizeof(data));
2112 if (ret == -1)
2113 return (KORE_RESULT_ERROR);
2114 if (ret == 0)
2115 return (KORE_RESULT_ERROR);
2116
2117 kore_buf_append(in, data, ret);
2118 continue;
2119 }
2120
2121 p = kore_mem_find(in->data, in->offset, &first, 1);
2122 if (p == NULL) {
2123 if (out != NULL)
2124 kore_buf_append(out, in->data, in->offset);
2125 if (olen != NULL)
2126 *olen += in->offset;
2127 kore_buf_reset(in);
2128 continue;
2129 }
2130
2131 left = in->offset - (p - in->data);
2132 if (left < len) {
2133 if (out != NULL)
2134 kore_buf_append(out, in->data, (p - in->data));
2135 if (olen != NULL)
2136 *olen += (p - in->data);
2137 memmove(in->data, p, left);
2138 in->offset = left;
2139 continue;
2140 }
2141
2142 if (!memcmp(p, needle, len)) {
2143 if (out != NULL)
2144 kore_buf_append(out, in->data, p - in->data);
2145 if (olen != NULL)
2146 *olen += (p - in->data);
2147
2148 in->offset = left - len;
2149 if (in->offset > 0)
2150 memmove(in->data, p + len, in->offset);
2151 return (KORE_RESULT_OK);
2152 }
2153
2154 if (out != NULL)
2155 kore_buf_append(out, in->data, (p - in->data) + 1);
2156 if (olen != NULL)
2157 *olen += (p - in->data) + 1;
2158
2159 in->offset = left - 1;
2160 if (in->offset > 0)
2161 memmove(in->data, p + 1, in->offset);
2162 }
2163
2164 return (KORE_RESULT_ERROR);
2165 }
2166
2167 static int
2168 multipart_parse_headers(struct http_request *req, struct kore_buf *in,
2169 struct kore_buf *hbuf, const char *boundary, const int blen)
2170 {
2171 int h, c, i;
2172 char *headers[5], *args[5], *opt[5];
2173 char *d, *val, *name, *fname, *string;
2174
2175 string = kore_buf_stringify(hbuf, NULL);
2176 h = kore_split_string(string, "\r\n", headers, 5);
2177 for (i = 0; i < h; i++) {
2178 c = kore_split_string(headers[i], ":", args, 5);
2179 if (c != 2)
2180 continue;
2181
2182 /* Ignore other headers for now. */
2183 if (strcasecmp(args[0], "content-disposition"))
2184 continue;
2185
2186 for (d = args[1]; isspace(*(unsigned char *)d); d++)
2187 ;
2188
2189 c = kore_split_string(d, ";", opt, 5);
2190 if (c < 2)
2191 continue;
2192
2193 if (strcasecmp(opt[0], "form-data"))
2194 continue;
2195
2196 if ((val = strchr(opt[1], '=')) == NULL)
2197 continue;
2198 if (strlen(val) < 3)
2199 continue;
2200
2201 val++;
2202 kore_strip_chars(val, '"', &name);
2203
2204 if (opt[2] == NULL) {
2205 multipart_add_field(req, in, name, boundary, blen);
2206 kore_free(name);
2207 continue;
2208 }
2209
2210 for (d = opt[2]; isspace(*(unsigned char *)d); d++)
2211 ;
2212
2213 if (!strncasecmp(d, "filename=", 9)) {
2214 if ((val = strchr(d, '=')) == NULL) {
2215 kore_free(name);
2216 continue;
2217 }
2218
2219 val++;
2220 kore_strip_chars(val, '"', &fname);
2221 if (strlen(fname) > 0) {
2222 multipart_file_add(req,
2223 in, name, fname, boundary, blen);
2224 }
2225 kore_free(fname);
2226 }
2227
2228 kore_free(name);
2229 }
2230
2231 return (KORE_RESULT_OK);
2232 }
2233
2234 static void
2235 multipart_add_field(struct http_request *req, struct kore_buf *in,
2236 char *name, const char *boundary, const int blen)
2237 {
2238 struct kore_buf *data;
2239 char *string;
2240
2241 data = kore_buf_alloc(128);
2242
2243 if (!multipart_find_data(in, data, NULL, req, boundary, blen)) {
2244 kore_buf_free(data);
2245 return;
2246 }
2247
2248 if (data->offset < 3) {
2249 kore_buf_free(data);
2250 return;
2251 }
2252
2253 data->offset -= 2;
2254 string = kore_buf_stringify(data, NULL);
2255 http_argument_add(req, name, string, 0, 0);
2256 kore_buf_free(data);
2257 }
2258
2259 static void
2260 multipart_file_add(struct http_request *req, struct kore_buf *in,
2261 const char *name, const char *fname, const char *boundary, const int blen)
2262 {
2263 struct http_file *f;
2264 size_t position, len;
2265
2266 position = req->http_body_offset - in->offset;
2267 if (!multipart_find_data(in, NULL, &len, req, boundary, blen))
2268 return;
2269
2270 if (len < 3)
2271 return;
2272 len -= 2;
2273
2274 f = kore_malloc(sizeof(struct http_file));
2275 f->req = req;
2276 f->offset = 0;
2277 f->length = len;
2278 f->position = position;
2279 f->name = kore_strdup(name);
2280 f->filename = kore_strdup(fname);
2281
2282 TAILQ_INSERT_TAIL(&(req->files), f, list);
2283 }
2284
2285 static void
2286 http_argument_add(struct http_request *req, char *name, char *value, int qs,
2287 int decode)
2288 {
2289 struct http_arg *q;
2290 struct kore_route_params *p;
2291
2292 if (decode) {
2293 if (!http_argument_urldecode(name, qs))
2294 return;
2295 }
2296
2297 TAILQ_FOREACH(p, &req->rt->params, list) {
2298 if (qs == 1 && !(p->flags & KORE_PARAMS_QUERY_STRING))
2299 continue;
2300 if (qs == 0 && (p->flags & KORE_PARAMS_QUERY_STRING))
2301 continue;
2302
2303 if (p->method != req->method)
2304 continue;
2305
2306 if (strcmp(p->name, name))
2307 continue;
2308
2309 if (decode) {
2310 if (!http_argument_urldecode(value, qs))
2311 return;
2312 }
2313
2314 if (!kore_validator_check(req, p->validator, value))
2315 break;
2316
2317 q = kore_malloc(sizeof(struct http_arg));
2318 q->name = kore_strdup(name);
2319 q->s_value = kore_strdup(value);
2320 TAILQ_INSERT_TAIL(&(req->arguments), q, list);
2321 break;
2322 }
2323 }
2324
2325 static int
2326 http_body_recv(struct netbuf *nb)
2327 {
2328 struct http_request *req = (struct http_request *)nb->extra;
2329
2330 return (http_body_update(req, nb->buf, nb->s_off));
2331 }
2332
2333 static int
2334 http_body_update(struct http_request *req, const void *data, size_t len)
2335 {
2336 ssize_t ret;
2337 u_int64_t bytes_left;
2338
2339 SHA256Update(&req->hashctx, data, len);
2340
2341 if (req->http_body_fd != -1) {
2342 ret = write(req->http_body_fd, data, len);
2343 if (ret == -1 || (size_t)ret != len) {
2344 req->flags |= HTTP_REQUEST_DELETE;
2345 http_error_response(req->owner,
2346 HTTP_STATUS_INTERNAL_ERROR);
2347 return (KORE_RESULT_ERROR);
2348 }
2349 } else if (req->http_body != NULL) {
2350 kore_buf_append(req->http_body, data, len);
2351 } else {
2352 req->flags |= HTTP_REQUEST_DELETE;
2353 http_error_response(req->owner,
2354 HTTP_STATUS_INTERNAL_ERROR);
2355 return (KORE_RESULT_ERROR);
2356 }
2357
2358 req->content_length -= len;
2359
2360 if (req->content_length == 0) {
2361 req->owner->http_timeout = 0;
2362 req->owner->rnb->extra = NULL;
2363 http_request_wakeup(req);
2364 req->flags |= HTTP_REQUEST_COMPLETE;
2365 req->flags &= ~HTTP_REQUEST_EXPECT_BODY;
2366 req->content_length = req->http_body_length;
2367 if (!http_body_rewind(req)) {
2368 req->flags |= HTTP_REQUEST_DELETE;
2369 http_error_response(req->owner,
2370 HTTP_STATUS_INTERNAL_ERROR);
2371 return (KORE_RESULT_ERROR);
2372 }
2373 SHA256Final(req->http_body_digest, &req->hashctx);
2374 } else {
2375 bytes_left = req->content_length;
2376 net_recv_reset(req->owner,
2377 MIN(bytes_left, NETBUF_SEND_PAYLOAD_MAX),
2378 http_body_recv);
2379 req->owner->rnb->extra = req;
2380 }
2381
2382 if (req->rt->on_body_chunk != NULL && len > 0) {
2383 kore_runtime_http_body_chunk(req->rt->on_body_chunk,
2384 req, data, len);
2385 }
2386
2387 return (KORE_RESULT_OK);
2388 }
2389
2390 static void
2391 http_error_response(struct connection *c, int status)
2392 {
2393 c->flags |= CONN_CLOSE_EMPTY;
2394
2395 switch (c->proto) {
2396 case CONN_PROTO_HTTP:
2397 http_response_normal(NULL, c, status, NULL, 0);
2398 break;
2399 default:
2400 fatal("http_error_response() bad proto %d", c->proto);
2401 /* NOTREACHED. */
2402 }
2403
2404 if (!net_send_flush(c))
2405 kore_connection_disconnect(c);
2406 }
2407
2408 static void
2409 http_response_normal(struct http_request *req, struct connection *c,
2410 int status, const void *d, size_t len)
2411 {
2412 struct kore_buf buf;
2413 struct http_cookie *ck;
2414 struct http_header *hdr;
2415 char version;
2416 const char *conn, *text;
2417 int connection_close, send_body;
2418
2419 send_body = 1;
2420 text = http_status_text(status);
2421
2422 kore_buf_reset(header_buf);
2423
2424 if (req != NULL) {
2425 if (req->flags & HTTP_VERSION_1_0)
2426 version = '0';
2427 else
2428 version = '1';
2429 } else {
2430 version = '1';
2431 }
2432
2433 kore_buf_appendf(header_buf, "HTTP/1.%c %d %s\r\n",
2434 version, status, text);
2435
2436 if (status == 100) {
2437 kore_buf_append(header_buf, "\r\n", 2);
2438 net_send_queue(c, header_buf->data, header_buf->offset);
2439 return;
2440 }
2441
2442 kore_buf_append(header_buf, http_version, http_version_len);
2443
2444 if ((c->flags & CONN_CLOSE_EMPTY) ||
2445 (req != NULL && (req->flags & HTTP_VERSION_1_0))) {
2446 connection_close = 1;
2447 } else {
2448 connection_close = 0;
2449 }
2450
2451 if (connection_close == 0 && req != NULL) {
2452 if (http_request_header(req, "connection", &conn)) {
2453 if ((*conn == 'c' || *conn == 'C') &&
2454 !strcasecmp(conn, "close")) {
2455 connection_close = 1;
2456 }
2457 }
2458 }
2459
2460 kore_buf_init(&buf, 1024);
2461
2462 /* Note that req CAN be NULL. */
2463 if (req == NULL || req->owner->proto != CONN_PROTO_WEBSOCKET) {
2464 if (http_keepalive_time && connection_close == 0) {
2465 kore_buf_appendf(header_buf,
2466 "connection: keep-alive\r\n");
2467 kore_buf_appendf(header_buf,
2468 "keep-alive: timeout=%d\r\n", http_keepalive_time);
2469 } else {
2470 c->flags |= CONN_CLOSE_EMPTY;
2471 kore_buf_appendf(header_buf, "connection: close\r\n");
2472 }
2473 }
2474
2475 if (c->tls && http_hsts_enable) {
2476 kore_buf_appendf(header_buf, "strict-transport-security: ");
2477 kore_buf_appendf(header_buf,
2478 "max-age=%" PRIu64 "; includeSubDomains\r\n",
2479 http_hsts_enable);
2480 }
2481
2482 if (http_pretty_error && d == NULL && status >= 400) {
2483 kore_buf_appendf(&buf, pretty_error_fmt,
2484 status, text, status, text);
2485
2486 d = buf.data;
2487 len = buf.offset;
2488 }
2489
2490 if (req != NULL) {
2491 TAILQ_FOREACH(ck, &(req->resp_cookies), list)
2492 http_write_response_cookie(ck);
2493
2494 TAILQ_FOREACH(hdr, &(req->resp_headers), list) {
2495 kore_buf_appendf(header_buf, "%s: %s\r\n",
2496 hdr->header, hdr->value);
2497 }
2498
2499 if (status != 204 && status >= 200 &&
2500 !(req->flags & HTTP_REQUEST_NO_CONTENT_LENGTH)) {
2501 kore_buf_appendf(header_buf,
2502 "content-length: %zu\r\n", len);
2503 }
2504 } else {
2505 if (status != 204 && status >= 200) {
2506 kore_buf_appendf(header_buf,
2507 "content-length: %zu\r\n", len);
2508 }
2509 }
2510
2511 kore_buf_append(header_buf, "\r\n", 2);
2512 net_send_queue(c, header_buf->data, header_buf->offset);
2513
2514 if (req != NULL && req->method == HTTP_METHOD_HEAD)
2515 send_body = 0;
2516
2517 if (d != NULL && send_body)
2518 net_send_queue(c, d, len);
2519
2520 if (!(c->flags & CONN_CLOSE_EMPTY) && !(c->flags & CONN_IS_BUSY))
2521 http_start_recv(c);
2522
2523 if (req != NULL)
2524 req->content_length = len;
2525
2526 kore_buf_cleanup(&buf);
2527 }
2528
2529 static void
2530 http_write_response_cookie(struct http_cookie *ck)
2531 {
2532 struct tm tm;
2533 char expires[HTTP_DATE_MAXSIZE];
2534
2535 kore_buf_reset(ckhdr_buf);
2536 kore_buf_appendf(ckhdr_buf, "%s=%s", ck->name, ck->value);
2537
2538 if (ck->path != NULL)
2539 kore_buf_appendf(ckhdr_buf, "; Path=%s", ck->path);
2540 if (ck->domain != NULL)
2541 kore_buf_appendf(ckhdr_buf, "; Domain=%s", ck->domain);
2542
2543 if (ck->expires > 0) {
2544 if (gmtime_r(&ck->expires, &tm) == NULL) {
2545 kore_log(LOG_ERR, "gmtime_r(): %s", errno_s);
2546 return;
2547 }
2548
2549 if (strftime(expires, sizeof(expires),
2550 "%a, %d %b %y %H:%M:%S GMT", &tm) == 0) {
2551 kore_log(LOG_ERR, "strftime(): %s", errno_s);
2552 return;
2553 }
2554
2555 kore_buf_appendf(ckhdr_buf, "; Expires=%s", expires);
2556 }
2557
2558 if (ck->maxage > 0)
2559 kore_buf_appendf(ckhdr_buf, "; Max-Age=%u", ck->maxage);
2560
2561 if (ck->flags & HTTP_COOKIE_HTTPONLY)
2562 kore_buf_appendf(ckhdr_buf, "; HttpOnly");
2563 if (ck->flags & HTTP_COOKIE_SECURE)
2564 kore_buf_appendf(ckhdr_buf, "; Secure");
2565
2566 kore_buf_appendf(header_buf, "set-cookie: %s\r\n",
2567 kore_buf_stringify(ckhdr_buf, NULL));
2568 }
2569
2570 static int
2571 http_data_convert(void *data, void **out, void *nout, int type)
2572 {
2573 switch (type) {
2574 case HTTP_ARG_TYPE_RAW:
2575 case HTTP_ARG_TYPE_STRING:
2576 *out = data;
2577 return (KORE_RESULT_OK);
2578 case HTTP_ARG_TYPE_BYTE:
2579 COPY_ARG_TYPE(*(u_int8_t *)data, u_int8_t);
2580 return (KORE_RESULT_OK);
2581 case HTTP_ARG_TYPE_INT16:
2582 COPY_AS_INTTYPE(SHRT_MIN, SHRT_MAX, int16_t);
2583 return (KORE_RESULT_OK);
2584 case HTTP_ARG_TYPE_UINT16:
2585 COPY_AS_INTTYPE(0, USHRT_MAX, u_int16_t);
2586 return (KORE_RESULT_OK);
2587 case HTTP_ARG_TYPE_INT32:
2588 COPY_AS_INTTYPE(INT_MIN, INT_MAX, int32_t);
2589 return (KORE_RESULT_OK);
2590 case HTTP_ARG_TYPE_UINT32:
2591 COPY_AS_INTTYPE(0, UINT_MAX, u_int32_t);
2592 return (KORE_RESULT_OK);
2593 case HTTP_ARG_TYPE_INT64:
2594 COPY_AS_INTTYPE_64(int64_t, 1);
2595 return (KORE_RESULT_OK);
2596 case HTTP_ARG_TYPE_UINT64:
2597 COPY_AS_INTTYPE_64(u_int64_t, 0);
2598 return (KORE_RESULT_OK);
2599 case HTTP_ARG_TYPE_FLOAT:
2600 COPY_ARG_DOUBLE(-FLT_MAX, FLT_MAX, float);
2601 return (KORE_RESULT_OK);
2602 case HTTP_ARG_TYPE_DOUBLE:
2603 COPY_ARG_DOUBLE(-DBL_MAX, DBL_MAX, double);
2604 return (KORE_RESULT_OK);
2605 default:
2606 break;
2607 }
2608
2609 return (KORE_RESULT_ERROR);
2610 }