diff options
Diffstat (limited to 'backends/networking/curl')
-rw-r--r-- | backends/networking/curl/curlrequest.cpp | 8 | ||||
-rw-r--r-- | backends/networking/curl/curlrequest.h | 4 | ||||
-rw-r--r-- | backends/networking/curl/networkreadstream.cpp | 38 | ||||
-rw-r--r-- | backends/networking/curl/networkreadstream.h | 16 |
4 files changed, 54 insertions, 12 deletions
diff --git a/backends/networking/curl/curlrequest.cpp b/backends/networking/curl/curlrequest.cpp index 861546b906..a3f997a4ff 100644 --- a/backends/networking/curl/curlrequest.cpp +++ b/backends/networking/curl/curlrequest.cpp @@ -31,7 +31,7 @@ namespace Networking { CurlRequest::CurlRequest(DataCallback cb, ErrorCallback ecb, Common::String url): - Request(cb, ecb), _url(url), _stream(nullptr), _headersList(nullptr), _bytesBuffer(nullptr), _bytesBufferSize(0) {} + Request(cb, ecb), _url(url), _stream(nullptr), _headersList(nullptr), _bytesBuffer(nullptr), _bytesBufferSize(0), _uploading(false) {} CurlRequest::~CurlRequest() { delete _stream; @@ -40,8 +40,8 @@ CurlRequest::~CurlRequest() { NetworkReadStream *CurlRequest::makeStream() { if (_bytesBuffer) - return new NetworkReadStream(_url.c_str(), _headersList, _bytesBuffer, _bytesBufferSize, true); - return new NetworkReadStream(_url.c_str(), _headersList, _postFields); + return new NetworkReadStream(_url.c_str(), _headersList, _bytesBuffer, _bytesBufferSize, _uploading, true); + return new NetworkReadStream(_url.c_str(), _headersList, _postFields, _uploading); } @@ -97,6 +97,8 @@ void CurlRequest::setBuffer(byte *buffer, uint32 size) { _bytesBufferSize = size; } +void CurlRequest::usePut() { _uploading = true; } + NetworkReadStreamResponse CurlRequest::execute() { if (!_stream) { _stream = makeStream(); diff --git a/backends/networking/curl/curlrequest.h b/backends/networking/curl/curlrequest.h index 660479e34a..5737078b2d 100644 --- a/backends/networking/curl/curlrequest.h +++ b/backends/networking/curl/curlrequest.h @@ -44,6 +44,7 @@ protected: Common::String _postFields; byte *_bytesBuffer; uint32 _bytesBufferSize; + bool _uploading; //using PUT method virtual NetworkReadStream *makeStream(); @@ -66,6 +67,9 @@ public: /** Sets bytes buffer. */ virtual void setBuffer(byte *buffer, uint32 size); + /** Remembers to use PUT method when it would create NetworkReadStream. */ + virtual void usePut(); + /** * Starts this Request with ConnMan. * @return its NetworkReadStream in NetworkReadStreamResponse. diff --git a/backends/networking/curl/networkreadstream.cpp b/backends/networking/curl/networkreadstream.cpp index f96a069e16..283e5e667f 100644 --- a/backends/networking/curl/networkreadstream.cpp +++ b/backends/networking/curl/networkreadstream.cpp @@ -35,11 +35,17 @@ static size_t curlDataCallback(char *d, size_t n, size_t l, void *p) { return 0; } -NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields): - NetworkReadStream(url, headersList, (byte *)postFields.c_str(), postFields.size(), false) {} +static size_t curlReadDataCallback(char *d, size_t n, size_t l, void *p) { + NetworkReadStream *stream = (NetworkReadStream *)p; + if (stream) return stream->fillWithSendingContents(d, n*l); + return 0; +} + +NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading): + NetworkReadStream(url, headersList, (byte *)postFields.c_str(), postFields.size(), uploading, false) {} -NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, byte *buffer, uint32 bufferSize, bool post) : - _easy(0), _eos(false), _requestComplete(false) { +NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, byte *buffer, uint32 bufferSize, bool uploading, bool post): + _easy(0), _eos(false), _requestComplete(false), _sendingContentsBuffer(nullptr), _sendingContentsSize(0), _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 @@ -49,9 +55,17 @@ NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, b 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); - if (post || bufferSize != 0) { - curl_easy_setopt(_easy, CURLOPT_POSTFIELDSIZE, bufferSize); - curl_easy_setopt(_easy, CURLOPT_COPYPOSTFIELDS, buffer); + if (uploading) { + curl_easy_setopt(_easy, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(_easy, CURLOPT_READDATA, this); + curl_easy_setopt(_easy, CURLOPT_READFUNCTION, curlReadDataCallback); + _sendingContentsBuffer = buffer; + _sendingContentsSize = bufferSize; + } else { + if (post || bufferSize != 0) { + curl_easy_setopt(_easy, CURLOPT_POSTFIELDSIZE, bufferSize); + curl_easy_setopt(_easy, CURLOPT_COPYPOSTFIELDS, buffer); + } } ConnMan.registerEasyHandle(_easy); } @@ -87,4 +101,14 @@ long NetworkReadStream::httpResponseCode() const { return responseCode; } +uint32 NetworkReadStream::fillWithSendingContents(char *bufferToFill, uint32 maxSize) { + uint32 size = _sendingContentsSize - _sendingContentsPos; + if (size > maxSize) size = maxSize; + for (uint32 i = 0; i < size; ++i) { + bufferToFill[i] = _sendingContentsBuffer[_sendingContentsPos + i]; + } + _sendingContentsPos += size; + return size; +} + } // End of namespace Cloud diff --git a/backends/networking/curl/networkreadstream.h b/backends/networking/curl/networkreadstream.h index f1f41264aa..d48d01b198 100644 --- a/backends/networking/curl/networkreadstream.h +++ b/backends/networking/curl/networkreadstream.h @@ -35,10 +35,13 @@ namespace Networking { class NetworkReadStream: public Common::MemoryReadWriteStream { CURL *_easy; bool _eos, _requestComplete; + byte *_sendingContentsBuffer; + uint32 _sendingContentsSize; + uint32 _sendingContentsPos; public: - NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields); - NetworkReadStream(const char *url, curl_slist *headersList, byte *buffer, uint32 bufferSize, bool post = true); + NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading = false); + NetworkReadStream(const char *url, curl_slist *headersList, byte *buffer, uint32 bufferSize, bool uploading = false, bool post = true); virtual ~NetworkReadStream(); /** @@ -82,6 +85,15 @@ public: * @note This method should be called when eos() == true. */ long httpResponseCode() const; + + /** + * Fills the passed buffer with _sendingContentsBuffer contents. + * It works similarly to read(), expect it's not for reading + * Stream's contents, but for sending our own data to the server. + * + * @returns how many bytes were actually read (filled in) + */ + uint32 fillWithSendingContents(char *bufferToFill, uint32 maxSize); }; } // End of namespace Networking |