mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-29 09:36:29 +03:00
More detailed request progress information.
Minor optimization. --HG-- branch : dev
This commit is contained in:
@@ -26,188 +26,6 @@ namespace EE { namespace Network {
|
||||
/** @brief A HTTP client */
|
||||
class EE_API Http : NonCopyable {
|
||||
public :
|
||||
/** @brief Define a HTTP request */
|
||||
class EE_API Request {
|
||||
public :
|
||||
/** @brief Enumerate the available HTTP methods for a request */
|
||||
enum Method {
|
||||
Get, ///< The GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
|
||||
Head, ///< Request a page's header only
|
||||
Post, ///< The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server.
|
||||
Put, ///< The PUT method replaces all current representations of the target resource with the request payload.
|
||||
Delete, ///< The DELETE method deletes the specified resource.
|
||||
Options, ///< The OPTIONS method is used to describe the communication options for the target resource.
|
||||
Patch, ///< The PATCH method is used to apply partial modifications to a resource.
|
||||
Connect ///< The CONNECT method starts two-way communications with the requested resource. It can be used to open a tunnel.
|
||||
};
|
||||
|
||||
/** @return Method from a method name string. */
|
||||
static Method methodFromString( std::string methodString );
|
||||
|
||||
/** @return The method string from a method */
|
||||
static std::string methodToString( const Method& method );
|
||||
|
||||
/** @brief Default constructor
|
||||
** This constructor creates a GET request, with the root
|
||||
** URI ("/") and an empty body.
|
||||
** @param uri Target URI
|
||||
** @param method Method to use for the request
|
||||
** @param body Content of the request's body
|
||||
** @param validateCertificate Enables certificate validation for https request
|
||||
** @param validateHostname Enables hostname validation for https request
|
||||
** @param followRedirect Allow follor redirects to the request.
|
||||
** @param compressedResponse Set if the requested response should be compressed ( if available )
|
||||
*/
|
||||
Request(const std::string& uri = "/", Method method = Get, const std::string& body = "", bool validateCertificate = true, bool validateHostname = true, bool followRedirect = true, bool compressedResponse = false);
|
||||
|
||||
/** @brief Set the value of a field
|
||||
** The field is created if it doesn't exist. The name of
|
||||
** the field is case insensitive.
|
||||
** By default, a request doesn't contain any field (but the
|
||||
** mandatory fields are added later by the HTTP client when
|
||||
** sending the request).
|
||||
** @param field Name of the field to set
|
||||
** @param value Value of the field */
|
||||
void setField(const std::string& field, const std::string& value);
|
||||
|
||||
/** @brief Check if the request defines a field
|
||||
** This function uses case-insensitive comparisons.
|
||||
** @param field Name of the field to test
|
||||
** @return True if the field exists, false otherwise */
|
||||
bool hasField(const std::string& field) const;
|
||||
|
||||
/** @brief Get the value of a field
|
||||
** If the field @a field is not found in the response header,
|
||||
** the empty string is returned. This function uses
|
||||
** case-insensitive comparisons.
|
||||
** @param field Name of the field to get
|
||||
** @return Value of the field, or empty string if not found */
|
||||
const std::string& getField(const std::string& field) const;
|
||||
|
||||
/** @brief Set the request method
|
||||
** See the Method enumeration for a complete list of all
|
||||
** the availale methods.
|
||||
** The method is Http::Request::Get by default.
|
||||
** @param method Method to use for the request */
|
||||
void setMethod(Method method);
|
||||
|
||||
/** @brief Set the requested URI
|
||||
** The URI is the resource (usually a web page or a file)
|
||||
** that you want to get or post.
|
||||
** The URI is "/" (the root page) by default.
|
||||
** @param uri URI to request, relative to the host */
|
||||
void setUri(const std::string& uri);
|
||||
|
||||
/** @brief Set the HTTP version for the request
|
||||
** The HTTP version is 1.0 by default.
|
||||
** @param major Major HTTP version number
|
||||
** @param minor Minor HTTP version number */
|
||||
void setHttpVersion(unsigned int major, unsigned int minor);
|
||||
|
||||
/** @brief Set the body of the request
|
||||
** The body of a request is optional and only makes sense
|
||||
** for POST requests. It is ignored for all other methods.
|
||||
** The body is empty by default.
|
||||
** @param body Content of the body */
|
||||
void setBody(const std::string& body);
|
||||
|
||||
/** @return The request Uri */
|
||||
const std::string& getUri() const;
|
||||
|
||||
/** @return If SSL certificate validation is enabled */
|
||||
const bool& getValidateCertificate() const;
|
||||
|
||||
/** Enable/disable SSL certificate validation */
|
||||
void setValidateCertificate( bool enable );
|
||||
|
||||
/** @return If SSL hostname validation is enabled */
|
||||
const bool& getValidateHostname() const;
|
||||
|
||||
/** Enable/disable SSL hostname validation */
|
||||
void setValidateHostname( bool enable );
|
||||
|
||||
/** @return If requests follow redirects */
|
||||
const bool& getFollowRedirect() const;
|
||||
|
||||
/** Enables/Disables follow redirects */
|
||||
void setFollowRedirect( bool follow );
|
||||
|
||||
/** @return The maximun number of redirects allowd if follow redirect is enabled. */
|
||||
const unsigned int& getMaxRedirects() const;
|
||||
|
||||
/** Set the maximun number of redirects allowed if follow redirect is enabled. */
|
||||
void setMaxRedirects( unsigned int maxRedirects );
|
||||
|
||||
/** Definition of the current progress callback
|
||||
* @param http The http client
|
||||
* @param request The http request
|
||||
* @param totalBytes The total bytes of the document / files ( only available if Content-Length is returned, otherwise is 0 )
|
||||
* @param currentBytes Current received total bytes
|
||||
* @return True if continue the request, false will cancel the current request.
|
||||
*/
|
||||
typedef std::function<bool( const Http& http, const Http::Request& request, std::size_t totalBytes, std::size_t currentBytes )> ProgressCallback;
|
||||
|
||||
/** Sets a progress callback */
|
||||
void setProgressCallback( const ProgressCallback& progressCallback );
|
||||
|
||||
/** Get the progress callback */
|
||||
const ProgressCallback& getProgressCallback() const;
|
||||
|
||||
/** Cancels the current request if being processed */
|
||||
void cancel();
|
||||
|
||||
/** @return True if the current request was cancelled */
|
||||
const bool& isCancelled() const;
|
||||
|
||||
/** @return If requests a compressed response */
|
||||
const bool& isCompressedResponse() const;
|
||||
|
||||
/** Set to request a compressed response from the server
|
||||
** The returned response will be automatically decompressed
|
||||
** by the client.
|
||||
*/
|
||||
void setCompressedResponse(const bool& compressedResponse);
|
||||
|
||||
/** Resumes download if a file is already present */
|
||||
void setContinue(const bool& resume);
|
||||
|
||||
/** @return If must continue a download previously started. */
|
||||
const bool& isContinue() const;
|
||||
|
||||
private:
|
||||
friend class Http;
|
||||
|
||||
/** @brief Prepare the final request to send to the server
|
||||
** This is used internally by Http before sending the
|
||||
** request to the web server.
|
||||
** @return String containing the request, ready to be sent */
|
||||
std::string prepare(const Http& http) const;
|
||||
|
||||
/** Prepares a http tunnel request */
|
||||
std::string prepareTunnel(const Http& http);
|
||||
|
||||
// Types
|
||||
typedef std::map<std::string, std::string> FieldTable;
|
||||
|
||||
// Member data
|
||||
FieldTable mFields; ///< Fields of the header associated to their value
|
||||
Method mMethod; ///< Method to use for the request
|
||||
std::string mUri; ///< Target URI of the request
|
||||
unsigned int mMajorVersion; ///< Major HTTP version
|
||||
unsigned int mMinorVersion; ///< Minor HTTP version
|
||||
std::string mBody; ///< Body of the request
|
||||
bool mValidateCertificate; ///< Validates the SSL certificate in case of an HTTPS request
|
||||
bool mValidateHostname; ///< Validates the hostname in case of an HTTPS request
|
||||
bool mFollowRedirect; ///< Follows redirect response codes
|
||||
bool mCompressedResponse; ///< Request comrpessed response
|
||||
bool mContinue; ///< Resume download
|
||||
mutable bool mCancel; ///< Cancel state of current request
|
||||
ProgressCallback mProgressCallback; ///< Progress callback
|
||||
unsigned int mMaxRedirections; ///< Maximun number of redirections allowed
|
||||
mutable unsigned int mRedirectionCount; ///< Number of redirections followed by the request
|
||||
URI mProxy; ///< Proxy information
|
||||
};
|
||||
|
||||
/** @brief Define a HTTP response */
|
||||
class EE_API Response {
|
||||
public:
|
||||
@@ -323,6 +141,197 @@ class EE_API Http : NonCopyable {
|
||||
std::string mBody; ///< Body of the response
|
||||
};
|
||||
|
||||
/** @brief Define a HTTP request */
|
||||
class EE_API Request {
|
||||
public :
|
||||
/** @brief Enumerate the available HTTP methods for a request */
|
||||
enum Method {
|
||||
Get, ///< The GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
|
||||
Head, ///< Request a page's header only
|
||||
Post, ///< The POST method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server.
|
||||
Put, ///< The PUT method replaces all current representations of the target resource with the request payload.
|
||||
Delete, ///< The DELETE method deletes the specified resource.
|
||||
Options, ///< The OPTIONS method is used to describe the communication options for the target resource.
|
||||
Patch, ///< The PATCH method is used to apply partial modifications to a resource.
|
||||
Connect ///< The CONNECT method starts two-way communications with the requested resource. It can be used to open a tunnel.
|
||||
};
|
||||
|
||||
/** @brief Enumerate the available states for a request */
|
||||
enum Status {
|
||||
Connected, ///< Connected to server.
|
||||
Sent, ///< Request sent to the server.
|
||||
HeaderReceived, ///< Header received.
|
||||
ContentReceived ///< Content received.
|
||||
};
|
||||
|
||||
/** @return Method from a method name string. */
|
||||
static Method methodFromString( std::string methodString );
|
||||
|
||||
/** @return The method string from a method */
|
||||
static std::string methodToString( const Method& method );
|
||||
|
||||
/** @brief Default constructor
|
||||
** This constructor creates a GET request, with the root
|
||||
** URI ("/") and an empty body.
|
||||
** @param uri Target URI
|
||||
** @param method Method to use for the request
|
||||
** @param body Content of the request's body
|
||||
** @param validateCertificate Enables certificate validation for https request
|
||||
** @param validateHostname Enables hostname validation for https request
|
||||
** @param followRedirect Allow follor redirects to the request.
|
||||
** @param compressedResponse Set if the requested response should be compressed ( if available )
|
||||
*/
|
||||
Request(const std::string& uri = "/", Method method = Get, const std::string& body = "", bool validateCertificate = true, bool validateHostname = true, bool followRedirect = true, bool compressedResponse = false);
|
||||
|
||||
/** @brief Set the value of a field
|
||||
** The field is created if it doesn't exist. The name of
|
||||
** the field is case insensitive.
|
||||
** By default, a request doesn't contain any field (but the
|
||||
** mandatory fields are added later by the HTTP client when
|
||||
** sending the request).
|
||||
** @param field Name of the field to set
|
||||
** @param value Value of the field */
|
||||
void setField(const std::string& field, const std::string& value);
|
||||
|
||||
/** @brief Check if the request defines a field
|
||||
** This function uses case-insensitive comparisons.
|
||||
** @param field Name of the field to test
|
||||
** @return True if the field exists, false otherwise */
|
||||
bool hasField(const std::string& field) const;
|
||||
|
||||
/** @brief Get the value of a field
|
||||
** If the field @a field is not found in the response header,
|
||||
** the empty string is returned. This function uses
|
||||
** case-insensitive comparisons.
|
||||
** @param field Name of the field to get
|
||||
** @return Value of the field, or empty string if not found */
|
||||
const std::string& getField(const std::string& field) const;
|
||||
|
||||
/** @brief Set the request method
|
||||
** See the Method enumeration for a complete list of all
|
||||
** the availale methods.
|
||||
** The method is Http::Request::Get by default.
|
||||
** @param method Method to use for the request */
|
||||
void setMethod(Method method);
|
||||
|
||||
/** @brief Set the requested URI
|
||||
** The URI is the resource (usually a web page or a file)
|
||||
** that you want to get or post.
|
||||
** The URI is "/" (the root page) by default.
|
||||
** @param uri URI to request, relative to the host */
|
||||
void setUri(const std::string& uri);
|
||||
|
||||
/** @brief Set the HTTP version for the request
|
||||
** The HTTP version is 1.0 by default.
|
||||
** @param major Major HTTP version number
|
||||
** @param minor Minor HTTP version number */
|
||||
void setHttpVersion(unsigned int major, unsigned int minor);
|
||||
|
||||
/** @brief Set the body of the request
|
||||
** The body of a request is optional and only makes sense
|
||||
** for POST requests. It is ignored for all other methods.
|
||||
** The body is empty by default.
|
||||
** @param body Content of the body */
|
||||
void setBody(const std::string& body);
|
||||
|
||||
/** @return The request Uri */
|
||||
const std::string& getUri() const;
|
||||
|
||||
/** @return If SSL certificate validation is enabled */
|
||||
const bool& getValidateCertificate() const;
|
||||
|
||||
/** Enable/disable SSL certificate validation */
|
||||
void setValidateCertificate( bool enable );
|
||||
|
||||
/** @return If SSL hostname validation is enabled */
|
||||
const bool& getValidateHostname() const;
|
||||
|
||||
/** Enable/disable SSL hostname validation */
|
||||
void setValidateHostname( bool enable );
|
||||
|
||||
/** @return If requests follow redirects */
|
||||
const bool& getFollowRedirect() const;
|
||||
|
||||
/** Enables/Disables follow redirects */
|
||||
void setFollowRedirect( bool follow );
|
||||
|
||||
/** @return The maximun number of redirects allowd if follow redirect is enabled. */
|
||||
const unsigned int& getMaxRedirects() const;
|
||||
|
||||
/** Set the maximun number of redirects allowed if follow redirect is enabled. */
|
||||
void setMaxRedirects( unsigned int maxRedirects );
|
||||
|
||||
/** Definition of the current progress callback
|
||||
* @param http The http client
|
||||
* @param request The http request
|
||||
* @param status The status of the progress event
|
||||
* @param totalBytes The total bytes of the document / files ( only available if Content-Length is returned, otherwise is 0 )
|
||||
* @param currentBytes Current received total bytes
|
||||
* @return True if continue the request, false will cancel the current request.
|
||||
*/
|
||||
typedef std::function<bool( const Http& http, const Http::Request& request, const Http::Response& response, const Status& status, std::size_t totalBytes, std::size_t currentBytes )> ProgressCallback;
|
||||
|
||||
/** Sets a progress callback */
|
||||
void setProgressCallback( const ProgressCallback& progressCallback );
|
||||
|
||||
/** Get the progress callback */
|
||||
const ProgressCallback& getProgressCallback() const;
|
||||
|
||||
/** Cancels the current request if being processed */
|
||||
void cancel();
|
||||
|
||||
/** @return True if the current request was cancelled */
|
||||
const bool& isCancelled() const;
|
||||
|
||||
/** @return If requests a compressed response */
|
||||
const bool& isCompressedResponse() const;
|
||||
|
||||
/** Set to request a compressed response from the server
|
||||
** The returned response will be automatically decompressed
|
||||
** by the client.
|
||||
*/
|
||||
void setCompressedResponse(const bool& compressedResponse);
|
||||
|
||||
/** Resumes download if a file is already present */
|
||||
void setContinue(const bool& resume);
|
||||
|
||||
/** @return If must continue a download previously started. */
|
||||
const bool& isContinue() const;
|
||||
|
||||
private:
|
||||
friend class Http;
|
||||
|
||||
/** @brief Prepare the final request to send to the server
|
||||
** This is used internally by Http before sending the
|
||||
** request to the web server.
|
||||
** @return String containing the request, ready to be sent */
|
||||
std::string prepare(const Http& http) const;
|
||||
|
||||
/** Prepares a http tunnel request */
|
||||
std::string prepareTunnel(const Http& http);
|
||||
|
||||
// Types
|
||||
typedef std::map<std::string, std::string> FieldTable;
|
||||
|
||||
// Member data
|
||||
FieldTable mFields; ///< Fields of the header associated to their value
|
||||
Method mMethod; ///< Method to use for the request
|
||||
std::string mUri; ///< Target URI of the request
|
||||
unsigned int mMajorVersion; ///< Major HTTP version
|
||||
unsigned int mMinorVersion; ///< Minor HTTP version
|
||||
std::string mBody; ///< Body of the request
|
||||
bool mValidateCertificate; ///< Validates the SSL certificate in case of an HTTPS request
|
||||
bool mValidateHostname; ///< Validates the hostname in case of an HTTPS request
|
||||
bool mFollowRedirect; ///< Follows redirect response codes
|
||||
bool mCompressedResponse; ///< Request comrpessed response
|
||||
bool mContinue; ///< Resume download
|
||||
mutable bool mCancel; ///< Cancel state of current request
|
||||
ProgressCallback mProgressCallback; ///< Progress callback
|
||||
unsigned int mMaxRedirections; ///< Maximun number of redirections allowed
|
||||
mutable unsigned int mRedirectionCount; ///< Number of redirections followed by the request
|
||||
URI mProxy; ///< Proxy information
|
||||
};
|
||||
|
||||
/** @brief Default constructor */
|
||||
Http();
|
||||
|
||||
|
||||
@@ -491,10 +491,16 @@ void Http::setHost(const std::string& host, unsigned short port, bool useSSL, UR
|
||||
Http::Response Http::sendRequest(const Http::Request& request, Time timeout) {
|
||||
IOStreamString stream;
|
||||
Response response = downloadRequest( request, stream, timeout );
|
||||
response.mBody = stream.getStream();
|
||||
response.mBody = std::move(stream.getStream());
|
||||
return response;
|
||||
}
|
||||
|
||||
static bool sendProgress( const Http& http, const Http::Request& request, const Http::Response& response, const Http::Request::Status& status, const std::size_t& totalBytes, const std::size_t& currentBytes ) {
|
||||
if ( request.getProgressCallback() )
|
||||
return request.getProgressCallback()( http, request, response, status, totalBytes, currentBytes );
|
||||
return true;
|
||||
}
|
||||
|
||||
Http::Response Http::downloadRequest(const Http::Request& request, IOStream& writeTo, Time timeout) {
|
||||
if ( 0 == mHost.toInteger() ) {
|
||||
return Response();
|
||||
@@ -549,6 +555,11 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
mConnection->setConnected(true);
|
||||
}
|
||||
}
|
||||
|
||||
if ( mConnection->isConnected() && !sendProgress( *this, request, received, Request::Connected, 0, 0 ) ) {
|
||||
mConnection->disconnect();
|
||||
return received;
|
||||
}
|
||||
}
|
||||
|
||||
// Connect the socket to the host
|
||||
@@ -627,6 +638,10 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
|
||||
// Send it through the socket
|
||||
if (mConnection->getSocket()->send(requestStr.c_str(), requestStr.size()) == Socket::Done) {
|
||||
if ( !sendProgress( *this, request, received, Request::Sent, 0, 0 ) ) {
|
||||
request.mCancel = true;
|
||||
}
|
||||
|
||||
// Wait for the server's response
|
||||
std::size_t currentTotalBytes = 0;
|
||||
std::size_t len = 0;
|
||||
@@ -739,6 +754,10 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
}
|
||||
}
|
||||
|
||||
if ( !sendProgress( *this, request, received, Request::HeaderReceived, contentLength, 0 ) ) {
|
||||
request.mCancel = true;
|
||||
}
|
||||
|
||||
// Move the readBuffer to the starting point
|
||||
// of the file buffer
|
||||
if ( len > 0 ) {
|
||||
@@ -764,11 +783,9 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
if ( readed > 0 )
|
||||
bufferStream->write( readBuffer, readed );
|
||||
|
||||
if ( request.getProgressCallback() ) {
|
||||
if ( !request.getProgressCallback()( *this, request, contentLength, currentTotalBytes ) ) {
|
||||
request.mCancel = true;
|
||||
break;
|
||||
}
|
||||
if ( !sendProgress( *this, request, received, Request::ContentReceived, contentLength, currentTotalBytes ) ) {
|
||||
request.mCancel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If the response is compressed and the stream ended means that we received
|
||||
|
||||
@@ -115,9 +115,11 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
|
||||
// If progress requested print a progress on screen
|
||||
if ( progress ) {
|
||||
request.setProgressCallback( []( const Http&, const Http::Request&, size_t totalBytes, size_t currentBytes ) {
|
||||
std::cout << "\rDownloaded " << FileSystem::sizeToString( currentBytes ).c_str() << " of " << FileSystem::sizeToString( totalBytes ).c_str() << " ";
|
||||
std::cout << std::flush;
|
||||
request.setProgressCallback( []( const Http&, const Http::Request&, const Http::Response&, const Http::Request::Status& status, size_t totalBytes, size_t currentBytes ) {
|
||||
if ( status == Http::Request::ContentReceived ) {
|
||||
std::cout << "\rDownloaded " << FileSystem::sizeToString( currentBytes ).c_str() << " of " << FileSystem::sizeToString( totalBytes ).c_str() << " ";
|
||||
std::cout << std::flush;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user