X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuclient.git;a=blobdiff_plain;f=uclient-http.c;h=1cc60e3051880303b9622ddacaa6275593463a29;hp=ef44a40645f65fcc54bbef3a81ed692c68798eff;hb=5e0b24f3a921081162706598d1ebea9d403d3187;hpb=dbd61a7a6d5b61ba24d73f56e97b4d56baedffaf diff --git a/uclient-http.c b/uclient-http.c index ef44a40..1cc60e3 100644 --- a/uclient-http.c +++ b/uclient-http.c @@ -12,9 +12,6 @@ #include "uclient-utils.h" #include "uclient-backend.h" -static struct ustream_ssl_ctx *ssl_ctx; -static uint32_t nc; - enum auth_type { AUTH_TYPE_UNKNOWN, AUTH_TYPE_NONE, @@ -47,6 +44,7 @@ static const char * const request_types[__REQ_MAX] = { struct uclient_http { struct uclient uc; + struct ustream_ssl_ctx *ssl_ctx; struct ustream *us; struct ustream_fd ufd; @@ -64,6 +62,8 @@ struct uclient_http { long read_chunked; long content_length; + uint32_t nc; + struct blob_buf headers; struct blob_buf meta; }; @@ -275,7 +275,7 @@ static bool strmatch(char **str, const char *prefix) static void get_cnonce(char *dest) { - uint32_t val = nc; + uint32_t val = 0; FILE *f; f = fopen("/dev/urandom", "r"); @@ -376,7 +376,7 @@ uclient_http_add_auth_digest(struct uclient_http *uh) if (!realm || !data.qop || !data.nonce) return; - sprintf(nc_str, "%08x", nc++); + sprintf(nc_str, "%08x", uh->nc++); get_cnonce(cnonce_str); data.qop = "auth"; @@ -653,13 +653,13 @@ static int uclient_setup_https(struct uclient_http *uh) if (ret) return ret; - if (!ssl_ctx) - ssl_ctx = ustream_ssl_context_new(false); + if (!uh->ssl_ctx) + uh->ssl_ctx = ustream_ssl_context_new(false); us->string_data = true; us->notify_state = uclient_ssl_notify_state; us->notify_read = uclient_ssl_notify_read; - ustream_ssl_init(&uh->ussl, &uh->ufd.stream, ssl_ctx, false); + ustream_ssl_init(&uh->ussl, &uh->ufd.stream, uh->ssl_ctx, false); return 0; } @@ -695,6 +695,9 @@ static void uclient_http_free(struct uclient *cl) { struct uclient_http *uh = container_of(cl, struct uclient_http, uc); + if (uh->ssl_ctx) + ustream_ssl_context_free(uh->ssl_ctx); + uclient_http_free_url_state(cl); blob_buf_free(&uh->headers); blob_buf_free(&uh->meta); @@ -850,7 +853,45 @@ uclient_http_read(struct uclient *cl, char *buf, unsigned int len) return len; } -const struct uclient_backend uclient_backend_http __hidden = { +bool uclient_http_redirect(struct uclient *cl) +{ + struct uclient_http *uh = container_of(cl, struct uclient_http, uc); + struct blobmsg_policy location = { + .name = "location", + .type = BLOBMSG_TYPE_STRING, + }; + struct uclient_url *url = cl->url; + struct blob_attr *tb; + + if (cl->backend != &uclient_backend_http) + return false; + + switch (cl->status_code) { + case 301: + case 302: + case 307: + break; + default: + return false; + } + + blobmsg_parse(&location, 1, &tb, blob_data(uh->meta.head), blob_len(uh->meta.head)); + if (!tb) + return false; + + url = uclient_get_url(blobmsg_data(tb), url->auth); + if (!url) + return false; + + free(cl->url); + cl->url = url; + uclient_http_connect(cl); + uclient_http_request_done(cl); + + return true; +} + +const struct uclient_backend uclient_backend_http = { .prefix = uclient_http_prefix, .alloc = uclient_http_alloc,