From 17e9fc3598c18278418c54aa59d116041ef80965 Mon Sep 17 00:00:00 2001 From: nkming2 Date: Mon, 15 Dec 2025 21:20:54 +0800 Subject: [PATCH 1/2] support setting http headers when using CurlIO --- include/exiv2/basicio.hpp | 6 ++++++ src/basicio.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/exiv2/basicio.hpp b/include/exiv2/basicio.hpp index d8d9a05320..4c0f3f1c6a 100644 --- a/include/exiv2/basicio.hpp +++ b/include/exiv2/basicio.hpp @@ -12,6 +12,7 @@ #include "types.hpp" // + standard includes +#include #include // ***************************************************************************** @@ -924,6 +925,11 @@ class EXIV2API CurlIo : public RemoteIo { */ size_t write(BasicIo& src) override; + /*! + @brief Add HTTP headers to subsequent requests. Only relevant for HTTP urls + */ + void addHttpHeaders(const std::map& headers); + protected: // Pimpl idiom class CurlImpl; diff --git a/src/basicio.cpp b/src/basicio.cpp index 6b42df5bde..f37c8dd112 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -18,6 +18,7 @@ #include // timestamp for the name of temporary file #include // write the temporary file #include +#include #if __has_include() #include // for mmap and munmap @@ -983,6 +984,7 @@ class RemoteIo::Impl { bool eof_{false}; //!< EOF indicator Protocol protocol_; //!< the protocol of url size_t totalRead_{0}; //!< bytes requested from host + std::map httpHeaders_; //!< Custom HTTP headers // METHODS /*! @@ -1519,6 +1521,13 @@ class CurlIo::CurlImpl : public Impl { void writeRemote(const byte* data, size_t size, size_t from, size_t to) override; private: + typedef std::unique_ptr curl_slist_ptr; + + /*! + @brief Build a header list for curl, or NULL if no headers are set + */ + curl_slist_ptr populateHttpHeaders() const; + long timeout_; //!< The number of seconds to wait while trying to connect. }; @@ -1546,6 +1555,10 @@ int64_t CurlIo::CurlImpl::getFileLength() const { curl_easy_setopt(curl_.get(), CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl_.get(), CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl_.get(), CURLOPT_CONNECTTIMEOUT, timeout_); + auto headers = populateHttpHeaders(); + if (headers) { + curl_easy_setopt(curl_.get(), CURLOPT_HTTPHEADER, headers.get()); + } // curl_easy_setopt(curl_.get(), CURLOPT_VERBOSE, 1); // debugging mode /* Perform the request, res will get the return code */ @@ -1573,6 +1586,10 @@ void CurlIo::CurlImpl::getDataByRange(size_t lowBlock, size_t highBlock, std::st curl_easy_setopt(curl_.get(), CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl_.get(), CURLOPT_CONNECTTIMEOUT, timeout_); curl_easy_setopt(curl_.get(), CURLOPT_SSL_VERIFYHOST, 0L); + auto headers = populateHttpHeaders(); + if (headers) { + curl_easy_setopt(curl_.get(), CURLOPT_HTTPHEADER, headers.get()); + } // curl_easy_setopt(curl_.get(), CURLOPT_VERBOSE, 1); // debugging mode @@ -1614,6 +1631,10 @@ void CurlIo::CurlImpl::writeRemote(const byte* data, size_t size, size_t from, s // curl_easy_setopt(curl_.get(), CURLOPT_VERBOSE, 1); // debugging mode curl_easy_setopt(curl_.get(), CURLOPT_URL, scriptPath.c_str()); curl_easy_setopt(curl_.get(), CURLOPT_SSL_VERIFYPEER, 0L); + auto headers = populateHttpHeaders(); + if (headers) { + curl_easy_setopt(curl_.get(), CURLOPT_HTTPHEADER, headers.get()); + } // encode base64 size_t encodeLength = (((size + 2) / 3) * 4) + 1; @@ -1635,6 +1656,14 @@ void CurlIo::CurlImpl::writeRemote(const byte* data, size_t size, size_t from, s } } +CurlIo::CurlImpl::curl_slist_ptr CurlIo::CurlImpl::populateHttpHeaders() const { + curl_slist* headers = nullptr; + for (auto e : httpHeaders_) { + headers = curl_slist_append(headers, (e.first + ": " + e.second).c_str()); + } + return curl_slist_ptr(headers, curl_slist_free_all); +} + size_t CurlIo::write(const byte* data, size_t wcount) { if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) { return RemoteIo::write(data, wcount); @@ -1649,6 +1678,10 @@ size_t CurlIo::write(BasicIo& src) { throw Error(ErrorCode::kerErrorMessage, "does not support write for this protocol."); } +void CurlIo::addHttpHeaders(const std::map& headers) { + p_->httpHeaders_.insert(headers.begin(), headers.end()); +} + CurlIo::CurlIo(const std::string& url, size_t blockSize) { p_ = std::make_unique(url, blockSize); } From 90d48e59995c65d8d1a55b9da8fe7a7ca0f2f646 Mon Sep 17 00:00:00 2001 From: nkming2 Date: Mon, 15 Dec 2025 22:01:58 +0800 Subject: [PATCH 2/2] run clang format --- src/basicio.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/basicio.cpp b/src/basicio.cpp index f37c8dd112..3066f91b7f 100644 --- a/src/basicio.cpp +++ b/src/basicio.cpp @@ -976,14 +976,14 @@ class RemoteIo::Impl { virtual ~Impl() = default; // DATA - std::string path_; //!< (Standard) path - size_t blockSize_; //!< Size of the block memory. - std::unique_ptr blocksMap_; //!< An array contains all blocksMap - size_t size_{0}; //!< The file size - size_t idx_{0}; //!< Index into the memory area - bool eof_{false}; //!< EOF indicator - Protocol protocol_; //!< the protocol of url - size_t totalRead_{0}; //!< bytes requested from host + std::string path_; //!< (Standard) path + size_t blockSize_; //!< Size of the block memory. + std::unique_ptr blocksMap_; //!< An array contains all blocksMap + size_t size_{0}; //!< The file size + size_t idx_{0}; //!< Index into the memory area + bool eof_{false}; //!< EOF indicator + Protocol protocol_; //!< the protocol of url + size_t totalRead_{0}; //!< bytes requested from host std::map httpHeaders_; //!< Custom HTTP headers // METHODS