Skip to content

Commit

Permalink
Add stream and cookie support for UtilHttpClient.
Browse files Browse the repository at this point in the history
  • Loading branch information
hzqst committed Jan 27, 2024
1 parent 1a6558a commit 81cb6a0
Show file tree
Hide file tree
Showing 3 changed files with 269 additions and 22 deletions.
272 changes: 253 additions & 19 deletions PluginLibs/UtilHTTPClient_SteamAPI/UtilHTTPClient_SteamAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ class CUtilHTTPPayload : public IUtilHTTPPayload
std::string m_payload;

public:

bool ReadStreamFromRequestHandle(HTTPRequestHandle handle, uint32_t offset, uint32_t size)
{
m_payload.resize(size);
if (SteamHTTP()->GetHTTPStreamingResponseBodyData(handle, offset, (uint8*)m_payload.data(), size))
{
return true;
}

return false;
}

bool ReadFromRequestHandle(HTTPRequestHandle handle)
{
uint32_t responseSize = 0;
Expand Down Expand Up @@ -139,19 +151,44 @@ class CUtilHTTPResponse : public IUtilHTTPResponse
private:
bool m_bResponseCompleted{};
bool m_bResponseError{};
bool m_bIsHeaderReceived{};
bool m_bIsStream{};
int m_iResponseStatusCode{};
CUtilHTTPPayload* m_pResponsePayload{};

HTTPRequestHandle m_RequestHandle{ INVALID_HTTPREQUEST_HANDLE };
public:

void OnSteamHTTPCompleted(HTTPRequestHandle RequestHandle, HTTPRequestCompleted_t* pResult, bool bHasError)
void OnSteamHTTPRecvHeader(HTTPRequestHeadersReceived_t* pResult, bool bHasError)
{
m_bIsHeaderReceived = true;
m_bIsStream = true;

m_RequestHandle = pResult->m_hRequest;
}

void OnSteamHTTPRecvData(HTTPRequestDataReceived_t* pResult, bool bHasError)
{
m_RequestHandle = pResult->m_hRequest;

if (m_bIsStream && !bHasError)
{
m_pResponsePayload->ReadStreamFromRequestHandle(pResult->m_hRequest, pResult->m_cOffset, pResult->m_cBytesReceived);
}
}

void OnSteamHTTPCompleted(HTTPRequestCompleted_t* pResult, bool bHasError)
{
m_RequestHandle = pResult->m_hRequest;

m_bIsHeaderReceived = true;
m_bResponseCompleted = true;
m_bResponseError = bHasError;
m_iResponseStatusCode = (int)pResult->m_eStatusCode;

if (pResult->m_bRequestSuccessful && !bHasError)
if (pResult->m_bRequestSuccessful && !bHasError && !m_bIsStream)
{
m_pResponsePayload->ReadFromRequestHandle(RequestHandle);
m_pResponsePayload->ReadFromRequestHandle(pResult->m_hRequest);
}
}

Expand All @@ -170,6 +207,16 @@ class CUtilHTTPResponse : public IUtilHTTPResponse
}
}

bool GetHeaderSize(const char* name, size_t *buflen) override
{
return SteamHTTP()->GetHTTPResponseHeaderSize(m_RequestHandle, name, buflen);
}

bool GetHeader(const char* name, char* buf, size_t buflen) override
{
return SteamHTTP()->GetHTTPResponseHeaderValue(m_RequestHandle, name, (uint8 *)buf, buflen);
}

bool IsResponseCompleted() const override
{
return m_bResponseCompleted;
Expand All @@ -180,6 +227,16 @@ class CUtilHTTPResponse : public IUtilHTTPResponse
return m_bResponseError;
}

bool IsHeaderReceived() const override
{
return m_bIsHeaderReceived;
}

bool IsStream() const override
{
return m_bIsStream;
}

