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