http.c (59817B)
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 (req->rt->on_body_chunk == NULL &&
944 http_body_disk_offload > 0 &&
945 req->content_length > http_body_disk_offload) {
946 req->http_body_path = kore_pool_get(&http_body_path);
947 l = snprintf(req->http_body_path, HTTP_BODY_PATH_MAX,
948 "%s/http_body.XXXXXX", http_body_disk_path);
949 if (l == -1 || (size_t)l >= HTTP_BODY_PATH_MAX) {
950 req->flags |= HTTP_REQUEST_DELETE;
951 http_error_response(req->owner,
952 HTTP_STATUS_INTERNAL_ERROR);
953 return (KORE_RESULT_ERROR);
954 }
955
956 req->http_body = NULL;
957 req->http_body_fd = mkstemp(req->http_body_path);
958 if (req->http_body_fd == -1) {
959 req->flags |= HTTP_REQUEST_DELETE;
960 http_error_response(req->owner,
961 HTTP_STATUS_INTERNAL_ERROR);
962 return (KORE_RESULT_OK);
963 }
964 } else if (req->rt->on_body_chunk == NULL) {
965 req->http_body_fd = -1;
966 req->http_body = kore_buf_alloc(req->content_length);
967 }
968
969 SHA256Init(&req->hashctx);
970 c->http_timeout = http_body_timeout * 1000;
971
972 if (!http_body_update(req, end_headers, nb->s_off - len)) {
973 req->flags |= HTTP_REQUEST_DELETE;
974 http_error_response(req->owner,
975 HTTP_STATUS_INTERNAL_ERROR);
976 return (KORE_RESULT_OK);
977 }
978 } else {
979 c->http_timeout = 0;
980 }
981
982 if (req->rt->on_headers != NULL) {
983 if (!kore_runtime_http_request(req->rt->on_headers, req)) {
984 req->flags |= HTTP_REQUEST_DELETE;
985 return (KORE_RESULT_OK);
986 }
987 }
988
989 return (KORE_RESULT_OK);
990 }
991
992 int
993 http_argument_get(struct http_request *req, const char *name,
994 void **out, void *nout, int type)
995 {
996 struct http_arg *q;
997
998 TAILQ_FOREACH(q, &(req->arguments), list) {
999 if (strcmp(q->name, name))
1000 continue;
1001
1002 if (http_data_convert(q->s_value, out, nout, type))
1003 return (KORE_RESULT_OK);
1004
1005 break;
1006 }
1007
1008 return (KORE_RESULT_ERROR);
1009 }
1010
1011 int
1012 http_argument_urldecode(char *arg, int url)
1013 {
1014 u_int8_t v;
1015 int err;
1016 size_t len;
1017 char *p, *in, h[5];
1018
1019 p = arg;
1020 in = arg;
1021 len = strlen(arg);
1022
1023 while (*p != '\0' && p < (arg + len)) {
1024 if (*p == '+')
1025 *p = ' ';
1026 if (*p != '%') {
1027 *in++ = *p++;
1028 continue;
1029 }
1030
1031 if ((p + 2) >= (arg + len))
1032 return (KORE_RESULT_ERROR);
1033
1034 if (!isxdigit((unsigned char)*(p + 1)) ||
1035 !isxdigit((unsigned char)*(p + 2))) {
1036 *in++ = *p++;
1037 continue;
1038 }
1039
1040 h[0] = '0';
1041 h[1] = 'x';
1042 h[2] = *(p + 1);
1043 h[3] = *(p + 2);
1044 h[4] = '\0';
1045
1046 v = kore_strtonum(h, 16, 0x0, 0xff, &err);
1047 if (err != KORE_RESULT_OK)
1048 return (err);
1049
1050 if (url) {
1051 if (v <= 0x1f || v == 0x7f)
1052 return (KORE_RESULT_ERROR);
1053 } else {
1054 if ((v <= 0x1f || v == 0x7f) &&
1055 (v != '\n' && v != '\r' && v != '\t'))
1056 return (KORE_RESULT_ERROR);
1057 }
1058
1059 *in++ = (char)v;
1060 p += 3;
1061 }
1062
1063 *in = '\0';
1064 return (KORE_RESULT_OK);
1065 }
1066
1067 struct http_file *
1068 http_file_lookup(struct http_request *req, const char *name)
1069 {
1070 struct http_file *f;
1071
1072 TAILQ_FOREACH(f, &(req->files), list) {
1073 if (!strcmp(f->name, name))
1074 return (f);
1075 }
1076
1077 return (NULL);
1078 }
1079
1080 ssize_t
1081 http_file_read(struct http_file *file, void *buf, size_t len)
1082 {
1083 ssize_t ret;
1084 size_t toread, off;
1085
1086 if (file->length < file->offset)
1087 return (-1);
1088 if ((file->offset + len) < file->offset)
1089 return (-1);
1090 if ((file->position + file->offset) < file->position)
1091 return (-1);
1092
1093 off = file->position + file->offset;
1094 toread = MIN(len, (file->length - file->offset));
1095 if (toread == 0)
1096 return (0);
1097
1098 if (file->req->http_body_fd != -1) {
1099 if (lseek(file->req->http_body_fd, off, SEEK_SET) == -1) {
1100 kore_log(LOG_ERR, "http_file_read: lseek(%s): %s",
1101 file->req->http_body_path, errno_s);
1102 return (-1);
1103 }
1104
1105 for (;;) {
1106 ret = read(file->req->http_body_fd, buf, toread);
1107 if (ret == -1) {
1108 if (errno == EINTR)
1109 continue;
1110 kore_log(LOG_ERR, "failed to read %s: %s",
1111 file->req->http_body_path, errno_s);
1112 return (-1);
1113 }
1114 if (ret == 0)
1115 return (0);
1116 break;
1117 }
1118 } else if (file->req->http_body != NULL) {
1119 if (off > file->req->http_body->length)
1120 return (0);
1121 memcpy(buf, file->req->http_body->data + off, toread);
1122 ret = toread;
1123 } else {
1124 kore_log(LOG_ERR, "http_file_read: called without body");
1125 return (-1);
1126 }
1127
1128 file->offset += (size_t)ret;
1129 return (ret);
1130 }
1131
1132 void
1133 http_file_rewind(struct http_file *file)
1134 {
1135 file->offset = 0;
1136 }
1137
1138 void
1139 http_response_cookie(struct http_request *req, const char *name,
1140 const char *val, const char *path, time_t expires, u_int32_t maxage,
1141 struct http_cookie **out)
1142 {
1143 char *p;
1144 struct http_cookie *ck;
1145
1146 if (name == NULL || val == NULL)
1147 fatal("http_response_cookie: invalid parameters");
1148
1149 ck = kore_pool_get(&http_cookie_pool);
1150
1151 ck->maxage = maxage;
1152 ck->expires = expires;
1153 ck->name = kore_strdup(name);
1154 ck->value = kore_strdup(val);
1155 ck->domain = kore_strdup(req->host);
1156 ck->flags = HTTP_COOKIE_HTTPONLY | HTTP_COOKIE_SECURE;
1157
1158 if ((p = strrchr(ck->domain, ':')) != NULL)
1159 *p = '\0';
1160
1161 if (path != NULL)
1162 ck->path = kore_strdup(path);
1163 else
1164 ck->path = NULL;
1165
1166 TAILQ_INSERT_TAIL(&(req->resp_cookies), ck, list);
1167
1168 if (out != NULL)
1169 *out = ck;
1170 }
1171
1172 void
1173 http_populate_cookies(struct http_request *req)
1174 {
1175 struct http_cookie *ck;
1176 const char *hdr;
1177 int i, v, n;
1178 char *c, *header, *pair[3];
1179 char *cookies[HTTP_MAX_COOKIES];
1180
1181 if (!http_request_header(req, "cookie", &hdr))
1182 return;
1183
1184 header = kore_strdup(hdr);
1185 v = kore_split_string(header, ";", cookies, HTTP_MAX_COOKIES);
1186 for (i = 0; i < v; i++) {
1187 for (c = cookies[i]; isspace(*(unsigned char *)c); c++)
1188 ;
1189
1190 n = kore_split_string(c, "=", pair, 3);
1191 if (n != 2)
1192 continue;
1193
1194 ck = kore_pool_get(&http_cookie_pool);
1195 ck->name = kore_strdup(pair[0]);
1196 ck->value = kore_strdup(pair[1]);
1197 TAILQ_INSERT_TAIL(&(req->req_cookies), ck, list);
1198 }
1199
1200 kore_free(header);
1201 }
1202
1203 void
1204 http_populate_post(struct http_request *req)
1205 {
1206 ssize_t ret;
1207 int i, v;
1208 struct kore_buf *body;
1209 char data[BUFSIZ];
1210 char *args[HTTP_MAX_QUERY_ARGS], *val[3], *string;
1211
1212 if (req->method != HTTP_METHOD_POST)
1213 return;
1214
1215 if (req->http_body != NULL) {
1216 body = NULL;
1217 req->http_body->offset = req->content_length;
1218 string = kore_buf_stringify(req->http_body, NULL);
1219 req->http_body_length = 0;
1220 req->http_body_offset = 0;
1221 } else {
1222 body = kore_buf_alloc(128);
1223 for (;;) {
1224 ret = http_body_read(req, data, sizeof(data));
1225 if (ret == -1)
1226 goto out;
1227 if (ret == 0)
1228 break;
1229 kore_buf_append(body, data, ret);
1230 }
1231 string = kore_buf_stringify(body, NULL);
1232 }
1233
1234 v = kore_split_string(string, "&", args, HTTP_MAX_QUERY_ARGS);
1235 for (i = 0; i < v; i++) {
1236 kore_split_string(args[i], "=", val, 3);
1237 if (val[0] != NULL && val[1] != NULL)
1238 http_argument_add(req, val[0], val[1], 0, 1);
1239 }
1240
1241 out:
1242 if (body != NULL)
1243 kore_buf_free(body);
1244 }
1245
1246 void
1247 http_populate_qs(struct http_request *req)
1248 {
1249 int i, v;
1250 char *query, *args[HTTP_MAX_QUERY_ARGS], *val[3];
1251
1252 if (req->query_string == NULL)
1253 return;
1254
1255 query = kore_strdup(req->query_string);
1256 v = kore_split_string(query, "&", args, HTTP_MAX_QUERY_ARGS);
1257 for (i = 0; i < v; i++) {
1258 kore_split_string(args[i], "=", val, 3);
1259 if (val[0] != NULL && val[1] != NULL)
1260 http_argument_add(req, val[0], val[1], 1, 1);
1261 }
1262
1263 kore_free(query);
1264 }
1265
1266 void
1267 http_populate_multipart_form(struct http_request *req)
1268 {
1269 const char *hdr;
1270 int h, blen;
1271 struct kore_buf in, out;
1272 char *type, *val, *args[3];
1273 char boundary[HTTP_BOUNDARY_MAX];
1274
1275 if (req->method != HTTP_METHOD_POST)
1276 return;
1277
1278 if (!http_request_header(req, "content-type", &hdr))
1279 return;
1280
1281 kore_buf_init(&in, 128);
1282 kore_buf_init(&out, 128);
1283
1284 type = kore_strdup(hdr);
1285 h = kore_split_string(type, ";", args, 3);
1286 if (h != 2)
1287 goto cleanup;
1288
1289 if (strcasecmp(args[0], "multipart/form-data"))
1290 goto cleanup;
1291
1292 if ((val = strchr(args[1], '=')) == NULL)
1293 goto cleanup;
1294
1295 val++;
1296 blen = snprintf(boundary, sizeof(boundary), "--%s", val);
1297 if (blen == -1 || (size_t)blen >= sizeof(boundary))
1298 goto cleanup;
1299
1300 if (!multipart_find_data(&in, NULL, NULL, req, boundary, blen))
1301 goto cleanup;
1302
1303 for (;;) {
1304 if (!multipart_find_data(&in, NULL, NULL, req, "\r\n", 2))
1305 break;
1306 if (in.offset < 4 && req->http_body_length == 0)
1307 break;
1308 if (!multipart_find_data(&in, &out, NULL, req, "\r\n\r\n", 4))
1309 break;
1310 if (!multipart_parse_headers(req, &in, &out, boundary, blen))
1311 break;
1312
1313 kore_buf_reset(&out);
1314 }
1315
1316 cleanup:
1317 kore_free(type);
1318 kore_buf_cleanup(&in);
1319 kore_buf_cleanup(&out);
1320 }
1321
1322 int
1323 http_body_rewind(struct http_request *req)
1324 {
1325 if (req->http_body_fd != -1) {
1326 if (lseek(req->http_body_fd, 0, SEEK_SET) == -1) {
1327 kore_log(LOG_ERR, "lseek(%s) failed: %s",
1328 req->http_body_path, errno_s);
1329 return (KORE_RESULT_ERROR);
1330 }
1331 } else if (req->http_body != NULL) {
1332 kore_buf_reset(req->http_body);
1333 }
1334
1335 req->http_body_offset = 0;
1336 req->http_body_length = req->content_length;
1337
1338 return (KORE_RESULT_OK);
1339 }
1340
1341 int
1342 http_body_digest(struct http_request *req, char *out, size_t len)
1343 {
1344 size_t idx;
1345 int slen;
1346
1347 if (len != HTTP_BODY_DIGEST_STRLEN) {
1348 fatal("http_body_digest: bad len:%zu wanted:%u",
1349 len, HTTP_BODY_DIGEST_STRLEN);
1350 }
1351
1352 if (!(req->flags & HTTP_REQUEST_COMPLETE))
1353 return (KORE_RESULT_ERROR);
1354
1355 for (idx = 0; idx < sizeof(req->http_body_digest); idx++) {
1356 slen = snprintf(out + (idx * 2), len - (idx * 2), "%02x",
1357 req->http_body_digest[idx]);
1358 if (slen == -1 || (size_t)slen >= len)
1359 fatal("failed to create hex string");
1360 }
1361
1362 return (KORE_RESULT_OK);
1363 }
1364
1365 ssize_t
1366 http_body_read(struct http_request *req, void *out, size_t len)
1367 {
1368 ssize_t ret;
1369 size_t toread;
1370
1371 toread = MIN(req->http_body_length, len);
1372 if (toread == 0)
1373 return (0);
1374
1375 if (req->http_body_fd != -1) {
1376 for (;;) {
1377 ret = read(req->http_body_fd, out, toread);
1378 if (ret == -1) {
1379 if (errno == EINTR)
1380 continue;
1381 kore_log(LOG_ERR, "failed to read %s: %s",
1382 req->http_body_path, errno_s);
1383 return (-1);
1384 }
1385 if (ret == 0)
1386 return (0);
1387 break;
1388 }
1389 } else if (req->http_body != NULL) {
1390 memcpy(out,
1391 (req->http_body->data + req->http_body->offset), toread);
1392 req->http_body->offset += toread;
1393 ret = toread;
1394 } else {
1395 kore_log(LOG_ERR, "http_body_read: called without body");
1396 return (-1);
1397 }
1398
1399 req->http_body_length -= (size_t)ret;
1400 req->http_body_offset += (size_t)ret;
1401
1402 return (ret);
1403 }
1404
1405 int
1406 http_state_run(struct http_state *states, u_int8_t elm,
1407 struct http_request *req)
1408 {
1409 int r, done;
1410
1411 done = 0;
1412
1413 while (!done) {
1414 if (req->fsm_state >= elm) {
1415 fatal("http_state_run: fsm_state > elm (%d/%d)",
1416 req->fsm_state, elm);
1417 }
1418
1419 r = states[req->fsm_state].cb(req);
1420 switch (r) {
1421 case HTTP_STATE_ERROR:
1422 return (KORE_RESULT_OK);
1423 case HTTP_STATE_RETRY:
1424 return (KORE_RESULT_RETRY);
1425 case HTTP_STATE_CONTINUE:
1426 break;
1427 case HTTP_STATE_COMPLETE:
1428 done = 1;
1429 break;
1430 default:
1431 fatal("http_state_run: unknown return value %d", r);
1432 }
1433 }
1434
1435 req->fsm_state = 0;
1436
1437 return (KORE_RESULT_OK);
1438 }
1439
1440 int
1441 http_state_exists(struct http_request *req)
1442 {
1443 return (req->hdlr_extra != NULL);
1444 }
1445
1446 void *
1447 http_state_create(struct http_request *req, size_t len)
1448 {
1449 if (req->hdlr_extra != NULL)
1450 fatal("http_state_create: state already exists");
1451
1452 req->state_len = len;
1453 req->hdlr_extra = kore_calloc(1, len);
1454
1455 return (req->hdlr_extra);
1456 }
1457
1458 void *
1459 http_state_get(struct http_request *req)
1460 {
1461 return (req->hdlr_extra);
1462 }
1463
1464 void
1465 http_state_cleanup(struct http_request *req)
1466 {
1467 kore_free(req->hdlr_extra);
1468 req->hdlr_extra = NULL;
1469 }
1470
1471 void
1472 http_start_recv(struct connection *c)
1473 {
1474 c->http_start = kore_time_ms();
1475 c->http_timeout = http_header_timeout * 1000;
1476 net_recv_reset(c, http_header_max, http_header_recv);
1477 }
1478
1479 void
1480 http_runlock_init(struct http_runlock *lock)
1481 {
1482 lock->owner = NULL;
1483 LIST_INIT(&lock->queue);
1484 }
1485
1486 int
1487 http_runlock_acquire(struct http_runlock *lock, struct http_request *req)
1488 {
1489 if (lock->owner != NULL) {
1490 if (req->runlock != NULL)
1491 fatal("%s: request already waiting on lock", __func__);
1492
1493 req->runlock = kore_pool_get(&http_rlq_pool);
1494 req->runlock->req = req;
1495 LIST_INSERT_HEAD(&lock->queue, req->runlock, list);
1496
1497 http_request_sleep(req);
1498 return (KORE_RESULT_ERROR);
1499 }
1500
1501 lock->owner = req;
1502
1503 return (KORE_RESULT_OK);
1504 }
1505
1506 void
1507 http_runlock_release(struct http_runlock *lock, struct http_request *req)
1508 {
1509 struct http_runlock_queue *next;
1510 struct http_request *nextreq;
1511
1512 if (lock->owner != req)
1513 fatal("%s: calling request != owner of runlock", __func__);
1514
1515 lock->owner = NULL;
1516
1517 if ((next = LIST_FIRST(&lock->queue)) != NULL) {
1518 LIST_REMOVE(next, list);
1519
1520 nextreq = next->req;
1521 nextreq->runlock = NULL;
1522
1523 http_request_wakeup(nextreq);
1524 kore_pool_put(&http_rlq_pool, next);
1525 }
1526 }
1527
1528 int
1529 http_redirect_add(struct kore_domain *dom, const char *path, int status,
1530 const char *target)
1531 {
1532 struct http_redirect *rdr;
1533
1534 rdr = kore_calloc(1, sizeof(*rdr));
1535
1536 if (regcomp(&(rdr->rctx), path, REG_EXTENDED)) {
1537 kore_free(rdr);
1538 return (KORE_RESULT_ERROR);
1539 }
1540
1541 rdr->status = status;
1542
1543 if (target != NULL)
1544 rdr->target = kore_strdup(target);
1545 else
1546 rdr->target = NULL;
1547
1548 TAILQ_INSERT_TAIL(&dom->redirects, rdr, list);
1549
1550 return (KORE_RESULT_OK);
1551 }
1552
1553 const char *
1554 http_status_text(int status)
1555 {
1556 const char *r;
1557
1558 switch (status) {
1559 case HTTP_STATUS_CONTINUE:
1560 r = "Continue";
1561 break;
1562 case HTTP_STATUS_SWITCHING_PROTOCOLS:
1563 r = "Switching Protocols";
1564 break;
1565 case HTTP_STATUS_OK:
1566 r = "OK";
1567 break;
1568 case HTTP_STATUS_CREATED:
1569 r = "Created";
1570 break;
1571 case HTTP_STATUS_ACCEPTED:
1572 r = "Accepted";
1573 break;
1574 case HTTP_STATUS_NON_AUTHORITATIVE:
1575 r = "Non-Authoritative Information";
1576 break;
1577 case HTTP_STATUS_NO_CONTENT:
1578 r = "No Content";
1579 break;
1580 case HTTP_STATUS_RESET_CONTENT:
1581 r = "Reset Content";
1582 break;
1583 case HTTP_STATUS_PARTIAL_CONTENT:
1584 r = "Partial Content";
1585 break;
1586 case HTTP_STATUS_MULTIPLE_CHOICES:
1587 r = "Multiple Choices";
1588 break;
1589 case HTTP_STATUS_MOVED_PERMANENTLY:
1590 r = "Moved Permanently";
1591 break;
1592 case HTTP_STATUS_FOUND:
1593 r = "Found";
1594 break;
1595 case HTTP_STATUS_SEE_OTHER:
1596 r = "See Other";
1597 break;
1598 case HTTP_STATUS_NOT_MODIFIED:
1599 r = "Not Modified";
1600 break;
1601 case HTTP_STATUS_USE_PROXY:
1602 r = "Use Proxy";
1603 break;
1604 case HTTP_STATUS_TEMPORARY_REDIRECT:
1605 r = "Temporary Redirect";
1606 break;
1607 case HTTP_STATUS_BAD_REQUEST:
1608 r = "Bad Request";
1609 break;
1610 case HTTP_STATUS_UNAUTHORIZED:
1611 r = "Unauthorized";
1612 break;
1613 case HTTP_STATUS_PAYMENT_REQUIRED:
1614 r = "Payment Required";
1615 break;
1616 case HTTP_STATUS_FORBIDDEN:
1617 r = "Forbidden";
1618 break;
1619 case HTTP_STATUS_NOT_FOUND:
1620 r = "Not Found";
1621 break;
1622 case HTTP_STATUS_METHOD_NOT_ALLOWED:
1623 r = "Method Not Allowed";
1624 break;
1625 case HTTP_STATUS_NOT_ACCEPTABLE:
1626 r = "Not Acceptable";
1627 break;
1628 case HTTP_STATUS_PROXY_AUTH_REQUIRED:
1629 r = "Proxy Authentication Required";
1630 break;
1631 case HTTP_STATUS_REQUEST_TIMEOUT:
1632 r = "Request Time-out";
1633 break;
1634 case HTTP_STATUS_CONFLICT:
1635 r = "Conflict";
1636 break;
1637 case HTTP_STATUS_GONE:
1638 r = "Gone";
1639 break;
1640 case HTTP_STATUS_LENGTH_REQUIRED:
1641 r = "Length Required";
1642 break;
1643 case HTTP_STATUS_PRECONDITION_FAILED:
1644 r = "Precondition Failed";
1645 break;
1646 case HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE:
1647 r = "Request Entity Too Large";
1648 break;
1649 case HTTP_STATUS_REQUEST_URI_TOO_LARGE:
1650 r = "Request-URI Too Large";
1651 break;
1652 case HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE:
1653 r = "Unsupported Media Type";
1654 break;
1655 case HTTP_STATUS_REQUEST_RANGE_INVALID:
1656 r = "Requested range not satisfiable";
1657 break;
1658 case HTTP_STATUS_EXPECTATION_FAILED:
1659 r = "Expectation Failed";
1660 break;
1661 case HTTP_STATUS_MISDIRECTED_REQUEST:
1662 r = "Misdirected Request";
1663 break;
1664 case HTTP_STATUS_INTERNAL_ERROR:
1665 r = "Internal Server Error";
1666 break;
1667 case HTTP_STATUS_NOT_IMPLEMENTED:
1668 r = "Not Implemented";
1669 break;
1670 case HTTP_STATUS_BAD_GATEWAY:
1671 r = "Bad Gateway";
1672 break;
1673 case HTTP_STATUS_SERVICE_UNAVAILABLE:
1674 r = "Service Unavailable";
1675 break;
1676 case HTTP_STATUS_GATEWAY_TIMEOUT:
1677 r = "Gateway Time-out";
1678 break;
1679 case HTTP_STATUS_BAD_VERSION:
1680 r = "HTTP Version not supported";
1681 break;
1682 default:
1683 r = "";
1684 break;
1685 }
1686
1687 return (r);
1688 }
1689
1690 const char *
1691 http_method_text(int method)
1692 {
1693 char *r;
1694
1695 switch(method) {
1696 case HTTP_METHOD_GET:
1697 r = "GET";
1698 break;
1699 case HTTP_METHOD_POST:
1700 r = "POST";
1701 break;
1702 case HTTP_METHOD_PUT:
1703 r = "PUT";
1704 break;
1705 case HTTP_METHOD_DELETE:
1706 r = "DELETE";
1707 break;
1708 case HTTP_METHOD_HEAD:
1709 r = "HEAD";
1710 break;
1711 case HTTP_METHOD_OPTIONS:
1712 r = "OPTIONS";
1713 break;
1714 case HTTP_METHOD_PATCH:
1715 r = "PATCH";
1716 break;
1717 default:
1718 r = "";
1719 break;
1720 }
1721
1722 return (r);
1723 }
1724
1725 int
1726 http_method_value(const char *method)
1727 {
1728 if (!strcasecmp(method, "GET"))
1729 return (HTTP_METHOD_GET);
1730
1731 if (!strcasecmp(method, "POST"))
1732 return (HTTP_METHOD_POST);
1733
1734 if (!strcasecmp(method, "PUT"))
1735 return (HTTP_METHOD_PUT);
1736
1737 if (!strcasecmp(method, "DELETE"))
1738 return (HTTP_METHOD_DELETE);
1739
1740 if (!strcasecmp(method, "HEAD"))
1741 return (HTTP_METHOD_HEAD);
1742
1743 if (!strcasecmp(method, "OPTIONS"))
1744 return (HTTP_METHOD_OPTIONS);
1745
1746 if (!strcasecmp(method, "PATCH"))
1747 return (HTTP_METHOD_PATCH);
1748
1749 return (0);
1750 }
1751
1752 int
1753 http_media_register(const char *ext, const char *type)
1754 {
1755 struct http_media_type *media;
1756
1757 LIST_FOREACH(media, &http_media_types, list) {
1758 if (!strcasecmp(media->ext, ext))
1759 return (KORE_RESULT_ERROR);
1760 }
1761
1762 media = kore_calloc(1, sizeof(*media));
1763 media->ext = kore_strdup(ext);
1764 media->type = kore_strdup(type);
1765
1766 LIST_INSERT_HEAD(&http_media_types, media, list);
1767
1768 return (KORE_RESULT_OK);
1769 }
1770
1771 const char *
1772 http_media_type(const char *path)
1773 {
1774 const char *p;
1775 struct http_media_type *media;
1776
1777 if ((p = strrchr(path, '.')) == NULL)
1778 return (NULL);
1779
1780 p++;
1781 if (*p == '\0')
1782 return (NULL);
1783
1784 LIST_FOREACH(media, &http_media_types, list) {
1785 if (!strcasecmp(media->ext, p))
1786 return (media->type);
1787 }
1788
1789 return (NULL);
1790 }
1791
1792 char *
1793 http_validate_header(char *header)
1794 {
1795 u_int8_t idx;
1796 char *p, *value;
1797
1798 for (p = header; *p != '\0'; p++) {
1799 idx = *p;
1800 if (idx > HTTP_MAP_LIMIT)
1801 return (NULL);
1802
1803 if (*p == ':') {
1804 *(p)++ = '\0';
1805 break;
1806 }
1807
1808 if (*p >= 'A' && *p <= 'Z')
1809 *p += 32;
1810
1811 if (http_token[idx] == 0x00)
1812 return (NULL);
1813 }
1814
1815 while (isspace(*(unsigned char *)p))
1816 p++;
1817
1818 if (*p == '\0')
1819 return (NULL);
1820
1821 value = p;
1822 while (*p != '\0') {
1823 idx = *p;
1824 if (idx > HTTP_MAP_LIMIT)
1825 return (NULL);
1826 if (http_field_content[idx] == 0x00)
1827 return (NULL);
1828 p++;
1829 }
1830
1831 return (value);
1832 }
1833
1834 static int
1835 http_release_buffer(struct netbuf *nb)
1836 {
1837 kore_buf_free(nb->extra);
1838
1839 return (KORE_RESULT_OK);
1840 }
1841
1842 static int
1843 http_check_redirect(struct http_request *req, struct kore_domain *dom)
1844 {
1845 int idx;
1846 struct http_redirect *rdr;
1847 const char *uri;
1848 char key[4];
1849 struct kore_buf location;
1850
1851 TAILQ_FOREACH(rdr, &dom->redirects, list) {
1852 if (!regexec(&(rdr->rctx), req->path,
1853 HTTP_CAPTURE_GROUPS, req->cgroups, 0))
1854 break;
1855 }
1856
1857 if (rdr == NULL)
1858 return (KORE_RESULT_ERROR);
1859
1860 uri = NULL;
1861 kore_buf_init(&location, 128);
1862
1863 if (rdr->target) {
1864 kore_buf_appendf(&location, "%s", rdr->target);
1865
1866 if (req->query_string != NULL) {
1867 kore_buf_replace_string(&location, "$qs",
1868 req->query_string, strlen(req->query_string));
1869 }
1870
1871 /* Starts at 1 to skip the full path. */
1872 for (idx = 1; idx < HTTP_CAPTURE_GROUPS - 1; idx++) {
1873 if (req->cgroups[idx].rm_so == -1 ||
1874 req->cgroups[idx].rm_eo == -1)
1875 break;
1876
1877 (void)snprintf(key, sizeof(key), "$%d", idx);
1878
1879 kore_buf_replace_string(&location, key,
1880 req->path + req->cgroups[idx].rm_so,
1881 req->cgroups[idx].rm_eo - req->cgroups[idx].rm_so);
1882 }
1883
1884 uri = kore_buf_stringify(&location, NULL);
1885 }
1886
1887 if (uri)
1888 http_response_header(req, "location", uri);
1889
1890 http_response(req, rdr->status, NULL, 0);
1891 kore_buf_cleanup(&location);
1892
1893 if (dom->accesslog)
1894 kore_accesslog(req);
1895
1896 return (KORE_RESULT_OK);
1897 }
1898
1899 static struct http_request *
1900 http_request_new(struct connection *c, const char *host,
1901 const char *method, char *path, const char *version)
1902 {
1903 struct kore_domain *dom;
1904 struct http_request *req;
1905 size_t qsoff;
1906 char *p, *hp;
1907 int m, flags, exists;
1908
1909 if (http_request_count >= http_request_limit) {
1910 http_error_response(c, HTTP_STATUS_SERVICE_UNAVAILABLE);
1911 return (NULL);
1912 }
1913
1914 if (strlen(host) >= KORE_DOMAINNAME_LEN - 1) {
1915 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
1916 return (NULL);
1917 }
1918
1919 if (strlen(path) >= HTTP_URI_LEN - 1) {
1920 http_error_response(c, HTTP_STATUS_REQUEST_URI_TOO_LARGE);
1921 return (NULL);
1922 }
1923
1924 if (strcasecmp(version, "http/1.1")) {
1925 if (strcasecmp(version, "http/1.0")) {
1926 http_error_response(c, HTTP_STATUS_BAD_VERSION);
1927 return (NULL);
1928 }
1929
1930 flags = HTTP_VERSION_1_0;
1931 } else {
1932 flags = HTTP_VERSION_1_1;
1933 }
1934
1935 if ((p = strchr(path, '?')) != NULL) {
1936 qsoff = p - path;
1937 } else {
1938 qsoff = 0;
1939 }
1940
1941 hp = NULL;
1942
1943 switch (c->family) {
1944 case AF_INET6:
1945 if (*host == '[') {
1946 if ((hp = strrchr(host, ']')) == NULL) {
1947 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
1948 return (NULL);
1949 }
1950 hp++;
1951 if (*hp == ':')
1952 *hp = '\0';
1953 else
1954 hp = NULL;
1955 }
1956 break;
1957 default:
1958 if ((hp = strrchr(host, ':')) != NULL)
1959 *hp = '\0';
1960 break;
1961 }
1962
1963 if (c->owner->server->tls && c->tls_sni != NULL) {
1964 if (strcasecmp(c->tls_sni, host)) {
1965 http_error_response(c, HTTP_STATUS_MISDIRECTED_REQUEST);
1966 return (NULL);
1967 }
1968 }
1969
1970 if ((dom = kore_domain_lookup(c->owner->server, host)) == NULL) {
1971 http_error_response(c, HTTP_STATUS_NOT_FOUND);
1972 return (NULL);
1973 }
1974
1975 if (dom->cafile != NULL && c->tls_cert == NULL) {
1976 http_error_response(c, HTTP_STATUS_FORBIDDEN);
1977 return (NULL);
1978 }
1979
1980 if (hp != NULL)
1981 *hp = ':';
1982
1983 if (!strcasecmp(method, "get")) {
1984 m = HTTP_METHOD_GET;
1985 flags |= HTTP_REQUEST_COMPLETE;
1986 } else if (!strcasecmp(method, "delete")) {
1987 m = HTTP_METHOD_DELETE;
1988 flags |= HTTP_REQUEST_EXPECT_BODY;
1989 } else if (!strcasecmp(method, "post")) {
1990 m = HTTP_METHOD_POST;
1991 flags |= HTTP_REQUEST_EXPECT_BODY;
1992 } else if (!strcasecmp(method, "put")) {
1993 m = HTTP_METHOD_PUT;
1994 flags |= HTTP_REQUEST_EXPECT_BODY;
1995 } else if (!strcasecmp(method, "head")) {
1996 m = HTTP_METHOD_HEAD;
1997 flags |= HTTP_REQUEST_COMPLETE;
1998 } else if (!strcasecmp(method, "options")) {
1999 m = HTTP_METHOD_OPTIONS;
2000 flags |= HTTP_REQUEST_COMPLETE;
2001 } else if (!strcasecmp(method, "patch")) {
2002 m = HTTP_METHOD_PATCH;
2003 flags |= HTTP_REQUEST_EXPECT_BODY;
2004 } else {
2005 http_error_response(c, HTTP_STATUS_BAD_REQUEST);
2006 return (NULL);
2007 }
2008
2009 if (flags & HTTP_VERSION_1_0) {
2010 if (m != HTTP_METHOD_GET && m != HTTP_METHOD_POST &&
2011 m != HTTP_METHOD_HEAD) {
2012 http_error_response(c, HTTP_STATUS_METHOD_NOT_ALLOWED);
2013 return (NULL);
2014 }
2015 }
2016
2017 req = kore_pool_get(&http_request_pool);
2018
2019 req->end = 0;
2020 req->total = 0;
2021 req->start = 0;
2022 req->owner = c;
2023 req->status = 0;
2024 req->method = m;
2025 req->agent = NULL;
2026 req->referer = NULL;
2027 req->runlock = NULL;
2028 req->flags = flags;
2029 req->fsm_state = 0;
2030 req->http_body = NULL;
2031 req->http_body_fd = -1;
2032 req->hdlr_extra = NULL;
2033 req->content_length = 0;
2034 req->query_string = NULL;
2035 req->http_body_length = 0;
2036 req->http_body_offset = 0;
2037 req->http_body_path = NULL;
2038
2039 req->host = host;
2040 req->path = path;
2041
2042 #if defined(KORE_USE_PYTHON)
2043 req->py_req = NULL;
2044 req->py_coro = NULL;
2045 req->py_rqnext = NULL;
2046 req->py_validator = NULL;
2047 #endif
2048
2049 if (qsoff > 0) {
2050 req->query_string = path + qsoff;
2051 *(req->query_string)++ = '\0';
2052 } else {
2053 req->query_string = NULL;
2054 }
2055
2056 /* Checked further down below if we need to 404. */
2057 exists = kore_route_lookup(req, dom, m, &req->rt);
2058
2059 TAILQ_INIT(&(req->resp_headers));
2060 TAILQ_INIT(&(req->req_headers));
2061 TAILQ_INIT(&(req->resp_cookies));
2062 TAILQ_INIT(&(req->req_cookies));
2063 TAILQ_INIT(&(req->arguments));
2064 TAILQ_INIT(&(req->files));
2065
2066 #if defined(KORE_USE_TASKS)
2067 LIST_INIT(&(req->tasks));
2068 #endif
2069
2070 #if defined(KORE_USE_PGSQL)
2071 LIST_INIT(&(req->pgsqls));
2072 #endif
2073
2074 http_request_count++;
2075 TAILQ_INSERT_HEAD(&http_requests, req, list);
2076 TAILQ_INSERT_TAIL(&(c->http_requests), req, olist);
2077
2078 if (http_check_redirect(req, dom)) {
2079 http_request_free(req);
2080 return (NULL);
2081 }
2082
2083 if (exists == 0) {
2084 http_request_free(req);
2085 http_error_response(c, HTTP_STATUS_NOT_FOUND);
2086 return (NULL);
2087 }
2088
2089 if (req->rt == NULL) {
2090 http_request_free(req);
2091 http_error_response(c, HTTP_STATUS_METHOD_NOT_ALLOWED);
2092 return (NULL);
2093 }
2094
2095 return (req);
2096 }
2097
2098 static int
2099 multipart_find_data(struct kore_buf *in, struct kore_buf *out,
2100 size_t *olen, struct http_request *req, const void *needle, size_t len)
2101 {
2102 ssize_t ret;
2103 size_t left;
2104 u_int8_t *p, first, data[4096];
2105
2106 if (olen != NULL)
2107 *olen = 0;
2108
2109 first = *(const u_int8_t *)needle;
2110 for (;;) {
2111 if (in->offset < len) {
2112 ret = http_body_read(req, data, sizeof(data));
2113 if (ret == -1)
2114 return (KORE_RESULT_ERROR);
2115 if (ret == 0)
2116 return (KORE_RESULT_ERROR);
2117
2118 kore_buf_append(in, data, ret);
2119 continue;
2120 }
2121
2122 p = kore_mem_find(in->data, in->offset, &first, 1);
2123 if (p == NULL) {
2124 if (out != NULL)
2125 kore_buf_append(out, in->data, in->offset);
2126 if (olen != NULL)
2127 *olen += in->offset;
2128 kore_buf_reset(in);
2129 continue;
2130 }
2131
2132 left = in->offset - (p - in->data);
2133 if (left < len) {
2134 if (out != NULL)
2135 kore_buf_append(out, in->data, (p - in->data));
2136 if (olen != NULL)
2137 *olen += (p - in->data);
2138 memmove(in->data, p, left);
2139 in->offset = left;
2140 continue;
2141 }
2142
2143 if (!memcmp(p, needle, len)) {
2144 if (out != NULL)
2145 kore_buf_append(out, in->data, p - in->data);
2146 if (olen != NULL)
2147 *olen += (p - in->data);
2148
2149 in->offset = left - len;
2150 if (in->offset > 0)
2151 memmove(in->data, p + len, in->offset);
2152 return (KORE_RESULT_OK);
2153 }
2154
2155 if (out != NULL)
2156 kore_buf_append(out, in->data, (p - in->data) + 1);
2157 if (olen != NULL)
2158 *olen += (p - in->data) + 1;
2159
2160 in->offset = left - 1;
2161 if (in->offset > 0)
2162 memmove(in->data, p + 1, in->offset);
2163 }
2164
2165 return (KORE_RESULT_ERROR);
2166 }
2167
2168 static int
2169 multipart_parse_headers(struct http_request *req, struct kore_buf *in,
2170 struct kore_buf *hbuf, const char *boundary, const int blen)
2171 {
2172 int h, c, i;
2173 char *headers[5], *args[5], *opt[5];
2174 char *d, *val, *name, *fname, *string;
2175
2176 string = kore_buf_stringify(hbuf, NULL);
2177 h = kore_split_string(string, "\r\n", headers, 5);
2178 for (i = 0; i < h; i++) {
2179 c = kore_split_string(headers[i], ":", args, 5);
2180 if (c != 2)
2181 continue;
2182
2183 /* Ignore other headers for now. */
2184 if (strcasecmp(args[0], "content-disposition"))
2185 continue;
2186
2187 for (d = args[1]; isspace(*(unsigned char *)d); d++)
2188 ;
2189
2190 c = kore_split_string(d, ";", opt, 5);
2191 if (c < 2)
2192 continue;
2193
2194 if (strcasecmp(opt[0], "form-data"))
2195 continue;
2196
2197 if ((val = strchr(opt[1], '=')) == NULL)
2198 continue;
2199 if (strlen(val) < 3)
2200 continue;
2201
2202 val++;
2203 kore_strip_chars(val, '"', &name);
2204
2205 if (opt[2] == NULL) {
2206 multipart_add_field(req, in, name, boundary, blen);
2207 kore_free(name);
2208 continue;
2209 }
2210
2211 for (d = opt[2]; isspace(*(unsigned char *)d); d++)
2212 ;
2213
2214 if (!strncasecmp(d, "filename=", 9)) {
2215 if ((val = strchr(d, '=')) == NULL) {
2216 kore_free(name);
2217 continue;
2218 }
2219
2220 val++;
2221 kore_strip_chars(val, '"', &fname);
2222 if (strlen(fname) > 0) {
2223 multipart_file_add(req,
2224 in, name, fname, boundary, blen);
2225 }
2226 kore_free(fname);
2227 }
2228
2229 kore_free(name);
2230 }
2231
2232 return (KORE_RESULT_OK);
2233 }
2234
2235 static void
2236 multipart_add_field(struct http_request *req, struct kore_buf *in,
2237 char *name, const char *boundary, const int blen)
2238 {
2239 struct kore_buf *data;
2240 char *string;
2241
2242 data = kore_buf_alloc(128);
2243
2244 if (!multipart_find_data(in, data, NULL, req, boundary, blen)) {
2245 kore_buf_free(data);
2246 return;
2247 }
2248
2249 if (data->offset < 3) {
2250 kore_buf_free(data);
2251 return;
2252 }
2253
2254 data->offset -= 2;
2255 string = kore_buf_stringify(data, NULL);
2256 http_argument_add(req, name, string, 0, 0);
2257 kore_buf_free(data);
2258 }
2259
2260 static void
2261 multipart_file_add(struct http_request *req, struct kore_buf *in,
2262 const char *name, const char *fname, const char *boundary, const int blen)
2263 {
2264 struct http_file *f;
2265 size_t position, len;
2266
2267 position = req->http_body_offset - in->offset;
2268 if (!multipart_find_data(in, NULL, &len, req, boundary, blen))
2269 return;
2270
2271 if (len < 3)
2272 return;
2273 len -= 2;
2274
2275 f = kore_malloc(sizeof(struct http_file));
2276 f->req = req;
2277 f->offset = 0;
2278 f->length = len;
2279 f->position = position;
2280 f->name = kore_strdup(name);
2281 f->filename = kore_strdup(fname);
2282
2283 TAILQ_INSERT_TAIL(&(req->files), f, list);
2284 }
2285
2286 static void
2287 http_argument_add(struct http_request *req, char *name, char *value, int qs,
2288 int decode)
2289 {
2290 struct http_arg *q;
2291 struct kore_route_params *p;
2292
2293 if (decode) {
2294 if (!http_argument_urldecode(name, qs))
2295 return;
2296 }
2297
2298 TAILQ_FOREACH(p, &req->rt->params, list) {
2299 if (qs == 1 && !(p->flags & KORE_PARAMS_QUERY_STRING))
2300 continue;
2301 if (qs == 0 && (p->flags & KORE_PARAMS_QUERY_STRING))
2302 continue;
2303
2304 if (p->method != req->method)
2305 continue;
2306
2307 if (strcmp(p->name, name))
2308 continue;
2309
2310 if (decode) {
2311 if (!http_argument_urldecode(value, qs))
2312 return;
2313 }
2314
2315 if (!kore_validator_check(req, p->validator, value))
2316 break;
2317
2318 q = kore_malloc(sizeof(struct http_arg));
2319 q->name = kore_strdup(name);
2320 q->s_value = kore_strdup(value);
2321 TAILQ_INSERT_TAIL(&(req->arguments), q, list);
2322 break;
2323 }
2324 }
2325
2326 static int
2327 http_body_recv(struct netbuf *nb)
2328 {
2329 struct http_request *req = (struct http_request *)nb->extra;
2330
2331 return (http_body_update(req, nb->buf, nb->s_off));
2332 }
2333
2334 static int
2335 http_body_update(struct http_request *req, const void *data, size_t len)
2336 {
2337 ssize_t ret;
2338 u_int64_t bytes_left;
2339
2340 SHA256Update(&req->hashctx, data, len);
2341
2342 if (req->rt->on_body_chunk != NULL) {
2343 if (kore_runtime_http_body_chunk(req->rt->on_body_chunk,
2344 req, data, len) != KORE_RESULT_OK) {
2345 req->flags |= HTTP_REQUEST_DELETE;
2346 http_error_response(req->owner,
2347 HTTP_STATUS_INTERNAL_ERROR);
2348 return (KORE_RESULT_ERROR);
2349 }
2350 } else if (req->http_body_fd != -1) {
2351 ret = write(req->http_body_fd, data, len);
2352 if (ret == -1 || (size_t)ret != len) {
2353 req->flags |= HTTP_REQUEST_DELETE;
2354 http_error_response(req->owner,
2355 HTTP_STATUS_INTERNAL_ERROR);
2356 return (KORE_RESULT_ERROR);
2357 }
2358 } else if (req->http_body != NULL) {
2359 kore_buf_append(req->http_body, data, len);
2360 } else {
2361 req->flags |= HTTP_REQUEST_DELETE;
2362 http_error_response(req->owner,
2363 HTTP_STATUS_INTERNAL_ERROR);
2364 return (KORE_RESULT_ERROR);
2365 }
2366
2367 req->content_length -= len;
2368
2369 if (req->content_length == 0) {
2370 req->owner->http_timeout = 0;
2371 req->owner->rnb->extra = NULL;
2372 http_request_wakeup(req);
2373 req->flags |= HTTP_REQUEST_COMPLETE;
2374 req->flags &= ~HTTP_REQUEST_EXPECT_BODY;
2375 req->content_length = req->http_body_length;
2376 if (!http_body_rewind(req)) {
2377 req->flags |= HTTP_REQUEST_DELETE;
2378 http_error_response(req->owner,
2379 HTTP_STATUS_INTERNAL_ERROR);
2380 return (KORE_RESULT_ERROR);
2381 }
2382 SHA256Final(req->http_body_digest, &req->hashctx);
2383 } else {
2384 bytes_left = req->content_length;
2385 net_recv_reset(req->owner,
2386 MIN(bytes_left, NETBUF_SEND_PAYLOAD_MAX),
2387 http_body_recv);
2388 req->owner->rnb->extra = req;
2389 }
2390
2391 return (KORE_RESULT_OK);
2392 }
2393
2394 static void
2395 http_error_response(struct connection *c, int status)
2396 {
2397 c->flags |= CONN_CLOSE_EMPTY;
2398
2399 switch (c->proto) {
2400 case CONN_PROTO_HTTP:
2401 http_response_normal(NULL, c, status, NULL, 0);
2402 break;
2403 default:
2404 fatal("http_error_response() bad proto %d", c->proto);
2405 /* NOTREACHED. */
2406 }
2407
2408 if (!net_send_flush(c))
2409 kore_connection_disconnect(c);
2410 }
2411
2412 static void
2413 http_response_normal(struct http_request *req, struct connection *c,
2414 int status, const void *d, size_t len)
2415 {
2416 struct kore_buf buf;
2417 struct http_cookie *ck;
2418 struct http_header *hdr;
2419 char version;
2420 const char *conn, *text;
2421 int connection_close, send_body;
2422
2423 send_body = 1;
2424 text = http_status_text(status);
2425
2426 kore_buf_reset(header_buf);
2427
2428 if (req != NULL) {
2429 if (req->flags & HTTP_VERSION_1_0)
2430 version = '0';
2431 else
2432 version = '1';
2433 } else {
2434 version = '1';
2435 }
2436
2437 kore_buf_appendf(header_buf, "HTTP/1.%c %d %s\r\n",
2438 version, status, text);
2439
2440 if (status == 100) {
2441 kore_buf_append(header_buf, "\r\n", 2);
2442 net_send_queue(c, header_buf->data, header_buf->offset);
2443 return;
2444 }
2445
2446 kore_buf_append(header_buf, http_version, http_version_len);
2447
2448 if ((c->flags & CONN_CLOSE_EMPTY) ||
2449 (req != NULL && (req->flags & HTTP_VERSION_1_0))) {
2450 connection_close = 1;
2451 } else {
2452 connection_close = 0;
2453 }
2454
2455 if (connection_close == 0 && req != NULL) {
2456 if (http_request_header(req, "connection", &conn)) {
2457 if ((*conn == 'c' || *conn == 'C') &&
2458 !strcasecmp(conn, "close")) {
2459 connection_close = 1;
2460 }
2461 }
2462 }
2463
2464 kore_buf_init(&buf, 1024);
2465
2466 /* Note that req CAN be NULL. */
2467 if (req == NULL || req->owner->proto != CONN_PROTO_WEBSOCKET) {
2468 if (http_keepalive_time && connection_close == 0) {
2469 kore_buf_appendf(header_buf,
2470 "connection: keep-alive\r\n");
2471 kore_buf_appendf(header_buf,
2472 "keep-alive: timeout=%d\r\n", http_keepalive_time);
2473 } else {
2474 c->flags |= CONN_CLOSE_EMPTY;
2475 kore_buf_appendf(header_buf, "connection: close\r\n");
2476 }
2477 }
2478
2479 if (c->tls && http_hsts_enable) {
2480 kore_buf_appendf(header_buf, "strict-transport-security: ");
2481 kore_buf_appendf(header_buf,
2482 "max-age=%" PRIu64 "; includeSubDomains\r\n",
2483 http_hsts_enable);
2484 }
2485
2486 if (http_pretty_error && d == NULL && status >= 400) {
2487 kore_buf_appendf(&buf, pretty_error_fmt,
2488 status, text, status, text);
2489
2490 d = buf.data;
2491 len = buf.offset;
2492 }
2493
2494 if (req != NULL) {
2495 TAILQ_FOREACH(ck, &(req->resp_cookies), list)
2496 http_write_response_cookie(ck);
2497
2498 TAILQ_FOREACH(hdr, &(req->resp_headers), list) {
2499 kore_buf_appendf(header_buf, "%s: %s\r\n",
2500 hdr->header, hdr->value);
2501 }
2502
2503 if (status != 204 && status >= 200 &&
2504 !(req->flags & HTTP_REQUEST_NO_CONTENT_LENGTH)) {
2505 kore_buf_appendf(header_buf,
2506 "content-length: %zu\r\n", len);
2507 }
2508 } else {
2509 if (status != 204 && status >= 200) {
2510 kore_buf_appendf(header_buf,
2511 "content-length: %zu\r\n", len);
2512 }
2513 }
2514
2515 kore_buf_append(header_buf, "\r\n", 2);
2516 net_send_queue(c, header_buf->data, header_buf->offset);
2517
2518 if (req != NULL && req->method == HTTP_METHOD_HEAD)
2519 send_body = 0;
2520
2521 if (d != NULL && send_body)
2522 net_send_queue(c, d, len);
2523
2524 if (!(c->flags & CONN_CLOSE_EMPTY) && !(c->flags & CONN_IS_BUSY))
2525 http_start_recv(c);
2526
2527 if (req != NULL)
2528 req->content_length = len;
2529
2530 kore_buf_cleanup(&buf);
2531 }
2532
2533 static void
2534 http_write_response_cookie(struct http_cookie *ck)
2535 {
2536 struct tm tm;
2537 char expires[HTTP_DATE_MAXSIZE];
2538
2539 kore_buf_reset(ckhdr_buf);
2540 kore_buf_appendf(ckhdr_buf, "%s=%s", ck->name, ck->value);
2541
2542 if (ck->path != NULL)
2543 kore_buf_appendf(ckhdr_buf, "; Path=%s", ck->path);
2544 if (ck->domain != NULL)
2545 kore_buf_appendf(ckhdr_buf, "; Domain=%s", ck->domain);
2546
2547 if (ck->expires > 0) {
2548 if (gmtime_r(&ck->expires, &tm) == NULL) {
2549 kore_log(LOG_ERR, "gmtime_r(): %s", errno_s);
2550 return;
2551 }
2552
2553 if (strftime(expires, sizeof(expires),
2554 "%a, %d %b %y %H:%M:%S GMT", &tm) == 0) {
2555 kore_log(LOG_ERR, "strftime(): %s", errno_s);
2556 return;
2557 }
2558
2559 kore_buf_appendf(ckhdr_buf, "; Expires=%s", expires);
2560 }
2561
2562 if (ck->maxage > 0)
2563 kore_buf_appendf(ckhdr_buf, "; Max-Age=%u", ck->maxage);
2564
2565 if (ck->flags & HTTP_COOKIE_HTTPONLY)
2566 kore_buf_appendf(ckhdr_buf, "; HttpOnly");
2567 if (ck->flags & HTTP_COOKIE_SECURE)
2568 kore_buf_appendf(ckhdr_buf, "; Secure");
2569
2570 kore_buf_appendf(header_buf, "set-cookie: %s\r\n",
2571 kore_buf_stringify(ckhdr_buf, NULL));
2572 }
2573
2574 static int
2575 http_data_convert(void *data, void **out, void *nout, int type)
2576 {
2577 switch (type) {
2578 case HTTP_ARG_TYPE_RAW:
2579 case HTTP_ARG_TYPE_STRING:
2580 *out = data;
2581 return (KORE_RESULT_OK);
2582 case HTTP_ARG_TYPE_BYTE:
2583 COPY_ARG_TYPE(*(u_int8_t *)data, u_int8_t);
2584 return (KORE_RESULT_OK);
2585 case HTTP_ARG_TYPE_INT16:
2586 COPY_AS_INTTYPE(SHRT_MIN, SHRT_MAX, int16_t);
2587 return (KORE_RESULT_OK);
2588 case HTTP_ARG_TYPE_UINT16:
2589 COPY_AS_INTTYPE(0, USHRT_MAX, u_int16_t);
2590 return (KORE_RESULT_OK);
2591 case HTTP_ARG_TYPE_INT32:
2592 COPY_AS_INTTYPE(INT_MIN, INT_MAX, int32_t);
2593 return (KORE_RESULT_OK);
2594 case HTTP_ARG_TYPE_UINT32:
2595 COPY_AS_INTTYPE(0, UINT_MAX, u_int32_t);
2596 return (KORE_RESULT_OK);
2597 case HTTP_ARG_TYPE_INT64:
2598 COPY_AS_INTTYPE_64(int64_t, 1);
2599 return (KORE_RESULT_OK);
2600 case HTTP_ARG_TYPE_UINT64:
2601 COPY_AS_INTTYPE_64(u_int64_t, 0);
2602 return (KORE_RESULT_OK);
2603 case HTTP_ARG_TYPE_FLOAT:
2604 COPY_ARG_DOUBLE(-FLT_MAX, FLT_MAX, float);
2605 return (KORE_RESULT_OK);
2606 case HTTP_ARG_TYPE_DOUBLE:
2607 COPY_ARG_DOUBLE(-DBL_MAX, DBL_MAX, double);
2608 return (KORE_RESULT_OK);
2609 default:
2610 break;
2611 }
2612
2613 return (KORE_RESULT_ERROR);
2614 }