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