summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/dload.c
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 /lib/libalpm/dload.c
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>
Diffstat (limited to 'lib/libalpm/dload.c')
-rw-r--r--lib/libalpm/dload.c21
1 files changed, 16 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: */