From 1e548fb6e3394e5a12604bf381c5d69aadb1ef3c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Feb 2022 11:11:38 +0100 Subject: [PATCH] lib/curl/Headers: central type definition for the header map --- src/input/plugins/CurlInputPlugin.cxx | 16 +++++----- src/input/plugins/CurlInputPlugin.hxx | 7 ++--- src/input/plugins/QobuzClient.cxx | 4 +-- src/input/plugins/QobuzClient.hxx | 6 ++-- src/input/plugins/QobuzErrorParser.cxx | 2 +- src/input/plugins/QobuzErrorParser.hxx | 7 ++--- src/input/plugins/QobuzLoginRequest.cxx | 7 ++--- src/input/plugins/QobuzLoginRequest.hxx | 2 +- src/input/plugins/QobuzTagScanner.cxx | 3 +- src/input/plugins/QobuzTagScanner.hxx | 2 +- src/input/plugins/QobuzTrackRequest.cxx | 2 +- src/input/plugins/QobuzTrackRequest.hxx | 2 +- src/lib/curl/Adapter.hxx | 13 +++----- src/lib/curl/Delegate.cxx | 5 ++- src/lib/curl/Delegate.hxx | 12 +++---- src/lib/curl/Form.cxx | 3 +- src/lib/curl/Form.hxx | 6 ++-- src/lib/curl/Handler.hxx | 11 ++----- src/lib/curl/Headers.hxx | 42 +++++++++++++++++++++++++ src/lib/upnp/Discovery.cxx | 2 +- src/lib/upnp/Discovery.hxx | 3 +- src/storage/plugins/CurlStorage.cxx | 5 ++- test/RunCurl.cxx | 3 +- 23 files changed, 90 insertions(+), 75 deletions(-) create mode 100644 src/lib/curl/Headers.hxx diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index be5efed91..cc2606714 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -82,7 +82,7 @@ class CurlInputStream final : public AsyncInputStream, CurlResponseHandler { public: template CurlInputStream(EventLoop &event_loop, const char *_url, - const std::multimap &headers, + const Curl::Headers &headers, I &&_icy, Mutex &_mutex); @@ -92,7 +92,7 @@ public: CurlInputStream &operator=(const CurlInputStream &) = delete; static InputStreamPtr Open(const char *url, - const std::multimap &headers, + const Curl::Headers &headers, Mutex &mutex); private: @@ -131,8 +131,7 @@ private: void SeekInternal(offset_type new_offset); /* virtual methods from CurlResponseHandler */ - void OnHeaders(unsigned status, - std::multimap &&headers) override; + void OnHeaders(unsigned status, Curl::Headers &&headers) override; void OnData(ConstBuffer data) override; void OnEnd() override; void OnError(std::exception_ptr e) noexcept override; @@ -227,7 +226,7 @@ WithConvertedTagValue(const char *uri, const char *value, F &&f) noexcept void CurlInputStream::OnHeaders(unsigned status, - std::multimap &&headers) + Curl::Headers &&headers) { assert(GetEventLoop().IsInside()); assert(!postponed_exception); @@ -391,7 +390,7 @@ input_curl_finish() noexcept template inline CurlInputStream::CurlInputStream(EventLoop &event_loop, const char *_url, - const std::multimap &headers, + const Curl::Headers &headers, I &&_icy, Mutex &_mutex) :AsyncInputStream(event_loop, _url, _mutex, @@ -491,7 +490,7 @@ CurlInputStream::DoSeek(offset_type new_offset) inline InputStreamPtr CurlInputStream::Open(const char *url, - const std::multimap &headers, + const Curl::Headers &headers, Mutex &mutex) { auto icy = std::make_shared(); @@ -510,8 +509,7 @@ CurlInputStream::Open(const char *url, } InputStreamPtr -OpenCurlInputStream(const char *uri, - const std::multimap &headers, +OpenCurlInputStream(const char *uri, const Curl::Headers &headers, Mutex &mutex) { return CurlInputStream::Open(uri, headers, mutex); diff --git a/src/input/plugins/CurlInputPlugin.hxx b/src/input/plugins/CurlInputPlugin.hxx index c3decf675..3595a84ea 100644 --- a/src/input/plugins/CurlInputPlugin.hxx +++ b/src/input/plugins/CurlInputPlugin.hxx @@ -20,12 +20,10 @@ #ifndef MPD_INPUT_CURL_HXX #define MPD_INPUT_CURL_HXX +#include "lib/curl/Headers.hxx" #include "input/Ptr.hxx" #include "thread/Mutex.hxx" -#include -#include - extern const struct InputPlugin input_plugin_curl; /** @@ -36,8 +34,7 @@ extern const struct InputPlugin input_plugin_curl; * Throws on error. */ InputStreamPtr -OpenCurlInputStream(const char *uri, - const std::multimap &headers, +OpenCurlInputStream(const char *uri, const Curl::Headers &headers, Mutex &mutex); #endif diff --git a/src/input/plugins/QobuzClient.cxx b/src/input/plugins/QobuzClient.cxx index 294456a5a..48f8d8ecd 100644 --- a/src/input/plugins/QobuzClient.cxx +++ b/src/input/plugins/QobuzClient.cxx @@ -164,7 +164,7 @@ QobuzClient::InvokeHandlers() noexcept std::string QobuzClient::MakeUrl(const char *object, const char *method, - const std::multimap &query) const noexcept + const Curl::Headers &query) const noexcept { assert(!query.empty()); @@ -183,7 +183,7 @@ QobuzClient::MakeUrl(const char *object, const char *method, std::string QobuzClient::MakeSignedUrl(const char *object, const char *method, - const std::multimap &query) const noexcept + const Curl::Headers &query) const noexcept { assert(!query.empty()); diff --git a/src/input/plugins/QobuzClient.hxx b/src/input/plugins/QobuzClient.hxx index 0fa00dce0..65c9ec49a 100644 --- a/src/input/plugins/QobuzClient.hxx +++ b/src/input/plugins/QobuzClient.hxx @@ -23,12 +23,12 @@ #include "QobuzSession.hxx" #include "QobuzLoginRequest.hxx" #include "lib/curl/Init.hxx" +#include "lib/curl/Headers.hxx" #include "thread/Mutex.hxx" #include "event/DeferEvent.hxx" #include "util/IntrusiveList.hxx" #include -#include #include class QobuzSessionHandler @@ -94,10 +94,10 @@ public: QobuzSession GetSession() const; std::string MakeUrl(const char *object, const char *method, - const std::multimap &query) const noexcept; + const Curl::Headers &query) const noexcept; std::string MakeSignedUrl(const char *object, const char *method, - const std::multimap &query) const noexcept; + const Curl::Headers &query) const noexcept; private: void StartLogin(); diff --git a/src/input/plugins/QobuzErrorParser.cxx b/src/input/plugins/QobuzErrorParser.cxx index 96ac1f743..ae19be5dc 100644 --- a/src/input/plugins/QobuzErrorParser.cxx +++ b/src/input/plugins/QobuzErrorParser.cxx @@ -38,7 +38,7 @@ static constexpr yajl_callbacks qobuz_error_parser_callbacks = { }; QobuzErrorParser::QobuzErrorParser(unsigned _status, - const std::multimap &headers) + const Curl::Headers &headers) :YajlResponseParser(&qobuz_error_parser_callbacks, nullptr, this), status(_status) { diff --git a/src/input/plugins/QobuzErrorParser.hxx b/src/input/plugins/QobuzErrorParser.hxx index 4f50f8265..23523af46 100644 --- a/src/input/plugins/QobuzErrorParser.hxx +++ b/src/input/plugins/QobuzErrorParser.hxx @@ -20,11 +20,9 @@ #ifndef QOBUZ_ERROR_PARSER_HXX #define QOBUZ_ERROR_PARSER_HXX +#include "lib/curl/Headers.hxx" #include "lib/yajl/ResponseParser.hxx" -#include -#include - template struct ConstBuffer; struct StringView; @@ -46,8 +44,7 @@ public: * May throw if there is a formal error in the response * headers. */ - QobuzErrorParser(unsigned status, - const std::multimap &headers); + QobuzErrorParser(unsigned status, const Curl::Headers &headers); protected: /* virtual methods from CurlResponseParser */ diff --git a/src/input/plugins/QobuzLoginRequest.cxx b/src/input/plugins/QobuzLoginRequest.cxx index 2a3e091d0..143c3f931 100644 --- a/src/input/plugins/QobuzLoginRequest.cxx +++ b/src/input/plugins/QobuzLoginRequest.cxx @@ -77,7 +77,7 @@ QobuzLoginRequest::ResponseParser::GetSession() return std::move(session); } -static std::multimap +static Curl::Headers MakeLoginForm(const char *app_id, const char *username, const char *email, const char *password, @@ -85,7 +85,7 @@ MakeLoginForm(const char *app_id, { assert(username != nullptr || email != nullptr); - std::multimap form{ + Curl::Headers form{ {"app_id", app_id}, {"password", password}, {"device_manufacturer_id", device_manufacturer_id}, @@ -134,8 +134,7 @@ QobuzLoginRequest::~QobuzLoginRequest() noexcept } std::unique_ptr -QobuzLoginRequest::MakeParser(unsigned status, - std::multimap &&headers) +QobuzLoginRequest::MakeParser(unsigned status, Curl::Headers &&headers) { if (status != 200) return std::make_unique(status, headers); diff --git a/src/input/plugins/QobuzLoginRequest.hxx b/src/input/plugins/QobuzLoginRequest.hxx index 189cb6896..1bf657ec6 100644 --- a/src/input/plugins/QobuzLoginRequest.hxx +++ b/src/input/plugins/QobuzLoginRequest.hxx @@ -56,7 +56,7 @@ public: private: /* virtual methods from DelegateCurlResponseHandler */ std::unique_ptr MakeParser(unsigned status, - std::multimap &&headers) override; + Curl::Headers &&headers) override; void FinishParser(std::unique_ptr p) override; /* virtual methods from CurlResponseHandler */ diff --git a/src/input/plugins/QobuzTagScanner.cxx b/src/input/plugins/QobuzTagScanner.cxx index 3629d9865..50a3f022b 100644 --- a/src/input/plugins/QobuzTagScanner.cxx +++ b/src/input/plugins/QobuzTagScanner.cxx @@ -99,8 +99,7 @@ QobuzTagScanner::~QobuzTagScanner() noexcept } std::unique_ptr -QobuzTagScanner::MakeParser(unsigned status, - std::multimap &&headers) +QobuzTagScanner::MakeParser(unsigned status, Curl::Headers &&headers) { if (status != 200) return std::make_unique(status, headers); diff --git a/src/input/plugins/QobuzTagScanner.hxx b/src/input/plugins/QobuzTagScanner.hxx index 3a8a3276e..ce596bc80 100644 --- a/src/input/plugins/QobuzTagScanner.hxx +++ b/src/input/plugins/QobuzTagScanner.hxx @@ -49,7 +49,7 @@ public: private: /* virtual methods from DelegateCurlResponseHandler */ std::unique_ptr MakeParser(unsigned status, - std::multimap &&headers) override; + Curl::Headers &&headers) override; void FinishParser(std::unique_ptr p) override; /* virtual methods from CurlResponseHandler */ diff --git a/src/input/plugins/QobuzTrackRequest.cxx b/src/input/plugins/QobuzTrackRequest.cxx index e48a3848e..b697d3ec3 100644 --- a/src/input/plugins/QobuzTrackRequest.cxx +++ b/src/input/plugins/QobuzTrackRequest.cxx @@ -93,7 +93,7 @@ QobuzTrackRequest::~QobuzTrackRequest() noexcept std::unique_ptr QobuzTrackRequest::MakeParser(unsigned status, - std::multimap &&headers) + Curl::Headers &&headers) { if (status != 200) return std::make_unique(status, headers); diff --git a/src/input/plugins/QobuzTrackRequest.hxx b/src/input/plugins/QobuzTrackRequest.hxx index 9de1890b6..a16ce760b 100644 --- a/src/input/plugins/QobuzTrackRequest.hxx +++ b/src/input/plugins/QobuzTrackRequest.hxx @@ -56,7 +56,7 @@ public: private: /* virtual methods from DelegateCurlResponseHandler */ std::unique_ptr MakeParser(unsigned status, - std::multimap &&headers) override; + Curl::Headers &&headers) override; void FinishParser(std::unique_ptr p) override; /* virtual methods from CurlResponseHandler */ diff --git a/src/lib/curl/Adapter.hxx b/src/lib/curl/Adapter.hxx index 1d26f46e6..fc4c946c3 100644 --- a/src/lib/curl/Adapter.hxx +++ b/src/lib/curl/Adapter.hxx @@ -1,5 +1,5 @@ /* - * Copyright 2008-2021 Max Kellermann + * Copyright 2008-2022 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,14 +27,13 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CURL_ADAPTER_HXX -#define CURL_ADAPTER_HXX +#pragma once + +#include "Headers.hxx" #include #include -#include -#include struct StringView; class CurlEasy; @@ -45,7 +44,7 @@ class CurlResponseHandlerAdapter { CurlResponseHandler &handler; - std::multimap headers; + Curl::Headers headers; /** error message provided by libcurl */ char error_buffer[CURL_ERROR_SIZE]; @@ -83,5 +82,3 @@ private: std::size_t size, std::size_t nmemb, void *stream) noexcept; }; - -#endif diff --git a/src/lib/curl/Delegate.cxx b/src/lib/curl/Delegate.cxx index a16793ed2..b6b6dc507 100644 --- a/src/lib/curl/Delegate.cxx +++ b/src/lib/curl/Delegate.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2018 Max Kellermann + * Copyright 2008-2022 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,8 +34,7 @@ #include void -DelegateCurlResponseHandler::OnHeaders(unsigned status, - std::multimap &&headers) +DelegateCurlResponseHandler::OnHeaders(unsigned status, Curl::Headers &&headers) { parser = MakeParser(status, std::move(headers)); assert(parser); diff --git a/src/lib/curl/Delegate.hxx b/src/lib/curl/Delegate.hxx index fe6a65f35..95c8576ce 100644 --- a/src/lib/curl/Delegate.hxx +++ b/src/lib/curl/Delegate.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2018 Max Kellermann + * Copyright 2008-2022 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,8 +27,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CURL_DELEGATE_HXX -#define CURL_DELEGATE_HXX +#pragma once #include "Handler.hxx" @@ -53,7 +52,7 @@ protected: * CurlResponseParser::OnError()). */ virtual std::unique_ptr MakeParser(unsigned status, - std::multimap &&headers) = 0; + Curl::Headers &&headers) = 0; /** * The parser has finished parsing the response body. This @@ -64,10 +63,7 @@ protected: virtual void FinishParser(std::unique_ptr p) = 0; public: - void OnHeaders(unsigned status, - std::multimap &&headers) final; + void OnHeaders(unsigned status, Curl::Headers &&headers) final; void OnData(ConstBuffer data) final; void OnEnd() final; }; - -#endif diff --git a/src/lib/curl/Form.cxx b/src/lib/curl/Form.cxx index 5b668ec46..5f45fdb56 100644 --- a/src/lib/curl/Form.cxx +++ b/src/lib/curl/Form.cxx @@ -31,8 +31,7 @@ #include "String.hxx" std::string -EncodeForm(CURL *curl, - const std::multimap &fields) noexcept +EncodeForm(CURL *curl, const Curl::Headers &fields) noexcept { std::string result; diff --git a/src/lib/curl/Form.hxx b/src/lib/curl/Form.hxx index 8c045ac22..1545d3e7d 100644 --- a/src/lib/curl/Form.hxx +++ b/src/lib/curl/Form.hxx @@ -30,17 +30,17 @@ #ifndef CURL_FORM_HXX #define CURL_FORM_HXX +#include "Headers.hxx" + #include #include -#include /** * Encode the given map of form fields to a * "application/x-www-form-urlencoded" string. */ std::string -EncodeForm(CURL *curl, - const std::multimap &fields) noexcept; +EncodeForm(CURL *curl, const Curl::Headers &fields) noexcept; #endif diff --git a/src/lib/curl/Handler.hxx b/src/lib/curl/Handler.hxx index 14a928a80..c0bdeced1 100644 --- a/src/lib/curl/Handler.hxx +++ b/src/lib/curl/Handler.hxx @@ -27,14 +27,12 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CURL_HANDLER_HXX -#define CURL_HANDLER_HXX +#pragma once +#include "Headers.hxx" #include "util/ConstBuffer.hxx" #include -#include -#include /** * Asynchronous response handler for a #CurlRequest. @@ -53,8 +51,7 @@ public: /** * Status line and headers have been received. */ - virtual void OnHeaders(unsigned status, - std::multimap &&headers) = 0; + virtual void OnHeaders(unsigned status, Curl::Headers &&headers) = 0; /** * Response body data has been received. @@ -75,5 +72,3 @@ public: */ virtual void OnError(std::exception_ptr e) noexcept = 0; }; - -#endif diff --git a/src/lib/curl/Headers.hxx b/src/lib/curl/Headers.hxx new file mode 100644 index 000000000..7ff04a6e4 --- /dev/null +++ b/src/lib/curl/Headers.hxx @@ -0,0 +1,42 @@ +/* + * Copyright 2020-2021 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include + +namespace Curl { + +using Headers = std::multimap; + +} // namespace Curl diff --git a/src/lib/upnp/Discovery.cxx b/src/lib/upnp/Discovery.cxx index 7bd8b8d90..e224b28bd 100644 --- a/src/lib/upnp/Discovery.cxx +++ b/src/lib/upnp/Discovery.cxx @@ -55,7 +55,7 @@ UPnPDeviceDirectory::Downloader::Destroy() noexcept void UPnPDeviceDirectory::Downloader::OnHeaders(unsigned status, - std::multimap &&) + Curl::Headers &&) { if (status != 200) { Destroy(); diff --git a/src/lib/upnp/Discovery.hxx b/src/lib/upnp/Discovery.hxx index 3391148dd..8052b1a31 100644 --- a/src/lib/upnp/Discovery.hxx +++ b/src/lib/upnp/Discovery.hxx @@ -113,8 +113,7 @@ class UPnPDeviceDirectory final : UpnpCallback { } /* virtual methods from CurlResponseHandler */ - void OnHeaders(unsigned status, - std::multimap &&headers) override; + void OnHeaders(unsigned status, Curl::Headers &&headers) override; void OnData(ConstBuffer data) override; void OnEnd() override; void OnError(std::exception_ptr e) noexcept override; diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx index d6f1a932d..4b5b84553 100644 --- a/src/storage/plugins/CurlStorage.cxx +++ b/src/storage/plugins/CurlStorage.cxx @@ -227,7 +227,7 @@ IsXmlContentType(const char *content_type) noexcept gcc_pure static bool -IsXmlContentType(const std::multimap &headers) noexcept +IsXmlContentType(const Curl::Headers &headers) noexcept { auto i = headers.find("content-type"); return i != headers.end() && IsXmlContentType(i->second.c_str()); @@ -297,8 +297,7 @@ private: } /* virtual methods from CurlResponseHandler */ - void OnHeaders(unsigned status, - std::multimap &&headers) final { + void OnHeaders(unsigned status, Curl::Headers &&headers) final { if (status != 207) throw FormatRuntimeError("Status %d from WebDAV server; expected \"207 Multi-Status\"", status); diff --git a/test/RunCurl.cxx b/test/RunCurl.cxx index 9d4874eb0..7ae233054 100644 --- a/test/RunCurl.cxx +++ b/test/RunCurl.cxx @@ -41,8 +41,7 @@ public: } /* virtual methods from CurlResponseHandler */ - void OnHeaders(unsigned status, - std::multimap &&headers) override { + void OnHeaders(unsigned status, Curl::Headers &&headers) override { fprintf(stderr, "status: %u\n", status); for (const auto &i : headers) fprintf(stderr, "%s: %s\n",