From 132e1ac10c7fef54372f4d8119b6cc3e82d2c957 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 15 Jan 2013 21:10:04 -0500 Subject: 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 Reported-by: Alexandre Filgueira Signed-off-by: Allan McRae --- lib/libalpm/dload.c | 21 ++++++++++++++++----- lib/libalpm/dload.h | 1 + 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'lib/libalpm') 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); -- cgit v1.2.3-70-g09d2