-
-
Save S4ddik/5f814cd90001653ba976ad7d6b8e52e7 to your computer and use it in GitHub Desktop.
win32 HTTP GET
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "win32_net.h" | |
#include <windows.h> | |
#include <wininet.h> | |
#pragma comment (lib, "Wininet.lib") | |
#include <stdio.h> | |
#include <wchar.h> | |
#include <cwctype> | |
#include <algorithm> | |
namespace net { | |
std::string HttpGet(std::wstring url, std::wstring headers) { | |
std::string response; | |
if (url.empty()) { | |
return response; | |
} | |
// to lowercase | |
std::wstring urlLower(url); | |
std::transform( | |
urlLower.begin(), urlLower.end(), | |
urlLower.begin(), | |
std::towlower); | |
bool ssl; | |
size_t schemeLen; | |
if (urlLower.find(L"http://") == 0) { | |
ssl = false; | |
schemeLen = 7; | |
} | |
else if (urlLower.find(L"https://") == 0) { | |
ssl = true; | |
schemeLen = 8; | |
} | |
else { | |
return response; // invalid url | |
} | |
// get host | |
std::wstring host(url.substr(schemeLen, url.length() - schemeLen)); | |
size_t posSlash = host.find(L"/"); | |
size_t posQuestion = host.find(L"?"); | |
size_t posEnd = host.length(); | |
if (posSlash != std::string::npos && posQuestion != std::string::npos) { | |
posEnd = std::min(posSlash, posQuestion); | |
} else if (posSlash != std::string::npos) { | |
posEnd = posSlash; | |
} else if (posQuestion != std::string::npos) { | |
posEnd = posQuestion; | |
} | |
host = host.substr(0, posEnd); | |
// get port if exists (and remove it from host name) | |
INTERNET_PORT port = ssl ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT; | |
size_t colonAndPortLen = 0; | |
size_t posColon = host.find(L":"); | |
if (posColon != std::string::npos) { | |
colonAndPortLen = 1; | |
if (posColon + 1 < host.length()) { | |
std::wstring sPort(host.substr(posColon + 1)); | |
colonAndPortLen += sPort.length(); | |
int iPort = _wtoi(sPort.c_str()); | |
if (iPort != 0) { | |
port = (INTERNET_PORT)iPort; | |
if (port == INTERNET_DEFAULT_HTTPS_PORT) { | |
ssl = true; | |
} | |
} | |
} | |
// remove from host name | |
host = host.substr(0, posColon); | |
} | |
if (host.empty()) { | |
return response; | |
} | |
// get the rest (everything after host and port) | |
std::wstring rest; | |
if (url.length() > schemeLen + host.length() + colonAndPortLen) | |
rest = url.substr(schemeLen + host.length() + colonAndPortLen); | |
// TODO: parameterize useragent | |
HINTERNET hIntSession = | |
::InternetOpenW(L"MyGreatAppName", // useragent | |
INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0); | |
if (!hIntSession) { | |
return response; | |
} | |
HINTERNET hHttpSession = | |
::InternetConnectW(hIntSession, host.c_str(), | |
port, | |
nullptr, nullptr, INTERNET_SERVICE_HTTP, 0, 0); | |
if (!hHttpSession) { | |
::InternetCloseHandle(hIntSession); | |
return response; | |
} | |
DWORD dwOpenFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_CACHE_WRITE; | |
if (ssl) { | |
dwOpenFlags |= INTERNET_FLAG_SECURE; | |
} | |
HINTERNET hHttpRequest = HttpOpenRequestW( | |
hHttpSession, | |
L"GET", | |
rest.empty() ? L"/" : rest.c_str(), // if lpszObjectName is empty string, must pass "/", otherwise no request will be made to the server (and there is no error). | |
0, 0, 0, dwOpenFlags, 0); | |
if (!hHttpRequest) { | |
::InternetCloseHandle(hHttpSession); | |
::InternetCloseHandle(hIntSession); | |
return response; | |
} | |
if(!::HttpSendRequestW(hHttpRequest, | |
headers.empty() ? nullptr : headers.c_str(), | |
headers.empty() ? -1 : headers.length(), | |
nullptr, 0)) { | |
::InternetCloseHandle(hHttpRequest); | |
::InternetCloseHandle(hHttpSession); | |
::InternetCloseHandle(hIntSession); | |
return response; | |
} | |
char szBuffer[1025]; | |
DWORD dwRead=0; | |
while(::InternetReadFile(hHttpRequest, szBuffer, sizeof(szBuffer)-1, &dwRead) && dwRead) { | |
szBuffer[dwRead] = 0; | |
//OutputDebugStringA(szBuffer); | |
dwRead=0; | |
} | |
::InternetCloseHandle(hHttpRequest); | |
::InternetCloseHandle(hHttpSession); | |
::InternetCloseHandle(hIntSession); | |
return response; | |
} | |
} // namespace net |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef WIN32_NET_H_ | |
#define WIN32_NET_H_ | |
#include <string> | |
namespace net { | |
// headers = L"Content-Type: text/html\nMySpecialHeder: whatever" | |
std::string HttpGet(std::wstring url, std::wstring headers = L""); | |
} | |
#endif // WIN32_NET_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment