aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/cloud/dropbox/dropboxstorage.cpp1
-rw-r--r--backends/networking/curl/connectionmanager.cpp2
-rw-r--r--backends/networking/curl/curljsonrequest.cpp36
-rw-r--r--backends/networking/curl/curljsonrequest.h6
-rw-r--r--backends/networking/curl/networkreadstream.cpp9
-rw-r--r--backends/networking/curl/networkreadstream.h16
6 files changed, 59 insertions, 11 deletions
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp
index 2db915de38..729283bcfa 100644
--- a/backends/cloud/dropbox/dropboxstorage.cpp
+++ b/backends/cloud/dropbox/dropboxstorage.cpp
@@ -56,6 +56,7 @@ void DropboxStorage::listDirectory(Common::String path) {
void DropboxStorage::syncSaves() {
//not so Dropbox, just testing JSON requesting & parsing:
addRequest(new Networking::CurlJsonRequest(curlJsonCallback, "https://api.vk.com/method/users.get?v=5.50&user_ids=205387401"));
+ addRequest(new Networking::CurlJsonRequest(curlJsonCallback, "https://api.vk.com/method/users.get?v=5.50&user_ids=28870501"));
}
} //end of namespace Dropbox
diff --git a/backends/networking/curl/connectionmanager.cpp b/backends/networking/curl/connectionmanager.cpp
index ceff8b62a4..8c718e019b 100644
--- a/backends/networking/curl/connectionmanager.cpp
+++ b/backends/networking/curl/connectionmanager.cpp
@@ -56,7 +56,7 @@ void ConnectionManager::handle() {
NetworkReadStream *stream;
curl_easy_getinfo(easyHandle, CURLINFO_PRIVATE, &stream);
- if (stream) stream->done(); //I'm not sure it's OK to notify "done()" on failure
+ if (stream) stream->finished();
if (curlMsg->msg == CURLMSG_DONE) {
debug("ConnectionManager: SUCCESS (%d - %s)", curlMsg->data.result, curl_easy_strerror(curlMsg->data.result));
diff --git a/backends/networking/curl/curljsonrequest.cpp b/backends/networking/curl/curljsonrequest.cpp
index acd9675aed..f5a7a7c8d0 100644
--- a/backends/networking/curl/curljsonrequest.cpp
+++ b/backends/networking/curl/curljsonrequest.cpp
@@ -30,7 +30,7 @@
namespace Networking {
-CurlJsonRequest::CurlJsonRequest(Callback cb, const char *url) : Request(cb), _stream(0) {
+CurlJsonRequest::CurlJsonRequest(Callback cb, const char *url) : Request(cb), _stream(0), _contentsStream(DisposeAfterUse::YES) {
_url = url;
}
@@ -38,6 +38,24 @@ CurlJsonRequest::~CurlJsonRequest() {
if (_stream) delete _stream;
}
+char *CurlJsonRequest::getPreparedContents() {
+ //write one more byte in the end
+ byte zero[1] = { 0 };
+ _contentsStream.write(zero, 1);
+
+ //replace all "bad" bytes with '.' character
+ byte *result = _contentsStream.getData();
+ uint32 size = _contentsStream.size();
+ for (uint32 i = 0; i < size; ++i)
+ if (result[i] < 0x20 || result[i] > 0x7f)
+ result[i] = '.';
+
+ //make it zero-terminated string
+ result[size - 1] = '\0';
+
+ return (char *)result;
+}
+
bool CurlJsonRequest::handle(ConnectionManager &manager) {
if (!_stream) _stream = manager.makeRequest(_url);
@@ -45,13 +63,17 @@ bool CurlJsonRequest::handle(ConnectionManager &manager) {
const int kBufSize = 16*1024;
char buf[kBufSize+1];
uint32 readBytes = _stream->read(buf, kBufSize);
- if (readBytes != 0) _contents += Common::String(buf, readBytes);
- if (_stream->eos()) {
- //TODO: check that stream's CURL easy handle's HTTP response code is 200 OK
- debug("CurlJsonRequest: contents:\n%s", _contents.c_str());
+ if (readBytes != 0)
+ if (_contentsStream.write(buf, readBytes) != readBytes)
+ warning("MemoryWriteStreamDynamic was unable to write all the bytes");
+
+ if (_stream->eos()) {
+ if (_stream->httpResponseCode() != 200)
+ warning("HTTP response code is not 200 OK");
+
if (_callback) {
- Common::JSONValue *json = Common::JSON::parse(_contents.c_str()); //TODO: somehow fix JSON to work with UTF-8
- debug("CurlJsonRequest: JSONValue pointer = %p", json);
+ char *contents = getPreparedContents();
+ Common::JSONValue *json = Common::JSON::parse(contents);
_callback(json); //potential memory leak, free it in your callbacks!
}
return true;
diff --git a/backends/networking/curl/curljsonrequest.h b/backends/networking/curl/curljsonrequest.h
index 73e0144c64..e9634393dc 100644
--- a/backends/networking/curl/curljsonrequest.h
+++ b/backends/networking/curl/curljsonrequest.h
@@ -24,6 +24,7 @@
#define BACKENDS_NETWORKING_CURL_CURLJSONREQUEST_H
#include "backends/cloud/request.h"
+#include "common/memstream.h"
namespace Networking {
@@ -32,7 +33,10 @@ class NetworkReadStream;
class CurlJsonRequest : public Cloud::Request {
const char *_url;
NetworkReadStream *_stream;
- Common::String _contents;
+ Common::MemoryWriteStreamDynamic _contentsStream;
+
+ /** Prepares raw bytes from _contentsStream to be parsed with Common::JSON::parse(). */
+ char *getPreparedContents();
public:
CurlJsonRequest(Callback cb, const char *url);
diff --git a/backends/networking/curl/networkreadstream.cpp b/backends/networking/curl/networkreadstream.cpp
index 5049ae507b..b8cb81aca2 100644
--- a/backends/networking/curl/networkreadstream.cpp
+++ b/backends/networking/curl/networkreadstream.cpp
@@ -63,8 +63,15 @@ uint32 NetworkReadStream::read(void *dataPtr, uint32 dataSize) {
return actuallyRead;
}
-void NetworkReadStream::done() {
+void NetworkReadStream::finished() {
_requestComplete = true;
}
+long NetworkReadStream::httpResponseCode() {
+ long responseCode = -1;
+ if (_easy)
+ curl_easy_getinfo(_easy, CURLINFO_RESPONSE_CODE, &responseCode);
+ return responseCode;
+}
+
} //end of namespace Cloud
diff --git a/backends/networking/curl/networkreadstream.h b/backends/networking/curl/networkreadstream.h
index 9c7d8f83b6..0333e4fb16 100644
--- a/backends/networking/curl/networkreadstream.h
+++ b/backends/networking/curl/networkreadstream.h
@@ -67,7 +67,21 @@ public:
*/
virtual uint32 read(void *dataPtr, uint32 dataSize);
- void done();
+ /**
+ * This method is called by ConnectionManager to indicate
+ * that transfer is finished.
+ *
+ * @note It's called on failure too.
+ */
+ void finished();
+
+ /**
+ * Returns HTTP response code from inner CURL handle.
+ * It returns -1 to indicate there is no inner handle.
+ *
+ * @note This method should be called when eos() == true.
+ */
+ long httpResponseCode();
};
} //end of namespace Cloud