2013-11-06 10:03:20 +02:00
|
|
|
#ifndef _library__httpreq__hpp__included__
|
|
|
|
#define _library__httpreq__hpp__included__
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
2014-03-23 09:45:42 +02:00
|
|
|
#include "threads.hpp"
|
2013-11-06 10:03:20 +02:00
|
|
|
|
|
|
|
class http_request
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Input handler.
|
|
|
|
*/
|
|
|
|
class input_handler
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
input_handler() { canceled = false; }
|
|
|
|
virtual ~input_handler();
|
|
|
|
static size_t read_fn(char* ptr, size_t size, size_t nmemb, void* userdata);
|
|
|
|
/**
|
|
|
|
* Get length of input.
|
|
|
|
*/
|
|
|
|
virtual uint64_t get_length() = 0;
|
|
|
|
/**
|
|
|
|
* Read block of input.
|
|
|
|
*/
|
|
|
|
virtual size_t read(char* target, size_t maxread) = 0;
|
|
|
|
/**
|
|
|
|
* Cancel.
|
|
|
|
*/
|
|
|
|
void cancel() { canceled = true; }
|
|
|
|
/**
|
|
|
|
* Cancel flag.
|
|
|
|
*/
|
|
|
|
volatile bool canceled;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* NULL input handler.
|
|
|
|
*/
|
|
|
|
class null_input_handler : public input_handler
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
~null_input_handler();
|
|
|
|
uint64_t get_length();
|
|
|
|
size_t read(char* target, size_t maxread);
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Output handler.
|
|
|
|
*/
|
|
|
|
class output_handler
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
output_handler() { canceled = false; }
|
|
|
|
virtual ~output_handler();
|
|
|
|
static size_t write_fn(char* ptr, size_t size, size_t nmemb, void* userdata);
|
|
|
|
static size_t header_fn(void* ptr, size_t size, size_t nmemb, void* userdata);
|
|
|
|
/**
|
|
|
|
* Sink header.
|
|
|
|
*/
|
|
|
|
virtual void header(const std::string& name, const std::string& cotent) = 0;
|
|
|
|
/**
|
|
|
|
* Sink data.
|
|
|
|
*/
|
|
|
|
virtual void write(const char* source, size_t srcsize) = 0;
|
|
|
|
/**
|
|
|
|
* Cancel.
|
|
|
|
*/
|
|
|
|
void cancel() { canceled = true; }
|
|
|
|
/**
|
|
|
|
* Cancel flag.
|
|
|
|
*/
|
|
|
|
volatile bool canceled;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Obtain WWW-Authenticate responses.
|
|
|
|
*/
|
|
|
|
class www_authenticate_extractor : public output_handler
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
www_authenticate_extractor(std::function<void(const std::string& value)> _callback);
|
|
|
|
~www_authenticate_extractor();
|
|
|
|
void header(const std::string& name, const std::string& cotent);
|
|
|
|
void write(const char* source, size_t srcsize);
|
|
|
|
private:
|
|
|
|
std::function<void(const std::string& value)> callback;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Create a new request instance.
|
|
|
|
*/
|
|
|
|
http_request(const std::string& verb, const std::string& url);
|
|
|
|
/**
|
|
|
|
* Destructor.
|
|
|
|
*/
|
|
|
|
~http_request();
|
|
|
|
/**
|
|
|
|
* Set the authorization header to use.
|
|
|
|
*/
|
|
|
|
void set_authorization(const std::string& hdr)
|
|
|
|
{
|
|
|
|
authorization = hdr;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Do the transfer.
|
|
|
|
*
|
|
|
|
* Input handler is only used if verb is PUT or POST. It may be NULL for GET/HEAD.
|
|
|
|
*/
|
|
|
|
void do_transfer(input_handler* inhandler, output_handler* outhandler);
|
|
|
|
/**
|
|
|
|
* Get status of transfer. Safe to call from another thread while do_transfer is in progress.
|
|
|
|
*/
|
|
|
|
void get_xfer_status(int64_t& dnow, int64_t& dtotal, int64_t& unow, int64_t& utotal);
|
|
|
|
/**
|
|
|
|
* Do global initialization.
|
|
|
|
*/
|
|
|
|
static void global_init();
|
|
|
|
/**
|
|
|
|
* Get final code.
|
|
|
|
*/
|
|
|
|
long get_http_code();
|
|
|
|
private:
|
|
|
|
static int progress(void* userdata, double dltotal, double dlnow, double ultotal, double ulnow);
|
|
|
|
int _progress(double dltotal, double dlnow, double ultotal, double ulnow);
|
|
|
|
http_request(const http_request&);
|
|
|
|
http_request& operator=(const http_request&);
|
|
|
|
void* handle;
|
|
|
|
std::string authorization;
|
|
|
|
bool has_body;
|
|
|
|
double dltotal, dlnow, ultotal, ulnow;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* HTTP asynchronous request structure.
|
|
|
|
*/
|
|
|
|
struct http_async_request
|
|
|
|
{
|
|
|
|
http_async_request();
|
|
|
|
http_request::input_handler* ihandler; //Input handler (INPUT).
|
|
|
|
http_request::output_handler* ohandler; //Output handler (INPUT).
|
|
|
|
std::string verb; //HTTP verb (INPUT)
|
|
|
|
std::string url; //URL to access (INPUT)
|
|
|
|
std::string authorization; //Authorization to use (INPUT)
|
|
|
|
int64_t final_dl; //Final amount downloaded (OUTPUT).
|
|
|
|
int64_t final_ul; //Final amound uploaded (OUTPUT).
|
|
|
|
std::string errormsg; //Final error (OUTPUT).
|
|
|
|
long http_code; //HTTP error code (OUTPUT).
|
|
|
|
volatile bool finished; //Finished flag (semi-transient).
|
2014-03-23 09:45:42 +02:00
|
|
|
threads::cv finished_cond; //This condition variable is fired on finish.
|
2013-11-06 10:03:20 +02:00
|
|
|
http_request* req; //The HTTP request object (TRANSIENT).
|
2014-03-23 09:45:42 +02:00
|
|
|
threads::lock m; //Lock protecting the object (TRANSIENT).
|
2013-11-06 10:03:20 +02:00
|
|
|
void get_xfer_status(int64_t& dnow, int64_t& dtotal, int64_t& unow, int64_t& utotal);
|
|
|
|
void lauch_async(); //Lauch asynchronous request.
|
|
|
|
void cancel(); //Cancel request in flight.
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Property upload.
|
|
|
|
*/
|
|
|
|
struct property_upload_request : public http_request::input_handler
|
|
|
|
{
|
|
|
|
//Inherited methods.
|
|
|
|
property_upload_request();
|
|
|
|
~property_upload_request();
|
|
|
|
uint64_t get_length();
|
|
|
|
size_t read(char* target, size_t maxread);
|
|
|
|
void rewind();
|
|
|
|
/**
|
|
|
|
* Data to upload.
|
|
|
|
*/
|
|
|
|
std::map<std::string, std::string> data;
|
|
|
|
private:
|
|
|
|
unsigned state;
|
|
|
|
std::map<std::string, std::string>::iterator itr;
|
|
|
|
size_t sent;
|
|
|
|
void str_helper(const std::string& str, char*& target, size_t& maxread, size_t& x, unsigned next);
|
|
|
|
void chr_helper(char ch, char*& target, size_t& maxread, size_t& x, unsigned next);
|
|
|
|
void len_helper(size_t len, char*& target, size_t& maxread, size_t& x, unsigned next);
|
|
|
|
};
|
|
|
|
|
|
|
|
//Lowercase a string.
|
|
|
|
std::string http_strlower(const std::string& name);
|
|
|
|
|
|
|
|
#endif
|