int GetStatusCode() const override
{
return m_iResponseStatusCode;
Expand All @@ -195,7 +252,7 @@ class CUtilHTTPRequest : public IUtilHTTPRequest
{
protected:
HTTPRequestHandle m_RequestHandle{};
CCallResult<CUtilHTTPRequest, HTTPRequestCompleted_t> m_CallResult{};
CCallResult<CUtilHTTPRequest, HTTPRequestCompleted_t> m_CompleteCallResult{};
bool m_bRequesting{};
bool m_bResponding{};
bool m_bRequestSuccessful{};
Expand Down Expand Up @@ -239,9 +296,9 @@ class CUtilHTTPRequest : public IUtilHTTPRequest

~CUtilHTTPRequest()
{
if (m_CallResult.IsActive())
if (m_CompleteCallResult.IsActive())
{
m_CallResult.Cancel();
m_CompleteCallResult.Cancel();
}

if (m_RequestHandle != INVALID_HTTPREQUEST_HANDLE)
Expand All @@ -257,33 +314,51 @@ class CUtilHTTPRequest : public IUtilHTTPRequest
}
}

//TODO stream read?
virtual void OnSteamHTTPCompleted(HTTPRequestCompleted_t* pResult, bool bHasError)
virtual void OnRespondStart()
{
m_bRequesting = false;
m_bResponding = true;
if (!m_bResponding)
{
m_bRequesting = false;
m_bResponding = true;

if (m_Callbacks)
if (m_Callbacks)
{
m_Callbacks->OnUpdateState(UtilHTTPRequestState::Responding);
}
}
}

virtual void OnRespondFinish()
{
if (m_bResponding)
{
m_Callbacks->OnUpdateState(UtilHTTPRequestState::Responding);
m_bFinished = true;
m_bResponding = false;

if (m_Callbacks)
{
m_Callbacks->OnUpdateState(UtilHTTPRequestState::Finished);
}
}
}

virtual void OnSteamHTTPCompleted(HTTPRequestCompleted_t* pResult, bool bHasError)
{
OnRespondStart();

m_bRequestSuccessful = pResult->m_bRequestSuccessful;

m_pResponse->OnSteamHTTPCompleted(m_RequestHandle, pResult, bHasError);
m_pResponse->OnSteamHTTPCompleted(pResult, bHasError);

if (m_Callbacks)
{
m_Callbacks->OnResponse(this, m_pResponse);
m_Callbacks->OnResponseComplete(this, m_pResponse);
}

m_bFinished = true;
m_bResponding = false;

if (m_Callbacks)
{
m_Callbacks->OnUpdateState(UtilHTTPRequestState::Finished);
}
OnRespondFinish();
}

public:
Expand All @@ -298,7 +373,7 @@ class CUtilHTTPRequest : public IUtilHTTPRequest
SteamAPICall_t SteamApiCall;
if (SteamHTTP()->SendHTTPRequest(m_RequestHandle, &SteamApiCall))
{
m_CallResult.Set(SteamApiCall, this, &CUtilHTTPRequest::OnSteamHTTPCompleted);
m_CompleteCallResult.Set(SteamApiCall, this, &CUtilHTTPRequest::OnSteamHTTPCompleted);
}

m_bRequesting = true;
Expand Down Expand Up @@ -467,6 +542,11 @@ class CUtilHTTPSyncRequest : public CUtilHTTPRequest
return false;
}

bool IsStream() const override
{
return false;
}

void WaitForResponse() override
{
if (m_hResponseEvent)
Expand Down Expand Up @@ -525,6 +605,11 @@ class CUtilHTTPAsyncRequest : public CUtilHTTPRequest
return true;
}

bool IsStream() const override
{
return false;
}

void WaitForResponse() override
{

Expand All @@ -546,6 +631,135 @@ class CUtilHTTPAsyncRequest : public CUtilHTTPRequest
}
};

class CUtilHTTPAsyncStreamRequest : public CUtilHTTPAsyncRequest
{
private:
CCallResult<CUtilHTTPAsyncStreamRequest, HTTPRequestCompleted_t> m_StreamCompleteCallResult{};
CCallResult<CUtilHTTPAsyncStreamRequest, HTTPRequestHeadersReceived_t> m_RecvHeaderCallResult{};
CCallResult<CUtilHTTPAsyncStreamRequest, HTTPRequestDataReceived_t> m_RecvDataCallResult{};

IUtilHTTPStreamCallbacks* m_StreamCallbacks{};

public:
CUtilHTTPAsyncStreamRequest(
const UtilHTTPMethod method,
const std::string& host,
unsigned short port,
bool secure,
const std::string& target,
IUtilHTTPStreamCallbacks* callbacks,
HTTPCookieContainerHandle hCookieHandle) :
CUtilHTTPAsyncRequest(method, host, port, secure, target, nullptr, hCookieHandle), m_StreamCallbacks(callbacks)
{

}

~CUtilHTTPAsyncStreamRequest()
{
if (m_StreamCompleteCallResult.IsActive())
{
m_StreamCompleteCallResult.Cancel();
}
if (m_RecvHeaderCallResult.IsActive())
{
m_RecvHeaderCallResult.Cancel();
}
if (m_RecvDataCallResult.IsActive())
{
m_RecvDataCallResult.Cancel();
}
}

bool IsStream() const override
{
return true;
}

virtual void OnSteamHTTPRecvHeader(HTTPRequestHeadersReceived_t* pResult, bool bHasError)
{
OnRespondStart();

m_pResponse->OnSteamHTTPRecvHeader(pResult, bHasError);

if (m_StreamCallbacks)
{
m_StreamCallbacks->OnReceiveHeader(this, m_pResponse);
}
}

virtual void OnSteamHTTPRecvData(HTTPRequestDataReceived_t* pResult, bool bHasError)
{
m_pResponse->OnSteamHTTPRecvData(pResult, bHasError);

if (m_StreamCallbacks)
{
m_StreamCallbacks->OnReceiveData(this, m_pResponse);
}
}

void OnSteamHTTPCompleted(HTTPRequestCompleted_t* pResult, bool bHasError) override
{
OnRespondStart();

m_bRequestSuccessful = pResult->m_bRequestSuccessful;

m_pResponse->OnSteamHTTPCompleted(pResult, bHasError);

if (m_StreamCallbacks)
{
m_StreamCallbacks->OnResponseComplete(this, m_pResponse);
}

OnRespondFinish();
}

void OnRespondStart() override
{
if (!m_bResponding)
{
m_bRequesting = false;
m_bResponding = true;

if (m_StreamCallbacks)
{
m_StreamCallbacks->OnUpdateState(UtilHTTPRequestState::Responding);
}
}
}

void OnRespondFinish() override
{
if (m_bResponding)
{
m_bFinished = true;
m_bResponding = false;

if (m_StreamCallbacks)
{
m_StreamCallbacks->OnUpdateState(UtilHTTPRequestState::Finished);
}
}
}

void SendAsyncRequest() override
{
SteamAPICall_t SteamApiCall;
if (SteamHTTP()->SendHTTPRequestAndStreamResponse(m_RequestHandle, &SteamApiCall))
{
m_StreamCompleteCallResult.Set(SteamApiCall, this, &CUtilHTTPAsyncStreamRequest::OnSteamHTTPCompleted);
m_RecvHeaderCallResult.Set(SteamApiCall, this, &CUtilHTTPAsyncStreamRequest::OnSteamHTTPRecvHeader);
m_RecvDataCallResult.Set(SteamApiCall, this, &CUtilHTTPAsyncStreamRequest::OnSteamHTTPRecvData);
}

m_bRequesting = true;

if (m_StreamCallbacks)
{
m_StreamCallbacks->OnUpdateState(UtilHTTPRequestState::Requesting);
}
}
};

class CUtilHTTPClient : public IUtilHTTPClient
{
private:
Expand Down Expand Up @@ -768,6 +982,26 @@ class CUtilHTTPClient : public IUtilHTTPClient

return false;
}

IUtilHTTPRequest* CreateAsyncStreamRequestEx(const char* host, unsigned short port_us, const char* target, bool secure, const UtilHTTPMethod method, IUtilHTTPStreamCallbacks* callback)
{
return new CUtilHTTPAsyncStreamRequest(method, host, port_us, secure, target, callback, m_CookieHandle);
}

IUtilHTTPRequest* CreateAsyncStreamRequest(const char* url, const UtilHTTPMethod method, IUtilHTTPStreamCallbacks* callbacks) override
{
CURLParsedResult result;

if (!ParseUrlEx(url, &result))
return NULL;

auto RequestInstance = CreateAsyncStreamRequestEx(result.GetHost(), result.GetPort(), result.GetTarget(), result.IsSecure(), method, callbacks);

AddToRequestPool(RequestInstance);

return RequestInstance;
}

};

EXPOSE_INTERFACE(CUtilHTTPClient, IUtilHTTPClient, UTIL_HTTPCLIENT_STEAMAPI_INTERFACE_VERSION);
2 changes: 1 addition & 1 deletion Plugins/SCModelDownloader/SCModelDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class CUtilHTTPCallbacks : public IUtilHTTPCallbacks
delete this;
}

void OnResponse(IUtilHTTPRequest* RequestInstance, IUtilHTTPResponse* ResponseInstance) override
void OnResponseComplete(IUtilHTTPRequest* RequestInstance, IUtilHTTPResponse* ResponseInstance) override
{
if (!RequestInstance->IsRequestSuccessful())
{
Expand Down
Loading

0 comments on commit 81cb6a0

Please sign in to comment.