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