http and lots of formats
This commit is contained in:
@@ -35,42 +35,3 @@ DECLARE_BUILD_STAGE(funnyhttp)
|
||||
return 0;
|
||||
};
|
||||
|
||||
DECLARE_BUILD_STAGE(test)
|
||||
{
|
||||
|
||||
CProject_t compileProject = {};
|
||||
LinkProject_t ldProject = {};
|
||||
|
||||
filesystem2->MakeDirectory("build");
|
||||
filesystem2->CopyFile("build",GET_PROJECT_LIBRARY(funnyhttp, "funnyhttp"));
|
||||
filesystem2->CopyFile("build",GET_PROJECT_LIBRARY(tier0, "tier0"));
|
||||
|
||||
compileProject.m_szName = "funnyhttptest";
|
||||
compileProject.files = {
|
||||
"test.cpp"
|
||||
};
|
||||
compileProject.includeDirectories = {"../public"};
|
||||
compileProject.bFPIC = true;
|
||||
ldProject = ccompiler->Compile(&compileProject);
|
||||
ldProject.libraryObjects = {
|
||||
GET_PROJECT_LIBRARY(tier1, "tier1"),
|
||||
GET_PROJECT_LIBRARY(tier2, "tier2"),
|
||||
};
|
||||
ldProject.libraries = {
|
||||
"tier0",
|
||||
};
|
||||
ldProject.libraryDirectories = {
|
||||
"build",
|
||||
};
|
||||
ldProject.linkType = ELINK_EXECUTABLE;
|
||||
CUtlString szOutputDir = linker->Link(&ldProject);
|
||||
|
||||
filesystem2->CopyFile("build",szOutputDir);
|
||||
|
||||
|
||||
CUtlVector<CUtlString> args = {};
|
||||
runner->Run("build/funnyhttptest", args);
|
||||
runner->Wait();
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
446
http/client.cpp
446
http/client.cpp
@@ -1,3 +1,4 @@
|
||||
|
||||
#include "http/http.h"
|
||||
#include "tier1/interface.h"
|
||||
#include "tier1/utlstring.h"
|
||||
@@ -6,18 +7,34 @@
|
||||
#include "fcntl.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include "openssl/err.h"
|
||||
#include "arpa/inet.h"
|
||||
|
||||
abstract_class CHTTPClient: public IHTTPClient
|
||||
{
|
||||
public:
|
||||
virtual void Post( const char *szResource, HTTPHeader_t *pHeader, uint32_t uDataSize, const char *data ) override;
|
||||
void ConnectToServer();
|
||||
void CloseConnection();
|
||||
|
||||
virtual void Post( const char *szResource, HTTPHeader_t *pHeader, uint32_t uDataSize, const void *data ) override;
|
||||
virtual void Get( const char *szResource, HTTPHeader_t *pHeader ) override;
|
||||
virtual HTTPResponse_t GetResponse() override;
|
||||
|
||||
HTTPResponse_t ParseResponse( const char *szMessage );
|
||||
virtual bool WebSocket_Connect( const char *szResource ) override;
|
||||
virtual void WebSocket_Close( void ) override;
|
||||
virtual void WebSocket_SendText( const char *szData ) override;
|
||||
virtual CUtlString WebSocket_RecvText() override;
|
||||
virtual void WebSocket_SendBinary( size_t uSize, const void *pData ) override;
|
||||
virtual WebSocketPacket_t WebSocket_RecvBinary() override;
|
||||
|
||||
ssize_t Write( void *pData, ssize_t uSize );
|
||||
ssize_t Read( void *pData, ssize_t uSize );
|
||||
|
||||
HTTPResponse_t ParseResponse( const char *szMessage, uint32_t uDataSize );
|
||||
const char *GetVersion();
|
||||
HTTPHeaderParam_t ParseHeaderParams( const char *szHeaderLine );
|
||||
|
||||
const char *m_szHostName;
|
||||
uint16_t m_uPort;
|
||||
bool m_bIsSecure;
|
||||
SSL *m_pSSL;
|
||||
SSL_CTX *m_pSSLCtx;
|
||||
@@ -25,9 +42,37 @@ public:
|
||||
int m_iFileDescriptor;
|
||||
};
|
||||
|
||||
void CHTTPClient::Post( const char *szResource, HTTPHeader_t *pHeader, uint32_t uDataSize, const char *data )
|
||||
void CHTTPClient::Post( const char *szResource, HTTPHeader_t *pHeader, uint32_t uDataSize, const void *data )
|
||||
{
|
||||
if (pHeader == NULL)
|
||||
return;
|
||||
|
||||
ConnectToServer();
|
||||
|
||||
CUtlString szMessage = CUtlString(
|
||||
"POST %s HTTP/%s\r\n",
|
||||
szResource, GetVersion());
|
||||
CUtlString szHeader = CUtlString(
|
||||
"Host: %s\r\n"
|
||||
"Content-Length: %u\r\n",
|
||||
m_szHostName,
|
||||
uDataSize
|
||||
);
|
||||
|
||||
CUtlString szCombined;
|
||||
int i = 0;
|
||||
|
||||
for ( i = 0; i < pHeader->m_nParamCount; i++ )
|
||||
{
|
||||
szHeader.AppendTail(CUtlString("%s: %s\r\n", pHeader->m_params[i].m_szParamName.GetString(), pHeader->m_params[i].m_szValue.GetString()));
|
||||
}
|
||||
|
||||
szCombined = szMessage;
|
||||
szCombined.AppendTail(szHeader);
|
||||
szCombined.AppendTail("\r\n");
|
||||
|
||||
Write(szCombined.GetString(), szCombined.GetLenght());
|
||||
Write((void*)data, uDataSize);
|
||||
}
|
||||
|
||||
void CHTTPClient::Get( const char *szResource, HTTPHeader_t *pHeader )
|
||||
@@ -35,6 +80,8 @@ void CHTTPClient::Get( const char *szResource, HTTPHeader_t *pHeader )
|
||||
if (pHeader == NULL)
|
||||
return;
|
||||
|
||||
ConnectToServer();
|
||||
|
||||
CUtlString szMessage = CUtlString(
|
||||
"GET %s HTTP/%s\r\n",
|
||||
szResource, GetVersion());
|
||||
@@ -48,53 +95,54 @@ void CHTTPClient::Get( const char *szResource, HTTPHeader_t *pHeader )
|
||||
|
||||
for ( i = 0; i < pHeader->m_nParamCount; i++ )
|
||||
{
|
||||
szHeader.AppendTail(CUtlString("%s: %s\r\n", pHeader->m_params[i].m_szParamName, pHeader->m_params[i].m_szValue));
|
||||
szHeader.AppendTail(CUtlString("%s: %s\r\n", pHeader->m_params[i].m_szParamName.GetString(), pHeader->m_params[i].m_szValue.GetString()));
|
||||
}
|
||||
|
||||
szCombined = szMessage;
|
||||
szCombined.AppendTail(szHeader);
|
||||
szCombined.AppendTail("\r\n");
|
||||
|
||||
if (m_bIsSecure)
|
||||
SSL_write(m_pSSL, szCombined.GetString(), szCombined.GetLenght());
|
||||
else
|
||||
write(m_iFileDescriptor, szCombined.GetString(), szCombined.GetLenght());
|
||||
Write(szCombined.GetString(), szCombined.GetLenght());
|
||||
}
|
||||
|
||||
HTTPResponse_t CHTTPClient::GetResponse()
|
||||
{
|
||||
CUtlResizableBuffer<char> szCharBuffer(0);
|
||||
char response[4096];
|
||||
char response[4096] = {};
|
||||
int n;
|
||||
int nPreviousSize = 0;
|
||||
|
||||
if (m_bIsSecure)
|
||||
readSocket:
|
||||
|
||||
n = Read(response, sizeof(response));
|
||||
if (n == -1)
|
||||
goto responseDone;
|
||||
|
||||
|
||||
szCharBuffer.Resize(nPreviousSize+n);
|
||||
V_memcpy((char*)szCharBuffer.GetMemory()+nPreviousSize, response, n);
|
||||
nPreviousSize += n;
|
||||
V_printf("%s\n",response);
|
||||
|
||||
// HTTP 1.0 reacts either to socket being closed or Content-Lenght
|
||||
// HTTP 1.1 has Transfer-Encoding: chunked, which we need to respect
|
||||
// Still some response codes may not include a body
|
||||
if ( n > 0 )
|
||||
{
|
||||
secureRead:
|
||||
n = SSL_read(m_pSSL, response, sizeof(response));
|
||||
szCharBuffer.Resize(nPreviousSize+n);
|
||||
V_memcpy((char*)szCharBuffer.GetMemory()+nPreviousSize, response, n);
|
||||
nPreviousSize += n;
|
||||
if (SSL_pending(m_pSSL)>0)
|
||||
goto secureRead;
|
||||
}
|
||||
else {
|
||||
httpRead:
|
||||
n = read(m_iFileDescriptor, response, sizeof(response));
|
||||
V_printf("%i\n",n);
|
||||
szCharBuffer.Resize(nPreviousSize+n+1);
|
||||
szCharBuffer[nPreviousSize+n] = 0;
|
||||
V_memcpy((char*)szCharBuffer.GetMemory()+nPreviousSize, response, n);
|
||||
nPreviousSize += n;
|
||||
goto httpRead;
|
||||
}
|
||||
HTTPResponse_t r = ParseResponse(szCharBuffer, szCharBuffer.GetSize());
|
||||
if (r.m_bIsComplete)
|
||||
goto responseDone;
|
||||
|
||||
// these do not provide body
|
||||
}
|
||||
// there is some data so go and read back again
|
||||
goto readSocket;
|
||||
responseDone:
|
||||
|
||||
szCharBuffer.Resize(n+1);
|
||||
return ParseResponse(szCharBuffer);
|
||||
return ParseResponse(szCharBuffer, szCharBuffer.GetSize());
|
||||
}
|
||||
|
||||
HTTPResponse_t CHTTPClient::ParseResponse( const char *szMessage )
|
||||
HTTPResponse_t CHTTPClient::ParseResponse( const char *szMessage, uint32_t uDataSize )
|
||||
{
|
||||
char cPreviousCharacter = 0;
|
||||
char cCurrentCharacter = 0;
|
||||
@@ -115,12 +163,18 @@ HTTPResponse_t CHTTPClient::ParseResponse( const char *szMessage )
|
||||
if (bIsMessage)
|
||||
{
|
||||
uint32_t uResult = 0;
|
||||
V_sscanf(szBuffer, "HTTP/1.1 %i", &uResult);
|
||||
while (szBuffer[0] != ' ')
|
||||
szBuffer.RemoveHead(1);
|
||||
while (szBuffer[0] == ' ')
|
||||
szBuffer.RemoveHead(1);
|
||||
V_sscanf(szBuffer, "%i", &uResult);
|
||||
response.m_uCode = uResult;
|
||||
}
|
||||
if (szBuffer == "")
|
||||
break;
|
||||
if (!bIsMessage)
|
||||
headers.AppendTail(ParseHeaderParams(szBuffer));
|
||||
bIsMessage = false;
|
||||
if (szBuffer == "")
|
||||
break;
|
||||
szBuffer = "";
|
||||
cPreviousCharacter = 0;
|
||||
cCurrentCharacter = *pcCurrentCharacter++;
|
||||
@@ -133,12 +187,73 @@ HTTPResponse_t CHTTPClient::ParseResponse( const char *szMessage )
|
||||
|
||||
cPreviousCharacter = cCurrentCharacter;
|
||||
};
|
||||
switch (response.m_uCode)
|
||||
{
|
||||
case 100:
|
||||
case 101:
|
||||
case 204:
|
||||
case 205:
|
||||
case 304:
|
||||
response.m_bIsComplete = true;
|
||||
return response;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool bParseInChunks = false;
|
||||
uint64_t uBodySize;
|
||||
// check content lenght
|
||||
for ( int i = 0; i < response.m_params.GetSize(); i++ )
|
||||
{
|
||||
if ( !V_stricmp( response.m_params[i].m_szParamName, "Content-Length" ) )
|
||||
{
|
||||
uBodySize = atoll(response.m_params[i].m_szValue);
|
||||
};
|
||||
|
||||
|
||||
if ( !V_stricmp( response.m_params[i].m_szParamName, "Transfer-Encoding" ) )
|
||||
{
|
||||
if ( !V_stricmp( response.m_params[i].m_szValue, "Chunked" ) )
|
||||
{
|
||||
bParseInChunks = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
pcCurrentCharacter++;
|
||||
uint32_t nDataLen = V_strlen(pcCurrentCharacter);
|
||||
data = CUtlBuffer<char>(nDataLen+1);
|
||||
V_strcpy(data.GetMemory(), pcCurrentCharacter);
|
||||
data[nDataLen] = 0;
|
||||
response.m_message = data;
|
||||
if ( !bParseInChunks )
|
||||
{
|
||||
uint32_t nDataLen = uDataSize-(pcCurrentCharacter-szMessage);
|
||||
data = CUtlBuffer<char>(nDataLen+1);
|
||||
V_memcpy(data.GetMemory(), pcCurrentCharacter, nDataLen);
|
||||
data[nDataLen] = 0;
|
||||
response.m_params = CUtlBuffer<HTTPHeaderParam_t>(headers.GetSize());
|
||||
for (int i = 0; i < headers.GetSize(); i++ )
|
||||
{
|
||||
response.m_params[i] = headers[i];
|
||||
}
|
||||
response.m_message = data;
|
||||
|
||||
} else {
|
||||
szBuffer = "";
|
||||
while (*pcCurrentCharacter)
|
||||
{
|
||||
|
||||
cCurrentCharacter = *pcCurrentCharacter;
|
||||
if ( cPreviousCharacter == '\r')
|
||||
{
|
||||
if ( cCurrentCharacter == '\n')
|
||||
{
|
||||
uint32_t uChunkSize;
|
||||
uChunkSize = strtol(szBuffer, NULL, 0);
|
||||
}
|
||||
}
|
||||
if (cPreviousCharacter != 0)
|
||||
szBuffer.AppendTail(cPreviousCharacter);
|
||||
pcCurrentCharacter++;
|
||||
|
||||
cPreviousCharacter = cCurrentCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -148,57 +263,76 @@ const char *CHTTPClient::GetVersion()
|
||||
|
||||
return "1.1";
|
||||
}
|
||||
abstract_class CHTTPClientManager: public IHTTPClientManager
|
||||
HTTPHeaderParam_t CHTTPClient::ParseHeaderParams( const char *szHeaderLine )
|
||||
{
|
||||
public:
|
||||
CHTTPClientManager();
|
||||
virtual IHTTPClient *Connect( const char *szUrl, bool bSecure ) override;
|
||||
virtual void Disconnect( IHTTPClient *szConnection ) override;
|
||||
};
|
||||
const char *psz = szHeaderLine;
|
||||
CUtlString szName;
|
||||
CUtlString szValue;
|
||||
|
||||
IHTTPClient *CHTTPClientManager::Connect( const char *szUrl, bool bSecure )
|
||||
int stage = 0;
|
||||
while (*psz)
|
||||
{
|
||||
if (stage == 0)
|
||||
{
|
||||
if (*psz == ':')
|
||||
stage = 1;
|
||||
else
|
||||
szName.AppendTail(*psz);
|
||||
} else if (stage == 1)
|
||||
{
|
||||
if (*psz != ' ')
|
||||
break;
|
||||
}
|
||||
psz++;
|
||||
}
|
||||
szValue = psz;
|
||||
return {szName, szValue};
|
||||
}
|
||||
void CHTTPClient::ConnectToServer()
|
||||
{
|
||||
struct hostent *pServerHostName = NULL;
|
||||
struct sockaddr_in serverAddress;
|
||||
int fd = 0;
|
||||
int err;
|
||||
CHTTPClient *pClient;
|
||||
SSL_CTX *ctx;
|
||||
SSL *ssl;
|
||||
|
||||
pServerHostName = gethostbyname(szUrl);
|
||||
if (!pServerHostName)
|
||||
return NULL;
|
||||
if (V_strcmp(m_szHostName, "localhost"))
|
||||
{
|
||||
pServerHostName = gethostbyname(m_szHostName);
|
||||
if (!pServerHostName)
|
||||
return;
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if ( fd < 0 )
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
V_memset(&serverAddress, 0, sizeof(serverAddress));
|
||||
serverAddress.sin_family = AF_INET;
|
||||
V_memcpy(&serverAddress.sin_addr.s_addr, pServerHostName->h_addr, pServerHostName->h_length);
|
||||
if (!V_strcmp(m_szHostName, "localhost"))
|
||||
inet_pton(AF_INET, "127.0.0.1", &serverAddress.sin_addr);
|
||||
else
|
||||
V_memcpy(&serverAddress.sin_addr.s_addr, pServerHostName->h_addr, pServerHostName->h_length);
|
||||
|
||||
// https
|
||||
if ( bSecure )
|
||||
serverAddress.sin_port = htons(443);
|
||||
else
|
||||
serverAddress.sin_port = htons(80);
|
||||
serverAddress.sin_port = htons(m_uPort);
|
||||
|
||||
err = connect(fd, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
|
||||
if (err < 0)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
if (bSecure)
|
||||
if (m_bIsSecure)
|
||||
{
|
||||
ctx = SSL_CTX_new(TLS_client_method());
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
return;
|
||||
ssl =SSL_new(ctx);
|
||||
if (!ssl)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
SSL_set_fd(ssl, fd);
|
||||
SSL_set_tlsext_host_name(ssl, szUrl);
|
||||
SSL_set_tlsext_host_name(ssl, m_szHostName);
|
||||
|
||||
int r = SSL_connect(ssl);
|
||||
if (r <= 0)
|
||||
@@ -206,19 +340,192 @@ IHTTPClient *CHTTPClientManager::Connect( const char *szUrl, bool bSecure )
|
||||
ERR_print_errors_fp(stdout);
|
||||
SSL_free(ssl);
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
pClient = new CHTTPClient();
|
||||
pClient->m_iFileDescriptor = fd;
|
||||
pClient->m_szHostName = szUrl;
|
||||
if (bSecure)
|
||||
m_iFileDescriptor = fd;
|
||||
if (m_bIsSecure)
|
||||
{
|
||||
pClient->m_bIsSecure = bSecure;
|
||||
pClient->m_pSSL = ssl;
|
||||
pClient->m_pSSLCtx = ctx;
|
||||
m_pSSL = ssl;
|
||||
m_pSSLCtx = ctx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CHTTPClient::CloseConnection()
|
||||
{
|
||||
|
||||
}
|
||||
bool CHTTPClient::WebSocket_Connect( const char *szResource )
|
||||
{
|
||||
HTTPResponse_t stResponse;
|
||||
HTTPHeaderParam_t params[] = {
|
||||
{"Upgrade", "websocket"},
|
||||
{"Connection", "Upgrade"},
|
||||
{"Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ=="},
|
||||
{"Sec-WebSocket-Protocol", "chat, superchat"},
|
||||
{"Sec-WebSocket-Version", "13"},
|
||||
};
|
||||
HTTPHeader_t stHeader = {
|
||||
sizeof(params)/sizeof(params[0]),
|
||||
params
|
||||
};
|
||||
Get(szResource, &stHeader);
|
||||
stResponse = GetResponse();
|
||||
// According to spec 101 is a good sign
|
||||
if (stResponse.m_uCode == 101)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CHTTPClient::WebSocket_Close( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
enum EWebSocketOp
|
||||
{
|
||||
WEBSOCKET_CONTINUE = 0,
|
||||
WEBSOCKET_TEXT = 1,
|
||||
WEBSOCKET_BINARY = 2,
|
||||
WEBSOCKET_CLOSE = 8,
|
||||
WEBSOCKET_PING = 9,
|
||||
WEBSOCKET_PONG = 10,
|
||||
};
|
||||
|
||||
struct WebSocketFrame_t
|
||||
{
|
||||
EWebSocketOp nOpCode: 4;
|
||||
uint8_t nReserved: 3;
|
||||
uint8_t bFin: 1;
|
||||
uint8_t nPayloadLenght: 7;
|
||||
uint8_t bMasked: 1;
|
||||
};
|
||||
|
||||
void CHTTPClient::WebSocket_SendText( const char *szData )
|
||||
{
|
||||
size_t uLen;
|
||||
WebSocketFrame_t stFrame;
|
||||
uLen = V_strlen(szData);
|
||||
stFrame = (WebSocketFrame_t){
|
||||
.nOpCode = WEBSOCKET_TEXT,
|
||||
.bFin = 1,
|
||||
.bMasked = 1,
|
||||
};
|
||||
// im too lazy to mask it
|
||||
int iMask = 0;
|
||||
|
||||
if ( uLen <= 125 )
|
||||
{
|
||||
stFrame.nPayloadLenght = uLen;
|
||||
Write(&stFrame, 2);
|
||||
Write(&iMask, 4);
|
||||
}
|
||||
else if ( uLen <= 65535 )
|
||||
{
|
||||
stFrame.nPayloadLenght = 126;
|
||||
Write(&stFrame, 2);
|
||||
uint16_t uLenN = htons(uLen);
|
||||
Write(&uLenN, 2);
|
||||
Write(&iMask, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
stFrame.nPayloadLenght = 127;
|
||||
Write(&stFrame, 2);
|
||||
Write(&iMask, 4);
|
||||
Write(&uLen, 8);
|
||||
}
|
||||
Write((void*)szData, uLen);
|
||||
|
||||
}
|
||||
|
||||
CUtlString CHTTPClient::WebSocket_RecvText()
|
||||
{
|
||||
WebSocketFrame_t stFrame;
|
||||
size_t uLen = 0;
|
||||
CUtlBuffer<char> szText;
|
||||
Read(&stFrame, 2);
|
||||
if (stFrame.nPayloadLenght == 126)
|
||||
{
|
||||
Read(&uLen, 2);
|
||||
} else if (stFrame.nPayloadLenght == 127)
|
||||
{
|
||||
Read(&uLen, 8);
|
||||
} else {
|
||||
uLen = stFrame.nPayloadLenght;
|
||||
}
|
||||
szText = CUtlBuffer<char>(uLen+1);
|
||||
Read(szText, uLen);
|
||||
szText[uLen] = 0;
|
||||
return szText.GetMemory();
|
||||
}
|
||||
|
||||
void CHTTPClient::WebSocket_SendBinary( size_t uSize, const void *pData )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebSocketPacket_t CHTTPClient::WebSocket_RecvBinary()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
ssize_t CHTTPClient::Write( void *pData, ssize_t uSize )
|
||||
{
|
||||
if (m_bIsSecure)
|
||||
return SSL_write(m_pSSL, pData, uSize);
|
||||
else
|
||||
return write(m_iFileDescriptor, pData, uSize);
|
||||
}
|
||||
|
||||
ssize_t CHTTPClient::Read( void *pData, ssize_t uSize )
|
||||
{
|
||||
ssize_t n;
|
||||
if ( m_bIsSecure )
|
||||
{
|
||||
n = SSL_read(m_pSSL, pData, uSize);
|
||||
if (n == 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = read(m_iFileDescriptor, pData, uSize);
|
||||
if (n == -1)
|
||||
return -1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
abstract_class CHTTPClientManager: public IHTTPClientManager
|
||||
{
|
||||
public:
|
||||
CHTTPClientManager();
|
||||
virtual IHTTPClient *Connect( const char *szUrl, bool bSecure, uint16_t *pPort ) override;
|
||||
virtual void Disconnect( IHTTPClient *szConnection ) override;
|
||||
};
|
||||
|
||||
IHTTPClient *CHTTPClientManager::Connect( const char *szUrl, bool bSecure, uint16_t *pPort )
|
||||
{
|
||||
CHTTPClient *pClient;
|
||||
pClient = new CHTTPClient();
|
||||
if (pPort)
|
||||
pClient->m_uPort = *pPort;
|
||||
else
|
||||
{
|
||||
if (bSecure)
|
||||
pClient->m_uPort = 443;
|
||||
else
|
||||
pClient->m_uPort = 80;
|
||||
}
|
||||
pClient->m_szHostName = szUrl;
|
||||
pClient->m_bIsSecure = bSecure;
|
||||
return pClient;
|
||||
}
|
||||
|
||||
@@ -238,3 +545,4 @@ CHTTPClientManager::CHTTPClientManager()
|
||||
|
||||
CHTTPClientManager s_HttpClientManager;
|
||||
EXPOSE_INTERFACE_GLOBALVAR(IHTTPClientManager, CHTTPClientManager, HTTP_CLIENT_INTERFACE_VERSION, s_HttpClientManager);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ int main()
|
||||
g_pHttpClientMgr = (IHTTPClientManager*)pHttpFactory(HTTP_CLIENT_INTERFACE_VERSION, NULL);
|
||||
if ( !g_pHttpClientMgr )
|
||||
return 0;
|
||||
IHTTPClient *pClient = g_pHttpClientMgr->Connect("ani.sidestore.io", true);
|
||||
IHTTPClient *pClient = g_pHttpClientMgr->Connect("www.example.com", true, NULL);
|
||||
printf("%p\n",pClient);
|
||||
if ( pClient == NULL )
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user