125 lines
5.3 KiB
Diff
125 lines
5.3 KiB
Diff
|
From 614d7874bfa82cb19b328278590af0f99e1ec682 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonathan Dieter <jdieter@gmail.com>
|
||
|
Date: Fri, 14 Jun 2019 23:13:30 +0100
|
||
|
Subject: [PATCH] Handle webservers that don't support ranges when downloading zck
|
||
|
|
||
|
Make sure we fall back to downloading full zchunk file if a webserver
|
||
|
doesn't support ranges.
|
||
|
|
||
|
Signed-off-by: Jonathan Dieter <jdieter@gmail.com>
|
||
|
---
|
||
|
librepo/downloader.c | 37 ++++++++++++++++++++++++++-----------
|
||
|
librepo/downloadtarget.c | 1 +
|
||
|
librepo/downloadtarget.h | 4 ++++
|
||
|
3 files changed, 31 insertions(+), 11 deletions(-)
|
||
|
|
||
|
diff --git a/librepo/downloader.c b/librepo/downloader.c
|
||
|
index 6189681..53161f7 100644
|
||
|
--- a/librepo/downloader.c
|
||
|
+++ b/librepo/downloader.c
|
||
|
@@ -473,7 +473,7 @@ lr_headercb(void *ptr, size_t size, size_t nmemb, void *userdata)
|
||
|
}
|
||
|
|
||
|
#ifdef WITH_ZCHUNK
|
||
|
- if(lrtarget->target->is_zchunk)
|
||
|
+ if(lrtarget->target->is_zchunk && lrtarget->mirror->max_ranges > 0)
|
||
|
return lr_zckheadercb(ptr, size, nmemb, userdata);
|
||
|
#endif /* WITH_ZCHUNK */
|
||
|
|
||
|
@@ -586,7 +586,7 @@ lr_writecb(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||
|
size_t cur_written;
|
||
|
LrTarget *target = (LrTarget *) userdata;
|
||
|
#ifdef WITH_ZCHUNK
|
||
|
- if(target->target->is_zchunk)
|
||
|
+ if(target->target->is_zchunk && target->mirror->max_ranges > 0)
|
||
|
return lr_zck_writecb(ptr, size, nmemb, userdata);
|
||
|
#endif /* WITH_ZCHUNK */
|
||
|
|
||
|
@@ -1240,6 +1240,12 @@ check_zck(LrTarget *target, GError **err)
|
||
|
assert(!err || *err == NULL);
|
||
|
assert(target && target->f && target->target);
|
||
|
|
||
|
+ if(target->mirror->max_ranges == 0) {
|
||
|
+ target->zck_state = LR_ZCK_DL_BODY;
|
||
|
+ target->target->expectedsize = target->target->origsize;
|
||
|
+ return TRUE;
|
||
|
+ }
|
||
|
+
|
||
|
if(target->target->zck_dl == NULL) {
|
||
|
target->target->zck_dl = zck_dl_init(NULL);
|
||
|
if(target->target->zck_dl == NULL) {
|
||
|
@@ -2166,25 +2172,34 @@ check_transfer_statuses(LrDownload *dd, GError **err)
|
||
|
if (target->target->is_zchunk) {
|
||
|
zckCtx *zck = NULL;
|
||
|
if (target->zck_state == LR_ZCK_DL_HEADER) {
|
||
|
- if(!lr_zck_valid_header(target->target, target->target->path,
|
||
|
+ if(target->mirror->max_ranges > 0 &&
|
||
|
+ !lr_zck_valid_header(target->target, target->target->path,
|
||
|
fd, &transfer_err))
|
||
|
goto transfer_error;
|
||
|
} else if(target->zck_state == LR_ZCK_DL_BODY) {
|
||
|
- zckCtx *zck = zck_dl_get_zck(target->target->zck_dl);
|
||
|
- if(zck == NULL) {
|
||
|
- g_set_error(&transfer_err, LR_DOWNLOADER_ERROR, LRE_ZCK,
|
||
|
- "Unable to get zchunk file from download context");
|
||
|
- goto transfer_error;
|
||
|
+ if(target->mirror->max_ranges > 0) {
|
||
|
+ zckCtx *zck = zck_dl_get_zck(target->target->zck_dl);
|
||
|
+ if(zck == NULL) {
|
||
|
+ g_set_error(&transfer_err, LR_DOWNLOADER_ERROR, LRE_ZCK,
|
||
|
+ "Unable to get zchunk file from download context");
|
||
|
+ goto transfer_error;
|
||
|
+ }
|
||
|
+ if(zck_failed_chunks(zck) == 0 && zck_missing_chunks(zck) == 0)
|
||
|
+ target->zck_state = LR_ZCK_DL_FINISHED;
|
||
|
+ } else {
|
||
|
+ if(target->range_fail) {
|
||
|
+ target->range_fail = FALSE;
|
||
|
+ } else {
|
||
|
+ target->zck_state = LR_ZCK_DL_FINISHED;
|
||
|
+ }
|
||
|
}
|
||
|
- if(zck_failed_chunks(zck) == 0 && zck_missing_chunks(zck) == 0)
|
||
|
- target->zck_state = LR_ZCK_DL_FINISHED;
|
||
|
}
|
||
|
if(target->zck_state == LR_ZCK_DL_FINISHED) {
|
||
|
zck = lr_zck_init_read(target->target, target->target->path, fd,
|
||
|
&transfer_err);
|
||
|
if(!zck)
|
||
|
goto transfer_error;
|
||
|
- if(!zck_validate_checksums(zck)) {
|
||
|
+ if(zck_validate_checksums(zck) < 1) {
|
||
|
zck_free(&zck);
|
||
|
g_set_error(&transfer_err, LR_DOWNLOADER_ERROR, LRE_BADCHECKSUM,
|
||
|
"At least one of the zchunk checksums doesn't match in %s",
|
||
|
diff --git a/librepo/downloadtarget.c b/librepo/downloadtarget.c
|
||
|
index d20aa44..40c10f3 100644
|
||
|
--- a/librepo/downloadtarget.c
|
||
|
+++ b/librepo/downloadtarget.c
|
||
|
@@ -100,6 +100,7 @@ lr_downloadtarget_new(LrHandle *handle,
|
||
|
target->fn = lr_string_chunk_insert(target->chunk, fn);
|
||
|
target->checksums = possiblechecksums;
|
||
|
target->expectedsize = expectedsize;
|
||
|
+ target->origsize = expectedsize;
|
||
|
target->resume = resume;
|
||
|
target->progresscb = progresscb;
|
||
|
target->cbdata = cbdata;
|
||
|
diff --git a/librepo/downloadtarget.h b/librepo/downloadtarget.h
|
||
|
index f4c1f26..c935219 100644
|
||
|
--- a/librepo/downloadtarget.h
|
||
|
+++ b/librepo/downloadtarget.h
|
||
|
@@ -88,6 +88,10 @@ typedef struct {
|
||
|
gint64 expectedsize; /*!<
|
||
|
Expected size of the target */
|
||
|
|
||
|
+ gint64 origsize; /*!<
|
||
|
+ Original expected size of the target. Sometimes expectedsize will
|
||
|
+ change, especially if zchunk is in use, but this will never change */
|
||
|
+
|
||
|
gboolean resume; /*!<
|
||
|
Resume:
|
||
|
0 - no resume, download whole file,
|
||
|
--
|
||
|
libgit2 0.28.2
|
||
|
|