diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-04-10 18:17:05 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-04-10 18:17:05 +0000 |
commit | 6d7fa438a7dc33b20de746e31b5e8078c53c4d05 (patch) | |
tree | 97d81954d38c59c9ecd862ba429cf7fe4c399fb6 /networking/wget.c | |
parent | fd402941a7612b5254a65edfedc074d66da3883a (diff) | |
download | busybox-w32-6d7fa438a7dc33b20de746e31b5e8078c53c4d05.tar.gz busybox-w32-6d7fa438a7dc33b20de746e31b5e8078c53c4d05.tar.bz2 busybox-w32-6d7fa438a7dc33b20de746e31b5e8078c53c4d05.zip |
This patch from Laurence Anderson <laurence@zxmail.com> fixes
wget HTTP 1.1 support and addes chunked encoding so bb wget
is now fully RFC compliant.
Diffstat (limited to 'networking/wget.c')
-rw-r--r-- | networking/wget.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/networking/wget.c b/networking/wget.c index 5bec0ddd5..79f7e61cf 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -4,14 +4,6 @@ | |||
4 | * | 4 | * |
5 | * Chip Rosenthal Covad Communications <chip@laserlink.net> | 5 | * Chip Rosenthal Covad Communications <chip@laserlink.net> |
6 | * | 6 | * |
7 | * Note: According to RFC2616 section 3.6.1, "All HTTP/1.1 applications MUST be | ||
8 | * able to receive and decode the "chunked" transfer-coding, and MUST ignore | ||
9 | * chunk-extension extensions they do not understand." | ||
10 | * | ||
11 | * This prevents this particular wget app from completely RFC compliant, and as | ||
12 | * such, prevents it from being used as a general purpose web browser... This | ||
13 | * is a design decision, since it makes the code smaller. | ||
14 | * | ||
15 | */ | 7 | */ |
16 | 8 | ||
17 | #include <stdio.h> | 9 | #include <stdio.h> |
@@ -63,6 +55,7 @@ static void progressmeter(int flag); | |||
63 | 55 | ||
64 | /* Globals (can be accessed from signal handlers */ | 56 | /* Globals (can be accessed from signal handlers */ |
65 | static off_t filesize = 0; /* content-length of the file */ | 57 | static off_t filesize = 0; /* content-length of the file */ |
58 | static int chunked = 0; /* chunked transfer encoding */ | ||
66 | #ifdef BB_FEATURE_WGET_STATUSBAR | 59 | #ifdef BB_FEATURE_WGET_STATUSBAR |
67 | static char *curfile; /* Name of current file being transferred. */ | 60 | static char *curfile; /* Name of current file being transferred. */ |
68 | static struct timeval start; /* Time a transfer started. */ | 61 | static struct timeval start; /* Time a transfer started. */ |
@@ -231,11 +224,11 @@ int wget_main(int argc, char **argv) | |||
231 | * Send HTTP request. | 224 | * Send HTTP request. |
232 | */ | 225 | */ |
233 | if (proxy) { | 226 | if (proxy) { |
234 | fprintf(sfp, "GET %stp://%s:%d/%s HTTP/1.0\r\n", | 227 | fprintf(sfp, "GET %stp://%s:%d/%s HTTP/1.1\r\n", |
235 | target.is_ftp ? "f" : "ht", target.host, | 228 | target.is_ftp ? "f" : "ht", target.host, |
236 | target.port, target.path); | 229 | target.port, target.path); |
237 | } else { | 230 | } else { |
238 | fprintf(sfp, "GET /%s HTTP/1.0\r\n", target.path); | 231 | fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path); |
239 | } | 232 | } |
240 | 233 | ||
241 | fprintf(sfp, "Host: %s\r\nUser-Agent: Wget\r\n", target.host); | 234 | fprintf(sfp, "Host: %s\r\nUser-Agent: Wget\r\n", target.host); |
@@ -258,7 +251,7 @@ int wget_main(int argc, char **argv) | |||
258 | /* | 251 | /* |
259 | * Retrieve HTTP response line and check for "200" status code. | 252 | * Retrieve HTTP response line and check for "200" status code. |
260 | */ | 253 | */ |
261 | if (fgets(buf, sizeof(buf), sfp) == NULL) | 254 | read_response: if (fgets(buf, sizeof(buf), sfp) == NULL) |
262 | close_delete_and_die("no response from server"); | 255 | close_delete_and_die("no response from server"); |
263 | 256 | ||
264 | for (s = buf ; *s != '\0' && !isspace(*s) ; ++s) | 257 | for (s = buf ; *s != '\0' && !isspace(*s) ; ++s) |
@@ -267,6 +260,9 @@ int wget_main(int argc, char **argv) | |||
267 | ; | 260 | ; |
268 | switch (status = atoi(s)) { | 261 | switch (status = atoi(s)) { |
269 | case 0: | 262 | case 0: |
263 | case 100: | ||
264 | while (gethdr(buf, sizeof(buf), sfp, &n) != NULL); | ||
265 | goto read_response; | ||
270 | case 200: | 266 | case 200: |
271 | if (do_continue && output != stdout) | 267 | if (do_continue && output != stdout) |
272 | output = freopen(fname_out, "w", output); | 268 | output = freopen(fname_out, "w", output); |
@@ -295,9 +291,13 @@ int wget_main(int argc, char **argv) | |||
295 | got_clen = 1; | 291 | got_clen = 1; |
296 | continue; | 292 | continue; |
297 | } | 293 | } |
298 | if (strcasecmp(buf, "transfer-encoding") == 0) | 294 | if (strcasecmp(buf, "transfer-encoding") == 0) { |
295 | if (strcasecmp(s, "chunked") == 0) { | ||
296 | chunked = got_clen = 1; | ||
297 | } else { | ||
299 | close_delete_and_die("server wants to do %s transfer encoding", s); | 298 | close_delete_and_die("server wants to do %s transfer encoding", s); |
300 | 299 | } | |
300 | } | ||
301 | if (strcasecmp(buf, "location") == 0) { | 301 | if (strcasecmp(buf, "location") == 0) { |
302 | if (s[0] == '/') | 302 | if (s[0] == '/') |
303 | target.path = xstrdup(s+1); | 303 | target.path = xstrdup(s+1); |
@@ -386,12 +386,17 @@ int wget_main(int argc, char **argv) | |||
386 | /* | 386 | /* |
387 | * Retrieve file | 387 | * Retrieve file |
388 | */ | 388 | */ |
389 | if (chunked) { | ||
390 | fgets(buf, sizeof(buf), dfp); | ||
391 | filesize = strtol(buf, (char **) NULL, 16); | ||
392 | } | ||
393 | do { | ||
389 | #ifdef BB_FEATURE_WGET_STATUSBAR | 394 | #ifdef BB_FEATURE_WGET_STATUSBAR |
390 | statbytes=0; | 395 | statbytes=0; |
391 | if (quiet_flag==FALSE) | 396 | if (quiet_flag==FALSE) |
392 | progressmeter(-1); | 397 | progressmeter(-1); |
393 | #endif | 398 | #endif |
394 | while ((filesize > 0 || !got_clen) && (n = fread(buf, 1, sizeof(buf), dfp)) > 0) { | 399 | while ((filesize > 0 || !got_clen) && (n = fread(buf, 1, chunked ? (filesize > sizeof(buf) ? sizeof(buf) : filesize) : sizeof(buf), dfp)) > 0) { |
395 | fwrite(buf, 1, n, output); | 400 | fwrite(buf, 1, n, output); |
396 | #ifdef BB_FEATURE_WGET_STATUSBAR | 401 | #ifdef BB_FEATURE_WGET_STATUSBAR |
397 | statbytes+=n; | 402 | statbytes+=n; |
@@ -402,8 +407,16 @@ int wget_main(int argc, char **argv) | |||
402 | filesize -= n; | 407 | filesize -= n; |
403 | } | 408 | } |
404 | 409 | ||
410 | if (chunked) { | ||
411 | fgets(buf, sizeof(buf), dfp); /* This is a newline */ | ||
412 | fgets(buf, sizeof(buf), dfp); | ||
413 | filesize = strtol(buf, (char **) NULL, 16); | ||
414 | if (filesize==0) chunked = 0; /* all done! */ | ||
415 | } | ||
416 | |||
405 | if (n == 0 && ferror(dfp)) | 417 | if (n == 0 && ferror(dfp)) |
406 | perror_msg_and_die("network read error"); | 418 | perror_msg_and_die("network read error"); |
419 | } while (chunked); | ||
407 | 420 | ||
408 | if (!proxy && target.is_ftp) { | 421 | if (!proxy && target.is_ftp) { |
409 | fclose(dfp); | 422 | fclose(dfp); |
@@ -411,7 +424,7 @@ int wget_main(int argc, char **argv) | |||
411 | error_msg_and_die("ftp error: %s", buf+4); | 424 | error_msg_and_die("ftp error: %s", buf+4); |
412 | ftpcmd("QUIT", NULL, sfp, buf); | 425 | ftpcmd("QUIT", NULL, sfp, buf); |
413 | } | 426 | } |
414 | 427 | printf("\n"); | |
415 | exit(EXIT_SUCCESS); | 428 | exit(EXIT_SUCCESS); |
416 | } | 429 | } |
417 | 430 | ||
@@ -608,7 +621,7 @@ progressmeter(int flag) | |||
608 | 621 | ||
609 | (void) gettimeofday(&now, (struct timezone *) 0); | 622 | (void) gettimeofday(&now, (struct timezone *) 0); |
610 | cursize = statbytes; | 623 | cursize = statbytes; |
611 | if (filesize != 0) { | 624 | if (filesize != 0 && !chunked) { |
612 | ratio = 100.0 * cursize / filesize; | 625 | ratio = 100.0 * cursize / filesize; |
613 | ratio = MAX(ratio, 0); | 626 | ratio = MAX(ratio, 0); |
614 | ratio = MIN(ratio, 100); | 627 | ratio = MIN(ratio, 100); |
@@ -719,7 +732,7 @@ progressmeter(int flag) | |||
719 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 732 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
720 | * SUCH DAMAGE. | 733 | * SUCH DAMAGE. |
721 | * | 734 | * |
722 | * $Id: wget.c,v 1.31 2001/04/05 21:45:53 andersen Exp $ | 735 | * $Id: wget.c,v 1.32 2001/04/10 18:17:05 andersen Exp $ |
723 | */ | 736 | */ |
724 | 737 | ||
725 | 738 | ||