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