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