Network: refactor
This commit is contained in:
parent
e50c3317a2
commit
2536881452
120
network.cpp
120
network.cpp
@ -1,120 +0,0 @@
|
|||||||
#include "network.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
// shamelessly stolen from http://www.cplusplus.com/forum/windows/109799/
|
|
||||||
|
|
||||||
Curl::Curl() {
|
|
||||||
connect = InternetOpen( L"WinInet/1.0", INTERNET_OPEN_TYPE_PRECONFIG,
|
|
||||||
nullptr, nullptr, 0 );
|
|
||||||
if ( !connect )
|
|
||||||
std::wcerr << "Something went wrong while connecting" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl::~Curl() {
|
|
||||||
if ( connect )
|
|
||||||
InternetCloseHandle( connect );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Curl::execute( const std::wstring &url ) {
|
|
||||||
std::string source{};
|
|
||||||
source.reserve( 10000 );
|
|
||||||
|
|
||||||
HINTERNET openAddress = InternetOpenUrl(
|
|
||||||
connect, url.c_str(), nullptr, 0,
|
|
||||||
INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0 );
|
|
||||||
|
|
||||||
if ( !openAddress ) {
|
|
||||||
unsigned long errorNum = GetLastError();
|
|
||||||
std::wcout << "Failed to open URL" << std::endl
|
|
||||||
<< "Error No: " << errorNum << std::endl;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
char dataReceived[4096];
|
|
||||||
unsigned long numberOfBytesRead = 0;
|
|
||||||
while ( InternetReadFile( openAddress, dataReceived, 4096,
|
|
||||||
&numberOfBytesRead ) &&
|
|
||||||
numberOfBytesRead ) {
|
|
||||||
source.append( dataReceived, numberOfBytesRead );
|
|
||||||
}
|
|
||||||
|
|
||||||
InternetCloseHandle( openAddress );
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
size_t writeCallback( void *contents, size_t size, size_t nmemb,
|
|
||||||
void *target ) {
|
|
||||||
*static_cast< std::string * >( target ) +=
|
|
||||||
std::string( static_cast< char * >( contents ), size * nmemb );
|
|
||||||
return size * nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl::Curl() {
|
|
||||||
curl_global_init( CURL_GLOBAL_ALL );
|
|
||||||
curl_handle = curl_easy_init();
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_WRITEFUNCTION, writeCallback );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0" );
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl::~Curl() {
|
|
||||||
curl_easy_cleanup( curl_handle );
|
|
||||||
curl_slist_free_all( chunk );
|
|
||||||
curl_global_cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanUp( CURL *curl_handle ) {
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_POST, 0 );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_POSTFIELDS, "" );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Curl::get( const std::string &url ) {
|
|
||||||
// get rid of garbage
|
|
||||||
cleanUp( curl_handle );
|
|
||||||
std::string source;
|
|
||||||
source.reserve( 100000 );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_WRITEDATA,
|
|
||||||
static_cast< void * >( &source ) );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_URL, url.c_str() );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_HTTPGET, 1 );
|
|
||||||
auto res = curl_easy_perform( curl_handle );
|
|
||||||
if ( res != CURLE_OK ) {
|
|
||||||
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror( res )
|
|
||||||
<< std::endl;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl::addHeader( const std::string &header ) {
|
|
||||||
chunk = curl_slist_append( chunk, header.c_str() );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_HTTPHEADER, chunk );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Curl::clearHeader() {
|
|
||||||
curl_slist_free_all( chunk );
|
|
||||||
chunk = NULL;
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_HTTPHEADER, chunk );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Curl::post( const std::string &url, const std::string &data ) {
|
|
||||||
std::string source;
|
|
||||||
source.reserve( 100000 );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_URL, url.c_str() );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_POST, 1 );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_POSTFIELDS, data.c_str() );
|
|
||||||
curl_easy_setopt( curl_handle, CURLOPT_WRITEDATA,
|
|
||||||
static_cast< void * >( &source ) );
|
|
||||||
auto res = curl_easy_perform( curl_handle );
|
|
||||||
if ( res != CURLE_OK ) {
|
|
||||||
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror( res )
|
|
||||||
<< std::endl;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
24
network.hpp
24
network.hpp
@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <WinInet.h>
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <WinInet.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
using string = std::wstring;
|
using string = std::wstring;
|
||||||
|
|
||||||
@ -17,21 +18,26 @@ using string = std::string;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Curl {
|
class Request {
|
||||||
public:
|
public:
|
||||||
Curl();
|
Request() = delete;
|
||||||
~Curl();
|
Request( const string &server );
|
||||||
|
~Request();
|
||||||
std::string get( const string &url );
|
std::string get( const string &url );
|
||||||
std::string post( const std::string &url, const std::string &data );
|
std::string post( const string &url, const std::string &data );
|
||||||
void addHeader( const std::string &header );
|
void addHeader( const string &header );
|
||||||
void clearHeader();
|
void clearHeader();
|
||||||
|
bool initSuccessful();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HINTERNET connect = nullptr;
|
HINTERNET _hInternet = nullptr;
|
||||||
|
HINTERNET _hConnect = nullptr;
|
||||||
|
std::wstring _headers = L"";
|
||||||
#else
|
#else
|
||||||
CURL *curl_handle;
|
CURL *_curl_handle = nullptr;
|
||||||
struct curl_slist *chunk = NULL;
|
struct curl_slist *_chunk = nullptr;
|
||||||
|
const string _server;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
81
unix/network.cpp
Normal file
81
unix/network.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include "../network.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
size_t writeCallback( void *contents, size_t size, size_t nmemb,
|
||||||
|
void *target ) {
|
||||||
|
*static_cast< std::string * >( target ) +=
|
||||||
|
std::string( static_cast< char * >( contents ), size * nmemb );
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request::Request( const string &server ) : _server( server ) {
|
||||||
|
curl_global_init( CURL_GLOBAL_ALL );
|
||||||
|
_curl_handle = curl_easy_init();
|
||||||
|
if ( _curl_handle == NULL ) {
|
||||||
|
std::cerr << "ERROR curl_easy_init" << std::endl;
|
||||||
|
}
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_WRITEFUNCTION, writeCallback );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0" );
|
||||||
|
}
|
||||||
|
|
||||||
|
Request::~Request() {
|
||||||
|
curl_easy_cleanup( _curl_handle );
|
||||||
|
curl_slist_free_all( _chunk );
|
||||||
|
curl_global_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanUp( CURL *curl_handle ) {
|
||||||
|
curl_easy_setopt( curl_handle, CURLOPT_POST, 0 );
|
||||||
|
curl_easy_setopt( curl_handle, CURLOPT_POSTFIELDS, "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Request::get( const std::string &url ) {
|
||||||
|
// get rid of garbage
|
||||||
|
cleanUp( _curl_handle );
|
||||||
|
std::string response;
|
||||||
|
response.reserve( 100000 );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_WRITEDATA,
|
||||||
|
static_cast< void * >( &response ) );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_URL, ( _server + url ).c_str() );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_HTTPGET, 1 );
|
||||||
|
auto res = curl_easy_perform( _curl_handle );
|
||||||
|
if ( res != CURLE_OK ) {
|
||||||
|
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror( res )
|
||||||
|
<< std::endl;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Request::post( const std::string &url, const std::string &data ) {
|
||||||
|
std::string response;
|
||||||
|
response.reserve( 100000 );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_URL, ( _server + url ).c_str() );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_POST, 1 );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_POSTFIELDS, data.c_str() );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_WRITEDATA,
|
||||||
|
static_cast< void * >( &response ) );
|
||||||
|
auto res = curl_easy_perform( _curl_handle );
|
||||||
|
if ( res != CURLE_OK ) {
|
||||||
|
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror( res )
|
||||||
|
<< std::endl;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Request::addHeader( const std::string &header ) {
|
||||||
|
_chunk = curl_slist_append( _chunk, header.c_str() );
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_HTTPHEADER, _chunk );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Request::clearHeader() {
|
||||||
|
curl_slist_free_all( _chunk );
|
||||||
|
_chunk = nullptr;
|
||||||
|
curl_easy_setopt( _curl_handle, CURLOPT_HTTPHEADER, _chunk );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Request::initSuccessful() {
|
||||||
|
return _curl_handle != nullptr;
|
||||||
|
}
|
85
windows/network.cpp
Normal file
85
windows/network.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include "../network.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
const wchar_t *acceptTypes[] = { L"text/*", L"application/json", nullptr };
|
||||||
|
|
||||||
|
Request::Request( const string &server ) {
|
||||||
|
// Start connection
|
||||||
|
_hInternet = InternetOpen( L"WinInet/1.0", INTERNET_OPEN_TYPE_PRECONFIG,
|
||||||
|
nullptr, nullptr, 0 );
|
||||||
|
if ( !_hInternet )
|
||||||
|
std::wcerr << "ERROR InternetOpen: " << GetLastError() << std::endl;
|
||||||
|
// connect to server
|
||||||
|
_hConnect = InternetConnect( _hInternet, server.c_str(),
|
||||||
|
INTERNET_DEFAULT_HTTPS_PORT, nullptr, nullptr,
|
||||||
|
INTERNET_SERVICE_HTTP, 0, 0 );
|
||||||
|
if ( !_hConnect )
|
||||||
|
std::wcerr << "ERROR InternetConnect: " << GetLastError() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request::~Request() {
|
||||||
|
if ( _hConnect )
|
||||||
|
InternetCloseHandle( _hConnect );
|
||||||
|
if ( _hInternet )
|
||||||
|
InternetCloseHandle( _hInternet );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sendRequest( HINTERNET hRequest, const std::wstring &headers,
|
||||||
|
const std::string &optional ) {
|
||||||
|
std::string response{};
|
||||||
|
response.reserve( 10000 );
|
||||||
|
|
||||||
|
// have to do a copy because c_str returns const
|
||||||
|
std::unique_ptr< char > opt( new char[optional.length()] );
|
||||||
|
memcpy( opt.get(), optional.c_str(), optional.length() );
|
||||||
|
|
||||||
|
auto requestSent = HttpSendRequest(
|
||||||
|
hRequest, headers.c_str(), headers.length(), opt, optional.length() );
|
||||||
|
|
||||||
|
if ( !requestSent )
|
||||||
|
std::wcerr << "ERROR HttpSendRequest: " << GetLastError() << std::endl;
|
||||||
|
|
||||||
|
char dataReceived[4096];
|
||||||
|
unsigned long numberOfBytesRead = 0;
|
||||||
|
// read while InternetReadFile returns true and reads more than 0 bytes
|
||||||
|
while (
|
||||||
|
InternetReadFile( hRequest, dataReceived, 4096, &numberOfBytesRead ) &&
|
||||||
|
numberOfBytesRead ) {
|
||||||
|
response.append( dataReceived, numberOfBytesRead );
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Request::get( const std::wstring &url ) {
|
||||||
|
HINTERNET hRequest =
|
||||||
|
HttpOpenRequest( _hConnect, L"GET", url.c_str(), nullptr, nullptr,
|
||||||
|
acceptTypes, INTERNET_FLAG_SECURE, 0 );
|
||||||
|
if ( !hRequest )
|
||||||
|
std::wcerr << "ERROR HttpOpenRequest: " << GetLastError() << std::endl;
|
||||||
|
|
||||||
|
return sendRequest( hRequest, _headers, "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Request::post( const std::wstring &url, const std::string &data ) {
|
||||||
|
HINTERNET hRequest =
|
||||||
|
HttpOpenRequest( _hConnect, L"POST", url.c_str(), nullptr, nullptr,
|
||||||
|
acceptTypes, INTERNET_FLAG_SECURE, 0 );
|
||||||
|
if ( !hRequest )
|
||||||
|
std::wcerr << "ERROR HttpOpenRequest: " << GetLastError() << std::endl;
|
||||||
|
|
||||||
|
return sendRequest( hRequest, _headers, data );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Request::addHeader( const std::wstring &header ) {
|
||||||
|
_headers += header + L"\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Request::clearHeader() {
|
||||||
|
_headers = L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Request::initSuccessful() {
|
||||||
|
return _hInternet != nullptr && _hConnect != nullptr;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user