#pragma once
#include "ofConstants.h"
#include "ofEvents.h"
#include "ofFileUtils.h"
#include <map>
class ofHttpResponse;
/// \class ofHttpRequest
/// \brief an HTTP GET or POST request
class ofHttpRequest{
public:
ofHttpRequest();
ofHttpRequest(const std::string& url, const std::string& name,bool saveTo=false);
std::string url; ///< request url
std::string name; ///< optional name key for sorting
bool saveTo; ///< save to a file once the request is finised?
std::map<std::string,std::string> headers; ///< HTTP header keys & values
std::string body; ///< POST body data
std::string contentType; ///< POST data mime type
std::function<void(const ofHttpResponse&)> done;
size_t timeoutSeconds = 0;
/// \return the unique id for this request
int getId() const;
OF_DEPRECATED_MSG("Use getId().", int getID());
/// HTTP request type
enum Method{
GET, ///< request data from a specified resource (via url)
POST ///< submit data to be processed to a specified resource (via url)
} method;
private:
int id; ///< unique id for this request
static int nextID; ///< global for computing next unique id
};
/// \class ofHttpResponse
/// \brief an HTTP response to a GET or POST request
class ofHttpResponse{
public:
ofHttpResponse();
ofHttpResponse(const ofHttpRequest& request, const ofBuffer& data, int status, const std::string& error);
ofHttpResponse(const ofHttpRequest& request, int status, const std::string& error);
operator ofBuffer&();
ofHttpRequest request; ///< matching HTTP request for this response
ofBuffer data; ///< response raw data
int status; ///< HTTP response status (200: OK, 404: Not Found, etc)
std::string error; ///< HTTP error string, if any (OK, Not Found, etc)
};
/// \brief make an HTTP GET request
/// blocks until a response is returned or the request times out
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \returns HTTP response
ofHttpResponse ofLoadURL(const std::string& url);
/// \brief make an asynchronous HTTP GET request
/// will not block, placed in a queue and run using a background thread
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param name optional key to use when sorting requests
/// \return unique id for the active HTTP request
int ofLoadURLAsync(const std::string& url, const std::string& name=""); // returns id
/// \brief make an HTTP GET request and save the response data to a file
/// blocks until a response is returned or the request times out
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param path file path to save to
/// \return HTTP response on success or failure
ofHttpResponse ofSaveURLTo(const std::string& url, const std::filesystem::path& path);
/// make an asynchronous HTTP request for a url and save the response to a file at path
/// \returns unique request id for the active HTTP request
/// \brief make an asynchronous HTTP request and save the response data to a file
/// will not block, placed in a queue and run using a background thread
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param path file path to save to
/// \returns unique id for the active HTTP request
int ofSaveURLAsync(const std::string& url, const std::filesystem::path& path);
/// \brief remove an active HTTP request from the queue
/// \param id HTTP request id
void ofRemoveURLRequest(int id);
/// \brief remove all active HTTP requests from the queue
void ofRemoveAllURLRequests();
/// \brief stop & remove all active and waiting HTTP requests
void ofStopURLLoader();
ofEvent<ofHttpResponse> & ofURLResponseEvent();
template<class T>
void ofRegisterURLNotification(T * obj){
ofAddListener(ofURLResponseEvent(),obj,&T::urlResponse);
}
template<class T>
void ofUnregisterURLNotification(T * obj){
ofRemoveListener(ofURLResponseEvent(),obj,&T::urlResponse);
}
class ofBaseURLFileLoader;
/// \class ofURLFileLoader
/// \brief loads a file from a URL using an HTTP request
class ofURLFileLoader {
public:
ofURLFileLoader();
/// \brief make an HTTP request
/// blocks until a response is returned or the request times out
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \return HTTP response on success or failure
ofHttpResponse get(const std::string& url);
/// \brief make an asynchronous HTTP request
/// will not block, placed in a queue and run using a background thread
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param name optional key to use when sorting requests
/// \return unique id for the active HTTP request
int getAsync(const std::string& url, const std::string& name="");
/// \brief make an HTTP request and save the response data to a file
/// blocks until a response is returned or the request times out
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param path file path to save to
/// \return HTTP response on success or failure
ofHttpResponse saveTo(const std::string& url, const std::filesystem::path& path);
/// \brief make an asynchronous HTTP request and save the response data to a file
/// will not block, placed in a queue and run using a background thread
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param path file path to save to
/// \returns unique id for the active HTTP request
int saveAsync(const std::string& url, const std::filesystem::path& path);
/// \brief remove an active HTTP request from the queue
/// \param id HTTP request id
void remove(int id);
/// \brief clear all active HTTP requests from the queue
void clear();
/// \brief stop & remove all active and waiting HTTP requests
void stop();
// \brief low level HTTP request implementation
/// blocks until a response is returned or the request times out
/// \return HTTP response on success or failure
ofHttpResponse handleRequest(const ofHttpRequest & request);
// \brief low level HTTP request implementation
/// this is a non-blocking version of handleRequest that will return a response in the urlResponse callback
/// \return unique id of the active HTTP request
int handleRequestAsync(const ofHttpRequest& request);
private:
std::shared_ptr<ofBaseURLFileLoader> impl;
};
/// \class ofBaseURLFileLoader
/// \brief loads a file from a URL using an HTTP request
class ofBaseURLFileLoader{
public:
virtual ~ofBaseURLFileLoader(){};
/// \brief make an HTTP request
/// blocks until a response is returned or the request times out
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \return HTTP response on success or failure
virtual ofHttpResponse get(const std::string& url)=0;
/// \brief make an asynchronous HTTP request
/// will not block, placed in a queue and run using a background thread
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param name optional key to use when sorting requests
/// \return unique id for the active HTTP request
virtual int getAsync(const std::string& url, const std::string& name="")=0;
/// \brief make an HTTP request and save the response data to a file
/// blocks until a response is returned or the request times out
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param path file path to save to
/// \return HTTP response on success or failure
virtual ofHttpResponse saveTo(const std::string& url, const std::filesystem::path& path)=0;
/// \brief make an asynchronous HTTP request and save the response data to a file
/// will not block, placed in a queue and run using a background thread
/// \param url HTTP url to request, ie. "http://somewebsite.com/someapi/someimage.jpg"
/// \param path file path to save to
/// \returns unique id for the active HTTP request
virtual int saveAsync(const std::string& url, const std::filesystem::path& path)=0;
/// \brief remove an active HTTP request from the queue
/// \param unique HTTP request id
virtual void remove(int id)=0;
/// \brief clear all active HTTP requests from the queue
virtual void clear()=0;
/// \brief stop & remove all active and waiting HTTP requests
virtual void stop()=0;
/// \brief low level HTTP request implementation
/// blocks until a response is returned or the request times out
/// \return HTTP response on success or failure
virtual ofHttpResponse handleRequest(const ofHttpRequest & request) = 0;
virtual int handleRequestAsync(const ofHttpRequest& request)=0; // returns id
};
Comments