Added some getters to web request and added some coverage for edge-cases ()

* Added some getters to web request and added some coverage for possible edge-cases

* Added the getter implements for web requests

* Escaped header options
This commit is contained in:
SMJS 2024-06-30 16:32:06 +02:00 committed by GitHub
parent 427e86ef6e
commit a96ec91f89
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 108 additions and 4 deletions
loader
include/Geode/utils
src/utils

View file

@ -126,7 +126,6 @@ namespace geode::utils::web {
WebRequest& header(std::string_view name, std::string_view value);
WebRequest& param(std::string_view name, std::string_view value);
template <std::integral T>
WebRequest& param(std::string_view name, T value) {
return this->param(name, std::to_string(value));
@ -251,5 +250,55 @@ namespace geode::utils::web {
* @return WebRequest&
*/
WebRequest& bodyJSON(matjson::Value const& json);
/**
* Gets the request method as a string
*
* @return std::string
*/
std::string getMethod() const;
/**
* Gets the request URL
*
* @return std::string
*/
std::string getUrl() const;
/**
* Gets the request headers
*
* @return std::unordered_map<std::string, std::string>
*/
std::unordered_map<std::string, std::string> getHeaders() const;
/**
* Gets the parameters inside the URL
*
* @return std::unordered_map<std::string, std::string>
*/
std::unordered_map<std::string, std::string> getUrlParams() const;
/**
* Gets the post body stream
*
* @return std::optional<ByteVector>
*/
std::optional<ByteVector> getBody() const;
/**
* Gets the request timeout in seconds
*
* @return std::optional<std::chrono::seconds>
*/
std::optional<std::chrono::seconds> getTimeout() const;
/**
* Gets HTTP versions applied to the request
*
* @return HttpVersion
*/
HttpVersion getHttpVersion() const;
};
}

View file

@ -279,9 +279,9 @@ WebTask WebRequest::send(std::string_view method, std::string_view url) {
// Add parameters to the URL and pass it to curl
auto url = impl->m_url;
bool first = true;
for (auto param : impl->m_urlParameters) {
url += (first ? "?" : "&") + urlParamEncode(param.first) + "=" + urlParamEncode(param.second);
bool first = url.find('?') == std::string::npos;
for (auto& [key, value] : impl->m_urlParameters) {
url += (first ? "?" : "&") + urlParamEncode(key) + "=" + urlParamEncode(value);
first = false;
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
@ -306,6 +306,7 @@ WebTask WebRequest::send(std::string_view method, std::string_view url) {
} else if (impl->m_method == "POST") {
// curl_easy_perform would freeze on a POST request with no fields, so set it to an empty string
// why? god knows
// SMJS: because the stream isn't complete without a body according to the spec
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
}
@ -470,13 +471,39 @@ WebTask WebRequest::patch(std::string_view url) {
}
WebRequest& WebRequest::header(std::string_view name, std::string_view value) {
if (name == "User-Agent") {
userAgent(value);
return *this;
} if (name == "Accept-Encoding") {
acceptEncoding(value);
return *this;
} if (name == "Keep-Alive") {
const size_t timeoutPos = value.find("timeout");
if (timeoutPos != std::string::npos) {
// At this point idc what happens if I get NPOS or string ends, you shouldn't custom format a spec header
const size_t numStart = value.find('=', timeoutPos) + 1;
const size_t comma = value.find(',', numStart);
const size_t numLength = (comma == std::string::npos ? value.size() : comma) - numStart;
timeout(std::chrono::seconds(std::stol(std::string(value.substr(numStart, numLength)))));
return *this;
}
}
m_impl->m_headers.insert_or_assign(std::string(name), std::string(value));
return *this;
}
WebRequest& WebRequest::param(std::string_view name, std::string_view value) {
m_impl->m_urlParameters.insert_or_assign(std::string(name), std::string(value));
return *this;
}
WebRequest& WebRequest::userAgent(std::string_view name) {
m_impl->m_userAgent = name;
return *this;
@ -540,3 +567,31 @@ WebRequest& WebRequest::bodyJSON(matjson::Value const& json) {
m_impl->m_body = ByteVector { str.begin(), str.end() };
return *this;
}
std::string WebRequest::getMethod() const {
return m_impl->m_method;
}
std::string WebRequest::getUrl() const {
return m_impl->m_url;
}
std::unordered_map<std::string, std::string> WebRequest::getHeaders() const {
return m_impl->m_headers;
}
std::unordered_map<std::string, std::string> WebRequest::getUrlParams() const {
return m_impl->m_urlParameters;
}
std::optional<ByteVector> WebRequest::getBody() const {
return m_impl->m_body;
}
std::optional<std::chrono::seconds> WebRequest::getTimeout() const {
return m_impl->m_timeout;
}
HttpVersion WebRequest::getHttpVersion() const {
return m_impl->m_httpVersion;
}