mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
Minor improvements on http requests and minor bug fix.
--HG-- branch : dev
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
#ifndef EE_MATH_BASE
|
||||
#define EE_MATH_BASE
|
||||
|
||||
#include <eepp/core.hpp>
|
||||
#include <eepp/math/ease.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef EE_MATHCINTERPOLATION_H
|
||||
#define EE_MATHCINTERPOLATION_H
|
||||
|
||||
#include <eepp/math/base.hpp>
|
||||
#include <eepp/core.hpp>
|
||||
#include <eepp/math/ease.hpp>
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef EE_MATHCWAYPOINTS_H
|
||||
#define EE_MATHCWAYPOINTS_H
|
||||
|
||||
#include <eepp/math/base.hpp>
|
||||
#include <eepp/core.hpp>
|
||||
#include <eepp/math/ease.hpp>
|
||||
#include <eepp/math/vector2.hpp>
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <vector>
|
||||
|
||||
@@ -40,6 +40,9 @@ class EE_API Http : NonCopyable {
|
||||
Patch ///< The PATCH method is used to apply partial modifications to a resource.
|
||||
};
|
||||
|
||||
/** @return Method from a method name string. */
|
||||
static Method methodFromString( std::string methodString );
|
||||
|
||||
/** @brief Default constructor
|
||||
** This constructor creates a GET request, with the root
|
||||
** URI ("/") and an empty body.
|
||||
@@ -62,6 +65,20 @@ class EE_API Http : NonCopyable {
|
||||
** @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.
|
||||
@@ -139,12 +156,6 @@ class EE_API Http : NonCopyable {
|
||||
** @return String containing the request, ready to be sent */
|
||||
std::string prepare() const;
|
||||
|
||||
/** @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;
|
||||
|
||||
// Types
|
||||
typedef std::map<std::string, std::string> FieldTable;
|
||||
|
||||
@@ -228,6 +239,9 @@ class EE_API Http : NonCopyable {
|
||||
** @return Status code of the response */
|
||||
Status getStatus() const;
|
||||
|
||||
/** @brief Get the response status description */
|
||||
const char * getStatusDescription() const;
|
||||
|
||||
/** @brief Get the major HTTP version number of the response
|
||||
** @return Major HTTP version number
|
||||
** @see GetMinorHttpVersion */
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#define EE_SDL_VERSION_2
|
||||
#define EE_X11_PLATFORM
|
||||
#define EE_DEBUG
|
||||
#define EE_LIBSNDFILE_ENABLED
|
||||
#define EE_MEMORY_MANAGER
|
||||
#define EE_SHADERS_SUPPORTED
|
||||
#define EE_GLEW_AVAILABLE
|
||||
@@ -10,7 +9,6 @@
|
||||
#define EE_BACKEND_SFML_ACTIVE
|
||||
#define EE_BACKEND_SDL2
|
||||
#define EE_GL3_ENABLED
|
||||
#define EE_SHADERS_SUPPORTED
|
||||
#define EE_BACKEND_SDL_ACTIVE
|
||||
#define EE_MBEDTLS
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
|
||||
@@ -143,7 +143,6 @@
|
||||
../../include/eepp/maps/mapobjectlayer.hpp
|
||||
../../include/eepp/maps/tilemap.hpp
|
||||
../../include/eepp/maps/tilemaplayer.hpp
|
||||
../../include/eepp/math/base.hpp
|
||||
../../include/eepp/math/ease.hpp
|
||||
../../include/eepp/math/easing.hpp
|
||||
../../include/eepp/math.hpp
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
../../include/eepp/thirdparty
|
||||
../../src/thirdparty/efsw/include
|
||||
../../src/thirdparty/libvorbis/include
|
||||
../../src/eepp/audio
|
||||
../../include/eepp/audio
|
||||
/usr/include/freetype2/
|
||||
|
||||
../../include/eepp/ui
|
||||
|
||||
@@ -13,6 +13,28 @@ using namespace EE::Network::SSL;
|
||||
|
||||
namespace EE { namespace Network {
|
||||
|
||||
Http::Request::Method Http::Request::methodFromString( std::string methodString ) {
|
||||
String::toLowerInPlace(methodString);
|
||||
|
||||
if ( "get" == methodString ) {
|
||||
return Method::Get;
|
||||
} else if ( "head" == methodString ) {
|
||||
return Method::Head;
|
||||
} else if ( "post" == methodString ) {
|
||||
return Method::Post;
|
||||
} else if ( "put" == methodString ) {
|
||||
return Method::Put;
|
||||
} else if ( "delete" == methodString ) {
|
||||
return Method::Delete;
|
||||
} else if ( "options" == methodString ) {
|
||||
return Method::Options;
|
||||
} else if ( "patch" == methodString ) {
|
||||
return Method::Patch;
|
||||
} else {
|
||||
return Method::Get;
|
||||
}
|
||||
}
|
||||
|
||||
Http::Request::Request(const std::string& uri, Method method, const std::string& body, bool validateCertificate, bool validateHostname , bool followRedirect) :
|
||||
mValidateCertificate( validateCertificate ),
|
||||
mValidateHostname( validateHostname ),
|
||||
@@ -133,6 +155,16 @@ bool Http::Request::hasField(const std::string& field) const {
|
||||
return mFields.find(String::toLower(field)) != mFields.end();
|
||||
}
|
||||
|
||||
const std::string& Http::Request::getField(const std::string& field) const {
|
||||
FieldTable::const_iterator it = mFields.find(String::toLower(field));
|
||||
if (it != mFields.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
static const std::string empty = "";
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
Http::Response::Response() :
|
||||
mStatus (ConnectionFailed),
|
||||
mMajorVersion(0),
|
||||
@@ -158,6 +190,44 @@ Http::Response::Status Http::Response::getStatus() const {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
const char * Http::Response::getStatusDescription() const {
|
||||
switch ( mStatus ) {
|
||||
// 2xx: success
|
||||
case Ok: return "Successfull";
|
||||
case Created: return "The resource has successfully been created";
|
||||
case Accepted: return "The request has been accepted, but will be processed later by the server";
|
||||
case NoContent: return "The server didn't send any data in return";
|
||||
case ResetContent: return "The server informs the client that it should clear the view (form) that caused the request to be sent";
|
||||
case PartialContent: return "The server has sent a part of the resource, as a response to a partial GET request";
|
||||
|
||||
// 3xx: redirection
|
||||
case MultipleChoices: return "The requested page can be accessed from several locations";
|
||||
case MovedPermanently: return "The requested page has permanently moved to a new location";
|
||||
case MovedTemporarily: return "The requested page has temporarily moved to a new location";
|
||||
case NotModified: return "For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed";
|
||||
|
||||
// 4xx: client error
|
||||
case BadRequest: return "The server couldn't understand the request (syntax error)";
|
||||
case Unauthorized: return "The requested page needs an authentification to be accessed";
|
||||
case Forbidden: return "The requested page cannot be accessed at all, even with authentification";
|
||||
case NotFound: return "The requested page doesn't exist";
|
||||
case RangeNotSatisfiable: return "The server can't satisfy the partial GET request (with a \"Range\" header field)";
|
||||
|
||||
// 5xx: server error
|
||||
case InternalServerError: return "The server encountered an unexpected error";
|
||||
case NotImplemented: return "The server doesn't implement a requested feature";
|
||||
case BadGateway: return "The gateway server has received an error from the source server";
|
||||
case ServiceNotAvailable: return "The server is temporarily unavailable (overloaded, in maintenance, ...)";
|
||||
case GatewayTimeout: return "The gateway server couldn't receive a response from the source server";
|
||||
case VersionNotSupported: return "The server doesn't support the requested HTTP version";
|
||||
|
||||
// 10xx: Custom codes
|
||||
case InvalidResponse: return "Response is not a valid HTTP one";
|
||||
case ConnectionFailed: return "Connection with server failed";
|
||||
default: return "Unknown response status";
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Http::Response::getMajorHttpVersion() const {
|
||||
return mMajorVersion;
|
||||
}
|
||||
@@ -435,24 +505,6 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
std::string header;
|
||||
|
||||
while (!request.isCancelled() && mConnection->receive(buffer, bufferSize, size) == Socket::Done) {
|
||||
if ( isnheader != 0 ) {
|
||||
currentTotalBytes += size;
|
||||
writeTo.write( buffer, size );
|
||||
|
||||
if ( request.getProgressCallback() ) {
|
||||
std::size_t length = 0;
|
||||
|
||||
if ( !received.getField("content-length").empty() ) {
|
||||
String::fromString( length, received.getField("content-length") );
|
||||
}
|
||||
|
||||
if ( !request.getProgressCallback()( *this, request, length, currentTotalBytes ) ) {
|
||||
request.mCancel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isnheader == 0 ) {
|
||||
// calculate combined length of unprocessed data and new data
|
||||
len += size;
|
||||
@@ -499,7 +551,7 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
bol += 1;
|
||||
|
||||
// calculate the amount of data remaining in the buffer
|
||||
len = len - ( bol - buffer );
|
||||
len = size - ( bol - buffer );
|
||||
|
||||
// write remaining data to FILE stream
|
||||
if ( len > 0 ) {
|
||||
@@ -545,6 +597,22 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
if ( isnheader == 0 ) {
|
||||
header.append( buffer, ( bol - buffer ) );
|
||||
}
|
||||
} else {
|
||||
currentTotalBytes += size;
|
||||
writeTo.write( buffer, size );
|
||||
|
||||
if ( request.getProgressCallback() ) {
|
||||
std::size_t length = 0;
|
||||
|
||||
if ( !received.getField("content-length").empty() ) {
|
||||
String::fromString( length, received.getField("content-length") );
|
||||
}
|
||||
|
||||
if ( !request.getProgressCallback()( *this, request, length, currentTotalBytes ) ) {
|
||||
request.mCancel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,13 @@ void printResponseHeaders( Http::Response& response ) {
|
||||
EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
args::ArgumentParser parser("HTTP request program example");
|
||||
args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});
|
||||
args::ValueFlag<std::string> output(parser, "file", "Write to file instead of stdout", {'o', "output"} );
|
||||
args::Flag head(parser, "head", "Show document info", {'I',"head"} );
|
||||
args::Flag progress(parser, "progress", "Show current progress of a download", {'p',"progress"} );
|
||||
args::ValueFlag<std::string> postData(parser, "data", "HTTP POST data", {'d', "data"});
|
||||
args::ValueFlagList<std::string> headers(parser, "header", "Pass custom header(s) to server", {'H', "header"});
|
||||
args::Flag head(parser, "head", "Show document info", {'I',"head"});
|
||||
args::Flag insecure(parser, "insecure", "Allow insecure server connections when using SSL", {'k',"insecure"});
|
||||
args::ValueFlag<std::string> output(parser, "file", "Write to file instead of stdout", {'o', "output"});
|
||||
args::Flag progress(parser, "progress", "Show current progress of a download", {'p',"progress"});
|
||||
args::ValueFlag<std::string> requestMethod(parser, "request", "Specify request command to use", {'X', "request"});
|
||||
args::Positional<std::string> url(parser, "url", "The url to request");
|
||||
|
||||
try {
|
||||
@@ -70,12 +74,38 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
uri = URI( "http://" + url.Get() );
|
||||
}
|
||||
|
||||
// Allow insecure connections if requested
|
||||
if ( insecure ) {
|
||||
request.setValidateCertificate(false);
|
||||
request.setValidateHostname(false);
|
||||
}
|
||||
|
||||
// Set the host and port from the URI
|
||||
http.setHost( uri.getHost(), uri.getPort() );
|
||||
|
||||
// Set the path and query parts for the request
|
||||
request.setUri( uri.getPathEtc() );
|
||||
|
||||
// Set the headers
|
||||
for ( const std::string& header : args::get(headers) ) {
|
||||
std::string::size_type pos = header.find_first_of( ':' );
|
||||
if ( std::string::npos != pos ) {
|
||||
std::string key( header.substr( 0, pos ) );
|
||||
std::string val( String::trim( header.substr( pos + 1 ) ) );
|
||||
request.setField(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the request method
|
||||
if ( requestMethod ) {
|
||||
request.setMethod( Http::Request::methodFromString( requestMethod.Get() ) );
|
||||
}
|
||||
|
||||
// Set the post data / body
|
||||
if ( postData ) {
|
||||
request.setBody( postData.Get() );
|
||||
}
|
||||
|
||||
if ( !output ) {
|
||||
// Send the request
|
||||
Http::Response response = http.sendRequest(request);
|
||||
@@ -92,11 +122,11 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
|
||||
std::cout << response.getBody() << std::endl;
|
||||
} else {
|
||||
std::cout << "Error " << status << std::endl;
|
||||
std::cout << "Error " << status << std::endl << response.getStatusDescription() << std::endl;
|
||||
}
|
||||
} else {
|
||||
if ( progress ) {
|
||||
request.setProgressCallback( []( const Http& http, const Http::Request& request, size_t totalBytes, size_t currentBytes ) {
|
||||
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;
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user