Skip to content

Commit

Permalink
More wget cleanup.
Browse files Browse the repository at this point in the history
Fix path, null terminate THIS line instead of chomp() whole header
(no guarantee the line we're looking for is last, although if it isn't
inserting the null terminator would truncate later searches),
don't assume server sent back a valid header with a " " in first line
(it SHOULD, but might not), don't interpret "-" filename from remote
end as stdout.
  • Loading branch information
landley committed Apr 8, 2022
1 parent 418405e commit 6018289
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions toys/pending/wget.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static void wget_info(char *url, char **host, char **port, char **path)
}
if (!url) error_exit("unsupported protocol: %s", ss);

if ((*path = strchr(*host = url, '/'))) *(*path++) = 0;
if ((*path = strchr(*host = url, '/'))) *((*path)++) = 0;
else *path = "";

// Get port number and trim literal IPv6 addresses
Expand Down Expand Up @@ -227,21 +227,27 @@ static void wget_close()

static char *wget_find_header(char *header, char *val)
{
char *result = strcasestr(chomp(header), val);
char *result = strcasestr(header, val);

return result ? result + strlen(val) : 0;
if (result) {
result += strlen(val);
result[strcspn(result, "\r\n")] = 0;
}

return result;
}

void wget_main(void)
{
long status = 0;
size_t len, c_len = 0;
int fd;
int fd = 0;
char *body, *index, *host, *port, *path, *chunked, *ss;
char agent[] = "toybox wget/" TOYBOX_VERSION;

TT.url = xstrdup(toys.optargs[0]);
TT.url = xstrdup(*toys.optargs);

// Ask server for URL, following redirects until success
while (status != 200) {
if (!TT.max_redirect--) error_exit("Too many redirects");

Expand All @@ -256,20 +262,20 @@ void wget_main(void)
wget_write(ss, strlen(ss));
free(ss);

// Read HTTP response until either complete or toybuf is full
// Read HTTP response into toybuf (probably with some body at end)
for (index = toybuf;
(len = wget_read(index, sizeof(toybuf)-(index-toybuf)))>0; index += len);

// Split response into header and body, and null terminate header.
// (RFC7230 says header cannot contain NUL.)
if (!(body = memmem(toybuf, index-toybuf, "\r\n\r\n", 4)))
if (!(body = memmem(ss = toybuf, index-toybuf, "\r\n\r\n", 4)))
error_exit("response header too large");
*body = 0;
body += 4;
len = index-body;
if (FLAG(d)) printf("--- Response\n%s\n\n", toybuf);

status = strtol(strafter(toybuf, " "), NULL, 10);
status = strstart(&ss, "HTTP/1.1 ") ? strtol(ss, 0, 10) : 0;
if ((status == 301) || (status == 302)) {
if (!(ss = wget_find_header(toybuf, "Location: ")))
error_exit("bad redirect");
Expand All @@ -279,14 +285,16 @@ void wget_main(void)
} else if (status != 200) error_exit("response: %ld", status);
}

if (!FLAG(O)) {
// Open output file
if (TT.O && !strcmp(TT.O, "-")) fd = 1;
else if (!TT.O) {
ss = wget_find_header(toybuf, "Content-Disposition: attachment; filename=");
if (!ss && strchr(path, '/')) ss = getbasename(path);
if (!ss || !*ss ) ss = "index.html";
if (!access((TT.O = ss), F_OK)) error_exit("%s already exists", TT.O);
}
// TODO: don't allow header/basename to write to stdout
fd = !strcmp(TT.O, "-") ? 1 : xcreate(TT.O, (O_WRONLY|O_CREAT|O_TRUNC), 0644);
if (!fd) fd = xcreate(TT.O, (O_WRONLY|O_CREAT|O_TRUNC), 0644);

// If chunked we offset the first buffer by 2 character, meaning it is
// pointing at half of the header boundary, aka '\r\n'. This simplifies
Expand Down

0 comments on commit 6018289

Please sign in to comment.