Reputation: 21
We have a legacy application that implements an SSL tunnel over Web proxies. It uses the wininet API and it worked fine for years on XP, but now it fails on Windows 7. I've tried to isolate the code and made a small program to reproduce the problem. It's a small C program compiled with MSVC 9. See below.
On Windows 7, once connected to the proxy (status code 200), I just cannot get the socket descriptor from the API. All I get is an INVALID_SOCKET, even though all wininet functions returned successfully and GetLastError() returned 0.
On the XP machine, all works fine and the returned socket is valid.
Does anyone have any idea? Thank you very much in advance.
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
const char *_connect()
{
HINTERNET hOpen = 0;
HINTERNET hConnect = 0;
HINTERNET hRequest = 0;
int remotePort = 443;
const char *remoteHost = "a.b.c.d"; // Cannot disclose
hOpen = InternetOpen("wininet-test", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (!hOpen) return "InternetOpen";
hConnect = InternetConnect(hOpen, remoteHost, remotePort, 0, 0, INTERNET_SERVICE_HTTP, 0, 0);
if (!hConnect) return "InternetConnect";
{
DWORD flags =
INTERNET_FLAG_CACHE_IF_NET_FAIL |
INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_PRAGMA_NOCACHE |
INTERNET_FLAG_RELOAD |
INTERNET_FLAG_RESYNCHRONIZE |
INTERNET_FLAG_SECURE;
char url[100];
sprintf(url, "http://%s:%d/", remoteHost, remotePort);
hRequest = HttpOpenRequest(hConnect, "GET", "connect.html", "HTTP/1.0", url, 0, flags, 0);
if (!hRequest) return "HttpOpenRequest";
}
{
DWORD flags=0;
DWORD bufferLength = sizeof(flags);
if (!InternetQueryOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, &bufferLength)) {
return "InternetQueryOption";
}
flags |= (SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_REVOCATION);
if (!InternetSetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, sizeof(flags))) {
return "InternetSetOption";
}
}
if (!HttpSendRequest(hRequest, 0, 0, 0, 0)) {
return "HttpSendRequest";
} else {
char buffer[4];
DWORD bufferSize = sizeof(buffer);
if (!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, &buffer, &bufferSize, NULL)) {
return "HttpQueryInfo";
} else if (atoi(buffer) != 200) {
return "status code";
}
}
{
INTERNET_DIAGNOSTIC_SOCKET_INFO idsi;
DWORD bufferSize = sizeof(idsi);
if (!InternetQueryOption(hRequest, INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, &idsi, &bufferSize)) {
return "InternetQueryOption";
} else if (idsi.Socket == INVALID_SOCKET) {
/* This is always the case on our Windows 7 platform, why? */
return "invalid socket";
}
}
return 0;
}
int main(int argc, const char **argv)
{
const char *error = _connect();
if (error) {
printf("ERROR: %s (%d)\n", error, GetLastError());
} else {
printf("SUCCESS\n");
}
return 0;
}
Upvotes: 2
Views: 4665
Reputation: 135
INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO 67
Retrieves an INTERNET_DIAGNOSTIC_SOCKET_INFO structure that contains data about a specified HTTP Request. This flag is used by InternetQueryOption.
Windows 7: This option is no longer supported.
Upvotes: 3
Reputation: 597951
Is the HTTP request using keep-alives? If not, then my guess would be that WinInet under Win7 is invalidating the socket handle after closing it when receiving the server's response, whereas XP does not invalidate the socket.
Upvotes: 2
Reputation: 70981
Are your sure your project is not compiling for unicode? In case it does you need to change your char
declaration to wchar_t
and prefix your constants with L
like:
const wchar_t * pszTmp = L"hello world";
Upvotes: 0