in iothub_client/src/iothubtransporthttp.c [1906:2081]
static void DoMessages(HTTPTRANSPORT_HANDLE_DATA* handleData, HTTPTRANSPORT_PERDEVICE_DATA* deviceData)
{
if (deviceData->DoWork_PullMessage)
{
time_t timeNow = get_time(NULL);
bool isPollingAllowed = deviceData->isFirstPoll || (timeNow == (time_t)(-1)) || (get_difftime(timeNow, deviceData->lastPollTime) > handleData->getMinimumPollingTime);
if (isPollingAllowed)
{
HTTP_HEADERS_HANDLE responseHTTPHeaders = HTTPHeaders_Alloc();
if (responseHTTPHeaders == NULL)
{
LogError("unable to HTTPHeaders_Alloc");
}
else
{
BUFFER_HANDLE responseContent = BUFFER_new();
if (responseContent == NULL)
{
LogError("unable to BUFFER_new");
}
else
{
unsigned int statusCode = 0;
HTTPAPIEX_RESULT r;
if (deviceData->deviceSasToken != NULL)
{
if (HTTPHeaders_ReplaceHeaderNameValuePair(deviceData->messageHTTPrequestHeaders, IOTHUB_AUTH_HEADER_VALUE, STRING_c_str(deviceData->deviceSasToken)) != HTTP_HEADERS_OK)
{
r = HTTPAPIEX_ERROR;
LogError("Unable to replace the old SAS Token.");
}
else if ((r = HTTPAPIEX_ExecuteRequest(
handleData->httpApiExHandle,
HTTPAPI_REQUEST_GET, /*requestType: GET*/
STRING_c_str(deviceData->messageHTTPrelativePath), /*relativePath: the message HTTP relative path*/
deviceData->messageHTTPrequestHeaders, /*requestHttpHeadersHandle: message HTTP request headers created by _Create*/
NULL, /*requestContent: NULL*/
&statusCode, /*statusCode: a pointer to unsigned int which shall be later examined*/
responseHTTPHeaders, /*responseHeadearsHandle: a new instance of HTTP headers*/
responseContent /*responseContent: a new instance of buffer*/
)) != HTTPAPIEX_OK)
{
LogError("Unable to HTTPAPIEX_ExecuteRequest.");
}
}
else if ((r = HTTPAPIEX_SAS_ExecuteRequest(
deviceData->sasObject,
handleData->httpApiExHandle,
HTTPAPI_REQUEST_GET, /*requestType: GET*/
STRING_c_str(deviceData->messageHTTPrelativePath), /*relativePath: the message HTTP relative path*/
deviceData->messageHTTPrequestHeaders, /*requestHttpHeadersHandle: message HTTP request headers created by _Create*/
NULL, /*requestContent: NULL*/
&statusCode, /*statusCode: a pointer to unsigned int which shall be later examined*/
responseHTTPHeaders, /*responseHeadearsHandle: a new instance of HTTP headers*/
responseContent /*responseContent: a new instance of buffer*/
)) != HTTPAPIEX_OK)
{
LogError("unable to HTTPAPIEX_SAS_ExecuteRequest");
}
if (r == HTTPAPIEX_OK)
{
/*HTTP dialogue was succesfull*/
if (timeNow == (time_t)(-1))
{
deviceData->isFirstPoll = true;
}
else
{
deviceData->isFirstPoll = false;
deviceData->lastPollTime = timeNow;
}
if (statusCode == 204)
{
/*this is an expected status code, means "no commands", but logging that creates panic*/
/*do nothing, advance to next action*/
}
else if (statusCode != 200)
{
LogError("expected status code was 200, but actually was received %u... moving on", statusCode);
}
else
{
const char* etagValue = HTTPHeaders_FindHeaderValue(responseHTTPHeaders, "ETag");
if (etagValue == NULL)
{
LogError("unable to find a received header called \"E-Tag\"");
}
else
{
size_t etagsize = strlen(etagValue);
if (
(etagsize < 2) ||
(etagValue[0] != '"') ||
(etagValue[etagsize - 1] != '"')
)
{
LogError("ETag is not a valid quoted string");
}
else
{
const unsigned char* resp_content;
size_t resp_len;
resp_content = BUFFER_u_char(responseContent);
resp_len = BUFFER_length(responseContent);
IOTHUB_MESSAGE_HANDLE receivedMessage = IoTHubMessage_CreateFromByteArray(resp_content, resp_len);
bool abandon = false;
if (receivedMessage == NULL)
{
LogError("unable to IoTHubMessage_CreateFromByteArray, trying to abandon the message... ");
abandon = true;
}
else
{
if (retrieve_message_properties(responseHTTPHeaders, receivedMessage) != 0)
{
LogError("Failed retrieving message properties");
abandon = true;
}
else
{
MESSAGE_DISPOSITION_CONTEXT* dispositionContext = CreateMessageDispositionContext(etagValue);
if (dispositionContext == NULL)
{
LogError("failed to create disposition context");
abandon = true;
}
else
{
if (IoTHubMessage_SetDispositionContext(receivedMessage, dispositionContext, DestroyMessageDispositionContext) != IOTHUB_MESSAGE_OK)
{
LogError("Failed setting disposition context in IOTHUB_MESSAGE_HANDLE");
DestroyMessageDispositionContext(dispositionContext);
abandon = true;
}
else if (!handleData->transport_callbacks.msg_cb(receivedMessage, deviceData->device_transport_ctx))
{
LogError("IoTHubClientCore_LL_MessageCallback failed");
abandon = true;
}
}
}
if (abandon)
{
// If IoTHubMessage_SetDispositionContext succeeds above, it transitions ownership of
// dispositionContext to the receivedMessage.
// IoTHubMessage_Destroy() below will handle freeing it.
IoTHubMessage_Destroy(receivedMessage);
}
}
if (abandon)
{
if (!abandonOrAcceptMessage(handleData, deviceData, etagValue, IOTHUBMESSAGE_ABANDONED))
{
LogError("HTTP Transport layer failed to report ABANDON disposition");
}
}
}
}
}
}
BUFFER_delete(responseContent);
}
HTTPHeaders_Free(responseHTTPHeaders);
}
}
else
{
/*isPollingAllowed is false... */
/*do nothing "shall be ignored*/
}
}
}