Here's the scenario:
A client PC issues an HTTP request to a local webserver using the
wininet CHttpFile::SendRequest() method. As part of processing that
initial request, the local webserver issues a secure HTTPS request to
a remote webserver, also using the SendRequest() method, before a
response is returned to the client. The initial SendRequest() call
sends the request successfully, but when the second SendRequest() call
is made (to the HTTPS URL), a CInternetException is thrown: A
connection with the server could not be established (error code is
12029).
If I manually attempt the HTTPS request to the remote server directly
by using a browser (IE 6), it succeeds. Also, if SSL is disabled on
the remote server and the corresponding "second request" is changed to
a standard HTTP request, the entire process succeeds as well using the
WinInet classes.
In my tests both servers were actually local, but meant to mimic
local/remote servers, so no firewall issues should be coming into play
here. In case it matters, both servers are running NES (3.6, I
believe).
This is a likely scenario for us in the real world, as the local
server sits inside a firewall and will have SSL disabled. Yet,
communications with any remote sites are required to be over SSL. Is
this a problem within wininet, or is something else going on here?
Here's a snippet of the code I'm using to setup and open the
connections:
CInternetSession session("TEST");
CHttpConnection* pServer = NULL;
CHttpFile* pFile = NULL;
if(dwServiceType == AFX_INET_SERVICE_HTTPS)
dwFlags = INTERNET_FLAG_SECURE|INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
else if (dwServiceType == AFX_INET_SERVICE_HTTP)
dwFlags = INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE;
pServer = session.GetHttpConnection(strServerName, dwFlags, nPort);
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
strObject, NULL, 1, NULL, NULL, dwFlags);
pFile->SendRequest(); <<-- Exception thrown on second request - over
HTTPS
The only difference I make between HTTP and HTTPS connections is to
use the appropriate HTTPS flags (I added the cert stuff in just in
case):
INTERNET_FLAG_SECURE
INTERNET_FLAG_IGNORE_CERT_CN_INVALID
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
Thanks in advance for any help or suggestions anyone might have.
http://support.microsoft.com/support/kb/articles/q182/8/88.asp
Essentially, the problem was with the secure webserver's SSL
certificate - there were two problems: 1. the root CA was not trusted
and 2. the hostname did not match the site name in the cert.
In order to handle this, the call to SendRequest needs to be made
twice. First, with the above flags set. This request will fail.
When handling that failure, additional security flags need to be set
and the request needs to be tried again. Having rewrote my code to
reflect these changes (and using the WinInet APIs instead of the
classes), I am now able to get the second sendRequest to succeed. I'm
glad the WinInet documentation specifies this.