summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Reisner <dreisner@archlinux.org>2013-01-16 03:10:04 +0100
committerAllan McRae <allan@archlinux.org>2013-01-17 13:32:54 +0100
commit132e1ac10c7fef54372f4d8119b6cc3e82d2c957 (patch)
treedb6c37a76fd44e2ee37ee4f31ece45e073e2e2cd
parentc628d649f6568fc2627c685add09fc4024e87e4b (diff)
downloadpacman-132e1ac10c7fef54372f4d8119b6cc3e82d2c957.tar.gz
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.c21
-rw-r--r--lib/libalpm/dload.h1
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);