CLOUD: Add ConnectionManager and NetworkReadStream

NetworkReadStream actually saves whole response in the memory now.

There is a pause mechanism in libcurl, but if libcurl is requesting
something compressed, it would have to uncompress data as it goes even
if we paused the request. Even though our own stream won't be notified
about this data when when "pause" the request, libcurl's own buffer
wound be expanding.
This commit is contained in:
Alexander Tkachev 2016-05-15 11:22:35 +06:00
parent 8b585d631b
commit 01abba4f1d
11 changed files with 311 additions and 41 deletions

View file

@ -23,55 +23,37 @@
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "backends/cloud/dropbox/curlrequest.h"
#include "backends/cloud/curl/networkreadstream.h"
#include "common/debug.h"
#include <curl/curl.h>
namespace Cloud {
namespace Dropbox {
static size_t curlDataCallback(char *d, size_t n, size_t l, void *p) {
debug("%p got %d more bytes", p, n * l);
return n * l;
}
CurlRequest::CurlRequest(Callback cb, char *url) : Request(cb), _firstTime(true) {
_curlm = curl_multi_init();
CurlRequest::CurlRequest(Callback cb, const char *url) : Request(cb), _firstTime(true), _stream(0) {
_url = url;
}
CurlRequest::~CurlRequest() {
curl_multi_cleanup(_curlm);
if (_stream) delete _stream;
}
bool CurlRequest::handle() {
bool CurlRequest::handle(ConnectionManager& manager) {
if (_firstTime) {
CURL *eh = curl_easy_init();
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, curlDataCallback);
curl_easy_setopt(eh, CURLOPT_WRITEDATA, this);
curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
curl_easy_setopt(eh, CURLOPT_URL, _url);
curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
curl_multi_add_handle(_curlm, eh);
_stream = manager.makeRequest(_url);
_firstTime = false;
}
int U;
curl_multi_perform(_curlm, &U);
int Q;
CURLMsg *_curlMsg;
while ((_curlMsg = curl_multi_info_read(_curlm, &Q))) {
if (_curlMsg->msg == CURLMSG_DONE) {
CURL *e = _curlMsg->easy_handle;
debug("R: %d - %s\n", _curlMsg->data.result, curl_easy_strerror(_curlMsg->data.result));
curl_multi_remove_handle(_curlm, e);
curl_easy_cleanup(e);
if (_stream) {
const int kBufSize = 10000;
char buf[kBufSize+1];
uint32 readBytes = _stream->read(buf, kBufSize);
debug("%d", readBytes);
//if(readBytes != 0) debug("%s", buf);
if(_stream->eos()) {
_callback(0);
return true;
} else {
debug("E: CURLMsg (%d)\n", _curlMsg->msg);
}
}