From f9dd4e560570384f505cfdd5a9f45fb65f1d67ad Mon Sep 17 00:00:00 2001 From: Thomas Bereknyei Date: Thu, 1 May 2025 02:28:17 -0400 Subject: [PATCH] fix: allow redirected HTTP uploads When a PUT is redirected, some of the data can be sent by curl before headers are read. This means the subsequent PUT operation needs to seek back to origin. (cherry picked from commit 90deb665eb58ee981389cd3dedc031140dbf52aa) --- src/libstore/filetransfer.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index a917188d9..e612ba2ed 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -309,6 +309,23 @@ struct curlFileTransfer : public FileTransfer } #endif + size_t seekCallback(curl_off_t offset, int origin) + { + if (origin == SEEK_SET) { + readOffset = offset; + } else if (origin == SEEK_CUR) { + readOffset += offset; + } else if (origin == SEEK_END) { + readOffset = request.data->length() + offset; + } + return CURL_SEEKFUNC_OK; + } + + static size_t seekCallbackWrapper(void *clientp, curl_off_t offset, int origin) + { + return ((TransferItem *) clientp)->seekCallback(offset, origin); + } + void init() { if (!req) req = curl_easy_init(); @@ -361,6 +378,8 @@ struct curlFileTransfer : public FileTransfer curl_easy_setopt(req, CURLOPT_READFUNCTION, readCallbackWrapper); curl_easy_setopt(req, CURLOPT_READDATA, this); curl_easy_setopt(req, CURLOPT_INFILESIZE_LARGE, (curl_off_t) request.data->length()); + curl_easy_setopt(req, CURLOPT_SEEKFUNCTION, seekCallbackWrapper); + curl_easy_setopt(req, CURLOPT_SEEKDATA, this); } if (request.verifyTLS) {