diff --git a/Makefile.am b/Makefile.am index b5b594302..0900f39a2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1285,6 +1285,7 @@ libinput_a_SOURCES += \ src/lib/curl/Handler.hxx \ src/lib/curl/Easy.hxx \ src/lib/curl/Multi.hxx \ + src/lib/curl/Slist.hxx \ src/IcyMetaDataParser.cxx src/IcyMetaDataParser.hxx endif diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index 61da1d3ad..b6208361d 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -23,6 +23,7 @@ #include "lib/curl/Global.hxx" #include "lib/curl/Request.hxx" #include "lib/curl/Handler.hxx" +#include "lib/curl/Slist.hxx" #include "../AsyncInputStream.hxx" #include "../IcyInputStream.hxx" #include "../InputPlugin.hxx" @@ -64,7 +65,7 @@ struct CurlInputStream final : public AsyncInputStream, CurlResponseHandler { /* some buffers which were passed to libcurl, which we have too free */ char range[32]; - struct curl_slist *request_headers; + CurlSlist request_headers; CurlRequest *request = nullptr; @@ -75,7 +76,6 @@ struct CurlInputStream final : public AsyncInputStream, CurlResponseHandler { :AsyncInputStream(_url, _mutex, _cond, CURL_MAX_BUFFERED, CURL_RESUME_AT), - request_headers(nullptr), icy(new IcyInputStream(this)) { } @@ -155,8 +155,7 @@ CurlInputStream::FreeEasy() delete request; request = nullptr; - curl_slist_free_all(request_headers); - request_headers = nullptr; + request_headers.Clear(); } void @@ -371,10 +370,9 @@ CurlInputStream::InitEasy() request->SetOption(CURLOPT_SSL_VERIFYPEER, verify_peer ? 1l : 0l); request->SetOption(CURLOPT_SSL_VERIFYHOST, verify_host ? 2l : 0l); - request_headers = nullptr; - request_headers = curl_slist_append(request_headers, - "Icy-Metadata: 1"); - request->SetOption(CURLOPT_HTTPHEADER, request_headers); + request_headers.Clear(); + request_headers.Append("Icy-Metadata: 1"); + request->SetOption(CURLOPT_HTTPHEADER, request_headers.Get()); } void diff --git a/src/lib/curl/Slist.hxx b/src/lib/curl/Slist.hxx new file mode 100644 index 000000000..d3cc34710 --- /dev/null +++ b/src/lib/curl/Slist.hxx @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2008-2017 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. + */ + +#ifndef CURL_SLIST_HXX +#define CURL_SLIST_HXX + +#include + +#include + +/** + * OO wrapper for "struct curl_slist *". + */ +class CurlSlist { + struct curl_slist *head = nullptr; + +public: + CurlSlist() = default; + + CurlSlist(CurlSlist &&src) + :head(std::exchange(src.head, nullptr)) {} + + ~CurlSlist() { + if (head != nullptr) + curl_slist_free_all(head); + } + + CurlSlist &operator=(CurlSlist &&src) { + std::swap(head, src.head); + return *this; + } + + struct curl_slist *Get() { + return head; + } + + void Clear() { + curl_slist_free_all(head); + head = nullptr; + } + + void Append(const char *value) { + auto *new_head = curl_slist_append(head, value); + if (new_head == nullptr) + throw std::runtime_error("curl_slist_append() failed"); + head = new_head; + } +}; + +#endif