Add MaxResponseSize to limit HTTP response sizes

This commit is contained in:
heinrich5991 2022-09-15 01:27:20 +02:00
parent cb2614ff5c
commit 0bf941e6c9
2 changed files with 20 additions and 6 deletions

View file

@ -123,10 +123,10 @@ CHttpRequest::CHttpRequest(const char *pUrl)
CHttpRequest::~CHttpRequest()
{
m_ResponseLength = 0;
if(!m_WriteToFile)
{
m_BufferSize = 0;
m_BufferLength = 0;
free(m_pBuffer);
m_pBuffer = nullptr;
}
@ -203,6 +203,10 @@ int CHttpRequest::RunImpl(CURL *pUser)
curl_easy_setopt(pHandle, CURLOPT_TIMEOUT_MS, m_Timeout.TimeoutMs);
curl_easy_setopt(pHandle, CURLOPT_LOW_SPEED_LIMIT, m_Timeout.LowSpeedLimit);
curl_easy_setopt(pHandle, CURLOPT_LOW_SPEED_TIME, m_Timeout.LowSpeedTime);
if(m_MaxResponseSize >= 0)
{
curl_easy_setopt(pHandle, CURLOPT_MAXFILESIZE_LARGE, (curl_off_t)m_MaxResponseSize);
}
curl_easy_setopt(pHandle, CURLOPT_SHARE, gs_pShare);
curl_easy_setopt(pHandle, CURLOPT_PROTOCOLS, Protocols);
@ -280,6 +284,12 @@ int CHttpRequest::RunImpl(CURL *pUser)
size_t CHttpRequest::OnData(char *pData, size_t DataSize)
{
// Need to check for the maximum response size here as curl can only
// guarantee it if the server sets a Content-Length header.
if(m_MaxResponseSize >= 0 && m_ResponseLength + DataSize > (uint64_t)m_MaxResponseSize)
{
return 0;
}
if(!m_WriteToFile)
{
if(DataSize == 0)
@ -287,7 +297,7 @@ size_t CHttpRequest::OnData(char *pData, size_t DataSize)
return DataSize;
}
size_t NewBufferSize = maximum((size_t)1024, m_BufferSize);
while(m_BufferLength + DataSize > NewBufferSize)
while(m_ResponseLength + DataSize > NewBufferSize)
{
NewBufferSize *= 2;
}
@ -296,12 +306,13 @@ size_t CHttpRequest::OnData(char *pData, size_t DataSize)
m_pBuffer = (unsigned char *)realloc(m_pBuffer, NewBufferSize);
m_BufferSize = NewBufferSize;
}
mem_copy(m_pBuffer + m_BufferLength, pData, DataSize);
m_BufferLength += DataSize;
mem_copy(m_pBuffer + m_ResponseLength, pData, DataSize);
m_ResponseLength += DataSize;
return DataSize;
}
else
{
m_ResponseLength += DataSize;
return io_write(m_File, pData, DataSize);
}
}
@ -367,7 +378,7 @@ void CHttpRequest::Result(unsigned char **ppResult, size_t *pResultLength) const
return;
}
*ppResult = m_pBuffer;
*pResultLength = m_BufferLength;
*pResultLength = m_ResponseLength;
}
json_value *CHttpRequest::ResultJson() const

View file

@ -55,13 +55,15 @@ class CHttpRequest : public IJob
size_t m_BodyLength = 0;
CTimeout m_Timeout = CTimeout{0, 0, 0, 0};
int64_t m_MaxResponseSize = -1;
REQUEST m_Type = REQUEST::GET;
bool m_WriteToFile = false;
uint64_t m_ResponseLength = 0;
// If `m_WriteToFile` is false.
size_t m_BufferSize = 0;
size_t m_BufferLength = 0;
unsigned char *m_pBuffer = nullptr;
// If `m_WriteToFile` is true.
@ -99,6 +101,7 @@ public:
~CHttpRequest();
void Timeout(CTimeout Timeout) { m_Timeout = Timeout; }
void MaxResponseSize(int64_t MaxResponseSize) { m_MaxResponseSize = MaxResponseSize; }
void LogProgress(HTTPLOG LogProgress) { m_LogProgress = LogProgress; }
void IpResolve(IPRESOLVE IpResolve) { m_IpResolve = IpResolve; }
void WriteToFile(IStorage *pStorage, const char *pDest, int StorageType);