in src/uhttp.c [176:318]
static int process_header_line(const unsigned char* buffer, size_t len, size_t* position, HTTP_HEADERS_HANDLE resp_header, size_t* contentLen, bool* isChunked)
{
int result = MU_FAILURE;
size_t index;
const unsigned char* targetPos = buffer;
bool crlfEncounted = false;
bool colonEncountered = false;
char* headerKey = NULL;
bool continueProcessing = true;
for (index = 0; index < len && continueProcessing; index++)
{
if (buffer[index] == ':' && !colonEncountered)
{
colonEncountered = true;
size_t keyLen = (&buffer[index]) - targetPos;
if (keyLen == 0)
{
LogError("Invalid header name with zero length.");
result = MU_FAILURE;
continueProcessing = false;
}
else
{
if (headerKey != NULL)
{
free(headerKey);
headerKey = NULL;
}
size_t malloc_size = safe_add_size_t(keyLen, 1);
if (malloc_size == SIZE_MAX ||
(headerKey = (char*)malloc(malloc_size)) == NULL)
{
LogError("Cannot malloc headerKey, size:%zu", malloc_size);
result = MU_FAILURE;
continueProcessing = false;
}
else
{
memcpy(headerKey, targetPos, keyLen);
headerKey[keyLen] = '\0';
// Convert to lower case
for (size_t inner = 0; inner < keyLen; inner++)
{
headerKey[inner] = (char)tolower(headerKey[inner]);
}
targetPos = buffer+index+1;
crlfEncounted = false;
}
}
}
else if (buffer[index] == '\r')
{
if (headerKey != NULL)
{
// Remove leading spaces
while (*targetPos == 32) { targetPos++; }
size_t valueLen = safe_subtract_size_t((&buffer[index]), targetPos);
size_t malloc_size = safe_add_size_t(valueLen, 1);
char* headerValue;
if (malloc_size == SIZE_MAX ||
(headerValue = (char*)malloc(malloc_size)) == NULL)
{
LogError("Cannot malloc headerValue, size:%zu", malloc_size);
result = MU_FAILURE;
continueProcessing = false;
headerValue = NULL;
}
else
{
memcpy(headerValue, targetPos, valueLen);
headerValue[valueLen] = '\0';
if (HTTPHeaders_AddHeaderNameValuePair(resp_header, headerKey, headerValue) != HTTP_HEADERS_OK)
{
result = MU_FAILURE;
continueProcessing = false;
}
else
{
if (strcmp(headerKey, HTTP_CONTENT_LEN) == 0)
{
*isChunked = false;
*contentLen = atol(headerValue);
}
else if (strcmp(headerKey, HTTP_TRANSFER_ENCODING) == 0)
{
*isChunked = true;
*contentLen = 0;
}
if (index < len)
{
*position = index;
}
else
{
*position = index-1;
}
}
}
free(headerKey);
headerKey = NULL;
free(headerValue);
}
}
else if (buffer[index] == '\n')
{
if (crlfEncounted)
{
if (index < len)
{
*position = index+1;
}
else
{
*position = index;
}
result = 0;
break;
}
else
{
colonEncountered = false;
crlfEncounted = true;
targetPos = buffer+index+1;
}
}
else
{
crlfEncounted = false;
}
}
if (headerKey != NULL)
{
free(headerKey);
}
return result;
}