From 6f5eaccd75960719d6d94ca5c4c6bfb8a57c90ff Mon Sep 17 00:00:00 2001 From: Jarno Mäkipää Date: Sat, 19 Oct 2019 08:37:09 +0300 Subject: wget: Added support for HTTP 301 and 302 redirects Added: parsing of redirectation responses, will now follow redirectation path until maximum of 10 jumps. This will probably lead to server advertising user the https url. --- toys/pending/wget.c | 67 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 26 deletions(-) (limited to 'toys/pending/wget.c') diff --git a/toys/pending/wget.c b/toys/pending/wget.c index eb496da2..405ed942 100644 --- a/toys/pending/wget.c +++ b/toys/pending/wget.c @@ -100,7 +100,7 @@ static int conn_svr(const char *hostname, const char *port) { continue; } if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) - break; // succeed in connecting to any server IP + break; // succeed in connecting to any server IP else perror_msg("connect error"); close(sock); } @@ -131,10 +131,10 @@ static char *get_body(ssize_t len, ssize_t *body_len) { void wget_main(void) { - int sock; + int sock, redirects = 10; FILE *fp; ssize_t len, body_len; - char *body, *result, *rc, *r_str; + char *body, *result, *rc, *r_str, *redir_loc = 0; char ua[18] = "toybox wget", ver[6], hostname[1024], port[6], path[1024]; // TODO extract filename to be saved from URL @@ -144,34 +144,49 @@ void wget_main(void) if(!toys.optargs[0]) help_exit("no URL"); get_info(toys.optargs[0], hostname, port, path); - sock = conn_svr(hostname, port); - // compose HTTP request - sprintf(toybuf, "GET %s HTTP/1.1\r\n", path); - mk_fld("Host", hostname); #ifdef TOYBOX_VERSION strcat(ua, "/"), strncpy(ver, TOYBOX_VERSION, 5), strcat(ua, ver); #endif - mk_fld("User-Agent", ua); - mk_fld("Connection", "close"); - strcat(toybuf, "\r\n"); + for (;; redirects--) { + sock = conn_svr(hostname, port); + // compose HTTP request + sprintf(toybuf, "GET %s HTTP/1.1\r\n", path); + mk_fld("Host", hostname); + mk_fld("User-Agent", ua); + mk_fld("Connection", "close"); + strcat(toybuf, "\r\n"); + + // send the HTTP request + len = strlen(toybuf); + if (write(sock, toybuf, len) != len) perror_exit("write error"); + + // read HTTP response + if ((len = read(sock, toybuf, 4096)) == -1) perror_exit("read error"); + if (!strstr(toybuf, "\r\n\r\n")) error_exit("too long HTTP response"); + body = get_body(len, &body_len); + redir_loc = strstr(toybuf, "Location: "); + result = strtok(toybuf, "\r"); + strtok(result, " "); + rc = strtok(NULL, " "); + r_str = strtok(NULL, " "); + + // HTTP res code check + if (!strcmp(rc, "301") || !strcmp(rc, "302")) { + char* eol = 0; + if ((eol = strchr(redir_loc, '\r')) > 0) *eol = 0; + else if (redir_loc) error_exit("Could not parse redirect URL"); + if (redirects < 0) error_exit("Too many redirects"); + + printf("Redirection: %s %s \n", rc, r_str); + printf("%s \n", redir_loc); + redir_loc = redir_loc+strlen("Location: "); + close(sock); + get_info(redir_loc, hostname, port, path); + } else if (!strcmp(rc, "200")) break; + else error_exit("res: %s(%s)", rc, r_str); + } - // send the HTTP request - len = strlen(toybuf); - if (write(sock, toybuf, len) != len) perror_exit("write error"); - - // read HTTP response - if ((len = read(sock, toybuf, 4096)) == -1) perror_exit("read error"); - if (!strstr(toybuf, "\r\n\r\n")) error_exit("too long HTTP response"); - body = get_body(len, &body_len); - result = strtok(toybuf, "\r"); - strtok(result, " "); - rc = strtok(NULL, " "); - r_str = strtok(NULL, " "); - - // HTTP res code check - // TODO handle HTTP 302 Found(Redirection) - if (strcmp(rc, "200")) error_exit("res: %s(%s)", rc, r_str); if (!(fp = fopen(TT.filename, "w"))) perror_exit("fopen error"); if (fwrite(body, 1, body_len, fp) != body_len) -- cgit v1.2.3