diff options
Diffstat (limited to 'src/libstore/filetransfer.cc')
-rw-r--r-- | src/libstore/filetransfer.cc | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index aa8f4be1d..67b9fef81 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -149,6 +149,8 @@ struct curlFileTransfer : public FileTransfer size_t writeCallback(void * contents, size_t size, size_t nmemb) { + const size_t realSize = size * nmemb; + try { if (!headersProcessed) { if (auto h = getHeader("content-encoding")) { @@ -161,7 +163,6 @@ struct curlFileTransfer : public FileTransfer headersProcessed = true; } - size_t realSize = size * nmemb; result.bodySize += realSize; if (successfulStatuses.count(getHTTPStatus()) && this->dataCallback) { @@ -174,7 +175,7 @@ struct curlFileTransfer : public FileTransfer return realSize; } catch (...) { writeException = std::current_exception(); - return 0; + return CURL_WRITEFUNC_ERROR; } } @@ -710,9 +711,8 @@ struct curlFileTransfer : public FileTransfer struct State { bool done = false, failed = false; std::exception_ptr exc; - std::string data; + std::string data, encoding; std::condition_variable avail, request; - std::unique_ptr<FinishSink> decompressor; }; auto _state = std::make_shared<Sync<State>>(); @@ -736,7 +736,7 @@ struct curlFileTransfer : public FileTransfer state->avail.notify_one(); state->request.notify_one(); }}, - [_state, &sink](TransferItem & transfer, std::string_view data) { + [_state](TransferItem & transfer, std::string_view data) { auto state(_state->lock()); if (state->failed) { @@ -744,10 +744,6 @@ struct curlFileTransfer : public FileTransfer throw std::exception{}; } - if (!state->decompressor) { - state->decompressor = makeDecompressionSink(transfer.encoding, sink); - } - /* If the buffer is full, then go to sleep until the calling thread wakes us up (i.e. when it has removed data from the buffer). We don't wait forever to prevent stalling the @@ -764,11 +760,12 @@ struct curlFileTransfer : public FileTransfer state->avail.notify_one(); }); + std::unique_ptr<FinishSink> decompressor; + while (true) { checkInterrupt(); std::string chunk; - FinishSink * sink = nullptr; /* Grab data if available, otherwise wait for the download thread to wake us up. */ @@ -779,8 +776,8 @@ struct curlFileTransfer : public FileTransfer if (state->done) { if (state->exc) std::rethrow_exception(state->exc); - if (state->decompressor) { - state->decompressor->finish(); + if (decompressor) { + decompressor->finish(); } return; } @@ -791,10 +788,13 @@ struct curlFileTransfer : public FileTransfer } chunk = std::move(state->data); - sink = state->decompressor.get(); /* Reset state->data after the move, since we check data.empty() */ state->data = ""; + if (!decompressor) { + decompressor = makeDecompressionSink(state->encoding, sink); + } + state->request.notify_one(); } @@ -802,7 +802,7 @@ struct curlFileTransfer : public FileTransfer if it's blocked on a full buffer. We don't hold the state lock while doing this to prevent blocking the download thread if sink() takes a long time. */ - (*sink)(chunk); + (*decompressor)(chunk); } } }; |