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
|
||||
|
||||
#include <WinInet.h>
|
||||
#include <Windows.h>
|
||||
#include <WinInet.h>
|
||||
#include <string>
|
||||
|
||||
using string = std::wstring;
|
||||
|
||||
@ -17,21 +18,26 @@ using string = std::string;
|
||||
|
||||
#endif
|
||||
|
||||
class Curl {
|
||||
class Request {
|
||||
public:
|
||||
Curl();
|
||||
~Curl();
|
||||
Request() = delete;
|
||||
Request( const string &server );
|
||||
~Request();
|
||||
std::string get( const string &url );
|
||||
std::string post( const std::string &url, const std::string &data );
|
||||
void addHeader( const std::string &header );
|
||||
std::string post( const string &url, const std::string &data );
|
||||
void addHeader( const string &header );
|
||||
void clearHeader();
|
||||
bool initSuccessful();
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
HINTERNET connect = nullptr;
|
||||
HINTERNET _hInternet = nullptr;
|
||||
HINTERNET _hConnect = nullptr;
|
||||
std::wstring _headers = L"";
|
||||
#else
|
||||
CURL *curl_handle;
|
||||
struct curl_slist *chunk = NULL;
|
||||
CURL *_curl_handle = nullptr;
|
||||
struct curl_slist *_chunk = nullptr;
|
||||
const string _server;
|
||||
#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