mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-29 17:46:29 +03:00
Added continue / resume download support for HTTP Requests.
--HG-- branch : dev
This commit is contained in:
@@ -168,6 +168,12 @@ class EE_API Http : NonCopyable {
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -194,6 +200,7 @@ class EE_API Http : NonCopyable {
|
||||
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
|
||||
@@ -261,6 +268,9 @@ class EE_API Http : NonCopyable {
|
||||
** @return Value of the field, or empty string if not found */
|
||||
const std::string& getField(const std::string& field) const;
|
||||
|
||||
/** @return If the field is found in the response headers. */
|
||||
bool hasField(const std::string& field) const;
|
||||
|
||||
/** @brief Get the response status code
|
||||
** The status code should be the first thing to be checked
|
||||
** after receiving a response, it defines whether it is a
|
||||
|
||||
@@ -52,6 +52,7 @@ Http::Request::Request(const std::string& uri, Method method, const std::string&
|
||||
mValidateHostname( validateHostname ),
|
||||
mFollowRedirect( followRedirect ),
|
||||
mCompressedResponse( compressedResponse ),
|
||||
mContinue( false ),
|
||||
mCancel( false ),
|
||||
mMaxRedirections( 10 ),
|
||||
mRedirectionCount( 0 )
|
||||
@@ -161,6 +162,14 @@ std::string Http::Request::prepareTunnel(const Http& http) {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void Http::Request::setContinue(const bool& resume) {
|
||||
mContinue = resume;
|
||||
}
|
||||
|
||||
const bool& Http::Request::isContinue() const {
|
||||
return mContinue;
|
||||
}
|
||||
|
||||
const bool& Http::Request::isCompressedResponse() const {
|
||||
return mCompressedResponse;
|
||||
}
|
||||
@@ -273,6 +282,10 @@ const std::string& Http::Response::getField(const std::string& field) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool Http::Response::hasField(const std::string & field) const {
|
||||
return mFields.find(String::toLower(field)) != mFields.end();
|
||||
}
|
||||
|
||||
Http::Response::Status Http::Response::getStatus() const {
|
||||
return mStatus;
|
||||
}
|
||||
@@ -579,6 +592,33 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
}
|
||||
}
|
||||
|
||||
if ( request.isContinue() ) {
|
||||
std::size_t continueLength = writeTo.getSize();
|
||||
|
||||
if ( continueLength > 0 ) {
|
||||
IOStreamString responseHeadBody;
|
||||
Request requestHead = request;
|
||||
requestHead.setContinue( false );
|
||||
requestHead.setMethod( Request::Head );
|
||||
Response responseHead = downloadRequest( requestHead, responseHeadBody );
|
||||
std::size_t contentLength = 0;
|
||||
|
||||
if ( responseHead.hasField("Accept-Ranges") &&
|
||||
responseHead.hasField("Content-Length") &&
|
||||
String::fromString( contentLength, responseHead.getField("Content-Length") ) &&
|
||||
contentLength > 0 &&
|
||||
continueLength < contentLength
|
||||
)
|
||||
{
|
||||
writeTo.seek( continueLength );
|
||||
Request newRequest( request );
|
||||
newRequest.setContinue( false );
|
||||
newRequest.setField( "Range", String::format( "bytes=%lu-%lu", continueLength, contentLength ) );
|
||||
return downloadRequest( newRequest, writeTo, timeout );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the request to string and send it through the connected socket
|
||||
std::string requestStr = toSend.prepare(*this);
|
||||
|
||||
@@ -771,8 +811,8 @@ Http::Response Http::downloadRequest(const Http::Request& request, IOStream& wri
|
||||
return received;
|
||||
}
|
||||
|
||||
Http::Response Http::downloadRequest(const Http::Request & request, std::string writePath, Time timeout) {
|
||||
IOStreamFile file( writePath, "wb+" );
|
||||
Http::Response Http::downloadRequest(const Http::Request& request, std::string writePath, Time timeout) {
|
||||
IOStreamFile file( writePath, request.isContinue() ? "ab+" : "wb+" );
|
||||
return downloadRequest( request, file, timeout );
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ 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::Flag resume(parser, "continue", "Resume getting a partially-downloaded file", {'c',"continue"});
|
||||
args::Flag compressed(parser, "compressed", "Request compressed response", {"compressed"});
|
||||
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"});
|
||||
@@ -130,7 +131,10 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
}
|
||||
|
||||
// Set the proxy for the request
|
||||
if ( proxy ) {
|
||||
char * http_proxy = getenv( "http_proxy" );
|
||||
if ( !proxy && NULL != http_proxy ) {
|
||||
http.setProxy( URI( http_proxy ) );
|
||||
} else if ( proxy ) {
|
||||
http.setProxy( URI( proxy.Get() ) );
|
||||
}
|
||||
|
||||
@@ -139,6 +143,11 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
request.setCompressedResponse( true );
|
||||
}
|
||||
|
||||
// Resume existing download
|
||||
if ( resume ) {
|
||||
request.setContinue( true );
|
||||
}
|
||||
|
||||
if ( !output ) {
|
||||
// Send the request
|
||||
Http::Response response = http.sendRequest(request);
|
||||
|
||||
Reference in New Issue
Block a user