uclient-http.c 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. /*
  2. * uclient - ustream based protocol client library
  3. *
  4. * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
  5. *
  6. * Permission to use, copy, modify, and/or distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include <stdio.h>
  19. #include <ctype.h>
  20. #include <unistd.h>
  21. #include <stdint.h>
  22. #include <libubox/ustream.h>
  23. #include <libubox/ustream-ssl.h>
  24. #include <libubox/usock.h>
  25. #include <libubox/blobmsg.h>
  26. #include "uclient.h"
  27. #include "uclient-utils.h"
  28. #include "uclient-backend.h"
  29. enum auth_type {
  30. AUTH_TYPE_UNKNOWN,
  31. AUTH_TYPE_NONE,
  32. AUTH_TYPE_BASIC,
  33. AUTH_TYPE_DIGEST,
  34. };
  35. enum request_type {
  36. REQ_GET,
  37. REQ_HEAD,
  38. REQ_POST,
  39. REQ_PUT,
  40. REQ_DELETE,
  41. __REQ_MAX
  42. };
  43. enum http_state {
  44. HTTP_STATE_INIT,
  45. HTTP_STATE_HEADERS_SENT,
  46. HTTP_STATE_REQUEST_DONE,
  47. HTTP_STATE_RECV_HEADERS,
  48. HTTP_STATE_RECV_DATA,
  49. HTTP_STATE_ERROR,
  50. };
  51. static const char * const request_types[__REQ_MAX] = {
  52. [REQ_GET] = "GET",
  53. [REQ_HEAD] = "HEAD",
  54. [REQ_POST] = "POST",
  55. [REQ_PUT] = "PUT",
  56. [REQ_DELETE] = "DELETE",
  57. };
  58. struct uclient_http {
  59. struct uclient uc;
  60. const struct ustream_ssl_ops *ssl_ops;
  61. struct ustream_ssl_ctx *ssl_ctx;
  62. struct ustream *us;
  63. struct ustream_fd ufd;
  64. struct ustream_ssl ussl;
  65. struct uloop_timeout disconnect_t;
  66. unsigned int seq;
  67. bool ssl_require_validation;
  68. bool ssl;
  69. bool eof;
  70. bool connection_close;
  71. bool disconnect;
  72. enum request_type req_type;
  73. enum http_state state;
  74. enum auth_type auth_type;
  75. char *auth_str;
  76. long read_chunked;
  77. long content_length;
  78. uint32_t nc;
  79. struct blob_buf headers;
  80. struct blob_buf meta;
  81. };
  82. enum {
  83. PREFIX_HTTP,
  84. PREFIX_HTTPS,
  85. __PREFIX_MAX,
  86. };
  87. static const char * const uclient_http_prefix[] = {
  88. [PREFIX_HTTP] = "http://",
  89. [PREFIX_HTTPS] = "https://",
  90. [__PREFIX_MAX] = NULL
  91. };
  92. static int uclient_do_connect(struct uclient_http *uh, const char *port)
  93. {
  94. socklen_t sl;
  95. int fd;
  96. if (uh->uc.url->port)
  97. port = uh->uc.url->port;
  98. memset(&uh->uc.remote_addr, 0, sizeof(uh->uc.remote_addr));
  99. fd = usock_inet(USOCK_TCP | USOCK_NONBLOCK, uh->uc.url->host, port, &uh->uc.remote_addr);
  100. if (fd < 0)
  101. return -1;
  102. ustream_fd_init(&uh->ufd, fd);
  103. sl = sizeof(uh->uc.local_addr);
  104. memset(&uh->uc.local_addr, 0, sl);
  105. getsockname(fd, &uh->uc.local_addr.sa, &sl);
  106. return 0;
  107. }
  108. static void uclient_http_disconnect(struct uclient_http *uh)
  109. {
  110. uloop_timeout_cancel(&uh->disconnect_t);
  111. if (!uh->us)
  112. return;
  113. if (uh->ssl)
  114. ustream_free(&uh->ussl.stream);
  115. ustream_free(&uh->ufd.stream);
  116. close(uh->ufd.fd.fd);
  117. uh->us = NULL;
  118. }
  119. static void uclient_http_free_url_state(struct uclient *cl)
  120. {
  121. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  122. uh->auth_type = AUTH_TYPE_UNKNOWN;
  123. free(uh->auth_str);
  124. uh->auth_str = NULL;
  125. uclient_http_disconnect(uh);
  126. }
  127. static void uclient_http_error(struct uclient_http *uh, int code)
  128. {
  129. uh->state = HTTP_STATE_ERROR;
  130. uh->us->eof = true;
  131. ustream_state_change(uh->us);
  132. uclient_backend_set_error(&uh->uc, code);
  133. }
  134. static void uclient_http_request_disconnect(struct uclient *cl)
  135. {
  136. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  137. if (!uh->us)
  138. return;
  139. uh->eof = true;
  140. uh->disconnect = true;
  141. uloop_timeout_set(&uh->disconnect_t, 1);
  142. }
  143. static void uclient_notify_eof(struct uclient_http *uh)
  144. {
  145. struct ustream *us = uh->us;
  146. if (uh->disconnect)
  147. return;
  148. if (!uh->eof) {
  149. if (!us->eof && !us->write_error)
  150. return;
  151. if (ustream_pending_data(us, false))
  152. return;
  153. }
  154. uclient_backend_set_eof(&uh->uc);
  155. if (uh->connection_close)
  156. uclient_http_request_disconnect(&uh->uc);
  157. }
  158. static void uclient_http_reset_state(struct uclient_http *uh)
  159. {
  160. uh->seq++;
  161. uclient_backend_reset_state(&uh->uc);
  162. uh->read_chunked = -1;
  163. uh->content_length = -1;
  164. uh->eof = false;
  165. uh->disconnect = false;
  166. uh->connection_close = false;
  167. uh->state = HTTP_STATE_INIT;
  168. if (uh->auth_type == AUTH_TYPE_UNKNOWN && !uh->uc.url->auth)
  169. uh->auth_type = AUTH_TYPE_NONE;
  170. }
  171. static void uclient_http_init_request(struct uclient_http *uh)
  172. {
  173. uh->seq++;
  174. uclient_http_reset_state(uh);
  175. blob_buf_init(&uh->meta, 0);
  176. }
  177. static enum auth_type
  178. uclient_http_update_auth_type(struct uclient_http *uh)
  179. {
  180. if (!uh->auth_str)
  181. return AUTH_TYPE_NONE;
  182. if (!strncasecmp(uh->auth_str, "basic", 5))
  183. return AUTH_TYPE_BASIC;
  184. if (!strncasecmp(uh->auth_str, "digest", 6))
  185. return AUTH_TYPE_DIGEST;
  186. return AUTH_TYPE_NONE;
  187. }
  188. static void uclient_http_process_headers(struct uclient_http *uh)
  189. {
  190. enum {
  191. HTTP_HDR_TRANSFER_ENCODING,
  192. HTTP_HDR_CONNECTION,
  193. HTTP_HDR_CONTENT_LENGTH,
  194. HTTP_HDR_AUTH,
  195. __HTTP_HDR_MAX,
  196. };
  197. static const struct blobmsg_policy hdr_policy[__HTTP_HDR_MAX] = {
  198. #define hdr(_name) { .name = _name, .type = BLOBMSG_TYPE_STRING }
  199. [HTTP_HDR_TRANSFER_ENCODING] = hdr("transfer-encoding"),
  200. [HTTP_HDR_CONNECTION] = hdr("connection"),
  201. [HTTP_HDR_CONTENT_LENGTH] = hdr("content-length"),
  202. [HTTP_HDR_AUTH] = hdr("www-authenticate"),
  203. #undef hdr
  204. };
  205. struct blob_attr *tb[__HTTP_HDR_MAX];
  206. struct blob_attr *cur;
  207. blobmsg_parse(hdr_policy, __HTTP_HDR_MAX, tb, blob_data(uh->meta.head), blob_len(uh->meta.head));
  208. cur = tb[HTTP_HDR_TRANSFER_ENCODING];
  209. if (cur && strstr(blobmsg_data(cur), "chunked"))
  210. uh->read_chunked = 0;
  211. cur = tb[HTTP_HDR_CONNECTION];
  212. if (cur && strstr(blobmsg_data(cur), "close"))
  213. uh->connection_close = true;
  214. cur = tb[HTTP_HDR_CONTENT_LENGTH];
  215. if (cur)
  216. uh->content_length = strtoul(blobmsg_data(cur), NULL, 10);
  217. cur = tb[HTTP_HDR_AUTH];
  218. if (cur) {
  219. free(uh->auth_str);
  220. uh->auth_str = strdup(blobmsg_data(cur));
  221. }
  222. uh->auth_type = uclient_http_update_auth_type(uh);
  223. }
  224. static void
  225. uclient_http_add_auth_basic(struct uclient_http *uh)
  226. {
  227. struct uclient_url *url = uh->uc.url;
  228. int auth_len = strlen(url->auth);
  229. char *auth_buf;
  230. if (auth_len > 512)
  231. return;
  232. auth_buf = alloca(base64_len(auth_len) + 1);
  233. base64_encode(url->auth, auth_len, auth_buf);
  234. ustream_printf(uh->us, "Authorization: Basic %s\r\n", auth_buf);
  235. }
  236. static char *digest_unquote_sep(char **str)
  237. {
  238. char *cur = *str + 1;
  239. char *start = cur;
  240. char *out;
  241. if (**str != '"')
  242. return NULL;
  243. out = cur;
  244. while (1) {
  245. if (!*cur)
  246. return NULL;
  247. if (*cur == '"') {
  248. cur++;
  249. break;
  250. }
  251. if (*cur == '\\')
  252. cur++;
  253. *(out++) = *(cur++);
  254. }
  255. if (*cur == ',')
  256. cur++;
  257. *out = 0;
  258. *str = cur;
  259. return start;
  260. }
  261. static char *digest_sep(char **str)
  262. {
  263. char *cur, *next;
  264. cur = *str;
  265. next = strchr(*str, ',');
  266. if (next) {
  267. *str = next + 1;
  268. *next = 0;
  269. } else {
  270. *str += strlen(*str);
  271. }
  272. return cur;
  273. }
  274. static bool strmatch(char **str, const char *prefix)
  275. {
  276. int len = strlen(prefix);
  277. if (strncmp(*str, prefix, len) != 0 || (*str)[len] != '=')
  278. return false;
  279. *str += len + 1;
  280. return true;
  281. }
  282. static void
  283. get_cnonce(char *dest)
  284. {
  285. uint32_t val = 0;
  286. FILE *f;
  287. f = fopen("/dev/urandom", "r");
  288. if (f) {
  289. fread(&val, sizeof(val), 1, f);
  290. fclose(f);
  291. }
  292. bin_to_hex(dest, &val, sizeof(val));
  293. }
  294. static void add_field(char **buf, int *ofs, int *len, const char *name, const char *val)
  295. {
  296. int available = *len - *ofs;
  297. int required;
  298. const char *next;
  299. char *cur;
  300. if (*len && !*buf)
  301. return;
  302. required = strlen(name) + 4 + strlen(val) * 2;
  303. if (required > available)
  304. *len += required - available + 64;
  305. *buf = realloc(*buf, *len);
  306. if (!*buf)
  307. return;
  308. cur = *buf + *ofs;
  309. cur += sprintf(cur, ", %s=\"", name);
  310. while ((next = strchr(val, '"'))) {
  311. if (next > val) {
  312. memcpy(cur, val, next - val);
  313. cur += next - val;
  314. }
  315. cur += sprintf(cur, "\\\"");
  316. val = next + 1;
  317. }
  318. cur += sprintf(cur, "%s\"", val);
  319. *ofs = cur - *buf;
  320. }
  321. static void
  322. uclient_http_add_auth_digest(struct uclient_http *uh)
  323. {
  324. struct uclient_url *url = uh->uc.url;
  325. const char *realm = NULL, *opaque = NULL;
  326. const char *user, *password;
  327. char *buf, *next;
  328. int len, ofs;
  329. char cnonce_str[9];
  330. char nc_str[9];
  331. char ahash[33];
  332. char hash[33];
  333. struct http_digest_data data = {
  334. .nc = nc_str,
  335. .cnonce = cnonce_str,
  336. .auth_hash = ahash,
  337. };
  338. len = strlen(uh->auth_str) + 1;
  339. if (len > 512)
  340. return;
  341. buf = alloca(len);
  342. strcpy(buf, uh->auth_str);
  343. /* skip auth type */
  344. strsep(&buf, " ");
  345. next = buf;
  346. while (*next) {
  347. const char **dest = NULL;
  348. const char *tmp;
  349. while (*next && isspace(*next))
  350. next++;
  351. if (strmatch(&next, "realm"))
  352. dest = &realm;
  353. else if (strmatch(&next, "qop"))
  354. dest = &data.qop;
  355. else if (strmatch(&next, "nonce"))
  356. dest = &data.nonce;
  357. else if (strmatch(&next, "opaque"))
  358. dest = &opaque;
  359. else if (strmatch(&next, "stale") ||
  360. strmatch(&next, "algorithm") ||
  361. strmatch(&next, "auth-param")) {
  362. digest_sep(&next);
  363. continue;
  364. } else if (strmatch(&next, "domain") ||
  365. strmatch(&next, "qop-options"))
  366. dest = &tmp;
  367. else {
  368. digest_sep(&next);
  369. continue;
  370. }
  371. *dest = digest_unquote_sep(&next);
  372. }
  373. if (!realm || !data.qop || !data.nonce)
  374. return;
  375. sprintf(nc_str, "%08x", uh->nc++);
  376. get_cnonce(cnonce_str);
  377. data.qop = "auth";
  378. data.uri = url->location;
  379. data.method = request_types[uh->req_type];
  380. password = strchr(url->auth, ':');
  381. if (password) {
  382. char *user_buf;
  383. len = password - url->auth;
  384. if (len > 256)
  385. return;
  386. user_buf = alloca(len + 1);
  387. strncpy(user_buf, url->auth, len);
  388. user_buf[len] = 0;
  389. user = user_buf;
  390. password++;
  391. } else {
  392. user = url->auth;
  393. password = "";
  394. }
  395. http_digest_calculate_auth_hash(ahash, user, realm, password);
  396. http_digest_calculate_response(hash, &data);
  397. buf = NULL;
  398. len = 0;
  399. ofs = 0;
  400. add_field(&buf, &ofs, &len, "username", user);
  401. add_field(&buf, &ofs, &len, "realm", realm);
  402. add_field(&buf, &ofs, &len, "nonce", data.nonce);
  403. add_field(&buf, &ofs, &len, "uri", data.uri);
  404. add_field(&buf, &ofs, &len, "cnonce", data.cnonce);
  405. add_field(&buf, &ofs, &len, "response", hash);
  406. if (opaque)
  407. add_field(&buf, &ofs, &len, "opaque", opaque);
  408. ustream_printf(uh->us, "Authorization: Digest nc=%s, qop=%s%s\r\n", data.nc, data.qop, buf);
  409. free(buf);
  410. }
  411. static void
  412. uclient_http_add_auth_header(struct uclient_http *uh)
  413. {
  414. if (!uh->uc.url->auth)
  415. return;
  416. switch (uh->auth_type) {
  417. case AUTH_TYPE_UNKNOWN:
  418. case AUTH_TYPE_NONE:
  419. break;
  420. case AUTH_TYPE_BASIC:
  421. uclient_http_add_auth_basic(uh);
  422. break;
  423. case AUTH_TYPE_DIGEST:
  424. uclient_http_add_auth_digest(uh);
  425. break;
  426. }
  427. }
  428. static void
  429. uclient_http_send_headers(struct uclient_http *uh)
  430. {
  431. struct uclient_url *url = uh->uc.url;
  432. struct blob_attr *cur;
  433. enum request_type req_type = uh->req_type;
  434. int rem;
  435. if (uh->state >= HTTP_STATE_HEADERS_SENT)
  436. return;
  437. ustream_printf(uh->us,
  438. "%s %s HTTP/1.1\r\n"
  439. "Host: %s\r\n",
  440. request_types[req_type],
  441. url->location, url->host);
  442. blobmsg_for_each_attr(cur, uh->headers.head, rem)
  443. ustream_printf(uh->us, "%s: %s\r\n", blobmsg_name(cur), (char *) blobmsg_data(cur));
  444. if (uh->req_type == REQ_POST || uh->req_type == REQ_PUT)
  445. ustream_printf(uh->us, "Transfer-Encoding: chunked\r\n");
  446. uclient_http_add_auth_header(uh);
  447. ustream_printf(uh->us, "\r\n");
  448. uh->state = HTTP_STATE_HEADERS_SENT;
  449. }
  450. static void uclient_http_headers_complete(struct uclient_http *uh)
  451. {
  452. enum auth_type auth_type = uh->auth_type;
  453. int seq = uh->uc.seq;
  454. uh->state = HTTP_STATE_RECV_DATA;
  455. uh->uc.meta = uh->meta.head;
  456. uclient_http_process_headers(uh);
  457. if (auth_type == AUTH_TYPE_UNKNOWN && uh->uc.status_code == 401 &&
  458. (uh->req_type == REQ_HEAD || uh->req_type == REQ_GET)) {
  459. uclient_http_init_request(uh);
  460. uclient_http_send_headers(uh);
  461. uh->state = HTTP_STATE_REQUEST_DONE;
  462. return;
  463. }
  464. if (uh->uc.cb->header_done)
  465. uh->uc.cb->header_done(&uh->uc);
  466. if (uh->eof || seq != uh->uc.seq)
  467. return;
  468. if (uh->req_type == REQ_HEAD || uh->uc.status_code == 204) {
  469. uh->eof = true;
  470. uclient_notify_eof(uh);
  471. }
  472. }
  473. static void uclient_parse_http_line(struct uclient_http *uh, char *data)
  474. {
  475. char *name;
  476. char *sep;
  477. if (uh->state == HTTP_STATE_REQUEST_DONE) {
  478. char *code;
  479. if (!strlen(data))
  480. return;
  481. /* HTTP/1.1 */
  482. strsep(&data, " ");
  483. code = strsep(&data, " ");
  484. if (!code)
  485. goto error;
  486. uh->uc.status_code = strtoul(code, &sep, 10);
  487. if (sep && *sep)
  488. goto error;
  489. uh->state = HTTP_STATE_RECV_HEADERS;
  490. return;
  491. }
  492. if (!*data) {
  493. uclient_http_headers_complete(uh);
  494. return;
  495. }
  496. sep = strchr(data, ':');
  497. if (!sep)
  498. return;
  499. *(sep++) = 0;
  500. for (name = data; *name; name++)
  501. *name = tolower(*name);
  502. name = data;
  503. while (isspace(*sep))
  504. sep++;
  505. blobmsg_add_string(&uh->meta, name, sep);
  506. return;
  507. error:
  508. uh->uc.status_code = 400;
  509. uh->eof = true;
  510. uclient_notify_eof(uh);
  511. }
  512. static void __uclient_notify_read(struct uclient_http *uh)
  513. {
  514. struct uclient *uc = &uh->uc;
  515. unsigned int seq = uh->seq;
  516. char *data;
  517. int len;
  518. if (uh->state < HTTP_STATE_REQUEST_DONE || uh->state == HTTP_STATE_ERROR)
  519. return;
  520. data = ustream_get_read_buf(uh->us, &len);
  521. if (!data || !len)
  522. return;
  523. if (uh->state < HTTP_STATE_RECV_DATA) {
  524. char *sep;
  525. int cur_len;
  526. do {
  527. sep = strstr(data, "\r\n");
  528. if (!sep)
  529. break;
  530. /* Check for multi-line HTTP headers */
  531. if (sep > data) {
  532. if (!sep[2])
  533. return;
  534. if (isspace(sep[2]) && sep[2] != '\r') {
  535. sep[0] = ' ';
  536. sep[1] = ' ';
  537. continue;
  538. }
  539. }
  540. *sep = 0;
  541. cur_len = sep + 2 - data;
  542. uclient_parse_http_line(uh, data);
  543. if (seq != uh->seq)
  544. return;
  545. ustream_consume(uh->us, cur_len);
  546. len -= cur_len;
  547. if (uh->eof)
  548. return;
  549. data = ustream_get_read_buf(uh->us, &len);
  550. } while (data && uh->state < HTTP_STATE_RECV_DATA);
  551. if (!len)
  552. return;
  553. }
  554. if (uh->eof)
  555. return;
  556. if (uh->state == HTTP_STATE_RECV_DATA) {
  557. /* Now it's uclient user turn to read some data */
  558. uloop_timeout_cancel(&uc->connection_timeout);
  559. if (uc->cb->data_read)
  560. uc->cb->data_read(uc);
  561. }
  562. }
  563. static void __uclient_notify_write(struct uclient_http *uh)
  564. {
  565. struct uclient *uc = &uh->uc;
  566. if (uc->cb->data_sent)
  567. uc->cb->data_sent(uc);
  568. }
  569. static void uclient_notify_read(struct ustream *us, int bytes)
  570. {
  571. struct uclient_http *uh = container_of(us, struct uclient_http, ufd.stream);
  572. __uclient_notify_read(uh);
  573. }
  574. static void uclient_notify_write(struct ustream *us, int bytes)
  575. {
  576. struct uclient_http *uh = container_of(us, struct uclient_http, ufd.stream);
  577. __uclient_notify_write(uh);
  578. }
  579. static void uclient_notify_state(struct ustream *us)
  580. {
  581. struct uclient_http *uh = container_of(us, struct uclient_http, ufd.stream);
  582. uclient_notify_eof(uh);
  583. }
  584. static int uclient_setup_http(struct uclient_http *uh)
  585. {
  586. struct ustream *us = &uh->ufd.stream;
  587. int ret;
  588. uh->us = us;
  589. uh->ssl = false;
  590. us->string_data = true;
  591. us->notify_state = uclient_notify_state;
  592. us->notify_read = uclient_notify_read;
  593. us->notify_write = uclient_notify_write;
  594. ret = uclient_do_connect(uh, "80");
  595. if (ret)
  596. return UCLIENT_ERROR_CONNECT;
  597. return 0;
  598. }
  599. static void uclient_ssl_notify_read(struct ustream *us, int bytes)
  600. {
  601. struct uclient_http *uh = container_of(us, struct uclient_http, ussl.stream);
  602. __uclient_notify_read(uh);
  603. }
  604. static void uclient_ssl_notify_write(struct ustream *us, int bytes)
  605. {
  606. struct uclient_http *uh = container_of(us, struct uclient_http, ussl.stream);
  607. __uclient_notify_write(uh);
  608. }
  609. static void uclient_ssl_notify_state(struct ustream *us)
  610. {
  611. struct uclient_http *uh = container_of(us, struct uclient_http, ussl.stream);
  612. uclient_notify_eof(uh);
  613. }
  614. static void uclient_ssl_notify_error(struct ustream_ssl *ssl, int error, const char *str)
  615. {
  616. struct uclient_http *uh = container_of(ssl, struct uclient_http, ussl);
  617. uclient_http_error(uh, UCLIENT_ERROR_CONNECT);
  618. }
  619. static void uclient_ssl_notify_verify_error(struct ustream_ssl *ssl, int error, const char *str)
  620. {
  621. struct uclient_http *uh = container_of(ssl, struct uclient_http, ussl);
  622. if (!uh->ssl_require_validation)
  623. return;
  624. uclient_http_error(uh, UCLIENT_ERROR_SSL_INVALID_CERT);
  625. }
  626. static void uclient_ssl_notify_connected(struct ustream_ssl *ssl)
  627. {
  628. struct uclient_http *uh = container_of(ssl, struct uclient_http, ussl);
  629. if (!uh->ssl_require_validation)
  630. return;
  631. if (!uh->ussl.valid_cn)
  632. uclient_http_error(uh, UCLIENT_ERROR_SSL_CN_MISMATCH);
  633. }
  634. static int uclient_setup_https(struct uclient_http *uh)
  635. {
  636. struct ustream *us = &uh->ussl.stream;
  637. int ret;
  638. uh->ssl = true;
  639. uh->us = us;
  640. if (!uh->ssl_ctx)
  641. return UCLIENT_ERROR_MISSING_SSL_CONTEXT;
  642. ret = uclient_do_connect(uh, "443");
  643. if (ret)
  644. return UCLIENT_ERROR_CONNECT;
  645. us->string_data = true;
  646. us->notify_state = uclient_ssl_notify_state;
  647. us->notify_read = uclient_ssl_notify_read;
  648. us->notify_write = uclient_ssl_notify_write;
  649. uh->ussl.notify_error = uclient_ssl_notify_error;
  650. uh->ussl.notify_verify_error = uclient_ssl_notify_verify_error;
  651. uh->ussl.notify_connected = uclient_ssl_notify_connected;
  652. uh->ussl.server_name = uh->uc.url->host;
  653. uh->ssl_ops->init(&uh->ussl, &uh->ufd.stream, uh->ssl_ctx, false);
  654. uh->ssl_ops->set_peer_cn(&uh->ussl, uh->uc.url->host);
  655. return 0;
  656. }
  657. static int uclient_http_connect(struct uclient *cl)
  658. {
  659. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  660. int ret;
  661. if (!cl->eof || uh->disconnect)
  662. uclient_http_disconnect(uh);
  663. uclient_http_init_request(uh);
  664. if (uh->us)
  665. return 0;
  666. uh->ssl = cl->url->prefix == PREFIX_HTTPS;
  667. if (uh->ssl)
  668. ret = uclient_setup_https(uh);
  669. else
  670. ret = uclient_setup_http(uh);
  671. return ret;
  672. }
  673. static void uclient_http_disconnect_cb(struct uloop_timeout *timeout)
  674. {
  675. struct uclient_http *uh = container_of(timeout, struct uclient_http, disconnect_t);
  676. uclient_http_disconnect(uh);
  677. }
  678. static struct uclient *uclient_http_alloc(void)
  679. {
  680. struct uclient_http *uh;
  681. uh = calloc_a(sizeof(*uh));
  682. uh->disconnect_t.cb = uclient_http_disconnect_cb;
  683. blob_buf_init(&uh->headers, 0);
  684. return &uh->uc;
  685. }
  686. static void uclient_http_free_ssl_ctx(struct uclient_http *uh)
  687. {
  688. uh->ssl_ops = NULL;
  689. uh->ssl_ctx = NULL;
  690. }
  691. static void uclient_http_free(struct uclient *cl)
  692. {
  693. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  694. uclient_http_free_url_state(cl);
  695. uclient_http_free_ssl_ctx(uh);
  696. blob_buf_free(&uh->headers);
  697. blob_buf_free(&uh->meta);
  698. free(uh);
  699. }
  700. int
  701. uclient_http_set_request_type(struct uclient *cl, const char *type)
  702. {
  703. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  704. int i;
  705. if (cl->backend != &uclient_backend_http)
  706. return -1;
  707. if (uh->state > HTTP_STATE_INIT)
  708. return -1;
  709. for (i = 0; i < ARRAY_SIZE(request_types); i++) {
  710. if (strcmp(request_types[i], type) != 0)
  711. continue;
  712. uh->req_type = i;
  713. return 0;
  714. }
  715. return -1;
  716. }
  717. int
  718. uclient_http_reset_headers(struct uclient *cl)
  719. {
  720. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  721. blob_buf_init(&uh->headers, 0);
  722. return 0;
  723. }
  724. int
  725. uclient_http_set_header(struct uclient *cl, const char *name, const char *value)
  726. {
  727. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  728. if (cl->backend != &uclient_backend_http)
  729. return -1;
  730. if (uh->state > HTTP_STATE_INIT)
  731. return -1;
  732. blobmsg_add_string(&uh->headers, name, value);
  733. return 0;
  734. }
  735. static int
  736. uclient_http_send_data(struct uclient *cl, const char *buf, unsigned int len)
  737. {
  738. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  739. if (uh->state >= HTTP_STATE_REQUEST_DONE)
  740. return -1;
  741. uclient_http_send_headers(uh);
  742. if (len > 0) {
  743. ustream_printf(uh->us, "%X\r\n", len);
  744. ustream_write(uh->us, buf, len, false);
  745. ustream_printf(uh->us, "\r\n");
  746. }
  747. return len;
  748. }
  749. static int
  750. uclient_http_request_done(struct uclient *cl)
  751. {
  752. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  753. if (uh->state >= HTTP_STATE_REQUEST_DONE)
  754. return -1;
  755. uclient_http_send_headers(uh);
  756. if (uh->req_type == REQ_POST || uh->req_type == REQ_PUT)
  757. ustream_printf(uh->us, "0\r\n\r\n");
  758. uh->state = HTTP_STATE_REQUEST_DONE;
  759. return 0;
  760. }
  761. static int
  762. uclient_http_read(struct uclient *cl, char *buf, unsigned int len)
  763. {
  764. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  765. int read_len = 0;
  766. char *data, *data_end;
  767. if (uh->state < HTTP_STATE_RECV_DATA || !uh->us)
  768. return 0;
  769. data = ustream_get_read_buf(uh->us, &read_len);
  770. if (!data || !read_len)
  771. return 0;
  772. data_end = data + read_len;
  773. read_len = 0;
  774. if (uh->read_chunked == 0) {
  775. char *sep;
  776. if (data[0] == '\r' && data[1] == '\n') {
  777. data += 2;
  778. read_len += 2;
  779. }
  780. sep = strstr(data, "\r\n");
  781. if (!sep)
  782. return 0;
  783. *sep = 0;
  784. uh->read_chunked = strtoul(data, NULL, 16);
  785. read_len += sep + 2 - data;
  786. data = sep + 2;
  787. if (!uh->read_chunked) {
  788. uh->eof = true;
  789. uh->uc.data_eof = true;
  790. }
  791. }
  792. if (len > data_end - data)
  793. len = data_end - data;
  794. if (uh->read_chunked >= 0) {
  795. if (len > uh->read_chunked)
  796. len = uh->read_chunked;
  797. uh->read_chunked -= len;
  798. } else if (uh->content_length >= 0) {
  799. if (len > uh->content_length)
  800. len = uh->content_length;
  801. uh->content_length -= len;
  802. if (!uh->content_length) {
  803. uh->eof = true;
  804. uh->uc.data_eof = true;
  805. }
  806. }
  807. if (len > 0) {
  808. read_len += len;
  809. memcpy(buf, data, len);
  810. }
  811. if (read_len > 0)
  812. ustream_consume(uh->us, read_len);
  813. uclient_notify_eof(uh);
  814. /* Now that we consumed something and if this isn't EOF, start timer again */
  815. if (!uh->uc.eof && !cl->connection_timeout.pending)
  816. uloop_timeout_set(&cl->connection_timeout, cl->timeout_msecs);
  817. return len;
  818. }
  819. bool uclient_http_redirect(struct uclient *cl)
  820. {
  821. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  822. struct blobmsg_policy location = {
  823. .name = "location",
  824. .type = BLOBMSG_TYPE_STRING,
  825. };
  826. struct uclient_url *url = cl->url;
  827. struct blob_attr *tb;
  828. if (cl->backend != &uclient_backend_http)
  829. return false;
  830. switch (cl->status_code) {
  831. case 301:
  832. case 302:
  833. case 307:
  834. break;
  835. default:
  836. return false;
  837. }
  838. blobmsg_parse(&location, 1, &tb, blob_data(uh->meta.head), blob_len(uh->meta.head));
  839. if (!tb)
  840. return false;
  841. url = uclient_get_url(blobmsg_data(tb), url->auth);
  842. if (!url)
  843. return false;
  844. free(cl->url);
  845. cl->url = url;
  846. uclient_http_connect(cl);
  847. uclient_http_request_done(cl);
  848. return true;
  849. }
  850. int uclient_http_set_ssl_ctx(struct uclient *cl, const struct ustream_ssl_ops *ops,
  851. struct ustream_ssl_ctx *ctx, bool require_validation)
  852. {
  853. struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
  854. if (cl->backend != &uclient_backend_http)
  855. return -1;
  856. uclient_http_free_url_state(cl);
  857. uclient_http_free_ssl_ctx(uh);
  858. uh->ssl_ops = ops;
  859. uh->ssl_ctx = ctx;
  860. uh->ssl_require_validation = !!ctx && require_validation;
  861. return 0;
  862. }
  863. const struct uclient_backend uclient_backend_http = {
  864. .prefix = uclient_http_prefix,
  865. .alloc = uclient_http_alloc,
  866. .free = uclient_http_free,
  867. .connect = uclient_http_connect,
  868. .disconnect = uclient_http_request_disconnect,
  869. .update_url = uclient_http_free_url_state,
  870. .read = uclient_http_read,
  871. .write = uclient_http_send_data,
  872. .request = uclient_http_request_done,
  873. };