After running the above code, the output result is not https, but Other(2).
Why does this happen?
The execution environment is Windows 10 (64-bit). The code is compiled as C++14.
#include <windows.h>
#include <WinInet.h>
#include <winhttp.h>
#include <iostream>
#include <string>
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "Winhttp.lib")
int main() {
std::wstring gitHubApiUrl = L"https://api.github.com";
URL_COMPONENTSW urlComponents = {};
urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
// Buffers for host and path
wchar_t hostName[256] = {};
wchar_t urlPath[1024] = {};
urlComponents.lpszHostName = hostName;
urlComponents.dwHostNameLength = ARRAYSIZE(hostName);
urlComponents.lpszUrlPath = urlPath;
urlComponents.dwUrlPathLength = ARRAYSIZE(urlPath);
// Call WinHttpCrackUrl
if (!WinHttpCrackUrl(gitHubApiUrl.c_str(), static_cast<DWORD>(gitHubApiUrl.size()), 0, &urlComponents)) {
std::wcerr << L"Failed to parse URL. Error: " << GetLastError() << std::endl;
return 0;
}
// Output parsed components
std::wcout << L"Scheme: ";
switch (urlComponents.nScheme) {
case INTERNET_SCHEME_HTTP: std::wcout << L"HTTP"; break;
case INTERNET_SCHEME_HTTPS: std::wcout << L"HTTPS"; break;
default: std::wcout << L"Other (" << urlComponents.nScheme << L")"; break;
}
std::wcout << std::endl;
std::wcout << L"Host Name: " << urlComponents.lpszHostName << std::endl;
std::wcout << L"URL Path: " << urlComponents.lpszUrlPath << std::endl;
return 0;
}
I found the reason, the reason for this problem is so weird. When #include <WinInet.h>
is above #include <winhttp.h>
, Other(2)
will be output.
Otherwise, if #include <winhttp.h>
is above #include <WinInet.h>
, https will be output normally, because the INTERNET_SCHEME
enumeration is defined in both header files.
Code:
#include <windows.h>
#include <WinInet.h>
#include <winhttp.h>
#include <iostream>
#include <string>
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "Winhttp.lib")
int main() {
std::wstring gitHubApiUrl = L"https://api.github.com";
URL_COMPONENTSW urlComponents = {};
urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
// Buffers for host and path
wchar_t hostName[256] = {};
wchar_t urlPath[1024] = {};
urlComponents.lpszHostName = hostName;
urlComponents.dwHostNameLength = ARRAYSIZE(hostName);
urlComponents.lpszUrlPath = urlPath;
urlComponents.dwUrlPathLength = ARRAYSIZE(urlPath);
// Call WinHttpCrackUrl
if (!WinHttpCrackUrl(gitHubApiUrl.c_str(), static_cast<DWORD>(gitHubApiUrl.size()), 0, &urlComponents)) {
std::wcerr << L"Failed to parse URL. Error: " << GetLastError() << std::endl;
return 0;
}
// Output parsed components
std::wcout << L"Scheme: ";
switch (urlComponents.nScheme) {
case INTERNET_SCHEME_HTTP: std::wcout << L"HTTP"; break;
case INTERNET_SCHEME_HTTPS: std::wcout << L"HTTPS"; break;
default: std::wcout << L"Other (" << urlComponents.nScheme << L")"; break;
}
std::wcout << std::endl;
std::wcout << L"Host Name: " << urlComponents.lpszHostName << std::endl;
std::wcout << L"URL Path: " << urlComponents.lpszUrlPath << std::endl;
return 0;
}