Addded Romeo that generates some doc. WIP.

This commit is contained in:
2026-07-18 18:58:29 -04:00
parent 446670bd29
commit 0c583b58da
120 changed files with 6167 additions and 18 deletions
+196
View File
@@ -0,0 +1,196 @@
#include "HttpClient.h"
#include <Windows.h>
#include <winhttp.h>
#include <Core/Memory/MemoryArena.h>
#include <Core/Common/CoreUtils.h>
namespace Romeo
{
static wchar_t* ConvertToWide(Juliet::Arena* arena, const Juliet::String& str)
{
Assert(arena != nullptr);
if (str.Size == 0)
{
return const_cast<wchar_t*>(L"");
}
int wLen = MultiByteToWideChar(CP_UTF8, 0, CStr(str), static_cast<int>(str.Size), nullptr, 0);
if (wLen <= 0)
{
return const_cast<wchar_t*>(L"");
}
wchar_t* wBuf = Juliet::ArenaPushArray<wchar_t>(arena, static_cast<size_t>(wLen + 1) JULIET_DEBUG_PARAM("WideStr"));
MultiByteToWideChar(CP_UTF8, 0, CStr(str), static_cast<int>(str.Size), wBuf, wLen);
wBuf[wLen] = L'\0';
return wBuf;
}
bool HttpClient::Post(
Juliet::Arena* arena,
const Juliet::String& host,
int port,
const Juliet::String& path,
bool isHttps,
const Juliet::String& requestBody,
Juliet::String& outResponse
)
{
Assert(arena != nullptr);
Assert(host.Size > 0);
bool success = false;
HINTERNET hSession = nullptr;
HINTERNET hConnect = nullptr;
HINTERNET hRequest = nullptr;
hSession = WinHttpOpen(
L"Romeo/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
nullptr,
nullptr,
0
);
if (hSession != nullptr)
{
WinHttpSetTimeouts(hSession, 60000, 60000, 60000, 1800000);
wchar_t* wHost = ConvertToWide(arena, host);
hConnect = WinHttpConnect(
hSession,
wHost,
static_cast<INTERNET_PORT>(port),
0
);
}
if (hConnect != nullptr)
{
wchar_t* wPath = ConvertToWide(arena, path);
hRequest = WinHttpOpenRequest(
hConnect,
L"POST",
wPath,
nullptr,
nullptr,
nullptr,
isHttps ? WINHTTP_FLAG_SECURE : 0
);
}
if (hRequest != nullptr)
{
const wchar_t* headers = L"Content-Type: application/json\r\n";
DWORD headersLen = static_cast<DWORD>(-1);
BOOL sendRes = WinHttpSendRequest(
hRequest,
headers,
headersLen,
const_cast<char*>(CStr(requestBody)),
static_cast<DWORD>(requestBody.Size),
static_cast<DWORD>(requestBody.Size),
0
);
if (sendRes != 0)
{
BOOL recvRes = WinHttpReceiveResponse(hRequest, nullptr);
if (recvRes != 0)
{
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
size_t totalBytes = 0;
size_t capacity = 1024;
char* responseData = Juliet::ArenaPushArray<char>(arena, capacity JULIET_DEBUG_PARAM("HttpResponse"));
do
{
dwSize = 0;
if (WinHttpQueryDataAvailable(hRequest, &dwSize) == 0)
{
break;
}
if (dwSize == 0)
{
break;
}
if (totalBytes + dwSize >= capacity)
{
size_t newCapacity = capacity * 2;
if (newCapacity < totalBytes + dwSize + 1)
{
newCapacity = totalBytes + dwSize + 1;
}
char* newBuf = Juliet::ArenaPushArray<char>(arena, newCapacity JULIET_DEBUG_PARAM("HttpResponseGrow"));
memcpy(newBuf, responseData, totalBytes);
responseData = newBuf;
capacity = newCapacity;
}
dwDownloaded = 0;
if (WinHttpReadData(hRequest, responseData + totalBytes, dwSize, &dwDownloaded) != 0)
{
totalBytes += dwDownloaded;
}
else
{
break;
}
} while (dwSize > 0);
DWORD dwStatusCode = 0;
DWORD dwHeaderSize = sizeof(dwStatusCode);
WinHttpQueryHeaders(
hRequest,
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
nullptr,
&dwStatusCode,
&dwHeaderSize,
nullptr
);
if (dwStatusCode == 200)
{
if (totalBytes > 0)
{
responseData[totalBytes] = '\0';
outResponse.Data = responseData;
outResponse.Size = totalBytes;
success = true;
}
}
else
{
if (totalBytes > 0)
{
responseData[totalBytes] = '\0';
printf("Romeo HttpClient: HTTP Error Status %u. Response: %s\n", static_cast<unsigned int>(dwStatusCode), responseData);
}
else
{
printf("Romeo HttpClient: HTTP Error Status %u. Empty response.\n", static_cast<unsigned int>(dwStatusCode));
}
}
}
}
}
if (hRequest != nullptr)
{
WinHttpCloseHandle(hRequest);
}
if (hConnect != nullptr)
{
WinHttpCloseHandle(hConnect);
}
if (hSession != nullptr)
{
WinHttpCloseHandle(hSession);
}
return success;
}
}