HTTP::Downloader::post() now supports pointers+sizes besides only std::strings.

This commit is contained in:
Thulinma 2020-03-12 12:24:29 +01:00
parent 1824100303
commit 35e3fb4bca
4 changed files with 41 additions and 18 deletions

View file

@ -64,8 +64,8 @@ namespace HTTP{
Downloader::~Downloader(){S.close();} Downloader::~Downloader(){S.close();}
/// Sends a request for the given URL, does no waiting. /// Prepares a request for the given URL, does not send anything
void Downloader::doRequest(const HTTP::URL &link, const std::string &method, const std::string &body){ void Downloader::prepareRequest(const HTTP::URL &link, const std::string &method){
if (!canRequest(link)){return;} if (!canRequest(link)){return;}
bool needSSL = (link.protocol == "https"); bool needSSL = (link.protocol == "https");
H.Clean(); H.Clean();
@ -131,12 +131,22 @@ namespace HTTP{
H.SetHeader(it->first, it->second); H.SetHeader(it->first, it->second);
} }
} }
nbLink = link; nbLink = link;
H.SendRequest(getSocket(), body); }
/// Sends a request for the given URL, does no waiting.
void Downloader::doRequest(const HTTP::URL &link, const std::string &method, const void * body, const size_t bodyLen){
prepareRequest(link, method);
H.sendRequest(getSocket(), body, bodyLen, false);
H.Clean(); H.Clean();
} }
/// Sends a request for the given URL, does no waiting.
void Downloader::doRequest(const HTTP::URL &link, const std::string &method, const std::string &body){
doRequest(link, method, body.data(), body.size());
}
/// Do a HEAD request to download the HTTP headers only, returns true on success /// Do a HEAD request to download the HTTP headers only, returns true on success
bool Downloader::head(const HTTP::URL &link, uint8_t maxRecursiveDepth){ bool Downloader::head(const HTTP::URL &link, uint8_t maxRecursiveDepth){
if (!canRequest(link)){return false;} if (!canRequest(link)){return false;}
@ -361,11 +371,15 @@ namespace HTTP{
} }
bool Downloader::post(const HTTP::URL &link, const std::string &payload, bool sync, uint8_t maxRecursiveDepth){ bool Downloader::post(const HTTP::URL &link, const std::string &payload, bool sync, uint8_t maxRecursiveDepth){
return post(link, payload.data(), payload.size(), sync, maxRecursiveDepth);
}
bool Downloader::post(const HTTP::URL &link, const void * payload, const size_t payloadLen, bool sync, uint8_t maxRecursiveDepth){
if (!canRequest(link)){return false;} if (!canRequest(link)){return false;}
size_t loop = retryCount; // max 5 attempts size_t loop = retryCount; // max 5 attempts
while (--loop){// loop while we are unsuccessful while (--loop){// loop while we are unsuccessful
MEDIUM_MSG("Posting to %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), retryCount - loop + 1, retryCount); MEDIUM_MSG("Posting to %s (%zu/%" PRIu32 ")", link.getUrl().c_str(), retryCount - loop + 1, retryCount);
doRequest(link, "POST", payload); doRequest(link, "POST", payload, payloadLen);
// Not synced? Ignore the response and immediately return true. // Not synced? Ignore the response and immediately return true.
if (!sync){return true;} if (!sync){return true;}
uint64_t reqTime = Util::bootSecs(); uint64_t reqTime = Util::bootSecs();
@ -390,9 +404,9 @@ namespace HTTP{
} }
if (!canContinue(link)){return false;} if (!canContinue(link)){return false;}
if (getStatusCode() >= 300 && getStatusCode() < 400){ if (getStatusCode() >= 300 && getStatusCode() < 400){
return post(link.link(getHeader("Location")), payload, sync, --maxRecursiveDepth); return post(link.link(getHeader("Location")), payload, payloadLen, sync, --maxRecursiveDepth);
}else{ }else{
return post(link, payload, sync, --maxRecursiveDepth); return post(link, payload, payloadLen, sync, --maxRecursiveDepth);
} }
} }
return true; // Success! return true; // Success!

View file

@ -10,13 +10,17 @@ namespace HTTP{
~Downloader(); ~Downloader();
std::string &data(); std::string &data();
const std::string &const_data() const; const std::string &const_data() const;
void doRequest(const HTTP::URL &link, const std::string &method = "", void prepareRequest(const HTTP::URL &link, const std::string &method = "");
const std::string &body = ""); void doRequest(const HTTP::URL &link, const std::string &method = "", const void * body = 0, const size_t bodyLen = 0);
void doRequest(const HTTP::URL &link, const std::string &method, const std::string &body);
bool get(const std::string &link, Util::DataCallback &cb = Util::defaultDataCallback); bool get(const std::string &link, Util::DataCallback &cb = Util::defaultDataCallback);
bool get(const HTTP::URL &link, uint8_t maxRecursiveDepth = 6, Util::DataCallback &cb = Util::defaultDataCallback); bool get(const HTTP::URL &link, uint8_t maxRecursiveDepth = 6, Util::DataCallback &cb = Util::defaultDataCallback);
bool head(const HTTP::URL &link,uint8_t maxRecursiveDepth = 6); bool head(const HTTP::URL &link, uint8_t maxRecursiveDepth = 6);
bool getRange(const HTTP::URL &link, size_t byteStart, size_t byteEnd, Util::DataCallback &cb = Util::defaultDataCallback); bool getRange(const HTTP::URL &link, size_t byteStart, size_t byteEnd,
bool getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd, Util::DataCallback &cb = Util::defaultDataCallback); Util::DataCallback &cb = Util::defaultDataCallback);
bool getRangeNonBlocking(const HTTP::URL &link, size_t byteStart, size_t byteEnd,
Util::DataCallback &cb = Util::defaultDataCallback);
bool post(const HTTP::URL &link, const void * payload, const size_t payloadLen, bool sync = true, uint8_t maxRecursiveDepth = 6);
bool post(const HTTP::URL &link, const std::string &payload, bool sync = true, bool post(const HTTP::URL &link, const std::string &payload, bool sync = true,
uint8_t maxRecursiveDepth = 6); uint8_t maxRecursiveDepth = 6);

View file

@ -163,6 +163,10 @@ std::string &HTTP::Parser::BuildRequest(){
/// The request is build from internal variables set before this call is made. /// The request is build from internal variables set before this call is made.
/// To be precise, method, url, protocol, headers and body are used. /// To be precise, method, url, protocol, headers and body are used.
void HTTP::Parser::SendRequest(Socket::Connection &conn, const std::string &reqbody, bool allAtOnce){ void HTTP::Parser::SendRequest(Socket::Connection &conn, const std::string &reqbody, bool allAtOnce){
sendRequest(conn, reqbody.data(), reqbody.size(), allAtOnce);
}
void HTTP::Parser::sendRequest(Socket::Connection &conn, const void * reqbody, const size_t reqbodyLen, bool allAtOnce){
/// \todo Include GET/POST variable parsing? /// \todo Include GET/POST variable parsing?
if (allAtOnce){ if (allAtOnce){
/// \TODO Make this less duplicated / more pretty. /// \TODO Make this less duplicated / more pretty.
@ -170,15 +174,15 @@ void HTTP::Parser::SendRequest(Socket::Connection &conn, const std::string &reqb
std::map<std::string, std::string>::iterator it; std::map<std::string, std::string>::iterator it;
if (protocol.size() < 5 || protocol[4] != '/'){protocol = "HTTP/1.0";} if (protocol.size() < 5 || protocol[4] != '/'){protocol = "HTTP/1.0";}
builder = method + " " + url + " " + protocol + "\r\n"; builder = method + " " + url + " " + protocol + "\r\n";
if (reqbody.size()){SetHeader("Content-Length", reqbody.length());} if (reqbodyLen){SetHeader("Content-Length", reqbodyLen);}
for (it = headers.begin(); it != headers.end(); it++){ for (it = headers.begin(); it != headers.end(); it++){
if ((*it).first != "" && (*it).second != ""){ if ((*it).first != "" && (*it).second != ""){
builder += (*it).first + ": " + (*it).second + "\r\n"; builder += (*it).first + ": " + (*it).second + "\r\n";
} }
} }
builder += "\r\n"; builder += "\r\n";
if (reqbody.size()){ if (reqbodyLen){
builder += reqbody; builder += std::string((char*)reqbody, reqbodyLen);
}else{ }else{
builder += body; builder += body;
} }
@ -189,7 +193,7 @@ void HTTP::Parser::SendRequest(Socket::Connection &conn, const std::string &reqb
if (protocol.size() < 5 || protocol[4] != '/'){protocol = "HTTP/1.0";} if (protocol.size() < 5 || protocol[4] != '/'){protocol = "HTTP/1.0";}
builder = method + " " + url + " " + protocol + "\r\n"; builder = method + " " + url + " " + protocol + "\r\n";
conn.SendNow(builder); conn.SendNow(builder);
if (reqbody.size()){SetHeader("Content-Length", reqbody.length());} if (reqbodyLen){SetHeader("Content-Length", reqbodyLen);}
for (it = headers.begin(); it != headers.end(); it++){ for (it = headers.begin(); it != headers.end(); it++){
if ((*it).first != "" && (*it).second != ""){ if ((*it).first != "" && (*it).second != ""){
builder = (*it).first + ": " + (*it).second + "\r\n"; builder = (*it).first + ": " + (*it).second + "\r\n";
@ -197,8 +201,8 @@ void HTTP::Parser::SendRequest(Socket::Connection &conn, const std::string &reqb
} }
} }
conn.SendNow("\r\n", 2); conn.SendNow("\r\n", 2);
if (reqbody.size()){ if (reqbodyLen){
conn.SendNow(reqbody); conn.SendNow((char*)reqbody, reqbodyLen);
}else{ }else{
conn.SendNow(body); conn.SendNow(body);
} }

View file

@ -39,6 +39,7 @@ namespace HTTP{
std::string &BuildResponse(); std::string &BuildResponse();
std::string &BuildResponse(std::string code, std::string message); std::string &BuildResponse(std::string code, std::string message);
void SendRequest(Socket::Connection &conn, const std::string &reqbody = "", bool allAtOnce = false); void SendRequest(Socket::Connection &conn, const std::string &reqbody = "", bool allAtOnce = false);
void sendRequest(Socket::Connection &conn, const void * body = 0, const size_t bodyLen = 0, bool allAtOnce = false);
void SendResponse(std::string code, std::string message, Socket::Connection &conn); void SendResponse(std::string code, std::string message, Socket::Connection &conn);
void StartResponse(std::string code, std::string message, Parser &request, void StartResponse(std::string code, std::string message, Parser &request,
Socket::Connection &conn, bool bufferAllChunks = false); Socket::Connection &conn, bool bufferAllChunks = false);