curl timeout management
This commit is contained in:
parent
b9bbcf0209
commit
08ed4523f3
3 changed files with 71 additions and 14 deletions
|
@ -25,6 +25,11 @@ struct UserInfo {
|
||||||
std::string avatarUrl;
|
std::string avatarUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum struct RequestError : u8 {
|
||||||
|
none,
|
||||||
|
timeout,
|
||||||
|
};
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
private:
|
private:
|
||||||
public:
|
public:
|
||||||
|
@ -36,13 +41,14 @@ public:
|
||||||
bool stopSyncing = false;
|
bool stopSyncing = false;
|
||||||
bool isSyncing = false;
|
bool isSyncing = false;
|
||||||
Thread syncThread;
|
Thread syncThread;
|
||||||
|
RequestError lastRequestError;
|
||||||
void (* sync_event_callback)(std::string roomId, json_t* event) = 0;
|
void (* sync_event_callback)(std::string roomId, json_t* event) = 0;
|
||||||
void processSync(json_t* sync);
|
void processSync(json_t* sync);
|
||||||
json_t* doSync(std::string token);
|
json_t* doSync(std::string token, int timeout);
|
||||||
void startSync();
|
void startSync();
|
||||||
json_t* doRequest(const char* method, std::string path, json_t* body = NULL);
|
json_t* doRequest(const char* method, std::string path, json_t* body = NULL, int timeout = 5);
|
||||||
json_t* doRequestCurl(const char* method, std::string url, json_t* body = NULL);
|
json_t* doRequestCurl(const char* method, std::string url, json_t* body, int timeout);
|
||||||
json_t* doRequestHttpc(const char* method, std::string url, json_t* body = NULL);
|
json_t* doRequestHttpc(const char* method, std::string url, json_t* body, int timeout);
|
||||||
public:
|
public:
|
||||||
Client(std::string homeserverUrl, std::string matrixToken = "", Store* clientStore = NULL);
|
Client(std::string homeserverUrl, std::string matrixToken = "", Store* clientStore = NULL);
|
||||||
std::string getToken();
|
std::string getToken();
|
||||||
|
|
|
@ -407,13 +407,15 @@ void Client::processSync(json_t* sync) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::startSync() {
|
void Client::startSync() {
|
||||||
|
int timeout = 60;
|
||||||
while (true) {
|
while (true) {
|
||||||
std::string token = store->getSyncToken();
|
std::string token = store->getSyncToken();
|
||||||
if (stopSyncing) {
|
if (stopSyncing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
json_t* ret = doSync(token);
|
json_t* ret = doSync(token, timeout);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
timeout = 60;
|
||||||
// set the token for the next batch
|
// set the token for the next batch
|
||||||
json_t* token = json_object_get(ret, "next_batch");
|
json_t* token = json_object_get(ret, "next_batch");
|
||||||
if (token) {
|
if (token) {
|
||||||
|
@ -423,19 +425,24 @@ void Client::startSync() {
|
||||||
}
|
}
|
||||||
processSync(ret);
|
processSync(ret);
|
||||||
json_decref(ret);
|
json_decref(ret);
|
||||||
|
} else {
|
||||||
|
if (lastRequestError == RequestError::timeout) {
|
||||||
|
timeout += 10*60;
|
||||||
|
D printf_top("Timeout reached, increasing it to %d\n", timeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svcSleepThread((u64)1000000ULL * (u64)200);
|
svcSleepThread((u64)1000000ULL * (u64)200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t* Client::doSync(std::string token) {
|
json_t* Client::doSync(std::string token, int timeout) {
|
||||||
// D printf_top("Doing sync with token %s\n", token.c_str());
|
// D printf_top("Doing sync with token %s\n", token.c_str());
|
||||||
|
|
||||||
std::string query = "?full_state=false&timeout=" + std::to_string(SYNC_TIMEOUT);
|
std::string query = "?full_state=false&timeout=" + std::to_string(SYNC_TIMEOUT);
|
||||||
if (token != "") {
|
if (token != "") {
|
||||||
query += "&since=" + token;
|
query += "&since=" + token;
|
||||||
}
|
}
|
||||||
return doRequest("GET", "/_matrix/client/r0/sync" + query, NULL);
|
return doRequest("GET", "/_matrix/client/r0/sync" + query, NULL, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DoRequestWriteCallback(char *contents, size_t size, size_t nmemb, void *userp) {
|
size_t DoRequestWriteCallback(char *contents, size_t size, size_t nmemb, void *userp) {
|
||||||
|
@ -444,21 +451,30 @@ size_t DoRequestWriteCallback(char *contents, size_t size, size_t nmemb, void *u
|
||||||
}
|
}
|
||||||
|
|
||||||
bool doingCurlRequest = false;
|
bool doingCurlRequest = false;
|
||||||
|
bool doingHttpcRequest = false;
|
||||||
|
|
||||||
json_t* Client::doRequest(const char* method, std::string path, json_t* body) {
|
json_t* Client::doRequest(const char* method, std::string path, json_t* body, int timeout) {
|
||||||
std::string url = hsUrl + path;
|
std::string url = hsUrl + path;
|
||||||
requestId++;
|
requestId++;
|
||||||
|
return doRequestCurl(method, url, body, timeout);
|
||||||
|
/*
|
||||||
if (!doingCurlRequest) {
|
if (!doingCurlRequest) {
|
||||||
doingCurlRequest = true;
|
doingCurlRequest = true;
|
||||||
json_t* ret = doRequestCurl(method, url, body);
|
json_t* ret = doRequestCurl(method, url, body, timeout);
|
||||||
doingCurlRequest = false;
|
doingCurlRequest = false;
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if (!doingHttpcRequest) {
|
||||||
|
doingHttpcRequest = true;
|
||||||
|
json_t* ret = doRequestHttpc(method, url, body, timeout);
|
||||||
|
doingHttpcRequest = false;
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
return doRequestHttpc(method, url, body);
|
return doRequestCurl(method, url, body, timeout);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body) {
|
json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body, int timeout) {
|
||||||
D printf_top("Opening Request %d with CURL\n%s\n", requestId, url.c_str());
|
D printf_top("Opening Request %d with CURL\n%s\n", requestId, url.c_str());
|
||||||
|
|
||||||
if (!SOC_buffer) {
|
if (!SOC_buffer) {
|
||||||
|
@ -499,7 +515,7 @@ json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body)
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DoRequestWriteCallback);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DoRequestWriteCallback);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
|
||||||
|
|
||||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
// curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
|
// curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
|
||||||
|
@ -507,6 +523,9 @@ json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body)
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
if (res != CURLE_OK) {
|
if (res != CURLE_OK) {
|
||||||
D printf_top("curl res not ok %d\n", res);
|
D printf_top("curl res not ok %d\n", res);
|
||||||
|
if (res == CURLE_OPERATION_TIMEDOUT) {
|
||||||
|
lastRequestError = RequestError::timeout;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +539,7 @@ json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body)
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t* Client::doRequestHttpc(const char* method, std::string url, json_t* body) {
|
json_t* Client::doRequestHttpc(const char* method, std::string url, json_t* body, int timeout) {
|
||||||
D printf_top("Opening Request %d with HTTPC\n%s\n", requestId, url.c_str());
|
D printf_top("Opening Request %d with HTTPC\n%s\n", requestId, url.c_str());
|
||||||
|
|
||||||
if (!HTTPC_inited) {
|
if (!HTTPC_inited) {
|
||||||
|
@ -565,7 +584,7 @@ json_t* Client::doRequestHttpc(const char* method, std::string url, json_t* body
|
||||||
}
|
}
|
||||||
ret = httpcBeginRequest(&context);
|
ret = httpcBeginRequest(&context);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
D printf_top("Failed to perform request\n");
|
D printf_top("Failed to perform request %ld\n", ret);
|
||||||
httpcCloseContext(&context);
|
httpcCloseContext(&context);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -576,6 +595,7 @@ json_t* Client::doRequestHttpc(const char* method, std::string url, json_t* body
|
||||||
url = std::string(newUrl);
|
url = std::string(newUrl);
|
||||||
}
|
}
|
||||||
} while ((statusCode >= 301 && statusCode <= 303) || (statusCode >= 307 && statusCode <= 308));
|
} while ((statusCode >= 301 && statusCode <= 303) || (statusCode >= 307 && statusCode <= 308));
|
||||||
|
D printf_top("Request http thingy successful\n");
|
||||||
ret = httpcGetDownloadSizeState(&context, NULL, &contentSize);
|
ret = httpcGetDownloadSizeState(&context, NULL, &contentSize);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
httpcCloseContext(&context);
|
httpcCloseContext(&context);
|
||||||
|
|
|
@ -22,3 +22,34 @@ std::string urlencode(std::string s) {
|
||||||
}
|
}
|
||||||
return e.str();
|
return e.str();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Result httpcDownloadDataTimeout(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize, u64 timeout)
|
||||||
|
{
|
||||||
|
Result ret=0;
|
||||||
|
Result dlret=HTTPC_RESULTCODE_DOWNLOADPENDING;
|
||||||
|
u32 pos=0, sz=0;
|
||||||
|
u32 dlstartpos=0;
|
||||||
|
u32 dlpos=0;
|
||||||
|
|
||||||
|
if(downloadedsize)*downloadedsize = 0;
|
||||||
|
|
||||||
|
ret=httpcGetDownloadSizeState(context, &dlstartpos, NULL);
|
||||||
|
if(R_FAILED(ret))return ret;
|
||||||
|
|
||||||
|
while(pos < size && dlret==HTTPC_RESULTCODE_DOWNLOADPENDING)
|
||||||
|
{
|
||||||
|
sz = size - pos;
|
||||||
|
|
||||||
|
dlret=httpcReceiveDataTimeout(context, &buffer[pos], sz, timeout);
|
||||||
|
|
||||||
|
ret=httpcGetDownloadSizeState(context, &dlpos, NULL);
|
||||||
|
if(R_FAILED(ret))return ret;
|
||||||
|
|
||||||
|
pos = dlpos - dlstartpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(downloadedsize)*downloadedsize = pos;
|
||||||
|
|
||||||
|
return dlret;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in a new issue