Closed dehng closed 6 years ago
Hi @dehng , please take a look at this sample: https://github.com/Azure/azure-iot-sdk-c/blob/master/iothub_client/samples/iothub_client_sample_upload_to_blob/iothub_client_sample_upload_to_blob.c#L63
You can set the user and password as well on that structure. https://github.com/Azure/azure-c-shared-utility/blob/41861a7f3b6c023eda22a7ad07cc9b8489999b14/inc/azure_c_shared_utility/shared_util_options.h#L12
As the name suggests, this option is for HTTP proxy. That can be leveraged if you use our HTTP transport or any of the WebSockets-based transports (AMQP-WS or MQTT-WS).
I would suggest you try using either AMQP over Websockets or MQTT over websockets if you have a client behind a firewall.
Hi @ewertons, thank you for your answer. I've added the code below to allow proxy settings to be set. For accessing the cloud, I'm using the example 'iothub_client_sample_http' My operating system is 'Windows Compact 2013'
HTTP_PROXY_OPTIONS http_proxy_options = { 0 };
http_proxy_options.host_address = "1.2.3.4"
http_proxy_options.port = 8080;
http_proxy_options.username = "domain\\user";
http_proxy_options.password = "pwd";
if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_HTTP_PROXY, &http_proxy_options) != IOTHUB_CLIENT_OK)
{
(void)printf("failure to set proxy\n");
}
With this extension: I now get this error. What am I doing wrong?
Starting the IoTHub client sample HTTP...
Info: IoT Hub SDK for C, version 1.1.29
Error: Time:Tue Jan 09 23:04:01 2018 File:..\..\azure-iot-sdk-c\c-utility\adapters\httpapi_wince.c Func:HTTPAPI_CloneOption Line:636 unknown option proxy_data
Error: Time:Tue Jan 09 23:04:01 2018 File:..\..\azure-iot-sdk-c\c-utility\src\httpapiex.c Func:HTTPAPIEX_SetOption Line:609 error code = HTTPAPIEX_INVALID_ARG
Error: Time:Tue Jan 09 23:04:01 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransporthttp.c Func:?IoTHubTransportHttp_SetOption@@YA?AW4IOTHUB_CLIENT
_RESULT_TAG@@PAXPBDPBX@Z Line:2426 HTTPAPIEX_SetOption failed
IoTHubClient_LL_SetMessageCallback...successful.
IoTHubClient_LL_SendEventAsync accepted message [zu] for transmission to IoT Hub.
Info: HTTPAPI_Init::Start
Info: HTTAPI_Init::Time is now (UTC) Tue Jan 09 23:04:01 2018
Info: HTTPAPI_Init::End
Info: HTTPAPI_CreateConnection::Start
Info: HTTPAPI_CreateConnection::Connecting to XXXXXXXX.azure-devices.net
Info: HTTPAPI_CreateConnection::End
Info: HTTPAPI_ExecuteRequest::Start
Error: Time:Tue Jan 09 23:04:23 2018 File:..\..\azure-iot-sdk-c\c-utility\adapters\httpapi_wince.c Func:HTTPAPI_ExecuteRequest Line:324 connect failed
Info: HTTPAPI_ExecuteRequest::End=0
The examples of AMQP-WS and MQTT-WS both do not work. I am not connected to the cloud. The example 'iothub_client_sample_amqp_websockets' contains an error that TLS for Windows Compact 2013 is not supported. Output from the sample program:
Info: IoT Hub SDK for C, version 1.1.29
Info: Retry policy set (5, timeout = 0)
Error: Time:Tue Jan 09 17:56:00 2018 File:..\..\azure-iot-sdk-c\c-utility\adapters\platform_win32.c Func:platform_get_default_tlsio Line:56 TLS IO interface currently not supported on WEC 2013
Error: Time:Tue Jan 09 17:56:07 2018 File:..\..\azure-iot-sdk-c\c-utility\src\uws_client.c Func:uws_client_create_with_io Line:350 Invalid arguments: io_interface = 00000000, resource_name = 003336AC, protocols = 0099F3B4, protocol_count =
zu
Error: Time:Tue Jan 09 17:56:08 2018 File:..\..\azure-iot-sdk-c\c-utility\src\wsio.c Func:wsio_create Line:257 Cannot create uws instance.
Error: Time:Tue Jan 09 17:56:09 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransport_amqp_common.c Func:get_new_underlying_io_transport Line:698 Failed to obtain a TLS I/O transport layer (underlying_io_transport_provider() failed)
Error: Time:Tue Jan 09 17:56:10 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransport_amqp_common.c Func:IoTHubTransport_AMQP_Common_SetOption Line:2072 transport failed setting option 'TrustedCerts' (failed to obtain a TLS I/Otransport).
Error: Time:Tue Jan 09 17:56:11 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothub_client_ll.c Func:IoTHubClient_LL_SetOption Line:1791 underlying transport failed, returned = IOTHUB_CLIENT_ERROR
Error: Time:Tue Jan 09 17:56:14 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothub_client.c Func:IoTHubClient_SetOption Line:1497 IoTHubClient_LL_SetOption failed
Error: Time:Tue Jan 09 17:56:15 2018 File:..\..\azure-iot-sdk-c\c-utility\adapters\platform_win32.c Func:platform_get_default_tlsio Line:56 TLS IO interface currently not supported on WEC 2013
Error: Time:Tue Jan 09 17:56:17 2018 File:..\..\azure-iot-sdk-c\c-utility\src\uws_client.c Func:uws_client_create_with_io Line:350 Invalid arguments: io_interface = 00000000, resource_name = 003336AC, protocols = 00C9FBC4, protocol_count =zu
Error: Time:Tue Jan 09 17:56:21 2018 File:..\..\azure-iot-sdk-c\c-utility\src\wsio.c Func:wsio_create Line:257 Cannot create uws instance.
Error: Time:Tue Jan 09 17:56:22 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransport_amqp_common.c Func:get_new_underlying_io_transport Line:698 Failed to obtain a TLS I/O transport layer (underlying_io_transport_provider() failed)
Error: Time:Tue Jan 09 17:56:25 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransport_amqp_common.c Func:establish_amqp_connection Line:783 Failed establishing connection (failed to obtain a TLS I/O transport layer).
Error: Time:Tue Jan 09 17:56:28 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransport_amqp_common.c Func:IoTHubTransport_AMQP_Common_DoWork Line:1572 AMQP transport failed to establish connection with service.
Info: Preparing transport for re-connection
Error: Time:Tue Jan 09 17:56:28 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransport_amqp_common.c Func:save_underlying_io_transport_options Line:605 failed saving underlying I/O transport options (tls_io instance is NULL)
Error: Time:Tue Jan 09 17:56:30 2018 File:..\..\azure-iot-sdk-c\iothub_client\src\iothubtransport_amqp_common.c Func:prepare_for_connection_retry Line:867 Failed saving TLS I/O options while preparing for connection retry; failure will be ignored
Oh, you are using Windows Compact 2013. I overlooked that. I need to check our support for that version.
Hi @ewertons, do you have information for me?
Hi @dehng , I confirmed, and we do support the version of Windows Compact you are using. However, proxy configuration is not implemented for that version of OS (httpapi_wince.c). That would be an improvement needed to the SDK.
Hi @everton Is there an appointment, when the SDK supports the proxy function for http protocol? What must be done for the AMQP-WS or MQTT-WS protocols to work under WinCE? I need a connection to the azure over a firewall.
Thanks
Traditionally the alternative way to getting the websockets-based protocols to work on a system where we do not implement HTTP proxy setting in code is to configure the HTTP proxy directly on the OS. Would you be able to try that option?
@ewertons. I asked the OS Image manufacturer if this is possible. He says that this is not a problem of the OS, but should be solved in azure sdk. Link: https://www.toradex.com/community/questions/18696/set.proxy-settings-in-windows-compact-2013-for-use.html?childToView=18967#comment-18967
Can you help me?
Hi @dehng - Because our CE implementation uses sockets directly and not a wrapper like Wininet, adding proxy support isn’t practical. The only tested configuration is HTTPS for WEC 2013. Currently there are no plans to support protocols like MQTT and AMQP, either.
One alternative can be to go with Windows IoT Core which has broader support in Azure IoT SDK.
Sorry we don’t have a better story for you here. -- John
Hi @jspaith , I looked at the file 'httpapi_wininet.c' and rebuilt it for testing so I can connect through a proxy server. Now my connection to the cloud works.
How can I install proxy support to be 'correct'?
Call in the client: `HTTP_PROXY_OPTIONS m_httpProxyOptions; m_httpProxyOptions.host_address = "proxy.myAddress.com"; m_httpProxyOptions.port = 8080; m_httpProxyOptions.username = "MyUserName"; m_httpProxyOptions.password = "MyPasswort";
resultIoClient = IoTHubClient_SetOption(m_iothubClientMainHandle, OPTION_HTTP_PROXY, &m_httpProxyOptions);`
Extension in the file httpapi_wininet.c: `///////////////////////////////////////// // File httpapi_wininet.c ///////////////////////////////////////// typedef struct HTTP_HANDLE_DATA_TAG { HINTERNET SessionHandle; HINTERNET ConnectionHandle; HTTP_PROXY_OPTIONS MyProxyOptions; // new setting } HTTP_HANDLE_DATA;
///////////////////////////////////////// // File httpapi_wininet.c, new functions ///////////////////////////////////////// HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char optionName, const void value) { HTTPAPI_RESULT result; if (strcmp(optionName, OPTION_HTTP_PROXY) == 0) { HTTP_PROXY_OPTIONS proxy_options = (HTTP_PROXY_OPTIONS )value; ... result = HTTPAPI_OK; } ... }
HTTPAPI_RESULT HTTPAPI_CloneOption(const char optionName, const void value, const void* savedValue) { HTTPAPI_RESULT result; if (strcmp(optionName, OPTION_HTTP_PROXY) == 0) { HTTP_PROXY_OPTIONS proxy_options = (HTTP_PROXY_OPTIONS *)value; ... result = HTTPAPI_OK; } ... }`
Is this the right way or does the option have to be set in another file? Thanks
You're correct - the SetOption & CloneOption are the places you need to wire up to make this work.
Were you having issues with this (it sounds like no?) or were you just double checking, in which case all should be well.
@dehng - since this thread has been quiet for a bit, I'm going to close it but as always if there's more to discuss by all means re-open it or create a new one.
hey guys, i want to ask you a question, how to use "http_proxy_io" with "httpapi_compact"? currently i'm using HTTP protocol to send and receive, and i want to use proxy configuration.
Hi @mohamedibrahimabdelrahman33, I replaced the file httpapi_wince with the file httpapi_wininet. In this file I have added the extensions for access with a proxy server.
New code in the file:
#include "azure_c_shared_utility/shared_util_options.h"
#include "azure_c_shared_utility/crt_abstractions.h"
#pragma comment (lib, "Wininet.lib")
#define TEMP_BUFFER_SIZE 1024
static char g_proxyServername[1024] = "";
static char g_proxyServernameAndPort[1024] = "";
typedef struct HTTP_HANDLE_DATA_TAG
{
HINTERNET SessionHandle;
HINTERNET ConnectionHandle;
HTTP_PROXY_OPTIONS proxy_options; // added
} HTTP_HANDLE_DATA;
new function
HTTPAPI_RESULT HTTPAPI_SetOption(HTTP_HANDLE handle, const char* optionName, const void* value)
{
HTTPAPI_RESULT result;
if (
(handle == NULL) ||
(optionName == NULL) ||
(value == NULL)
)
{
result = HTTPAPI_INVALID_ARG;
LogError("invalid parameter (NULL) passed to HTTPAPI_SetOption");
}
else if (strcmp(optionName, OPTION_HTTP_PROXY) == 0)
{
HTTP_PROXY_OPTIONS* proxy_options = (HTTP_PROXY_OPTIONS *)value;
HTTP_HANDLE_DATA* handleData = (HTTP_HANDLE_DATA*)handle;
if (handleData->ConnectionHandle != NULL)
{
BOOL state = FALSE;
// user and password for proxy server
if ((proxy_options->username != NULL) && (proxy_options->password != NULL))
{
if ((strlen(proxy_options->username) != 0) && ((strlen(proxy_options->password) != 0)))
{
LogInfo("Connection with proxy server. Set user and password ...");
state = InternetSetOptionA(handleData->ConnectionHandle, INTERNET_OPTION_PROXY_USERNAME, (void*)proxy_options->username, strlen(proxy_options->username));
if (state == TRUE)
{
state = InternetSetOptionA(handleData->ConnectionHandle, INTERNET_OPTION_PROXY_PASSWORD, (void*)proxy_options->password, strlen(proxy_options->password));
if (state == FALSE)
{
LogError("Connection with proxy server. Set password for connection with proxy server failed. WinError=%d", GetLastError());
}
}
else
{
LogError("Connection with proxy server. Set user for connection with proxy server failed. WinError=%d", GetLastError());
}
if (state == TRUE)
LogInfo("Connection with proxy server. Set user and password done.");
else
LogError("Connection with proxy server. Set user and password failed.");
}
}
}
result = HTTPAPI_OK;
}
else
{
result = HTTPAPI_INVALID_ARG;
LogError("unknown option %s", optionName);
}
return result;
}
HTTPAPI_RESULT HTTPAPI_CloneOption(const char* optionName, const void* value, const void** savedValue)
{
HTTPAPI_RESULT result;
if (
(optionName == NULL) ||
(value == NULL) ||
(savedValue == NULL)
)
{
result = HTTPAPI_INVALID_ARG;
LogError("invalid argument(NULL) passed to HTTPAPI_CloneOption");
}
else if (strcmp(optionName, OPTION_HTTP_PROXY) == 0)
{
HTTP_PROXY_OPTIONS* proxy_options = (HTTP_PROXY_OPTIONS *)value;
HTTP_PROXY_OPTIONS* temp = (HTTP_PROXY_OPTIONS*)malloc(sizeof(HTTP_PROXY_OPTIONS));
memset(temp, 0, sizeof(HTTP_PROXY_OPTIONS));
temp->port = proxy_options->port;
if (proxy_options->host_address != NULL)
mallocAndStrcpy_s((char**)&temp->host_address, (const char*)proxy_options->host_address);
if (proxy_options->username != NULL)
mallocAndStrcpy_s((char**)&temp->username, (const char*)proxy_options->username);
if (proxy_options->password != NULL)
mallocAndStrcpy_s((char**)&temp->password, (const char*)proxy_options->password);
*savedValue = temp;
// proxy server - address
if (proxy_options->host_address != NULL)
{
strncpy_s(g_proxyServername, _countof(g_proxyServername), proxy_options->host_address, min(_countof(g_proxyServername), strlen(proxy_options->host_address)));
if (proxy_options->port != 0)
sprintf_s(g_proxyServernameAndPort, _countof(g_proxyServernameAndPort), "%s:%d", proxy_options->host_address, proxy_options->port);
else
sprintf_s(g_proxyServernameAndPort, _countof(g_proxyServernameAndPort), "%s", proxy_options->host_address);
}
else
{
g_proxyServername[0] = 0;
g_proxyServernameAndPort[0] = 0;
}
result = HTTPAPI_OK;
}
else
{
*savedValue = NULL;
result = HTTPAPI_INVALID_ARG;
LogError("unknown option %s", optionName);
}
return result;
}
Change the function "HTTPAPI_CreateConnection"
if (strlen(g_proxyServernameAndPort) == 0)
{
LogInfo("Create connection with direct access to internet...", );
result->SessionHandle = InternetOpen(
NULL,
INTERNET_OPEN_TYPE_DIRECT,
NULL,
NULL,
0);
}
else
{
LogInfo("Create connection with proxy settings ('%s')...", g_proxyServernameAndPort);
result->SessionHandle = InternetOpen(
NULL,
INTERNET_OPEN_TYPE_PROXY,
g_proxyServernameAndPort,
NULL,
0);
}
We are trying to do the same. Is there a sample for windows?
@rkathire, i used the the standard api for using wininet and use it on windows compact.
Thanks @dehng for your effort, but actually i'm using "httpapi_compact" not "httpapi_wince". currently i'm working on STM32F7 platform.
OS and version used: Windows Compact 2013
SDK version used: Release 2017-11-17
Description of the issue:
Hello, is there a way to specify a proxy server (name, user, password, port)? My IoT client is behind a firewall and must first log on to the proxy in order to establish a connection.
Currently I'm using the example 'iothub_client_sample_http' and 'iothub_client_sample_mqtt'.
Thanks.