aboutsummaryrefslogtreecommitdiff
path: root/backends/networking
diff options
context:
space:
mode:
authorAlexander Tkachev2016-07-13 20:00:04 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commitdb72fa34d64f0ddcfb7b823e9060dde74fee63ed (patch)
tree47f302ba00e5f91d79d0ec3a1a59eddc2ee5fbfa /backends/networking
parent16ed625dfefd7cc71e5d4088d0714fb09332a9c3 (diff)
downloadscummvm-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.
Diffstat (limited to 'backends/networking')
-rw-r--r--backends/networking/curl/curlrequest.cpp25
-rw-r--r--backends/networking/curl/curlrequest.h10
-rw-r--r--backends/networking/curl/networkreadstream.cpp53
-rw-r--r--backends/networking/curl/networkreadstream.h12
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();