GNU wget follows http redirects but it treats 303 See Other as an error. This patch improves the handling in two ways:
- The location of the 'other' resource is printed as well as the error message. - The new option --follow-see-other causes 303 See Other to be treated the same as the other http redirects, and followed automatically by wget. Because wget does not currently have a maintainer I have also made a web page for the patch: <http://membled.com/work/patches/wget/>. diff -Naur wget-1.8.2/src/http.c wget-1.8.2-new/src/http.c --- wget-1.8.2/src/http.c 2002-05-19 04:04:53.000000000 +0100 +++ wget-1.8.2-new/src/http.c 2003-08-16 11:58:09.000000000 +0100 @@ -88,6 +88,7 @@ #define H_PARTIAL(x) ((x) == HTTP_STATUS_PARTIAL_CONTENTS) #define H_REDIRECTED(x) (((x) == HTTP_STATUS_MOVED_PERMANENTLY) \ || ((x) == HTTP_STATUS_MOVED_TEMPORARILY)) +#define H_OTHER(x) ((x) == HTTP_STATUS_SEE_OTHER) /* HTTP/1.0 status codes from RFC1945, provided for reference. */ /* Successful 2xx. */ @@ -101,6 +102,7 @@ #define HTTP_STATUS_MULTIPLE_CHOICES 300 #define HTTP_STATUS_MOVED_PERMANENTLY 301 #define HTTP_STATUS_MOVED_TEMPORARILY 302 +#define HTTP_STATUS_SEE_OTHER 303 #define HTTP_STATUS_NOT_MODIFIED 304 /* Client error 4xx. */ @@ -1147,7 +1149,9 @@ *dt |= RETROKF; /* Return if redirected. */ - if (H_REDIRECTED (statcode) || statcode == HTTP_STATUS_MULTIPLE_CHOICES) + if (H_REDIRECTED (statcode) + || (H_OTHER(statcode) && opt.follow_see_other) + || statcode == HTTP_STATUS_MULTIPLE_CHOICES) { /* RFC2068 says that in case of the 300 (multiple choices) response, the server can output a preferred URL through @@ -1169,6 +1173,12 @@ return NEWLOCATION; } } + else if (H_OTHER (statcode)) + /* Normal 303 behaviour. `Location:' should be there, but in case + it isn't... */ + if (hs->newloc) + fprintf(stderr, "303 See Other, use --follow-see-other to follow\n" + "Location: %s\n", hs->newloc); if (type && !strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S))) *dt |= TEXTHTML; diff -Naur wget-1.8.2/src/init.c wget-1.8.2-new/src/init.c --- wget-1.8.2/src/init.c 2002-05-18 04:05:19.000000000 +0100 +++ wget-1.8.2-new/src/init.c 2003-08-16 11:53:46.000000000 +0100 @@ -137,6 +137,7 @@ { "excludedirectories", &opt.excludes, cmd_directory_vector }, { "excludedomains", &opt.exclude_domains, cmd_vector }, { "followftp", &opt.follow_ftp, cmd_boolean }, + { "followseeother", &opt.follow_see_other, cmd_boolean }, { "followtags", &opt.follow_tags, cmd_vector }, { "forcehtml", &opt.force_html, cmd_boolean }, { "ftpproxy", &opt.ftp_proxy, cmd_string }, diff -Naur wget-1.8.2/src/main.c wget-1.8.2-new/src/main.c --- wget-1.8.2/src/main.c 2002-05-18 04:05:19.000000000 +0100 +++ wget-1.8.2-new/src/main.c 2003-08-16 11:45:54.000000000 +0100 @@ -231,6 +231,7 @@ -D, --domains=LIST comma-separated list of accepted domains.\n\ --exclude-domains=LIST comma-separated list of rejected domains.\n\ --follow-ftp follow FTP links from HTML documents.\n\ + --follow-see-other follow HTTP 303 See Other redirects.\n\ --follow-tags=LIST comma-separated list of followed HTML tags.\n\ -G, --ignore-tags=LIST comma-separated list of ignored HTML tags.\n\ -H, --span-hosts go to foreign hosts when recursive.\n\ @@ -260,6 +261,7 @@ { "delete-after", no_argument, NULL, 136 }, { "dont-remove-listing", no_argument, NULL, 149 }, { "follow-ftp", no_argument, NULL, 142 }, + { "follow-see-other", no_argument, NULL, 154 }, { "force-directories", no_argument, NULL, 'x' }, { "force-hier", no_argument, NULL, 'x' }, /* obsolete */ { "force-html", no_argument, NULL, 'F'}, @@ -408,6 +410,9 @@ case 149: setval ("removelisting", "off"); break; + case 154: + setval ("followseeother", "on"); + break; case 155: setval ("bindaddress", optarg); break; diff -Naur wget-1.8.2/src/options.h wget-1.8.2-new/src/options.h --- wget-1.8.2/src/options.h 2002-05-18 04:05:20.000000000 +0100 +++ wget-1.8.2-new/src/options.h 2003-08-16 11:44:25.000000000 +0100 @@ -77,6 +77,7 @@ retrieving? */ int retr_symlinks; /* Whether we retrieve symlinks in FTP. */ + int follow_see_other; /* Is 303 See Other treated as a redirect? */ char *output_document; /* The output file to which the documents will be printed. */ int od_known_regular; /* whether output_document is a -- Ed Avis <[EMAIL PROTECTED]>
