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 <sys/socket.h> 19 #include <stdio.h> 20 #include <ctype.h> 21 #include <unistd.h> 22 #include <stdint.h> 23 #include <string.h> 24 #include <fcntl.h> 25 26 #include <libubox/ustream.h> 27 #include <libubox/ustream-ssl.h> 28 #include <libubox/usock.h> 29 #include <libubox/blobmsg.h> 30 31 #include "uclient.h" 32 #include "uclient-utils.h" 33 #include "uclient-backend.h" 34 35 enum auth_type { 36 AUTH_TYPE_UNKNOWN, 37 AUTH_TYPE_NONE, 38 AUTH_TYPE_BASIC, 39 AUTH_TYPE_DIGEST, 40 }; 41 42 enum request_type { 43 REQ_GET, 44 REQ_HEAD, 45 REQ_POST, 46 REQ_PUT, 47 REQ_DELETE, 48 __REQ_MAX 49 }; 50 51 enum http_state { 52 HTTP_STATE_INIT, 53 HTTP_STATE_HEADERS_SENT, 54 HTTP_STATE_REQUEST_DONE, 55 HTTP_STATE_RECV_HEADERS, 56 HTTP_STATE_PROCESS_HEADERS, 57 HTTP_STATE_RECV_DATA, 58 HTTP_STATE_ERROR, 59 }; 60 61 static const char * const request_types[__REQ_MAX] = { 62 [REQ_GET] = "GET", 63 [REQ_HEAD] = "HEAD", 64 [REQ_POST] = "POST", 65 [REQ_PUT] = "PUT", 66 [REQ_DELETE] = "DELETE", 67 }; 68 69 struct uclient_http { 70 struct uclient uc; 71 72 const struct ustream_ssl_ops *ssl_ops; 73 struct ustream_ssl_ctx *ssl_ctx; 74 struct ustream *us; 75 76 union { 77 struct ustream_fd ufd; 78 struct ustream_ssl ussl; 79 }; 80 81 struct uloop_timeout disconnect_t; 82 struct uloop_timeout process_headers_t; 83 unsigned int seq; 84 int fd; 85 86 bool ssl_require_validation; 87 bool ssl; 88 bool eof; 89 bool connection_close; 90 bool disconnect; 91 enum request_type req_type; 92 enum http_state state; 93 94 enum auth_type auth_type; 95 char *auth_str; 96 97 long read_chunked; 98 long content_length; 99 100 int usock_flags; 101 102 uint32_t nc; 103 104 struct blob_buf headers; 105 struct blob_buf meta; 106 }; 107 108 enum { 109 PREFIX_HTTP, 110 PREFIX_HTTPS, 111 __PREFIX_MAX, 112 }; 113 114 static const char * const uclient_http_prefix[] = { 115 [PREFIX_HTTP] = "http://", 116 [PREFIX_HTTPS] = "https://", 117 [__PREFIX_MAX] = NULL 118 }; 119 120 static int uclient_http_connect(struct uclient *cl); 121 static void __uclient_notify_read(struct uclient_http *uh); 122 123 static int uclient_do_connect(struct uclient_http *uh, const char *port) 124 { 125 socklen_t sl; 126 int fd; 127 128 if (uh->uc.url->port) 129 port = uh->uc.url->port; 130 131 memset(&uh->uc.remote_addr, 0, sizeof(uh->uc.remote_addr)); 132 133 fd = usock_inet_timeout(USOCK_TCP | USOCK_NONBLOCK | uh->usock_flags, 134 uh->uc.url->host, port, &uh->uc.remote_addr, 135 uh->uc.timeout_msecs); 136 if (fd < 0) 137 return -1; 138 139 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 140 uh->fd = fd; 141 142 sl = sizeof(uh->uc.local_addr); 143 memset(&uh->uc.local_addr, 0, sl); 144 getsockname(fd, &uh->uc.local_addr.sa, &sl); 145 146 return 0; 147 } 148 149 static void uclient_http_disconnect(struct uclient_http *uh) 150 { 151 uloop_timeout_cancel(&uh->disconnect_t); 152 uloop_timeout_cancel(&uh->process_headers_t); 153 if (!uh->us) 154 return; 155 156 if (uh->ssl) 157 ustream_free(&uh->ussl.stream); 158 else 159 ustream_free(&uh->ufd.stream); 160 if(uh->fd >= 0) 161 close(uh->fd); 162 uh->fd = -1; 163 uh->us = NULL; 164 } 165 166 static void uclient_http_free_url_state(struct uclient *cl) 167 { 168 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 169 170 uh->auth_type = AUTH_TYPE_UNKNOWN; 171 free(uh->auth_str); 172 uh->auth_str = NULL; 173 uclient_http_disconnect(uh); 174 } 175 176 static void uclient_http_error(struct uclient_http *uh, int code) 177 { 178 uh->state = HTTP_STATE_ERROR; 179 uh->us->eof = true; 180 ustream_state_change(uh->us); 181 uclient_backend_set_error(&uh->uc, code); 182 } 183 184 static void uclient_http_request_disconnect(struct uclient *cl) 185 { 186 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 187 188 if (!uh->us) 189 return; 190 191 uh->eof = true; 192 uh->disconnect = true; 193 uloop_timeout_set(&uh->disconnect_t, 1); 194 } 195 196 static void uclient_notify_eof(struct uclient_http *uh) 197 { 198 struct ustream *us = uh->us; 199 200 if (uh->disconnect) 201 return; 202 203 if (!uh->eof) { 204 if (!us->eof && !us->write_error) 205 return; 206 207 if (ustream_pending_data(us, false)) 208 return; 209 } 210 211 if ((uh->content_length < 0 && uh->read_chunked >= 0) || 212 uh->content_length == 0) 213 uh->uc.data_eof = true; 214 215 uclient_backend_set_eof(&uh->uc); 216 217 if (uh->connection_close) 218 uclient_http_request_disconnect(&uh->uc); 219 } 220 221 static void uclient_http_reset_state(struct uclient_http *uh) 222 { 223 uh->seq++; 224 uclient_backend_reset_state(&uh->uc); 225 uh->read_chunked = -1; 226 uh->content_length = -1; 227 uh->eof = false; 228 uh->disconnect = false; 229 uh->connection_close = false; 230 uh->state = HTTP_STATE_INIT; 231 232 if (uh->auth_type == AUTH_TYPE_UNKNOWN && !uh->uc.url->auth) 233 uh->auth_type = AUTH_TYPE_NONE; 234 } 235 236 static void uclient_http_init_request(struct uclient_http *uh) 237 { 238 uh->seq++; 239 uclient_http_reset_state(uh); 240 blob_buf_init(&uh->meta, 0); 241 } 242 243 static enum auth_type 244 uclient_http_update_auth_type(struct uclient_http *uh) 245 { 246 if (!uh->auth_str) 247 return AUTH_TYPE_NONE; 248 249 if (!strncasecmp(uh->auth_str, "basic", 5)) 250 return AUTH_TYPE_BASIC; 251 252 if (!strncasecmp(uh->auth_str, "digest", 6)) 253 return AUTH_TYPE_DIGEST; 254 255 return AUTH_TYPE_NONE; 256 } 257 258 static void uclient_http_process_headers(struct uclient_http *uh) 259 { 260 enum { 261 HTTP_HDR_TRANSFER_ENCODING, 262 HTTP_HDR_CONNECTION, 263 HTTP_HDR_CONTENT_LENGTH, 264 HTTP_HDR_AUTH, 265 __HTTP_HDR_MAX, 266 }; 267 static const struct blobmsg_policy hdr_policy[__HTTP_HDR_MAX] = { 268 #define hdr(_name) { .name = _name, .type = BLOBMSG_TYPE_STRING } 269 [HTTP_HDR_TRANSFER_ENCODING] = hdr("transfer-encoding"), 270 [HTTP_HDR_CONNECTION] = hdr("connection"), 271 [HTTP_HDR_CONTENT_LENGTH] = hdr("content-length"), 272 [HTTP_HDR_AUTH] = hdr("www-authenticate"), 273 #undef hdr 274 }; 275 struct blob_attr *tb[__HTTP_HDR_MAX]; 276 struct blob_attr *cur; 277 278 blobmsg_parse(hdr_policy, __HTTP_HDR_MAX, tb, blob_data(uh->meta.head), blob_len(uh->meta.head)); 279 280 cur = tb[HTTP_HDR_TRANSFER_ENCODING]; 281 if (cur && strstr(blobmsg_data(cur), "chunked")) 282 uh->read_chunked = 0; 283 284 cur = tb[HTTP_HDR_CONNECTION]; 285 if (cur && strstr(blobmsg_data(cur), "close")) 286 uh->connection_close = true; 287 288 cur = tb[HTTP_HDR_CONTENT_LENGTH]; 289 if (cur) 290 uh->content_length = strtoul(blobmsg_data(cur), NULL, 10); 291 292 cur = tb[HTTP_HDR_AUTH]; 293 if (cur) { 294 free(uh->auth_str); 295 uh->auth_str = strdup(blobmsg_data(cur)); 296 } 297 298 uh->auth_type = uclient_http_update_auth_type(uh); 299 } 300 301 static bool uclient_request_supports_body(enum request_type req_type) 302 { 303 switch (req_type) { 304 case REQ_POST: 305 case REQ_PUT: 306 case REQ_DELETE: 307 return true; 308 default: 309 return false; 310 } 311 } 312 313 static int 314 uclient_http_add_auth_basic(struct uclient_http *uh) 315 { 316 struct uclient_url *url = uh->uc.url; 317 int auth_len = strlen(url->auth); 318 char *auth_buf; 319 320 if (auth_len > 512) 321 return -EINVAL; 322 323 auth_buf = alloca(base64_len(auth_len) + 1); 324 if (!auth_buf) 325 return -ENOMEM; 326 327 base64_encode(url->auth, auth_len, auth_buf); 328 ustream_printf(uh->us, "Authorization: Basic %s\r\n", auth_buf); 329 330 return 0; 331 } 332 333 static char *digest_unquote_sep(char **str) 334 { 335 char *cur = *str + 1; 336 char *start = cur; 337 char *out; 338 339 if (**str != '"') 340 return NULL; 341 342 out = cur; 343 while (1) { 344 if (!*cur) 345 return NULL; 346 347 if (*cur == '"') { 348 cur++; 349 break; 350 } 351 352 if (*cur == '\\') 353 cur++; 354 355 *(out++) = *(cur++); 356 } 357 358 if (*cur == ',') 359 cur++; 360 361 *out = 0; 362 *str = cur; 363 364 return start; 365 } 366 367 static char *digest_sep(char **str) 368 { 369 char *cur, *next; 370 371 cur = *str; 372 next = strchr(*str, ','); 373 if (next) { 374 *str = next + 1; 375 *next = 0; 376 } else { 377 *str += strlen(*str); 378 } 379 380 return cur; 381 } 382 383 static bool strmatch(char **str, const char *prefix) 384 { 385 int len = strlen(prefix); 386 387 if (strncmp(*str, prefix, len) != 0 || (*str)[len] != '=') 388 return false; 389 390 *str += len + 1; 391 return true; 392 } 393 394 static void 395 get_cnonce(char *dest) 396 { 397 uint32_t val = 0; 398 FILE *f; 399 size_t n; 400 401 f = fopen("/dev/urandom", "r"); 402 if (f) { 403 n = fread(&val, sizeof(val), 1, f); 404 fclose(f); 405 if (n != 1) 406 return; 407 } 408 409 bin_to_hex(dest, &val, sizeof(val)); 410 } 411 412 static void add_field(char **buf, int *ofs, int *len, const char *name, const char *val) 413 { 414 int available = *len - *ofs; 415 int required; 416 const char *next; 417 char *cur; 418 419 if (*len && !*buf) 420 return; 421 422 required = strlen(name) + 4 + strlen(val) * 2; 423 if (required > available) 424 *len += required - available + 64; 425 426 *buf = realloc(*buf, *len); 427 if (!*buf) 428 return; 429 430 cur = *buf + *ofs; 431 cur += sprintf(cur, ", %s=\"", name); 432 433 while ((next = strchr(val, '"'))) { 434 if (next > val) { 435 memcpy(cur, val, next - val); 436 cur += next - val; 437 } 438 439 cur += sprintf(cur, "\\\""); 440 val = next + 1; 441 } 442 443 cur += sprintf(cur, "%s\"", val); 444 *ofs = cur - *buf; 445 } 446 447 static int 448 uclient_http_add_auth_digest(struct uclient_http *uh) 449 { 450 struct uclient_url *url = uh->uc.url; 451 const char *realm = NULL, *opaque = NULL; 452 const char *user, *password; 453 char *buf, *next; 454 int len, ofs; 455 int err = 0; 456 457 char cnonce_str[9]; 458 char nc_str[9]; 459 char ahash[33]; 460 char hash[33]; 461 462 struct http_digest_data data = { 463 .nc = nc_str, 464 .cnonce = cnonce_str, 465 .auth_hash = ahash, 466 }; 467 468 len = strlen(uh->auth_str) + 1; 469 if (len > 512) { 470 err = -EINVAL; 471 goto fail; 472 } 473 474 buf = alloca(len); 475 if (!buf) { 476 err = -ENOMEM; 477 goto fail; 478 } 479 480 strcpy(buf, uh->auth_str); 481 482 /* skip auth type */ 483 strsep(&buf, " "); 484 485 next = buf; 486 while (*next) { 487 const char **dest = NULL; 488 const char *tmp; 489 490 while (*next && isspace(*next)) 491 next++; 492 493 if (strmatch(&next, "realm")) 494 dest = &realm; 495 else if (strmatch(&next, "qop")) 496 dest = &data.qop; 497 else if (strmatch(&next, "nonce")) 498 dest = &data.nonce; 499 else if (strmatch(&next, "opaque")) 500 dest = &opaque; 501 else if (strmatch(&next, "stale") || 502 strmatch(&next, "algorithm") || 503 strmatch(&next, "auth-param")) { 504 digest_sep(&next); 505 continue; 506 } else if (strmatch(&next, "domain") || 507 strmatch(&next, "qop-options")) 508 dest = &tmp; 509 else { 510 digest_sep(&next); 511 continue; 512 } 513 514 *dest = digest_unquote_sep(&next); 515 } 516 517 if (!realm || !data.qop || !data.nonce) { 518 err = -EINVAL; 519 goto fail; 520 } 521 522 sprintf(nc_str, "%08x", uh->nc++); 523 get_cnonce(cnonce_str); 524 525 data.qop = "auth"; 526 data.uri = url->location; 527 data.method = request_types[uh->req_type]; 528 529 password = strchr(url->auth, ':'); 530 if (password) { 531 char *user_buf; 532 533 len = password - url->auth; 534 if (len > 256) { 535 err = -EINVAL; 536 goto fail; 537 } 538 539 user_buf = alloca(len + 1); 540 if (!user_buf) { 541 err = -ENOMEM; 542 goto fail; 543 } 544 545 strncpy(user_buf, url->auth, len); 546 user_buf[len] = 0; 547 user = user_buf; 548 password++; 549 } else { 550 user = url->auth; 551 password = ""; 552 } 553 554 http_digest_calculate_auth_hash(ahash, user, realm, password); 555 http_digest_calculate_response(hash, &data); 556 557 buf = NULL; 558 len = 0; 559 ofs = 0; 560 561 add_field(&buf, &ofs, &len, "username", user); 562 add_field(&buf, &ofs, &len, "realm", realm); 563 add_field(&buf, &ofs, &len, "nonce", data.nonce); 564 add_field(&buf, &ofs, &len, "uri", data.uri); 565 add_field(&buf, &ofs, &len, "cnonce", data.cnonce); 566 add_field(&buf, &ofs, &len, "response", hash); 567 if (opaque) 568 add_field(&buf, &ofs, &len, "opaque", opaque); 569 570 ustream_printf(uh->us, "Authorization: Digest nc=%s, qop=%s%s\r\n", data.nc, data.qop, buf); 571 572 free(buf); 573 574 return 0; 575 576 fail: 577 return err; 578 } 579 580 static int 581 uclient_http_add_auth_header(struct uclient_http *uh) 582 { 583 if (!uh->uc.url->auth) 584 return 0; 585 586 switch (uh->auth_type) { 587 case AUTH_TYPE_UNKNOWN: 588 case AUTH_TYPE_NONE: 589 break; 590 case AUTH_TYPE_BASIC: 591 return uclient_http_add_auth_basic(uh); 592 case AUTH_TYPE_DIGEST: 593 return uclient_http_add_auth_digest(uh); 594 } 595 596 return 0; 597 } 598 599 static int 600 uclient_http_send_headers(struct uclient_http *uh) 601 { 602 struct uclient_url *url = uh->uc.url; 603 struct blob_attr *cur; 604 enum request_type req_type = uh->req_type; 605 bool literal_ipv6; 606 int err; 607 size_t rem; 608 609 if (uh->state >= HTTP_STATE_HEADERS_SENT) 610 return 0; 611 612 if (uh->uc.proxy_url) 613 url = uh->uc.proxy_url; 614 615 literal_ipv6 = strchr(url->host, ':'); 616 617 ustream_printf(uh->us, 618 "%s %s HTTP/1.1\r\n" 619 "Host: %s%s%s%s%s\r\n", 620 request_types[req_type], url->location, 621 literal_ipv6 ? "[" : "", 622 url->host, 623 literal_ipv6 ? "]" : "", 624 url->port ? ":" : "", 625 url->port ? url->port : ""); 626 627 blobmsg_for_each_attr(cur, uh->headers.head, rem) 628 ustream_printf(uh->us, "%s: %s\r\n", blobmsg_name(cur), (char *) blobmsg_data(cur)); 629 630 if (uclient_request_supports_body(uh->req_type)) 631 ustream_printf(uh->us, "Transfer-Encoding: chunked\r\n"); 632 633 err = uclient_http_add_auth_header(uh); 634 if (err) 635 return err; 636 637 ustream_printf(uh->us, "\r\n"); 638 639 uh->state = HTTP_STATE_HEADERS_SENT; 640 641 return 0; 642 } 643 644 static void uclient_http_process_headers_cb(struct uloop_timeout *timeout) 645 { 646 struct uclient_http *uh = container_of(timeout, struct uclient_http, process_headers_t); 647 enum auth_type auth_type = uh->auth_type; 648 unsigned int seq = uh->seq; 649 650 if (auth_type == AUTH_TYPE_UNKNOWN && uh->uc.status_code == 401 && 651 (uh->req_type == REQ_HEAD || uh->req_type == REQ_GET)) { 652 uclient_http_connect(&uh->uc); 653 uclient_http_send_headers(uh); 654 uh->state = HTTP_STATE_REQUEST_DONE; 655 return; 656 } 657 658 uh->state = HTTP_STATE_RECV_DATA; 659 660 if (uh->uc.cb->header_done) 661 uh->uc.cb->header_done(&uh->uc); 662 663 if (uh->eof || seq != uh->seq) 664 return; 665 666 if (uh->req_type == REQ_HEAD || uh->uc.status_code == 204 || 667 uh->content_length == 0) { 668 uh->eof = true; 669 uclient_notify_eof(uh); 670 return; 671 } 672 673 __uclient_notify_read(uh); 674 } 675 676 static void uclient_http_headers_complete(struct uclient_http *uh) 677 { 678 uh->state = HTTP_STATE_PROCESS_HEADERS; 679 uh->uc.meta = uh->meta.head; 680 uclient_http_process_headers(uh); 681 682 uh->process_headers_t.cb = uclient_http_process_headers_cb; 683 uloop_timeout_set(&uh->process_headers_t, 1); 684 } 685 686 static void uclient_parse_http_line(struct uclient_http *uh, char *data) 687 { 688 char *name; 689 char *sep; 690 691 if (uh->state == HTTP_STATE_REQUEST_DONE) { 692 char *code; 693 694 if (!strlen(data)) 695 return; 696 697 /* HTTP/1.1 */ 698 strsep(&data, " "); 699 700 code = strsep(&data, " "); 701 if (!code) 702 goto error; 703 704 uh->uc.status_code = strtoul(code, &sep, 10); 705 if (sep && *sep) 706 goto error; 707 708 uh->state = HTTP_STATE_RECV_HEADERS; 709 return; 710 } 711 712 if (!*data) { 713 uclient_http_headers_complete(uh); 714 return; 715 } 716 717 sep = strchr(data, ':'); 718 if (!sep) 719 return; 720 721 *(sep++) = 0; 722 723 for (name = data; *name; name++) 724 *name = tolower(*name); 725 726 name = data; 727 while (isspace(*sep)) 728 sep++; 729 730 blobmsg_add_string(&uh->meta, name, sep); 731 return; 732 733 error: 734 uh->uc.status_code = 400; 735 uh->eof = true; 736 uclient_notify_eof(uh); 737 } 738 739 static void __uclient_notify_read(struct uclient_http *uh) 740 { 741 struct uclient *uc = &uh->uc; 742 unsigned int seq = uh->seq; 743 char *data; 744 int len; 745 746 if (uh->state < HTTP_STATE_REQUEST_DONE || uh->state == HTTP_STATE_ERROR) 747 return; 748 749 if (uh->state == HTTP_STATE_PROCESS_HEADERS) 750 return; 751 752 data = ustream_get_read_buf(uh->us, &len); 753 if (!data || !len) 754 return; 755 756 if (uh->state < HTTP_STATE_RECV_DATA) { 757 char *sep, *next; 758 int cur_len; 759 760 do { 761 sep = strchr(data, '\n'); 762 if (!sep) 763 break; 764 765 next = sep + 1; 766 if (sep > data && sep[-1] == '\r') 767 sep--; 768 769 /* Check for multi-line HTTP headers */ 770 if (sep > data) { 771 if (!*next) 772 return; 773 774 if (isspace(*next) && *next != '\r' && *next != '\n') { 775 sep[0] = ' '; 776 if (sep + 1 < next) 777 sep[1] = ' '; 778 continue; 779 } 780 } 781 782 *sep = 0; 783 cur_len = next - data; 784 uclient_parse_http_line(uh, data); 785 if (seq != uh->seq) 786 return; 787 788 ustream_consume(uh->us, cur_len); 789 len -= cur_len; 790 791 if (uh->eof) 792 return; 793 794 data = ustream_get_read_buf(uh->us, &len); 795 } while (data && uh->state == HTTP_STATE_RECV_HEADERS); 796 797 if (!len) 798 return; 799 } 800 801 if (uh->eof) 802 return; 803 804 if (uh->state == HTTP_STATE_RECV_DATA) { 805 /* Now it's uclient user turn to read some data */ 806 uloop_timeout_cancel(&uc->connection_timeout); 807 uclient_backend_read_notify(uc); 808 } 809 } 810 811 static void __uclient_notify_write(struct uclient_http *uh) 812 { 813 struct uclient *uc = &uh->uc; 814 815 if (uc->cb->data_sent) 816 uc->cb->data_sent(uc); 817 } 818 819 static void uclient_notify_read(struct ustream *us, int bytes) 820 { 821 struct uclient_http *uh = container_of(us, struct uclient_http, ufd.stream); 822 823 __uclient_notify_read(uh); 824 } 825 826 static void uclient_notify_write(struct ustream *us, int bytes) 827 { 828 struct uclient_http *uh = container_of(us, struct uclient_http, ufd.stream); 829 830 __uclient_notify_write(uh); 831 } 832 833 static void uclient_notify_state(struct ustream *us) 834 { 835 struct uclient_http *uh = container_of(us, struct uclient_http, ufd.stream); 836 837 if (uh->ufd.stream.write_error) { 838 uclient_http_error(uh, UCLIENT_ERROR_CONNECT); 839 return; 840 } 841 uclient_notify_eof(uh); 842 } 843 844 static int uclient_setup_http(struct uclient_http *uh) 845 { 846 struct ustream *us = &uh->ufd.stream; 847 int ret; 848 849 memset(&uh->ufd, 0, sizeof(uh->ufd)); 850 uh->us = us; 851 uh->ssl = false; 852 853 us->string_data = true; 854 us->notify_state = uclient_notify_state; 855 us->notify_read = uclient_notify_read; 856 us->notify_write = uclient_notify_write; 857 858 ret = uclient_do_connect(uh, "80"); 859 if (ret) 860 return UCLIENT_ERROR_CONNECT; 861 862 ustream_fd_init(&uh->ufd, uh->fd); 863 864 return 0; 865 } 866 867 static void uclient_ssl_notify_read(struct ustream *us, int bytes) 868 { 869 struct uclient_http *uh = container_of(us, struct uclient_http, ussl.stream); 870 871 __uclient_notify_read(uh); 872 } 873 874 static void uclient_ssl_notify_write(struct ustream *us, int bytes) 875 { 876 struct uclient_http *uh = container_of(us, struct uclient_http, ussl.stream); 877 878 __uclient_notify_write(uh); 879 } 880 881 static void uclient_ssl_notify_state(struct ustream *us) 882 { 883 struct uclient_http *uh = container_of(us, struct uclient_http, ussl.stream); 884 885 uclient_notify_eof(uh); 886 } 887 888 static void uclient_ssl_notify_error(struct ustream_ssl *ssl, int error, const char *str) 889 { 890 struct uclient_http *uh = container_of(ssl, struct uclient_http, ussl); 891 struct uclient *uc = &uh->uc; 892 893 if (uc->cb->log_msg) 894 uc->cb->log_msg(uc, UCLIENT_LOG_SSL_ERROR, str); 895 uclient_http_error(uh, UCLIENT_ERROR_CONNECT); 896 } 897 898 static void uclient_ssl_notify_verify_error(struct ustream_ssl *ssl, int error, const char *str) 899 { 900 struct uclient_http *uh = container_of(ssl, struct uclient_http, ussl); 901 struct uclient *uc = &uh->uc; 902 903 if (!uh->ssl_require_validation) 904 return; 905 906 if (uc->cb->log_msg) 907 uc->cb->log_msg(uc, UCLIENT_LOG_SSL_VERIFY_ERROR, str); 908 uclient_http_error(uh, UCLIENT_ERROR_SSL_INVALID_CERT); 909 } 910 911 static void uclient_ssl_notify_connected(struct ustream_ssl *ssl) 912 { 913 struct uclient_http *uh = container_of(ssl, struct uclient_http, ussl); 914 915 if (!uh->ssl_require_validation) 916 return; 917 918 if (!uh->ussl.valid_cn) 919 uclient_http_error(uh, UCLIENT_ERROR_SSL_CN_MISMATCH); 920 } 921 922 static int uclient_setup_https(struct uclient_http *uh) 923 { 924 struct ustream *us = &uh->ussl.stream; 925 int ret; 926 927 memset(&uh->ussl, 0, sizeof(uh->ussl)); 928 uh->ufd.fd.fd = -1; 929 uh->ssl = true; 930 uh->us = us; 931 932 if (!uh->ssl_ctx) 933 return UCLIENT_ERROR_MISSING_SSL_CONTEXT; 934 935 ret = uclient_do_connect(uh, "443"); 936 if (ret) 937 return UCLIENT_ERROR_CONNECT; 938 939 us->string_data = true; 940 us->notify_state = uclient_ssl_notify_state; 941 us->notify_read = uclient_ssl_notify_read; 942 us->notify_write = uclient_ssl_notify_write; 943 uh->ussl.notify_error = uclient_ssl_notify_error; 944 uh->ussl.notify_verify_error = uclient_ssl_notify_verify_error; 945 uh->ussl.notify_connected = uclient_ssl_notify_connected; 946 uh->ussl.server_name = uh->uc.url->host; 947 uh->ssl_ops->init_fd(&uh->ussl, uh->fd, uh->ssl_ctx, false); 948 uh->ssl_ops->set_peer_cn(&uh->ussl, uh->uc.url->host); 949 950 return 0; 951 } 952 953 static int uclient_http_connect(struct uclient *cl) 954 { 955 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 956 bool ssl = cl->url->prefix == PREFIX_HTTPS; 957 int ret; 958 959 if (!cl->eof || uh->disconnect || uh->connection_close || uh->ssl != ssl) 960 uclient_http_disconnect(uh); 961 962 uclient_http_init_request(uh); 963 964 if (uh->us) 965 return 0; 966 967 uh->ssl = ssl; 968 969 if (uh->ssl) 970 ret = uclient_setup_https(uh); 971 else 972 ret = uclient_setup_http(uh); 973 974 return ret; 975 } 976 977 static void uclient_http_disconnect_cb(struct uloop_timeout *timeout) 978 { 979 struct uclient_http *uh = container_of(timeout, struct uclient_http, disconnect_t); 980 981 uclient_http_disconnect(uh); 982 } 983 984 static struct uclient *uclient_http_alloc(void) 985 { 986 struct uclient_http *uh; 987 988 uh = calloc_a(sizeof(*uh)); 989 if (!uh) 990 return NULL; 991 992 uh->disconnect_t.cb = uclient_http_disconnect_cb; 993 blob_buf_init(&uh->headers, 0); 994 995 return &uh->uc; 996 } 997 998 static void uclient_http_free_ssl_ctx(struct uclient_http *uh) 999 { 1000 uh->ssl_ops = NULL; 1001 uh->ssl_ctx = NULL; 1002 } 1003 1004 static void uclient_http_free(struct uclient *cl) 1005 { 1006 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1007 1008 uclient_http_free_url_state(cl); 1009 uclient_http_free_ssl_ctx(uh); 1010 blob_buf_free(&uh->headers); 1011 blob_buf_free(&uh->meta); 1012 free(uh); 1013 } 1014 1015 int 1016 uclient_http_set_request_type(struct uclient *cl, const char *type) 1017 { 1018 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1019 unsigned int i; 1020 1021 if (cl->backend != &uclient_backend_http) 1022 return -1; 1023 1024 if (uh->state > HTTP_STATE_INIT) 1025 return -1; 1026 1027 for (i = 0; i < ARRAY_SIZE(request_types); i++) { 1028 if (strcmp(request_types[i], type) != 0) 1029 continue; 1030 1031 uh->req_type = i; 1032 return 0; 1033 } 1034 1035 return -1; 1036 } 1037 1038 int 1039 uclient_http_reset_headers(struct uclient *cl) 1040 { 1041 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1042 1043 blob_buf_init(&uh->headers, 0); 1044 1045 return 0; 1046 } 1047 1048 int 1049 uclient_http_set_header(struct uclient *cl, const char *name, const char *value) 1050 { 1051 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1052 1053 if (cl->backend != &uclient_backend_http) 1054 return -1; 1055 1056 if (uh->state > HTTP_STATE_INIT) 1057 return -1; 1058 1059 blobmsg_add_string(&uh->headers, name, value); 1060 return 0; 1061 } 1062 1063 static int 1064 uclient_http_send_data(struct uclient *cl, const char *buf, unsigned int len) 1065 { 1066 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1067 int err; 1068 1069 if (uh->state >= HTTP_STATE_REQUEST_DONE) 1070 return -1; 1071 1072 err = uclient_http_send_headers(uh); 1073 if (err) 1074 return err; 1075 1076 if (len > 0) { 1077 ustream_printf(uh->us, "%X\r\n", len); 1078 ustream_write(uh->us, buf, len, false); 1079 ustream_printf(uh->us, "\r\n"); 1080 } 1081 1082 return len; 1083 } 1084 1085 static int 1086 uclient_http_request_done(struct uclient *cl) 1087 { 1088 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1089 int err; 1090 1091 if (uh->state >= HTTP_STATE_REQUEST_DONE) 1092 return -1; 1093 1094 err = uclient_http_send_headers(uh); 1095 if (err) 1096 return err; 1097 1098 if (uclient_request_supports_body(uh->req_type)) 1099 ustream_printf(uh->us, "\r\n\r\n"); 1100 uh->state = HTTP_STATE_REQUEST_DONE; 1101 1102 return 0; 1103 } 1104 1105 static int 1106 uclient_http_read(struct uclient *cl, char *buf, unsigned int len) 1107 { 1108 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1109 int read_len = 0; 1110 char *data, *data_end; 1111 1112 if (uh->state < HTTP_STATE_RECV_DATA || !uh->us) 1113 return 0; 1114 1115 data = ustream_get_read_buf(uh->us, &read_len); 1116 if (!data || !read_len) { 1117 ustream_poll(uh->us); 1118 data = ustream_get_read_buf(uh->us, &read_len); 1119 if (!data || !read_len) 1120 return 0; 1121 } 1122 1123 data_end = data + read_len; 1124 read_len = 0; 1125 1126 if (uh->read_chunked == 0) { 1127 char *sep; 1128 1129 if (data[0] == '\r' && data[1] == '\n') { 1130 data += 2; 1131 read_len += 2; 1132 } 1133 1134 sep = strstr(data, "\r\n"); 1135 if (!sep) 1136 return 0; 1137 1138 *sep = 0; 1139 uh->read_chunked = strtoul(data, NULL, 16); 1140 1141 read_len += sep + 2 - data; 1142 data = sep + 2; 1143 1144 if (!uh->read_chunked) { 1145 uh->eof = true; 1146 uh->uc.data_eof = true; 1147 } 1148 } 1149 1150 unsigned int diff = data_end - data; 1151 if (len > diff) 1152 len = diff; 1153 1154 if (uh->read_chunked >= 0) { 1155 if (len > (unsigned long) uh->read_chunked) 1156 len = uh->read_chunked; 1157 1158 uh->read_chunked -= len; 1159 } else if (uh->content_length >= 0) { 1160 if (len > (unsigned long) uh->content_length) 1161 len = uh->content_length; 1162 1163 uh->content_length -= len; 1164 if (!uh->content_length) { 1165 uh->eof = true; 1166 uh->uc.data_eof = true; 1167 } 1168 } 1169 1170 if (len > 0) { 1171 read_len += len; 1172 memcpy(buf, data, len); 1173 } 1174 1175 if (read_len > 0) 1176 ustream_consume(uh->us, read_len); 1177 1178 uclient_notify_eof(uh); 1179 1180 /* Now that we consumed something and if this isn't EOF, start timer again */ 1181 if (!uh->uc.eof && !cl->connection_timeout.pending) 1182 uloop_timeout_set(&cl->connection_timeout, cl->timeout_msecs); 1183 1184 return len; 1185 } 1186 1187 int uclient_http_redirect(struct uclient *cl) 1188 { 1189 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1190 struct blobmsg_policy location = { 1191 .name = "location", 1192 .type = BLOBMSG_TYPE_STRING, 1193 }; 1194 struct uclient_url *url = cl->url; 1195 struct blob_attr *tb; 1196 1197 if (cl->backend != &uclient_backend_http) 1198 return false; 1199 1200 if (!uclient_http_status_redirect(cl)) 1201 return false; 1202 1203 blobmsg_parse(&location, 1, &tb, blob_data(uh->meta.head), blob_len(uh->meta.head)); 1204 if (!tb) 1205 return false; 1206 1207 url = uclient_get_url_location(url, blobmsg_data(tb)); 1208 if (!url) 1209 return false; 1210 1211 if (cl->proxy_url) { 1212 free(cl->proxy_url); 1213 cl->proxy_url = url; 1214 } 1215 else { 1216 free(cl->url); 1217 cl->url = url; 1218 } 1219 1220 if (uclient_http_connect(cl)) 1221 return -1; 1222 1223 if (uclient_request(cl)) 1224 return -1; 1225 1226 return true; 1227 } 1228 1229 int uclient_http_set_ssl_ctx(struct uclient *cl, const struct ustream_ssl_ops *ops, 1230 struct ustream_ssl_ctx *ctx, bool require_validation) 1231 { 1232 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1233 1234 if (cl->backend != &uclient_backend_http) 1235 return -1; 1236 1237 uclient_http_free_url_state(cl); 1238 1239 uclient_http_free_ssl_ctx(uh); 1240 uh->ssl_ops = ops; 1241 uh->ssl_ctx = ctx; 1242 uh->ssl_require_validation = !!ctx && require_validation; 1243 1244 return 0; 1245 } 1246 1247 int uclient_http_set_address_family(struct uclient *cl, int af) 1248 { 1249 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1250 1251 if (cl->backend != &uclient_backend_http) 1252 return -1; 1253 1254 switch (af) { 1255 case AF_INET: 1256 uh->usock_flags = USOCK_IPV4ONLY; 1257 break; 1258 case AF_INET6: 1259 uh->usock_flags = USOCK_IPV6ONLY; 1260 break; 1261 default: 1262 uh->usock_flags = 0; 1263 break; 1264 } 1265 1266 return 0; 1267 } 1268 1269 static int 1270 uclient_http_pending_bytes(struct uclient *cl, bool write) 1271 { 1272 struct uclient_http *uh = container_of(cl, struct uclient_http, uc); 1273 1274 return ustream_pending_data(uh->us, write); 1275 } 1276 1277 const struct uclient_backend uclient_backend_http = { 1278 .prefix = uclient_http_prefix, 1279 1280 .alloc = uclient_http_alloc, 1281 .free = uclient_http_free, 1282 .connect = uclient_http_connect, 1283 .disconnect = uclient_http_request_disconnect, 1284 .update_url = uclient_http_free_url_state, 1285 .update_proxy_url = uclient_http_free_url_state, 1286 1287 .read = uclient_http_read, 1288 .write = uclient_http_send_data, 1289 .request = uclient_http_request_done, 1290 .pending_bytes = uclient_http_pending_bytes, 1291 }; 1292
This page was automatically generated by LXR 0.3.1. • OpenWrt