From 9a66d92f60baaff16a513d167c4ea8c6e6a0b1f6 Mon Sep 17 00:00:00 2001 From: mtortonesi Date: Fri, 28 Apr 2006 02:15:14 -0700 Subject: [PATCH] [svn] Improvements/fixes to HTTP Content-Disposition header support. --- src/ChangeLog | 13 +++++++++++ src/http.c | 62 +++++++++++++++++++++++++++++++++------------------ src/init.c | 3 +++ src/main.c | 3 +++ src/options.h | 2 ++ 5 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 27778fde..ec7f0ff9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2006-04-28 Mauro Tortonesi + + * http.c: If Content-Disposition header is present, allow unique + filename generation unless -nc is given. Permit to disable parsing of + Content-Disposition header. + + * options.h: Added option --no-content-disposition to disable parsing + of HTTP Content-Disposition header. + + * init.c: Ditto. + + * main.c: Ditto. + 2006-04-11 Hrvoje Niksic * hash.c (TOLOWER): Wrap macro arg in parentheses. diff --git a/src/http.c b/src/http.c index 70f6aa00..a0e04bfb 100644 --- a/src/http.c +++ b/src/http.c @@ -1726,33 +1726,49 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy) /* Determine the local filename if needed. Notice that if -O is used * hstat.local_file is set by http_loop to the argument of -O. */ - if (!hs->local_file) + if (!hs->local_file) { /* Honor Content-Disposition whether possible. */ - if (!resp_header_copy (resp, "Content-Disposition", hdrval, sizeof (hdrval)) + if (!opt.content_disposition + || !resp_header_copy (resp, "Content-Disposition", + hdrval, sizeof (hdrval)) || !parse_content_disposition (hdrval, &hs->local_file)) { - /* Choose filename according to URL name. */ + /* The Content-Disposition header is missing or broken. + * Choose unique file name according to given URL. */ hs->local_file = url_file_name (u); } } + DEBUGP (("hs->local_file is: %s %s\n", hs->local_file, + file_exists_p (hs->local_file) ? "(existing)" : "(not existing)")); + /* TODO: perform this check only once. */ - if (opt.noclobber && file_exists_p (hs->local_file)) + if (file_exists_p (hs->local_file)) { - /* If opt.noclobber is turned on and file already exists, do not - retrieve the file */ - logprintf (LOG_VERBOSE, _("\ + if (opt.noclobber) + { + /* If opt.noclobber is turned on and file already exists, do not + retrieve the file */ + logprintf (LOG_VERBOSE, _("\ File `%s' already there; not retrieving.\n\n"), hs->local_file); - /* If the file is there, we suppose it's retrieved OK. */ - *dt |= RETROKF; + /* If the file is there, we suppose it's retrieved OK. */ + *dt |= RETROKF; - /* #### Bogusness alert. */ - /* If its suffix is "html" or "htm" or similar, assume text/html. */ - if (has_html_suffix_p (hs->local_file)) - *dt |= TEXTHTML; + /* #### Bogusness alert. */ + /* If its suffix is "html" or "htm" or similar, assume text/html. */ + if (has_html_suffix_p (hs->local_file)) + *dt |= TEXTHTML; - return RETROK; + return RETROK; + } + else + { + char *unique = unique_name (hs->local_file, true); + if (unique != hs->local_file) + xfree (hs->local_file); + hs->local_file = unique; + } } /* Support timestamping */ @@ -1998,11 +2014,13 @@ File `%s' already there; not retrieving.\n\n"), hs->local_file); content-type. */ if (!type || 0 == strncasecmp (type, TEXTHTML_S, strlen (TEXTHTML_S)) || - 0 == strncasecmp (type, TEXTXHTML_S, strlen (TEXTXHTML_S))) + 0 == strncasecmp (type, TEXTXHTML_S, strlen (TEXTXHTML_S))) *dt |= TEXTHTML; else *dt &= ~TEXTHTML; + DEBUGP (("TEXTHTML is %s.\n", *dt | TEXTHTML ? "on": "off")); + if (opt.html_extension && (*dt & TEXTHTML)) /* -E / --html-extension / html_extension = on was specified, and this is a text/html file. If some case-insensitive variation on ".htm[l]" isn't @@ -2121,13 +2139,6 @@ File `%s' already there; not retrieving.\n\n"), hs->local_file); return RETRFINISHED; } - /* Print fetch message, if opt.verbose. */ - if (opt.verbose) - { - logprintf (LOG_NOTQUIET, _("Saving to: `%s'\n"), - HYPHENP (hs->local_file) ? "STDOUT" : hs->local_file); - } - /* Open the local file. */ if (!output_stream) { @@ -2164,6 +2175,13 @@ File `%s' already there; not retrieving.\n\n"), hs->local_file); else fp = output_stream; + /* Print fetch message, if opt.verbose. */ + if (opt.verbose) + { + logprintf (LOG_NOTQUIET, _("Saving to: `%s'\n"), + HYPHENP (hs->local_file) ? "STDOUT" : hs->local_file); + } + /* This confuses the timestamping code that checks for file size. #### The timestamping code should be smarter about file size. */ if (opt.save_headers && hs->restval == 0) diff --git a/src/init.c b/src/init.c index 820f84db..2e51291a 100644 --- a/src/init.c +++ b/src/init.c @@ -126,6 +126,7 @@ static struct { { "connecttimeout", &opt.connect_timeout, cmd_time }, { "continue", &opt.always_rest, cmd_boolean }, { "convertlinks", &opt.convert_links, cmd_boolean }, + { "contentdisposition", &opt.content_disposition, cmd_boolean }, { "cookies", &opt.cookies, cmd_boolean }, { "cutdirs", &opt.cut_dirs, cmd_number }, #ifdef ENABLE_DEBUG @@ -313,6 +314,8 @@ defaults (void) opt.restrict_files_os = restrict_windows; #endif opt.restrict_files_ctrl = true; + + opt.content_disposition = true; } /* Return the user's home directory (strdup-ed), or NULL if none is diff --git a/src/main.c b/src/main.c index fe9c8f33..1f3fb25a 100644 --- a/src/main.c +++ b/src/main.c @@ -143,6 +143,7 @@ static struct cmdline_option option_data[] = { "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 }, { "continue", 'c', OPT_BOOLEAN, "continue", -1 }, { "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 }, + { "content-disposition", 0, OPT_BOOLEAN, "contentdisposition", -1 }, { "cookies", 0, OPT_BOOLEAN, "cookies", -1 }, { "cut-dirs", 0, OPT_VALUE, "cutdirs", -1 }, { WHEN_DEBUG ("debug"), 'd', OPT_BOOLEAN, "debug", -1 }, @@ -518,6 +519,8 @@ HTTP options:\n"), --post-data=STRING use the POST method; send STRING as the data.\n"), N_("\ --post-file=FILE use the POST method; send contents of FILE.\n"), + N_("\ + --no-content-disposition don't honor Content-Disposition header.\n"), "\n", #ifdef HAVE_SSL diff --git a/src/options.h b/src/options.h index c9399d3c..f1b9cd75 100644 --- a/src/options.h +++ b/src/options.h @@ -220,6 +220,8 @@ struct options prefer_none } prefer_family; /* preferred address family when more than one type is available */ + + bool content_disposition; /* Honor HTTP Content-Disposition header. */ }; extern struct options opt;