HTTP Connection fails but returns an error code of 0
HTTP Connection fails but returns an error code of 0
Loading saved threads...
Woody1193 · External communityPost link
External question — Stack Overflow Stack Exchange
Author: Woody1193
Original post: https://stackoverflow.com/questions/75577659
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
I'm writing an HTTP requester for a library in MQL4. This is what I have so far:
#define INTERNET_OPEN_TYPE_PRECONFIG 0
#define INTERNET_OPEN_TYPE_DIRECT 1
#define INTERNET_FLAG_NO_UI 0x00000200
#define INTERNET_FLAG_SECURE 0x00800000
#define INTERNET_FLAG_NO_CACHE_WRITE 0x04000000
#define INTERNET_SERVICE_HTTP 3
#define INTERNET_SERVICE_HTTPS 6
HttpRequester::HttpRequester(const string verb, const string host, const string resource,
const int port, const bool secure, const string referrer = NULL) {
m_ready = false;
ResetLastError();
// First, set the secure flag if we want a secure connection and define the service
int service = INTERNET_SERVICE_HTTP;
int flags = INTERNET_OPEN_TYPE_DIRECT | INTERNET_OPEN_TYPE_PRECONFIG | INTERNET_FLAG_NO_CACHE_WRITE;
if (secure) {
flags |= INTERNET_FLAG_SECURE;
service = INTERNET_SERVICE_HTTPS;
}
// Next, report to Windows the user agent that we'll request HTTP data with. If this fails
// then return an error
m_open_handle = InternetOpenW(GetUserAgentString(), flags, NULL, NULL, 0);
if (m_open_handle == INTERNET_INVALID_HANDLE) {
SetUserError(INTERNET_OPEN_FAILED_ERROR);
return;
}
// Now, attempt to create an intenrnet connection to the URL at the desired port;
// if this fails then return an error
m_session_handle = InternetConnectW(m_open_handle, host, port, "", "", service, flags, 1);
if (m_session_handle == INTERNET_INVALID_HANDLE) {
SetUserError(INTERNET_CONNECT_FAILED_ERROR);
return;
}
// Finally, open the HTTP request with the session variable, verb and URL; if this fails
// then log and return an error
string accepts[];
m_request_handle = HttpOpenRequestW(m_session_handle, verb, resource, NULL, referrer,
accepts, INTERNET_FLAG_NO_UI, 1);
if (m_request_handle == INTERNET_INVALID_HANDLE) {
SetUserError(INTERNET_OPEN_REQUEST_FAILED_ERROR);
return;
}
m_ready = true;
}
When calling this code, the issue I'm having is that
InternetConnectW
returns a handle of 0, but
GetLastError
also returns 0. I have verified the host ("https://qh7g3o0ypc.execute-api.ap-northeast-1.amazonaws.com") and port (443). What is going on here and how do I fix this?
Quote
Report
Woody1193 · External communityPost link
External answer — Stack Overflow Stack Exchange
Author: Woody1193
Original post: https://stackoverflow.com/a/75586676
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
I found the issue. It turns out that I was setting my flags and service improperly.
First, according to
this
,
INTERNET_OPEN_TYPE_DIRECT
and
INTERNET_OPEN_TYPE_PRECONFIG
conflict with each other. So, I removed
INTERNET_OPEN_TYPE_DIRECT
to tell Windows that I would like to use the network settings stored in the registry.
Next, I looked at the Windows documentation,
here
, and found out that, although
INTERNET_SERVICE_HTTPS
is defined, both HTTP and HTTPS requests are defined by the
INTERNET_SERVICE_HTTP
service flag.
Finally, I was not including the
INTERNET_FLAG_SECURE
flag in the right place. I discovered, from
this question
, that this flag needs to be included on the call to
HttpOpenRequestW
and including it anywhere else would be redundant.
After making all these changes, my code looks like this:
HttpRequester::HttpRequester(const string verb, const string host, const string resource,
const int port, const bool secure, const string referrer = NULL) {
m_ready = false;
ResetLastError();
// First, report to Windows the user agent that we'll request HTTP data with. If this fails
// then return an error
int flags = INTERNET_OPEN_TYPE_PRECONFIG | INTERNET_FLAG_NO_CACHE_WRITE;
m_open_handle = InternetOpenW(GetUserAgentString(), flags, NULL, NULL, 0);
if (m_open_handle == INTERNET_INVALID_HANDLE) {
SetUserError(INTERNET_OPEN_FAILED_ERROR);
return;
}
// Next, attempt to create an intenrnet connection to the URL at the desired port;
// if this fails then return an error
m_session_handle = InternetConnectW(m_open_handle, host, port, "", "", INTERNET_SERVICE_HTTP, flags, 0);
if (m_session_handle == INTERNET_INVALID_HANDLE) {
SetUserError(INTERNET_CONNECT_FAILED_ERROR);
return;
}
// Now, if we want a secure connection then add the secure flag to the connection
if (secure) {
flags |= INTERNET_FLAG_SECURE;
}
// Finally, open the HTTP request with the session variable, verb and URL; if this fails
// then log and return an error
string accepts[];
m_request_handle = HttpOpenRequestW(m_session_handle, verb, resource, NULL, referrer,
accepts, flags, 0);
if (m_request_handle == INTERNET_INVALID_HANDLE) {
SetUserError(INTERNET_OPEN_REQUEST_FAILED_ERROR);
return;
}
m_ready = true;
}
Quote
Report
Post Reply
Quoted from Forex.com.bd-Editorial External answer — Stack Overflow Stack Exchange Author: Woody1193 Source score (net votes, not local likes): 0 Original post: https://stackoverflow.com/a/75586676 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. I found the issue. It turns out that I was setting my flags and service improperly. First, according to this , INTERNET_OPEN_TYPE_DIRECT and INTERNET_OPEN_TYPE_PRECONFIG conflict with each other. So, I removed INTERNET_OPEN_TYPE_DIRECT to tell Windows that I would like to use the network settings stored in the registry. Next, I looked at the Windows documentation, here , and found out that, although INTERNET_SERVICE_HTTPS is defined, both HTTP and HTTPS requests are defined by the INTERNET_SERVICE_HTTP service flag. Finally, I was not including the INTERNET_FLAG_SECURE flag in the right place. I discovered, from this question , that this flag needs to be included on the call to HttpOpenRequestW and including it anywhere else would be redundant. After making all these changes, my code looks like this: HttpRequester::HttpRequester(const string verb, const string host, const string resource, const int port, const bool secure, const string referrer = NULL) { m_ready = false; ResetLastError(); // First, report to Windows the user agent that we'll request HTTP data with. If this fails // then return an error int flags = INTERNET_OPEN_TYPE_PRECONFIG | INTERNET_FLAG_NO_CACHE_WRITE; m_open_handle = InternetOpenW(GetUserAgentString(), flags, NULL, NULL, 0); if (m_open_handle == INTERNET_INVALID_HANDLE) { SetUserError(INTERNET_OPEN_FAILED_ERROR); return; } // Next, attempt to create an intenrnet connection to the URL at the desired port; // if this fails then return an error m_session_handle = InternetConnectW(m_open_handle, host, port, "", "", INTERNET_SERVICE_HTTP, flags, 0); if (m_session_handle == INTERNET_INVALID_HANDLE) { SetUserError(INTERNET_CONNECT_FAILED_ERROR); return; } // Now, if we want a secure connection then add the secure flag to the connection if (secure) { flags |= INTERNET_FLAG_SECURE; } // Finally, open the HTTP request with the session variable, verb and URL; if this fails // then log and return an error string accepts[]; m_request_handle = HttpOpenRequestW(m_session_handle, verb, resource, NULL, referrer, accepts, flags, 0); if (m_request_handle == INTERNET_INVALID_HANDLE) { SetUserError(INTERNET_OPEN_REQUEST_FAILED_ERROR); return; } m_ready = true; }
Checking account access…