uclient: fix http regression
[project/uclient.git] / uclient-http.c
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, "0\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 };