diff options
author | Dave Reisner <dreisner@archlinux.org> | 2013-01-15 21:10:04 -0500 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2013-01-17 22:32:54 +1000 |
commit | 132e1ac10c7fef54372f4d8119b6cc3e82d2c957 (patch) | |
tree | db6c37a76fd44e2ee37ee4f31ece45e073e2e2cd | |
parent | c628d649f6568fc2627c685add09fc4024e87e4b (diff) | |
download | pacman-132e1ac10c7fef54372f4d8119b6cc3e82d2c957.tar.xz |
dload: avoid showing progress bars on some redirects
RFC 2616 doesn't forbid a 301 or 302 repsonse from having a body, and
servers exist in the wild that show this behavior. In order to prevent
pacman from showing a progress bar when we aren't actually downloading a
package (and merely following one of these pain in the butt redirects),
capture the server response code in the response header, rather than
waiting to peel it off the handle after the download has finished.
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Reported-by: Alexandre Filgueira <alexfilgueira@cinnarch.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r-- | lib/libalpm/dload.c | 21 | ||||
-rw-r--r-- | lib/libalpm/dload.h | 1 |
2 files changed, 17 insertions, 5 deletions
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index ee19adb6..83d2051e 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -96,6 +96,11 @@ static int dload_progress_cb(void *file, double dltotal, double dlnow, struct dload_payload *payload = (struct dload_payload *)file; off_t current_size, total_size; + /* avoid displaying progress bar for redirects with a body */ + if(payload->respcode >= 300) { + return 0; + } + /* SIGINT sent, abort by alerting curl */ if(dload_interrupted) { return 1; @@ -199,6 +204,7 @@ static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *u const char * const cd_header = "Content-Disposition:"; const char * const fn_key = "filename="; struct dload_payload *payload = (struct dload_payload *)user; + long respcode; if(_alpm_raw_ncmp(cd_header, ptr, strlen(cd_header)) == 0) { if((fptr = strstr(ptr, fn_key))) { @@ -220,6 +226,11 @@ static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *u } } + curl_easy_getinfo(payload->handle->curl, CURLINFO_RESPONSE_CODE, &respcode); + if(payload->respcode != respcode) { + payload->respcode = respcode; + } + return realsize; } @@ -383,7 +394,7 @@ static int curl_download_internal(struct dload_payload *payload, char hostname[HOSTNAME_SIZE]; char error_buffer[CURL_ERROR_SIZE] = {0}; struct stat st; - long timecond, respcode = 0, remote_time = -1; + long timecond, remote_time = -1; double remote_size, bytes_dl; struct sigaction orig_sig_pipe, orig_sig_int; /* shortcut to our handle within the payload */ @@ -463,13 +474,12 @@ static int curl_download_internal(struct dload_payload *payload, switch(payload->curlerr) { case CURLE_OK: /* get http/ftp response code */ - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &respcode); - _alpm_log(handle, ALPM_LOG_DEBUG, "response code: %ld\n", respcode); - if(respcode >= 400) { + _alpm_log(handle, ALPM_LOG_DEBUG, "response code: %ld\n", payload->respcode); + if(payload->respcode >= 400) { payload->unlink_on_fail = 1; /* non-translated message is same as libcurl */ snprintf(error_buffer, sizeof(error_buffer), - "The requested URL returned error: %ld", respcode); + "The requested URL returned error: %ld", payload->respcode); _alpm_log(handle, ALPM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), payload->remote_name, hostname, error_buffer); @@ -725,6 +735,7 @@ void _alpm_dload_payload_reset(struct dload_payload *payload) FREE(payload->destfile_name); FREE(payload->content_disp_name); FREE(payload->fileurl); + memset(payload, '\0', sizeof(*payload)); } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index ca172006..70e34791 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -42,6 +42,7 @@ struct dload_payload { #ifdef HAVE_LIBCURL CURLcode curlerr; /* last error produced by curl */ #endif + long respcode; }; void _alpm_dload_payload_reset(struct dload_payload *payload); |