client.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. * uhttpd - Tiny single-threaded httpd
  3. *
  4. * Copyright (C) 2010-2013 Jo-Philipp Wich <xm@subsignal.org>
  5. * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  6. *
  7. * Permission to use, copy, modify, and/or distribute this software for any
  8. * purpose with or without fee is hereby granted, provided that the above
  9. * copyright notice and this permission notice appear in all copies.
  10. *
  11. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  14. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  15. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  16. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. #include <libubox/blobmsg.h>
  20. #include <ctype.h>
  21. #include "uhttpd.h"
  22. #include "tls.h"
  23. static LIST_HEAD(clients);
  24. static bool client_done = false;
  25. int n_clients = 0;
  26. struct config conf = {};
  27. const char * const http_versions[] = {
  28. [UH_HTTP_VER_0_9] = "HTTP/0.9",
  29. [UH_HTTP_VER_1_0] = "HTTP/1.0",
  30. [UH_HTTP_VER_1_1] = "HTTP/1.1",
  31. };
  32. const char * const http_methods[] = {
  33. [UH_HTTP_MSG_GET] = "GET",
  34. [UH_HTTP_MSG_POST] = "POST",
  35. [UH_HTTP_MSG_HEAD] = "HEAD",
  36. [UH_HTTP_MSG_OPTIONS] = "OPTIONS",
  37. [UH_HTTP_MSG_PUT] = "PUT",
  38. [UH_HTTP_MSG_PATCH] = "PATCH",
  39. [UH_HTTP_MSG_DELETE] = "DELETE",
  40. };
  41. void uh_http_header(struct client *cl, int code, const char *summary)
  42. {
  43. struct http_request *r = &cl->request;
  44. struct blob_attr *cur;
  45. const char *enc = "Transfer-Encoding: chunked\r\n";
  46. const char *conn;
  47. int rem;
  48. cl->http_code = code;
  49. if (!uh_use_chunked(cl))
  50. enc = "";
  51. if (r->connection_close)
  52. conn = "Connection: close";
  53. else
  54. conn = "Connection: Keep-Alive";
  55. ustream_printf(cl->us, "%s %03i %s\r\n%s\r\n%s",
  56. http_versions[cl->request.version],
  57. code, summary, conn, enc);
  58. if (!r->connection_close)
  59. ustream_printf(cl->us, "Keep-Alive: timeout=%d\r\n", conf.http_keepalive);
  60. blobmsg_for_each_attr(cur, cl->hdr_response.head, rem)
  61. ustream_printf(cl->us, "%s: %s\r\n", blobmsg_name(cur),
  62. blobmsg_get_string(cur));
  63. }
  64. static void uh_connection_close(struct client *cl)
  65. {
  66. cl->state = CLIENT_STATE_CLOSE;
  67. cl->us->eof = true;
  68. ustream_state_change(cl->us);
  69. }
  70. static void uh_dispatch_done(struct client *cl)
  71. {
  72. if (cl->dispatch.free)
  73. cl->dispatch.free(cl);
  74. if (cl->dispatch.req_free)
  75. cl->dispatch.req_free(cl);
  76. }
  77. static void client_timeout(struct uloop_timeout *timeout)
  78. {
  79. struct client *cl = container_of(timeout, struct client, timeout);
  80. cl->state = CLIENT_STATE_CLOSE;
  81. cl->request.connection_close = true;
  82. uh_request_done(cl);
  83. }
  84. static void uh_set_client_timeout(struct client *cl, int timeout)
  85. {
  86. cl->timeout.cb = client_timeout;
  87. uloop_timeout_set(&cl->timeout, timeout * 1000);
  88. }
  89. static void uh_keepalive_poll_cb(struct uloop_timeout *timeout)
  90. {
  91. struct client *cl = container_of(timeout, struct client, timeout);
  92. int sec = cl->requests > 0 ? conf.http_keepalive : conf.network_timeout;
  93. uh_set_client_timeout(cl, sec);
  94. cl->us->notify_read(cl->us, 0);
  95. }
  96. static void uh_poll_connection(struct client *cl)
  97. {
  98. cl->timeout.cb = uh_keepalive_poll_cb;
  99. uloop_timeout_set(&cl->timeout, 1);
  100. }
  101. void uh_request_done(struct client *cl)
  102. {
  103. uh_chunk_eof(cl);
  104. uh_dispatch_done(cl);
  105. blob_buf_init(&cl->hdr_response, 0);
  106. memset(&cl->dispatch, 0, sizeof(cl->dispatch));
  107. if (!conf.http_keepalive || cl->request.connection_close)
  108. return uh_connection_close(cl);
  109. cl->state = CLIENT_STATE_INIT;
  110. cl->requests++;
  111. uh_poll_connection(cl);
  112. }
  113. void __printf(4, 5)
  114. uh_client_error(struct client *cl, int code, const char *summary, const char *fmt, ...)
  115. {
  116. struct http_request *r = &cl->request;
  117. va_list arg;
  118. uh_http_header(cl, code, summary);
  119. ustream_printf(cl->us, "Content-Type: text/html\r\n\r\n");
  120. uh_chunk_printf(cl, "<h1>%s</h1>", summary);
  121. if (fmt) {
  122. va_start(arg, fmt);
  123. uh_chunk_vprintf(cl, fmt, arg);
  124. va_end(arg);
  125. }
  126. /* Close the connection even when keep alive is set, when it
  127. * contains a request body, as it was not read and we are
  128. * currently out of sync. Without handling this the body will be
  129. * interpreted as part of the next request. The alternative
  130. * would be to read and discard the request body here.
  131. */
  132. if (r->transfer_chunked || r->content_length > 0) {
  133. cl->state = CLIENT_STATE_CLOSE;
  134. cl->request.connection_close = true;
  135. }
  136. uh_request_done(cl);
  137. }
  138. static void uh_header_error(struct client *cl, int code, const char *summary)
  139. {
  140. uh_client_error(cl, code, summary, NULL);
  141. uh_connection_close(cl);
  142. }
  143. static int find_idx(const char * const *list, int max, const char *str)
  144. {
  145. int i;
  146. for (i = 0; i < max; i++)
  147. if (!strcmp(list[i], str))
  148. return i;
  149. return -1;
  150. }
  151. static int client_parse_request(struct client *cl, char *data)
  152. {
  153. struct http_request *req = &cl->request;
  154. char *type, *path, *version;
  155. int h_method, h_version;
  156. type = strtok(data, " ");
  157. path = strtok(NULL, " ");
  158. version = strtok(NULL, " ");
  159. if (!type || !path || !version)
  160. return CLIENT_STATE_DONE;
  161. blobmsg_add_string(&cl->hdr, "URL", path);
  162. memset(&cl->request, 0, sizeof(cl->request));
  163. h_method = find_idx(http_methods, ARRAY_SIZE(http_methods), type);
  164. h_version = find_idx(http_versions, ARRAY_SIZE(http_versions), version);
  165. if (h_method < 0 || h_version < 0) {
  166. req->version = UH_HTTP_VER_1_0;
  167. return CLIENT_STATE_DONE;
  168. }
  169. req->method = h_method;
  170. req->version = h_version;
  171. if (req->version < UH_HTTP_VER_1_1 || !conf.http_keepalive)
  172. req->connection_close = true;
  173. return CLIENT_STATE_HEADER;
  174. }
  175. static bool client_init_cb(struct client *cl, char *buf, int len)
  176. {
  177. char *newline;
  178. newline = strstr(buf, "\r\n");
  179. if (!newline)
  180. return false;
  181. if (newline == buf) {
  182. ustream_consume(cl->us, 2);
  183. return true;
  184. }
  185. *newline = 0;
  186. blob_buf_init(&cl->hdr, 0);
  187. cl->state = client_parse_request(cl, buf);
  188. ustream_consume(cl->us, newline + 2 - buf);
  189. if (cl->state == CLIENT_STATE_DONE)
  190. uh_header_error(cl, 400, "Bad Request");
  191. return true;
  192. }
  193. static bool rfc1918_filter_check(struct client *cl)
  194. {
  195. if (!conf.rfc1918_filter)
  196. return true;
  197. if (!uh_addr_rfc1918(&cl->peer_addr) || uh_addr_rfc1918(&cl->srv_addr))
  198. return true;
  199. uh_client_error(cl, 403, "Forbidden",
  200. "Rejected request from RFC1918 IP "
  201. "to public server address");
  202. return false;
  203. }
  204. static bool tls_redirect_check(struct client *cl)
  205. {
  206. int rem, port;
  207. struct blob_attr *cur;
  208. char *ptr, *url = NULL, *host = NULL;
  209. if (cl->tls || !conf.tls_redirect)
  210. return true;
  211. if ((port = uh_first_tls_port(cl->srv_addr.family)) == -1)
  212. return true;
  213. blob_for_each_attr(cur, cl->hdr.head, rem) {
  214. if (!strncmp(blobmsg_name(cur), "host", 4))
  215. host = blobmsg_get_string(cur);
  216. if (!strncmp(blobmsg_name(cur), "URL", 3))
  217. url = blobmsg_get_string(cur);
  218. if (url && host)
  219. break;
  220. }
  221. if (!url || !host)
  222. return true;
  223. if ((ptr = strchr(host, ']')) != NULL)
  224. *(ptr+1) = 0;
  225. else if ((ptr = strchr(host, ':')) != NULL)
  226. *ptr = 0;
  227. cl->request.disable_chunked = true;
  228. cl->request.connection_close = true;
  229. uh_http_header(cl, 307, "Temporary Redirect");
  230. if (port != 443)
  231. ustream_printf(cl->us, "Location: https://%s:%d%s\r\n\r\n", host, port, url);
  232. else
  233. ustream_printf(cl->us, "Location: https://%s%s\r\n\r\n", host, url);
  234. uh_request_done(cl);
  235. return false;
  236. }
  237. static void client_header_complete(struct client *cl)
  238. {
  239. struct http_request *r = &cl->request;
  240. if (!rfc1918_filter_check(cl))
  241. return;
  242. if (!tls_redirect_check(cl))
  243. return;
  244. if (r->expect_cont)
  245. ustream_printf(cl->us, "HTTP/1.1 100 Continue\r\n\r\n");
  246. switch(r->ua) {
  247. case UH_UA_MSIE_OLD:
  248. if (r->method != UH_HTTP_MSG_POST)
  249. break;
  250. /* fall through */
  251. case UH_UA_SAFARI:
  252. r->connection_close = true;
  253. break;
  254. default:
  255. break;
  256. }
  257. uh_handle_request(cl);
  258. }
  259. static void client_parse_header(struct client *cl, char *data)
  260. {
  261. struct http_request *r = &cl->request;
  262. char *err;
  263. char *name;
  264. char *val;
  265. if (!*data) {
  266. uloop_timeout_cancel(&cl->timeout);
  267. cl->state = CLIENT_STATE_DATA;
  268. client_header_complete(cl);
  269. return;
  270. }
  271. val = uh_split_header(data);
  272. if (!val) {
  273. cl->state = CLIENT_STATE_DONE;
  274. return;
  275. }
  276. for (name = data; *name; name++)
  277. if (isupper(*name))
  278. *name = tolower(*name);
  279. if (!strcmp(data, "expect")) {
  280. if (!strcasecmp(val, "100-continue"))
  281. r->expect_cont = true;
  282. else {
  283. uh_header_error(cl, 412, "Precondition Failed");
  284. return;
  285. }
  286. } else if (!strcmp(data, "content-length")) {
  287. r->content_length = strtoul(val, &err, 0);
  288. if ((err && *err) || r->content_length < 0) {
  289. uh_header_error(cl, 400, "Bad Request");
  290. return;
  291. }
  292. } else if (!strcmp(data, "transfer-encoding")) {
  293. if (!strcmp(val, "chunked"))
  294. r->transfer_chunked = true;
  295. } else if (!strcmp(data, "connection")) {
  296. if (!strcasecmp(val, "close"))
  297. r->connection_close = true;
  298. } else if (!strcmp(data, "user-agent")) {
  299. char *str;
  300. if (strstr(val, "Opera"))
  301. r->ua = UH_UA_OPERA;
  302. else if ((str = strstr(val, "MSIE ")) != NULL) {
  303. r->ua = UH_UA_MSIE_NEW;
  304. if (str[5] && str[6] == '.') {
  305. switch (str[5]) {
  306. case '6':
  307. if (strstr(str, "SV1"))
  308. break;
  309. /* fall through */
  310. case '5':
  311. case '4':
  312. r->ua = UH_UA_MSIE_OLD;
  313. break;
  314. }
  315. }
  316. }
  317. else if (strstr(val, "Chrome/"))
  318. r->ua = UH_UA_CHROME;
  319. else if (strstr(val, "Safari/") && strstr(val, "Mac OS X"))
  320. r->ua = UH_UA_SAFARI;
  321. else if (strstr(val, "Gecko/"))
  322. r->ua = UH_UA_GECKO;
  323. else if (strstr(val, "Konqueror"))
  324. r->ua = UH_UA_KONQUEROR;
  325. }
  326. blobmsg_add_string(&cl->hdr, data, val);
  327. cl->state = CLIENT_STATE_HEADER;
  328. }
  329. void client_poll_post_data(struct client *cl)
  330. {
  331. struct dispatch *d = &cl->dispatch;
  332. struct http_request *r = &cl->request;
  333. enum client_state st;
  334. char *buf;
  335. int len;
  336. if (cl->state == CLIENT_STATE_DONE)
  337. return;
  338. while (1) {
  339. char *sep;
  340. int offset = 0;
  341. int cur_len;
  342. buf = ustream_get_read_buf(cl->us, &len);
  343. if (!buf || !len)
  344. break;
  345. if (!d->data_send)
  346. return;
  347. cur_len = min(r->content_length, len);
  348. if (cur_len) {
  349. if (d->data_blocked)
  350. break;
  351. if (d->data_send)
  352. cur_len = d->data_send(cl, buf, cur_len);
  353. r->content_length -= cur_len;
  354. ustream_consume(cl->us, cur_len);
  355. continue;
  356. }
  357. if (!r->transfer_chunked)
  358. break;
  359. if (r->transfer_chunked > 1)
  360. offset = 2;
  361. sep = strstr(buf + offset, "\r\n");
  362. if (!sep)
  363. break;
  364. *sep = 0;
  365. r->content_length = strtoul(buf + offset, &sep, 16);
  366. r->transfer_chunked++;
  367. ustream_consume(cl->us, sep + 2 - buf);
  368. /* invalid chunk length */
  369. if ((sep && *sep) || r->content_length < 0) {
  370. r->content_length = 0;
  371. r->transfer_chunked = 0;
  372. break;
  373. }
  374. /* empty chunk == eof */
  375. if (!r->content_length) {
  376. r->transfer_chunked = false;
  377. break;
  378. }
  379. }
  380. buf = ustream_get_read_buf(cl->us, &len);
  381. if (!r->content_length && !r->transfer_chunked &&
  382. cl->state != CLIENT_STATE_DONE) {
  383. st = cl->state;
  384. if (cl->dispatch.data_done)
  385. cl->dispatch.data_done(cl);
  386. if (cl->state == st)
  387. cl->state = CLIENT_STATE_DONE;
  388. }
  389. }
  390. static bool client_data_cb(struct client *cl, char *buf, int len)
  391. {
  392. client_poll_post_data(cl);
  393. return false;
  394. }
  395. static bool client_header_cb(struct client *cl, char *buf, int len)
  396. {
  397. char *newline;
  398. int line_len;
  399. newline = strstr(buf, "\r\n");
  400. if (!newline)
  401. return false;
  402. *newline = 0;
  403. client_parse_header(cl, buf);
  404. line_len = newline + 2 - buf;
  405. ustream_consume(cl->us, line_len);
  406. if (cl->state == CLIENT_STATE_DATA)
  407. return client_data_cb(cl, newline + 2, len - line_len);
  408. return true;
  409. }
  410. typedef bool (*read_cb_t)(struct client *cl, char *buf, int len);
  411. static read_cb_t read_cbs[] = {
  412. [CLIENT_STATE_INIT] = client_init_cb,
  413. [CLIENT_STATE_HEADER] = client_header_cb,
  414. [CLIENT_STATE_DATA] = client_data_cb,
  415. };
  416. void uh_client_read_cb(struct client *cl)
  417. {
  418. struct ustream *us = cl->us;
  419. char *str;
  420. int len;
  421. client_done = false;
  422. do {
  423. str = ustream_get_read_buf(us, &len);
  424. if (!str || !len)
  425. break;
  426. if (cl->state >= array_size(read_cbs) || !read_cbs[cl->state])
  427. break;
  428. if (!read_cbs[cl->state](cl, str, len)) {
  429. if (len == us->r.buffer_len &&
  430. cl->state != CLIENT_STATE_DATA &&
  431. cl->state != CLIENT_STATE_DONE)
  432. uh_header_error(cl, 413, "Request Entity Too Large");
  433. break;
  434. }
  435. } while (!client_done);
  436. }
  437. static void client_close(struct client *cl)
  438. {
  439. if (cl->refcount) {
  440. cl->state = CLIENT_STATE_CLEANUP;
  441. return;
  442. }
  443. client_done = true;
  444. n_clients--;
  445. uh_dispatch_done(cl);
  446. uloop_timeout_cancel(&cl->timeout);
  447. if (cl->tls)
  448. uh_tls_client_detach(cl);
  449. ustream_free(&cl->sfd.stream);
  450. close(cl->sfd.fd.fd);
  451. list_del(&cl->list);
  452. blob_buf_free(&cl->hdr);
  453. blob_buf_free(&cl->hdr_response);
  454. free(cl);
  455. uh_unblock_listeners();
  456. }
  457. void uh_client_notify_state(struct client *cl)
  458. {
  459. struct ustream *s = cl->us;
  460. if (!s->write_error && cl->state != CLIENT_STATE_CLEANUP) {
  461. if (cl->state == CLIENT_STATE_DATA)
  462. return;
  463. if (!s->eof || s->w.data_bytes)
  464. return;
  465. #ifdef HAVE_TLS
  466. if (cl->tls && cl->ssl.conn && cl->ssl.conn->w.data_bytes) {
  467. cl->ssl.conn->eof = s->eof;
  468. if (!ustream_write_pending(cl->ssl.conn))
  469. return;
  470. }
  471. #endif
  472. }
  473. return client_close(cl);
  474. }
  475. static void client_ustream_read_cb(struct ustream *s, int bytes)
  476. {
  477. struct client *cl = container_of(s, struct client, sfd.stream);
  478. uh_client_read_cb(cl);
  479. }
  480. static void client_ustream_write_cb(struct ustream *s, int bytes)
  481. {
  482. struct client *cl = container_of(s, struct client, sfd.stream);
  483. if (cl->dispatch.write_cb)
  484. cl->dispatch.write_cb(cl);
  485. }
  486. static void client_notify_state(struct ustream *s)
  487. {
  488. struct client *cl = container_of(s, struct client, sfd.stream);
  489. uh_client_notify_state(cl);
  490. }
  491. static void set_addr(struct uh_addr *addr, void *src)
  492. {
  493. struct sockaddr_in *sin = src;
  494. struct sockaddr_in6 *sin6 = src;
  495. addr->family = sin->sin_family;
  496. if (addr->family == AF_INET) {
  497. addr->port = ntohs(sin->sin_port);
  498. memcpy(&addr->in, &sin->sin_addr, sizeof(addr->in));
  499. } else {
  500. addr->port = ntohs(sin6->sin6_port);
  501. memcpy(&addr->in6, &sin6->sin6_addr, sizeof(addr->in6));
  502. }
  503. }
  504. bool uh_accept_client(int fd, bool tls)
  505. {
  506. static struct client *next_client;
  507. struct client *cl;
  508. unsigned int sl;
  509. int sfd;
  510. static int client_id = 0;
  511. struct sockaddr_in6 addr;
  512. if (!next_client)
  513. next_client = calloc(1, sizeof(*next_client));
  514. cl = next_client;
  515. sl = sizeof(addr);
  516. sfd = accept(fd, (struct sockaddr *) &addr, &sl);
  517. if (sfd < 0)
  518. return false;
  519. set_addr(&cl->peer_addr, &addr);
  520. sl = sizeof(addr);
  521. getsockname(sfd, (struct sockaddr *) &addr, &sl);
  522. set_addr(&cl->srv_addr, &addr);
  523. cl->us = &cl->sfd.stream;
  524. if (tls) {
  525. uh_tls_client_attach(cl);
  526. } else {
  527. cl->us->notify_read = client_ustream_read_cb;
  528. cl->us->notify_write = client_ustream_write_cb;
  529. cl->us->notify_state = client_notify_state;
  530. }
  531. cl->us->string_data = true;
  532. ustream_fd_init(&cl->sfd, sfd);
  533. uh_poll_connection(cl);
  534. list_add_tail(&cl->list, &clients);
  535. next_client = NULL;
  536. n_clients++;
  537. cl->id = client_id++;
  538. cl->tls = tls;
  539. return true;
  540. }
  541. void uh_close_fds(void)
  542. {
  543. struct client *cl;
  544. uloop_done();
  545. uh_close_listen_fds();
  546. list_for_each_entry(cl, &clients, list) {
  547. close(cl->sfd.fd.fd);
  548. if (cl->dispatch.close_fds)
  549. cl->dispatch.close_fds(cl);
  550. }
  551. }