-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Common: Add HttpRequest to simplify HTTP requests
Too much boilerplate that is duplicated if we use curl directly. Let's add a simple wrapper class that hides the implementation details and just allows to simply make HTTP requests and get responses.
- Loading branch information
Showing
8 changed files
with
148 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright 2017 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#include "Common/HttpRequest.h" | ||
|
||
#include <cstddef> | ||
|
||
#include "Common/Logging/Log.h" | ||
|
||
namespace Common | ||
{ | ||
HttpRequest::HttpRequest() | ||
{ | ||
if (!m_curl) | ||
return; | ||
|
||
// libcurl may not have been built with async DNS support, so we disable | ||
// signal handlers to avoid a possible and likely crash if a resolve times out. | ||
curl_easy_setopt(m_curl.get(), CURLOPT_NOSIGNAL, true); | ||
curl_easy_setopt(m_curl.get(), CURLOPT_TIMEOUT, 3); | ||
#ifdef _WIN32 | ||
// ALPN support is enabled by default but requires Windows >= 8.1. | ||
curl_easy_setopt(m_curl.get(), CURLOPT_SSL_ENABLE_ALPN, false); | ||
#endif | ||
} | ||
|
||
HttpRequest::~HttpRequest() = default; | ||
|
||
bool HttpRequest::IsValid() const | ||
{ | ||
return m_curl != nullptr; | ||
} | ||
|
||
static size_t CurlCallback(u8* data, size_t size, size_t nmemb, std::vector<u8>* buffer) | ||
{ | ||
const size_t actual_size = size * nmemb; | ||
buffer->insert(buffer->end(), data, data + actual_size); | ||
return actual_size; | ||
} | ||
|
||
HttpRequest::Response HttpRequest::Get(const std::string& url) | ||
{ | ||
return Fetch(url, Method::GET, nullptr, 0); | ||
} | ||
|
||
HttpRequest::Response HttpRequest::Post(const std::string& url, const std::vector<u8>& payload) | ||
{ | ||
return Fetch(url, Method::POST, payload.data(), payload.size()); | ||
} | ||
|
||
HttpRequest::Response HttpRequest::Post(const std::string& url, const std::string& payload) | ||
{ | ||
return Fetch(url, Method::POST, reinterpret_cast<const u8*>(payload.data()), payload.size()); | ||
} | ||
|
||
HttpRequest::Response HttpRequest::Fetch(const std::string& url, Method method, 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()); | ||
if (method == Method::POST) | ||
{ | ||
curl_easy_setopt(m_curl.get(), CURLOPT_POSTFIELDS, payload); | ||
curl_easy_setopt(m_curl.get(), CURLOPT_POSTFIELDSIZE, size); | ||
} | ||
|
||
std::vector<u8> buffer; | ||
curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, CurlCallback); | ||
curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, &buffer); | ||
|
||
const char* type = method == Method::POST ? "POST" : "GET"; | ||
const CURLcode res = curl_easy_perform(m_curl.get()); | ||
if (res != CURLE_OK) | ||
{ | ||
ERROR_LOG(COMMON, "Failed to %s %s: %s", type, url.c_str(), curl_easy_strerror(res)); | ||
return {}; | ||
} | ||
|
||
long response_code = 0; | ||
curl_easy_getinfo(m_curl.get(), CURLINFO_RESPONSE_CODE, &response_code); | ||
if (response_code != 200) | ||
{ | ||
ERROR_LOG(COMMON, "Failed to %s %s: response code was %li", type, url.c_str(), response_code); | ||
return {}; | ||
} | ||
|
||
return buffer; | ||
} | ||
} // namespace Common |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2017 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
#include <optional> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <curl/curl.h> | ||
|
||
#include "Common/CommonTypes.h" | ||
|
||
namespace Common | ||
{ | ||
class HttpRequest final | ||
{ | ||
public: | ||
HttpRequest(); | ||
~HttpRequest(); | ||
bool IsValid() const; | ||
|
||
using Response = std::optional<std::vector<u8>>; | ||
Response Get(const std::string& url); | ||
Response Post(const std::string& url, const std::vector<u8>& payload); | ||
Response Post(const std::string& url, const std::string& payload); | ||
|
||
private: | ||
enum class Method | ||
{ | ||
GET, | ||
POST, | ||
}; | ||
Response Fetch(const std::string& url, Method method, const u8* payload, size_t size); | ||
|
||
std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> m_curl{curl_easy_init(), curl_easy_cleanup}; | ||
}; | ||
} // namespace Common |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters