diff --git a/src/import/pull-job.c b/src/import/pull-job.c index 2dc960c392..31d6d34af6 100644 --- a/src/import/pull-job.c +++ b/src/import/pull-job.c @@ -299,6 +299,29 @@ static int pull_job_open_disk(PullJob *j) { return 0; } +static int pull_job_begin_running(PullJob *j) { + int r; + + assert(j); + assert(j->state == PULL_JOB_ANALYZING); + assert(j->compress); + + r = pull_job_open_disk(j); + if (r < 0) + return r; + + /* Now, take the payload we read so far, and decompress it */ + _cleanup_(iovec_done) struct iovec stub = TAKE_STRUCT(j->payload); + + j->state = PULL_JOB_RUNNING; + + r = pull_job_write_compressed(j, &stub); + if (r < 0) + return r; + + return 0; +} + static int pull_job_curl_on_finished(CurlSlot *slot, CURL *curl, CURLcode result, void *userdata) { PullJob *j = ASSERT_PTR(userdata); char *scheme = NULL; @@ -382,6 +405,20 @@ static int pull_job_curl_on_finished(CurlSlot *slot, CURL *curl, CURLcode result return pull_job_finish(j, log_error_errno(SYNTHETIC_ERRNO(EIO), "HTTP request to %s finished with unexpected code %li.", j->url, status)); } + if (j->state == PULL_JOB_ANALYZING) { + /* When curl finished the download while we were still looking for a compression magic + * header the content isn't compressed but should be written out as is. */ + assert(result == CURLE_OK); + + r = decompressor_force_off(&j->compress); + if (r < 0) + return pull_job_finish(j, r); + + r = pull_job_begin_running(j); + if (r < 0) + return pull_job_finish(j, r); + } + if (j->state != PULL_JOB_RUNNING) return pull_job_finish(j, log_error_errno(SYNTHETIC_ERRNO(EIO), "Premature connection termination.")); @@ -483,20 +520,7 @@ static int pull_job_detect_compression(PullJob *j) { log_debug("Stream is compressed: %s", compression_to_string(compressor_type(j->compress))); - r = pull_job_open_disk(j); - if (r < 0) - return r; - - /* Now, take the payload we read so far, and decompress it */ - _cleanup_(iovec_done) struct iovec stub = TAKE_STRUCT(j->payload); - - j->state = PULL_JOB_RUNNING; - - r = pull_job_write_compressed(j, &stub); - if (r < 0) - return r; - - return 0; + return pull_job_begin_running(j); } static size_t pull_job_write_callback(void *contents, size_t size, size_t nmemb, void *userdata) { diff --git a/test/units/TEST-72-SYSUPDATE.sh b/test/units/TEST-72-SYSUPDATE.sh index 0e1c9afa83..21a3ea00a5 100755 --- a/test/units/TEST-72-SYSUPDATE.sh +++ b/test/units/TEST-72-SYSUPDATE.sh @@ -552,4 +552,28 @@ EOF done done +# Make sure the processing of compressed streams still handles uncompressed streams shorter than +# COMPRESSION_MAGIC_BYTES_MAX correctly. +rm -rf "$CONFIGDIR" "$WORKDIR/blobs" +mkdir -p "$CONFIGDIR" "$WORKDIR/blobs" +printf 'xx' >"$WORKDIR/source/tiny-v1.bin" +(cd "$WORKDIR/source" && sha256sum tiny-v1.bin >SHA256SUMS) +cat >"$CONFIGDIR/01-tiny-url.transfer" <