Made the request stuff work.
This commit is contained in:
@@ -24,6 +24,12 @@ public:
|
||||
}
|
||||
} gCURLGuard [[maybe_unused]];
|
||||
|
||||
struct ReadData
|
||||
{
|
||||
mijin::TypelessBuffer* buffer;
|
||||
std::size_t pos;
|
||||
};
|
||||
|
||||
bool initCURL() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (gCurlInited)
|
||||
@@ -38,23 +44,139 @@ bool initCURL() MIJIN_NOEXCEPT
|
||||
gCurlInited = (curl_global_init(0) == CURLE_OK);
|
||||
return gCurlInited;
|
||||
}
|
||||
|
||||
std::size_t writeCallback(char* ptr, std::size_t /* size */, std::size_t nmemb, void* userdata) noexcept
|
||||
{
|
||||
TypelessBuffer& body = *static_cast<TypelessBuffer*>(userdata);
|
||||
body.append(std::span<const char>(ptr, nmemb));
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
Task<StreamResult<HTTPResponse>> c_request(const URL& url, HTTPRequest request) MIJIN_NOEXCEPT
|
||||
std::size_t readCallback(char* ptr, std::size_t size, std::size_t nmemb, void* userdata) noexcept
|
||||
{
|
||||
(void) url;
|
||||
(void) request;
|
||||
ReadData& data = *static_cast<ReadData*>(userdata);
|
||||
const std::size_t bytesToRead = std::min(size * nmemb, data.buffer->byteSize() - data.pos);
|
||||
std::memcpy(ptr, static_cast<std::byte*>(data.buffer->data()) + data.pos, bytesToRead);
|
||||
data.pos += bytesToRead;
|
||||
|
||||
return bytesToRead;
|
||||
}
|
||||
}
|
||||
|
||||
Task<StreamResult<HTTPResponse>> c_request(const URL& url, HTTPRequestOptions options) MIJIN_NOEXCEPT
|
||||
{
|
||||
ReadData readData;
|
||||
|
||||
if (!initCURL())
|
||||
{
|
||||
co_return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
curl::CurlEasy easy;
|
||||
if (!easy.init())
|
||||
{
|
||||
co_return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
easy.setURL(url);
|
||||
|
||||
curl::SList requestHeaders;
|
||||
for (const auto& [name, value] : options.headers)
|
||||
{
|
||||
requestHeaders.append(std::format("{}: {}", name, value).c_str());
|
||||
}
|
||||
|
||||
co_return StreamError::UNKNOWN_ERROR;
|
||||
#define HANDLE_CURL_RESULT(result) \
|
||||
if (const curl::Error error = (result); !error.isSuccess()) \
|
||||
{ \
|
||||
co_return StreamError::UNKNOWN_ERROR; \
|
||||
}
|
||||
HANDLE_CURL_RESULT(easy.setHeaders(std::move(requestHeaders)))
|
||||
|
||||
if (options.method == http_method::POST)
|
||||
{
|
||||
HANDLE_CURL_RESULT(easy.setPostFields(options.body.makeSpan<const char>().data()))
|
||||
}
|
||||
else if (options.method == http_method::PUT)
|
||||
{
|
||||
HANDLE_CURL_RESULT(easy.setUpload(true))
|
||||
HANDLE_CURL_RESULT(easy.setInFileSize(options.body.byteSize()));
|
||||
HANDLE_CURL_RESULT(easy.setReadFunction(&readCallback));
|
||||
readData.buffer = &options.body;
|
||||
readData.pos = 0;
|
||||
HANDLE_CURL_RESULT(easy.setReadData(&readData));
|
||||
}
|
||||
else if (options.method == http_method::HEAD)
|
||||
{
|
||||
HANDLE_CURL_RESULT(easy.setNoBody(true))
|
||||
}
|
||||
else if (options.method != http_method::GET)
|
||||
{
|
||||
// different option, let's do our best
|
||||
HANDLE_CURL_RESULT(easy.setCustomRequest(true))
|
||||
if (!options.body.empty())
|
||||
{
|
||||
HANDLE_CURL_RESULT(easy.setUpload(true))
|
||||
HANDLE_CURL_RESULT(easy.setInFileSize(options.body.byteSize()));
|
||||
HANDLE_CURL_RESULT(easy.setReadFunction(&readCallback));
|
||||
readData.buffer = &options.body;
|
||||
readData.pos = 0;
|
||||
HANDLE_CURL_RESULT(easy.setReadData(&readData));
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE_CURL_RESULT(easy.setURL(url))
|
||||
HANDLE_CURL_RESULT(easy.setWriteFunction(&writeCallback))
|
||||
TypelessBuffer body;
|
||||
HANDLE_CURL_RESULT(easy.setWriteData(&body))
|
||||
HANDLE_CURL_RESULT(easy.perform())
|
||||
#undef HANDLE_CURL_RESULT
|
||||
|
||||
HTTPResponse response = {
|
||||
.body = std::move(body)
|
||||
};
|
||||
if (const curl::Result<int> httpVersion = easy.getHTTPVersion(); httpVersion.isSuccess())
|
||||
{
|
||||
switch (*httpVersion)
|
||||
{
|
||||
case CURL_HTTP_VERSION_1_0:
|
||||
response.version = {1, 0};
|
||||
break;
|
||||
case CURL_HTTP_VERSION_1_1:
|
||||
response.version = {1, 1};
|
||||
break;
|
||||
case CURL_HTTP_VERSION_2_0:
|
||||
response.version = {2, 0};
|
||||
break;
|
||||
case CURL_HTTP_VERSION_3:
|
||||
response.version = {3, 0};
|
||||
break;
|
||||
default:
|
||||
MIJIN_ERROR("Unknown CURL http version returned.");
|
||||
response.version = {1, 0};
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
co_return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
if (const curl::Result<int> status = easy.getStatus(); status.isSuccess())
|
||||
{
|
||||
response.status = *status;
|
||||
}
|
||||
else
|
||||
{
|
||||
co_return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
if (curl::Result<std::multimap<std::string, std::string>> headers = easy.getResponseHeaders(); headers.isSuccess())
|
||||
{
|
||||
response.headers = std::move(*headers);
|
||||
}
|
||||
else
|
||||
{
|
||||
co_return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
co_return response;
|
||||
}
|
||||
} // namespace mijin
|
||||
|
||||
Reference in New Issue
Block a user