From ba3f16edbfe8b152f12a66b8fb3da215c8e52a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Tue, 13 Jun 2017 12:52:10 +0200 Subject: [PATCH] HttpRequest: Add support for sending custom headers --- Source/Core/Common/HttpRequest.cpp | 37 ++++++++++++++++++++++-------- Source/Core/Common/HttpRequest.h | 9 +++++--- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Source/Core/Common/HttpRequest.cpp b/Source/Core/Common/HttpRequest.cpp index 0f4c1695d1..5c83521972 100644 --- a/Source/Core/Common/HttpRequest.cpp +++ b/Source/Core/Common/HttpRequest.cpp @@ -8,6 +8,8 @@ #include #include "Common/Logging/Log.h" +#include "Common/ScopeGuard.h" +#include "Common/StringUtil.h" namespace Common { @@ -23,7 +25,8 @@ public: Impl(); bool IsValid() const; - Response Fetch(const std::string& url, Method method, const u8* payload, size_t size); + Response Fetch(const std::string& url, Method method, const Headers& headers, const u8* payload, + size_t size); private: std::unique_ptr m_curl{curl_easy_init(), curl_easy_cleanup}; @@ -40,20 +43,22 @@ bool HttpRequest::IsValid() const return m_impl->IsValid(); } -HttpRequest::Response HttpRequest::Get(const std::string& url) +HttpRequest::Response HttpRequest::Get(const std::string& url, const Headers& headers) { - return m_impl->Fetch(url, Impl::Method::GET, nullptr, 0); + return m_impl->Fetch(url, Impl::Method::GET, headers, nullptr, 0); } -HttpRequest::Response HttpRequest::Post(const std::string& url, const std::vector& payload) +HttpRequest::Response HttpRequest::Post(const std::string& url, const std::vector& payload, + const Headers& headers) { - return m_impl->Fetch(url, Impl::Method::POST, payload.data(), payload.size()); + return m_impl->Fetch(url, Impl::Method::POST, headers, payload.data(), payload.size()); } -HttpRequest::Response HttpRequest::Post(const std::string& url, const std::string& payload) +HttpRequest::Response HttpRequest::Post(const std::string& url, const std::string& payload, + const Headers& headers) { - return m_impl->Fetch(url, Impl::Method::POST, reinterpret_cast(payload.data()), - payload.size()); + return m_impl->Fetch(url, Impl::Method::POST, headers, + reinterpret_cast(payload.data()), payload.size()); } HttpRequest::Impl::Impl() @@ -85,7 +90,8 @@ static size_t CurlCallback(char* data, size_t size, size_t nmemb, void* userdata } HttpRequest::Response HttpRequest::Impl::Fetch(const std::string& url, Method method, - const u8* payload, size_t size) + const Headers& headers, const u8* payload, + size_t size) { curl_easy_setopt(m_curl.get(), CURLOPT_POST, method == Method::POST); curl_easy_setopt(m_curl.get(), CURLOPT_URL, url.c_str()); @@ -95,6 +101,19 @@ HttpRequest::Response HttpRequest::Impl::Fetch(const std::string& url, Method me curl_easy_setopt(m_curl.get(), CURLOPT_POSTFIELDSIZE, size); } + curl_slist* list = nullptr; + Common::ScopeGuard list_guard{[&list] { curl_slist_free_all(list); }}; + for (const std::pair>& header : headers) + { + if (!header.second) + list = curl_slist_append(list, (header.first + ":").c_str()); + else if (header.second->empty()) + list = curl_slist_append(list, (header.first + ";").c_str()); + else + list = curl_slist_append(list, (header.first + ": " + *header.second).c_str()); + } + curl_easy_setopt(m_curl.get(), CURLOPT_HTTPHEADER, list); + std::vector buffer; curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, CurlCallback); curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, &buffer); diff --git a/Source/Core/Common/HttpRequest.h b/Source/Core/Common/HttpRequest.h index e4e35d1cbf..0a1a86da82 100644 --- a/Source/Core/Common/HttpRequest.h +++ b/Source/Core/Common/HttpRequest.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include @@ -21,9 +22,11 @@ public: bool IsValid() const; using Response = std::optional>; - Response Get(const std::string& url); - Response Post(const std::string& url, const std::vector& payload); - Response Post(const std::string& url, const std::string& payload); + using Headers = std::map>; + Response Get(const std::string& url, const Headers& headers = {}); + Response Post(const std::string& url, const std::vector& payload, + const Headers& headers = {}); + Response Post(const std::string& url, const std::string& payload, const Headers& headers = {}); private: class Impl;