in adapters/httpapi_winhttp.c [797:908]
static HTTPAPI_RESULT ReceiveResponseHeaders(HINTERNET requestHandle, HTTP_HEADERS_HANDLE responseHeadersHandle)
{
HTTPAPI_RESULT result;
wchar_t* responseHeadersTemp = NULL;
DWORD responseHeadersTempLength = 0;
// Don't explicictly check return code here - since this should fail (to determine length)
// and checking return code means an explicit GetLastError() comparison. Instead
// rely on subsequent WinHttpQueryHeaders() to fail.
WinHttpQueryHeaders(
requestHandle,
WINHTTP_QUERY_RAW_HEADERS_CRLF,
WINHTTP_HEADER_NAME_BY_INDEX,
WINHTTP_NO_OUTPUT_BUFFER,
&responseHeadersTempLength,
WINHTTP_NO_HEADER_INDEX);
size_t malloc_size = safe_add_size_t((size_t)responseHeadersTempLength, 2);
if (malloc_size == SIZE_MAX)
{
LogError("Invalid malloc size");
responseHeadersTemp = NULL;
}
else
{
responseHeadersTemp = (wchar_t*)malloc(malloc_size);
}
if (responseHeadersTemp == NULL)
{
result = HTTPAPI_ALLOC_FAILED;
LogError("malloc failed: (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
}
else if (! WinHttpQueryHeaders(
requestHandle,
WINHTTP_QUERY_RAW_HEADERS_CRLF,
WINHTTP_HEADER_NAME_BY_INDEX,
responseHeadersTemp,
&responseHeadersTempLength,
WINHTTP_NO_HEADER_INDEX))
{
result = HTTPAPI_QUERY_HEADERS_FAILED;
LogErrorWinHTTPWithGetLastErrorAsString("WinHttpQueryHeaders failed (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(HTTPAPI_RESULT, result));
}
else
{
wchar_t *next_token = NULL;
wchar_t* token = wcstok_s(responseHeadersTemp, L"\r\n", &next_token);
char* tokenTemp = NULL;
result = HTTPAPI_OK;
while ((token != NULL) &&
(token[0] != L'\0'))
{
size_t tokenTemp_size;
tokenTemp_size = WideCharToMultiByte(CP_ACP, 0, token, -1, NULL, 0, NULL, NULL);
if (tokenTemp_size == 0)
{
result = HTTPAPI_STRING_PROCESSING_ERROR;
LogError("WideCharToMultiByte failed");
break;
}
else if ((malloc_size = safe_multiply_size_t(sizeof(char), tokenTemp_size)) == SIZE_MAX)
{
result = HTTPAPI_ALLOC_FAILED;
LogError("invalid malloc size");
break;
}
else if ((tokenTemp = (char*)malloc(malloc_size)) == NULL)
{
result = HTTPAPI_ALLOC_FAILED;
LogError("malloc failed");
break;
}
else if (WideCharToMultiByte(CP_ACP, 0, token, -1, tokenTemp, (int)tokenTemp_size, NULL, NULL) == 0)
{
result = HTTPAPI_STRING_PROCESSING_ERROR;
LogError("WideCharToMultiByte failed");
break;
}
else
{
/*breaking the token in 2 parts: everything before the first ":" and everything after the first ":"*/
/*if there is no such character, then skip it*/
/*if there is a : then replace is by a '\0' and so it breaks the original string in name and value*/
char* whereIsColon = strchr(tokenTemp, ':');
if (whereIsColon != NULL)
{
*whereIsColon = '\0';
if (HTTPHeaders_AddHeaderNameValuePair(responseHeadersHandle, tokenTemp, whereIsColon + 1) != HTTP_HEADERS_OK)
{
LogError("HTTPHeaders_AddHeaderNameValuePair failed");
result = HTTPAPI_HTTP_HEADERS_FAILED;
break;
}
}
}
free(tokenTemp);
tokenTemp = NULL;
token = wcstok_s(NULL, L"\r\n", &next_token);
}
free(tokenTemp);
tokenTemp = NULL;
}
free(responseHeadersTemp);
return result;
}