Skip to content

Instantly share code, notes, and snippets.

@S4ddik
Forked from MordechaiMaman/HttpRequest.cpp
Created April 1, 2022 18:35
Show Gist options
  • Save S4ddik/4f37c0ef4ddf1c8c3484e194cd1d1619 to your computer and use it in GitHub Desktop.
Save S4ddik/4f37c0ef4ddf1c8c3484e194cd1d1619 to your computer and use it in GitHub Desktop.
http request module for windows (using wininet.lib)
#include "HttpRequest.h"
#include <iostream>
#pragma comment(lib, "Wininet.lib")
void main()
{
std::cout << "A simple HTTP request" << std::endl;
HTTP::HttpRequest request;
request.send(L"http://stackoverflow.com");
std::vector<BYTE> temp = request.response_text();
std::cout << std::string(temp.begin(), temp.begin()+10) << "..." << std::endl
<< request.response_status_code() << std::endl;
std::cout << "The same HTTP request but with HTTP headers" << std::endl;
HTTP::HttpRequest request_with_headers;
request_with_headers.send(L"http://stackoverflow.com", { {L"Accept-Encoding", L"gzip"} });
temp = request_with_headers.response_text();
std::cout << std::string(temp.begin(), temp.begin()+10) << "..." << std::endl
<< request_with_headers.response_status_code() << std::endl;
std::cout << "A simple HTTPS request" << std::endl;
HTTP::HttpRequest request_https;
request_https.send(L"https://google.com");
temp = request_https.response_text();
std::cout << std::string(temp.begin(), temp.begin() + 10) << "..." << std::endl
<< request_https.response_status_code() << std::endl;
}
#include "HttpRequest.h"
#include <sstream>
HTTP::HttpRequest::HttpRequest(const std::wstring& user_agent)
{
_connection = InternetOpenW(user_agent.c_str(),
INTERNET_OPEN_TYPE_DIRECT,
NULL, NULL, 0);
if (_connection == NULL)
throw wininet_error("InternetOpenW");
}
HTTP::HttpRequest::HttpRequest() : HttpRequest(L"")
{
}
HTTP::HttpRequest::~HttpRequest()
{
try
{
if (_current_url != NULL) InternetCloseHandle(_current_url);
if (_connection != NULL) InternetCloseHandle(_connection);
}
catch (...) {}
}
void HTTP::HttpRequest::send(const std::wstring& url, const HeadersMap& headers, int flags)
{
std::wstring additional_headers;
if (headers.size() > 0)
{
std::wstringstream stream;
for (auto i : headers) stream << i.first << L": " << i.second << "\r\n";
additional_headers = stream.str();
}
_current_url = InternetOpenUrlW(_connection, url.c_str(), additional_headers.c_str(), -1, flags, 0);
if (_current_url == NULL)
throw wininet_error("InternetOpenUrlW");
}
void HTTP::HttpRequest::send(const std::wstring& url, int flags)
{
send(url, HeadersMap(), flags);
}
int HTTP::HttpRequest::response_status_code()
{
wchar_t status_code_text[4];
DWORD status_code_text_size = sizeof(status_code_text);
if (HttpQueryInfoW(_current_url,
HTTP_QUERY_STATUS_CODE,
&status_code_text,
&status_code_text_size,
NULL) == FALSE)
throw wininet_error("HttpQueryInfoW");
return _wtoi(status_code_text);
}
std::vector<BYTE> HTTP::HttpRequest::response_text()
{
static const int buffer_size = 4096;
std::vector<BYTE> receive_buffer(buffer_size);
DWORD num_of_bytes_read = 0;
std::vector<BYTE> return_buffer;
do
{
if (InternetReadFile(_current_url,
receive_buffer.data(),
buffer_size,
&num_of_bytes_read) == FALSE)
throw wininet_error("InternetReadFile");
return_buffer.insert(return_buffer.end(), receive_buffer.begin(), receive_buffer.end());
} while (num_of_bytes_read != 0);
return return_buffer;
}
#pragma once
#include <string>
#include <map>
#include <exception>
#include <Windows.h>
#include <wininet.h>
#include <vector>
namespace HTTP
{
typedef std::map<std::wstring, std::wstring> HeadersMap;
static const int DEFAULT_FLAGS =
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_PRAGMA_NOCACHE |
INTERNET_FLAG_RELOAD;
class HttpRequest
{
public:
HttpRequest(const std::wstring& user_agent);
HttpRequest();
~HttpRequest();
void send(const std::wstring& url, const HeadersMap& headers, int flags = DEFAULT_FLAGS);
void send(const std::wstring& url, int flags = DEFAULT_FLAGS);
int response_status_code();
std::vector<BYTE> response_text();
private:
HINTERNET _connection;
HINTERNET _current_url;
};
class wininet_error : std::exception
{
public:
wininet_error() : std::exception() {}
explicit wininet_error(char const* const m) : std::exception(m, GetLastError()) {}
wininet_error(char const* const m, int i) : std::exception(m, i) {}
wininet_error(wininet_error const& e) : std::exception(e) {}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment