Files
Leviathan/Library/Internal/source/internet/XHttpSyncDelegate.cpp
T
2026-06-01 12:46:52 +02:00

180 lines
3.7 KiB
C++

#include "XHttpSyncDelegate.h"
#include "../../include/internet/XHttpResponseHeader.h"
#include "../../include/internet/XHttpBuffer.h"
#include "XHttpUtil.h"
XHttpSyncDelegate::XHttpSyncDelegate()
: m_hConnect( NULL )
, m_hRequest( NULL )
{
}
XHttpSyncDelegate::~XHttpSyncDelegate()
{
Close();
}
void XHttpSyncDelegate::Close()
{
if( m_hRequest != NULL )
{
::WinHttpCloseHandle( m_hRequest );
m_hRequest = NULL;
}
if( m_hConnect != NULL )
{
::WinHttpCloseHandle( m_hConnect );
m_hConnect = NULL;
}
}
bool XHttpSyncDelegate::Execute( HINTERNET hSession,
const wchar_t* pVerb,
const XHttpRequest& Request,
XHttpContent* pContent,
size_t nMinBufferSize )
{
if( OpenRequest( hSession, pVerb, Request ) == false )
{
return false;
}
try
{
RequestProcess( Request );
if( pContent == NULL || pContent->OnCallbackHeader( XHttpResponseHeader( m_hRequest ) ) == false )
{
return false;
}
if( ReadProcess( pContent, nMinBufferSize ) == false )
{
return false;
}
}
catch( const XHttpUtil::XHttpException& except )
{
if( pContent != NULL )
{
pContent->OnCallbackError( XHttpUtil::GetErrorFunction( except.m_dwWhere ), except.m_dwError,
except.m_szFunction, except.m_nLine );
}
}
Close();
return true;
}
void XHttpSyncDelegate::RequestProcess( const XHttpRequest& Request )
{
if( SendRequest( Request ) == false )
{
throw XHttpUtil::XHttpException( API_SEND_REQUEST, ::GetLastError(), __FUNCTIONW__, __LINE__ );
}
if( ::WinHttpReceiveResponse( m_hRequest, NULL ) == FALSE )
{
throw XHttpUtil::XHttpException( API_RECEIVE_RESPONSE, ::GetLastError(), __FUNCTIONW__, __LINE__ );
}
XHttpResponseHeader Header( m_hRequest );
DWORD dwStatusCode = Header.StatusCode();
if( dwStatusCode != HTTP_STATUS_OK )
{
throw XHttpUtil::XHttpException( API_HEADER_STATUS_CODE, dwStatusCode, __FUNCTIONW__, __LINE__ );
}
}
bool XHttpSyncDelegate::ReadProcess( XHttpContent* pContent, size_t nMinBufferSize )
{
if( pContent == NULL )
{
return false;
}
XHttpBuffer Buffer( nMinBufferSize );
while( true )
{
DWORD dwReadBytes = 0;
if( ::WinHttpReadData( m_hRequest, Buffer.Buffer(), static_cast< DWORD >( Buffer.MaxSize() ), &dwReadBytes ) == FALSE )
{
throw XHttpUtil::XHttpException( API_READ_DATA, ::GetLastError(), __FUNCTIONW__, __LINE__ );
}
if( dwReadBytes > 0 )
{
Buffer.HadCopied( dwReadBytes );
if( pContent->OnCallbackBody( Buffer.Buffer(), Buffer.Size() ) == false )
{
return false;
}
Buffer.Clear();
}
else
{
pContent->OnCallbackComplete();
break;
}
}
return true;
}
bool XHttpSyncDelegate::OpenRequest( HINTERNET hSession, const wchar_t* pVerb, const XHttpRequest& Request )
{
const XHttpURL& URL = Request.URL();
m_hConnect = ::WinHttpConnect( hSession, URL.Host().c_str(), URL.Port(), 0 );
if( m_hConnect == NULL )
{
return false;
}
DWORD dwFlag = URL.IsSecure() ? WINHTTP_FLAG_SECURE : 0;
m_hRequest = ::WinHttpOpenRequest(
m_hConnect,
pVerb,
URL.Path().c_str(),
NULL,
(Request.Referer().empty() == true) ? WINHTTP_NO_REFERER : Request.Referer().c_str(),
WINHTTP_DEFAULT_ACCEPT_TYPES,
dwFlag );
if( m_hRequest == NULL )
{
return false;
}
return true;
}
bool XHttpSyncDelegate::SendRequest( const XHttpRequest& Request )
{
XHttpUtil::XHttpSetRequestHeader Header( m_hRequest );
if( Header.Add( Request.GetHeader() ) == false )
{
return false;
}
const XHttpBuffer& Buffer = Request.GetData();
void* pData = const_cast< void* >( Buffer.Buffer() );
DWORD nDataSize = static_cast< DWORD >( Buffer.Size() );
if( ::WinHttpSendRequest(
m_hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0,
pData,
nDataSize,
nDataSize,
NULL )
== FALSE )
{
return false;
}
return true;
}