diff options
author | Alexander Tkachev | 2016-07-13 20:00:04 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | db72fa34d64f0ddcfb7b823e9060dde74fee63ed (patch) | |
tree | 47f302ba00e5f91d79d0ec3a1a59eddc2ee5fbfa | |
parent | 16ed625dfefd7cc71e5d4088d0714fb09332a9c3 (diff) | |
download | scummvm-rg350-db72fa34d64f0ddcfb7b823e9060dde74fee63ed.tar.gz scummvm-rg350-db72fa34d64f0ddcfb7b823e9060dde74fee63ed.tar.bz2 scummvm-rg350-db72fa34d64f0ddcfb7b823e9060dde74fee63ed.zip |
CLOUD: Update NetworkReadStream and CurlRequest
Now those support POST multipart/form upload.
-rw-r--r-- | backends/networking/curl/curlrequest.cpp | 25 | ||||
-rw-r--r-- | backends/networking/curl/curlrequest.h | 10 | ||||
-rw-r--r-- | backends/networking/curl/networkreadstream.cpp | 53 | ||||
-rw-r--r-- | backends/networking/curl/networkreadstream.h | 12 |
4 files changed, 99 insertions, 1 deletions
diff --git a/backends/networking/curl/curlrequest.cpp b/backends/networking/curl/curlrequest.cpp index 3a143e5af8..05dfc4a362 100644 --- a/backends/networking/curl/curlrequest.cpp +++ b/backends/networking/curl/curlrequest.cpp @@ -42,6 +42,8 @@ CurlRequest::~CurlRequest() { NetworkReadStream *CurlRequest::makeStream() { if (_bytesBuffer) return new NetworkReadStream(_url.c_str(), _headersList, _bytesBuffer, _bytesBufferSize, _uploading, _usingPatch, true); + if (!_formFields.empty() || !_formFiles.empty()) + return new NetworkReadStream(_url.c_str(), _headersList, _formFields, _formFiles); return new NetworkReadStream(_url.c_str(), _headersList, _postFields, _uploading, _usingPatch); } @@ -100,12 +102,35 @@ void CurlRequest::addPostField(Common::String keyValuePair) { if (_bytesBuffer) warning("CurlRequest: added POST fields would be ignored, because there is buffer present"); + if (!_formFields.empty() || !_formFiles.empty()) + warning("CurlRequest: added POST fields would be ignored, because there are form fields/files present"); + if (_postFields == "") _postFields = keyValuePair; else _postFields += "&" + keyValuePair; } +void CurlRequest::addFormField(Common::String name, Common::String value) { + if (_bytesBuffer) + warning("CurlRequest: added POST form fields would be ignored, because there is buffer present"); + + if (_formFields.contains(name)) + warning("CurlRequest: form field '%s' already had a value", name.c_str()); + + _formFields[name] = value; +} + +void CurlRequest::addFormFile(Common::String name, Common::String filename) { + if (_bytesBuffer) + warning("CurlRequest: added POST form files would be ignored, because there is buffer present"); + + if (_formFields.contains(name)) + warning("CurlRequest: form file field '%s' already had a value", name.c_str()); + + _formFiles[name] = filename; +} + void CurlRequest::setBuffer(byte *buffer, uint32 size) { if (_postFields != "") warning("CurlRequest: added POST fields would be ignored, because buffer added"); diff --git a/backends/networking/curl/curlrequest.h b/backends/networking/curl/curlrequest.h index 68ea3a58d7..6ce94f8983 100644 --- a/backends/networking/curl/curlrequest.h +++ b/backends/networking/curl/curlrequest.h @@ -26,6 +26,8 @@ #include "backends/networking/curl/request.h" #include "common/str.h" #include "common/array.h" +#include "common/hashmap.h" +#include "common/hash-str.h" struct curl_slist; @@ -42,6 +44,8 @@ protected: NetworkReadStream *_stream; curl_slist *_headersList; Common::String _postFields; + Common::HashMap<Common::String, Common::String> _formFields; + Common::HashMap<Common::String, Common::String> _formFiles; byte *_bytesBuffer; uint32 _bytesBufferSize; bool _uploading; //using PUT method @@ -66,6 +70,12 @@ public: /** Adds a post field (key=value pair). */ virtual void addPostField(Common::String field); + /** Adds a form/multipart field (name, value). */ + virtual void addFormField(Common::String name, Common::String value); + + /** Adds a form/multipart file (field name, file name). */ + virtual void addFormFile(Common::String name, Common::String filename); + /** Sets bytes buffer. */ virtual void setBuffer(byte *buffer, uint32 size); diff --git a/backends/networking/curl/networkreadstream.cpp b/backends/networking/curl/networkreadstream.cpp index 5c3730645b..41839f79c9 100644 --- a/backends/networking/curl/networkreadstream.cpp +++ b/backends/networking/curl/networkreadstream.cpp @@ -80,10 +80,63 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, const byt ConnMan.registerEasyHandle(_easy); } +void NetworkReadStream::init(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles) { + _eos = _requestComplete = false; + _sendingContentsBuffer = nullptr; + _sendingContentsSize = _sendingContentsPos = 0; + + _easy = curl_easy_init(); + curl_easy_setopt(_easy, CURLOPT_WRITEFUNCTION, curlDataCallback); + curl_easy_setopt(_easy, CURLOPT_WRITEDATA, this); //so callback can call us + curl_easy_setopt(_easy, CURLOPT_PRIVATE, this); //so ConnectionManager can call us when request is complete + curl_easy_setopt(_easy, CURLOPT_HEADER, 0L); + curl_easy_setopt(_easy, CURLOPT_HEADERDATA, this); + curl_easy_setopt(_easy, CURLOPT_HEADERFUNCTION, curlHeadersCallback); + curl_easy_setopt(_easy, CURLOPT_URL, url); + curl_easy_setopt(_easy, CURLOPT_VERBOSE, 0L); + curl_easy_setopt(_easy, CURLOPT_FOLLOWLOCATION, 1L); //probably it's OK to have it always on + curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList); + + // set POST multipart upload form fields/files + struct curl_httppost *formpost = NULL; + struct curl_httppost *lastptr = NULL; + + for (Common::HashMap<Common::String, Common::String>::iterator i = formFields.begin(); i != formFields.end(); ++i) { + if (0 != curl_formadd(&formpost, &lastptr, + CURLFORM_COPYNAME, i->_key.c_str(), + CURLFORM_COPYCONTENTS, i->_value.c_str(), + CURLFORM_END)) debug("file failed formadd"); + } + + /* + curl_formadd(&formpost, &lastptr, + CURLFORM_COPYNAME, "fieldname", + CURLFORM_BUFFER, "filename", + CURLFORM_BUFFERPTR, buffer, + CURLFORM_BUFFERLENGTH, bufferSize, + CURLFORM_END); + */ + + for (Common::HashMap<Common::String, Common::String>::iterator i = formFiles.begin(); i != formFiles.end(); ++i) { + if (0 != curl_formadd(&formpost, &lastptr, + CURLFORM_COPYNAME, i->_key.c_str(), + CURLFORM_FILE, i->_value.c_str(), + CURLFORM_END)) debug("file failed formadd"); + } + + curl_easy_setopt(_easy, CURLOPT_HTTPPOST, formpost); + + ConnMan.registerEasyHandle(_easy); +} + NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading, bool usingPatch) { init(url, headersList, (const byte *)postFields.c_str(), postFields.size(), uploading, usingPatch, false); } +NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles) { + init(url, headersList, formFields, formFiles); +} + NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post) { init(url, headersList, buffer, bufferSize, uploading, usingPatch, post); } diff --git a/backends/networking/curl/networkreadstream.h b/backends/networking/curl/networkreadstream.h index 6f521cbc4b..acd8eee1c9 100644 --- a/backends/networking/curl/networkreadstream.h +++ b/backends/networking/curl/networkreadstream.h @@ -26,6 +26,8 @@ #include "common/memstream.h" #include "common/stream.h" #include "common/str.h" +#include "common/hashmap.h" +#include "common/hash-str.h" typedef void CURL; struct curl_slist; @@ -40,9 +42,17 @@ class NetworkReadStream: public Common::MemoryReadWriteStream { uint32 _sendingContentsPos; Common::String _responseHeaders; void init(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post); + void init(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles); -public: +public: + /** Send <postFields>, using POST by default. */ NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading = false, bool usingPatch = false); + /** Send <formFields>, <formFiles>, using POST multipart/form. */ + NetworkReadStream( + const char *url, curl_slist *headersList, + Common::HashMap<Common::String, Common::String> formFields, + Common::HashMap<Common::String, Common::String> formFiles); + /** Send <buffer, using POST by default. */ NetworkReadStream(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading = false, bool usingPatch = false, bool post = true); virtual ~NetworkReadStream(); |