aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarno Mäkipää <jmakip87@gmail.com>2019-10-19 08:37:09 +0300
committerRob Landley <rob@landley.net>2019-10-19 22:33:31 -0500
commit6f5eaccd75960719d6d94ca5c4c6bfb8a57c90ff (patch)
tree760c10f4f25027af46602d765f670f4a1900dbd8
parentfb04b1c4f8ec11c1ee049691d23d73dd483b69f2 (diff)
downloadtoybox-6f5eaccd75960719d6d94ca5c4c6bfb8a57c90ff.tar.gz
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.
-rw-r--r--toys/pending/wget.c67
1 files changed, 41 insertions, 26 deletions
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)