better error passing around
This commit is contained in:
parent
ec282dab0d
commit
2e9ff07df6
4 changed files with 16 additions and 54 deletions
|
@ -6,6 +6,7 @@
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
namespace Matrix {
|
namespace Matrix {
|
||||||
|
|
||||||
|
@ -33,11 +34,6 @@ struct ExtraRoomInfo {
|
||||||
std::map<std::string, MemberInfo> members;
|
std::map<std::string, MemberInfo> members;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct RequestError : u8 {
|
|
||||||
none,
|
|
||||||
timeout,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*eventCallback)(std::string roomId, json_t* event);
|
typedef void (*eventCallback)(std::string roomId, json_t* event);
|
||||||
typedef void (*roomInfoCallback)(std::string roomId, RoomInfo info);
|
typedef void (*roomInfoCallback)(std::string roomId, RoomInfo info);
|
||||||
typedef void (*roomLimitedCallback)(std::string roomId, std::string prevBatch);
|
typedef void (*roomLimitedCallback)(std::string roomId, std::string prevBatch);
|
||||||
|
@ -52,7 +48,6 @@ private:
|
||||||
bool stopSyncing = false;
|
bool stopSyncing = false;
|
||||||
bool isSyncing = false;
|
bool isSyncing = false;
|
||||||
Thread syncThread;
|
Thread syncThread;
|
||||||
RequestError lastRequestError;
|
|
||||||
struct {
|
struct {
|
||||||
eventCallback event = NULL;
|
eventCallback event = NULL;
|
||||||
eventCallback leaveRoom = NULL;
|
eventCallback leaveRoom = NULL;
|
||||||
|
@ -62,9 +57,9 @@ private:
|
||||||
} callbacks;
|
} callbacks;
|
||||||
void processSync(json_t* sync);
|
void processSync(json_t* sync);
|
||||||
void registerFilter();
|
void registerFilter();
|
||||||
json_t* doSync(std::string token, std::string filter, u32 timeout);
|
json_t* doSync(std::string token, std::string filter, u32 timeout, CURLcode* res);
|
||||||
json_t* doRequest(const char* method, std::string path, json_t* body = NULL, u32 timeout = 5);
|
json_t* doRequest(const char* method, std::string path, json_t* body = NULL, u32 timeout = 5, CURLcode* retRes = NULL);
|
||||||
json_t* doRequestCurl(const char* method, std::string url, json_t* body, u32 timeout);
|
json_t* doRequestCurl(const char* method, std::string url, json_t* body, u32 timeout, CURLcode* retRes);
|
||||||
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();
|
||||||
|
|
|
@ -683,7 +683,8 @@ void Client::syncLoop() {
|
||||||
registerFilter();
|
registerFilter();
|
||||||
filterId = store->getFilterId();
|
filterId = store->getFilterId();
|
||||||
}
|
}
|
||||||
json_t* ret = doSync(token, filterId, timeout);
|
CURLcode res;
|
||||||
|
json_t* ret = doSync(token, filterId, timeout, &res);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
timeout = 60;
|
timeout = 60;
|
||||||
// set the token for the next batch
|
// set the token for the next batch
|
||||||
|
@ -696,7 +697,7 @@ void Client::syncLoop() {
|
||||||
processSync(ret);
|
processSync(ret);
|
||||||
json_decref(ret);
|
json_decref(ret);
|
||||||
} else {
|
} else {
|
||||||
if (lastRequestError == RequestError::timeout) {
|
if (res == CURLE_OPERATION_TIMEDOUT) {
|
||||||
timeout += 10*60;
|
timeout += 10*60;
|
||||||
printf_top("Timeout reached, increasing it to %lu\n", timeout);
|
printf_top("Timeout reached, increasing it to %lu\n", timeout);
|
||||||
}
|
}
|
||||||
|
@ -705,14 +706,14 @@ void Client::syncLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t* Client::doSync(std::string token, std::string filter, u32 timeout) {
|
json_t* Client::doSync(std::string token, std::string filter, u32 timeout, CURLcode* res) {
|
||||||
// printf_top("Doing sync with token %s\n", token.c_str());
|
// printf_top("Doing sync with token %s\n", token.c_str());
|
||||||
|
|
||||||
std::string query = "?full_state=false&timeout=" + std::to_string(SYNC_TIMEOUT) + "&filter=" + urlencode(filter);
|
std::string query = "?full_state=false&timeout=" + std::to_string(SYNC_TIMEOUT) + "&filter=" + urlencode(filter);
|
||||||
if (token != "") {
|
if (token != "") {
|
||||||
query += "&since=" + token;
|
query += "&since=" + token;
|
||||||
}
|
}
|
||||||
return doRequest("GET", "/_matrix/client/r0/sync" + query, NULL, timeout);
|
return doRequest("GET", "/_matrix/client/r0/sync" + query, NULL, timeout, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -724,10 +725,10 @@ size_t DoRequestWriteCallback(char *contents, size_t size, size_t nmemb, void *u
|
||||||
bool doingCurlRequest = false;
|
bool doingCurlRequest = false;
|
||||||
bool doingHttpcRequest = false;
|
bool doingHttpcRequest = false;
|
||||||
|
|
||||||
json_t* Client::doRequest(const char* method, std::string path, json_t* body, u32 timeout) {
|
json_t* Client::doRequest(const char* method, std::string path, json_t* body, u32 timeout, CURLcode* retRes) {
|
||||||
std::string url = hsUrl + path;
|
std::string url = hsUrl + path;
|
||||||
requestId++;
|
requestId++;
|
||||||
return doRequestCurl(method, url, body, timeout);
|
return doRequestCurl(method, url, body, timeout, retRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLM* curl_multi_handle;
|
CURLM* curl_multi_handle;
|
||||||
|
@ -743,9 +744,6 @@ void curl_multi_loop(void* p) {
|
||||||
printf_top("curl multi fail: %u\n", mc);
|
printf_top("curl multi fail: %u\n", mc);
|
||||||
}
|
}
|
||||||
// curl_multi_wait(curl_multi_handle, NULL, 0, 1000, &openHandles);
|
// curl_multi_wait(curl_multi_handle, NULL, 0, 1000, &openHandles);
|
||||||
if (!openHandles) {
|
|
||||||
svcSleepThread((u64)1000000ULL * 100);
|
|
||||||
}
|
|
||||||
CURLMsg* msg;
|
CURLMsg* msg;
|
||||||
int msgsLeft;
|
int msgsLeft;
|
||||||
while ((msg = curl_multi_info_read(curl_multi_handle, &msgsLeft))) {
|
while ((msg = curl_multi_info_read(curl_multi_handle, &msgsLeft))) {
|
||||||
|
@ -753,10 +751,13 @@ void curl_multi_loop(void* p) {
|
||||||
curl_handles_done[msg->easy_handle] = msg->data.result;
|
curl_handles_done[msg->easy_handle] = msg->data.result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!openHandles) {
|
||||||
|
svcSleepThread((u64)1000000ULL * 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body, u32 timeout) {
|
json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body, u32 timeout, CURLcode* retRes) {
|
||||||
printf_top("Opening Request %d with CURL\n%s\n", requestId, url.c_str());
|
printf_top("Opening Request %d with CURL\n%s\n", requestId, url.c_str());
|
||||||
|
|
||||||
if (!SOC_buffer) {
|
if (!SOC_buffer) {
|
||||||
|
@ -817,11 +818,9 @@ json_t* Client::doRequestCurl(const char* method, std::string url, json_t* body,
|
||||||
// curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
|
// curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
if (bodyStr) free(bodyStr);
|
if (bodyStr) free(bodyStr);
|
||||||
|
if (retRes) *retRes = res;
|
||||||
if (res != CURLE_OK) {
|
if (res != CURLE_OK) {
|
||||||
printf_top("curl res not ok %d\n", res);
|
printf_top("curl res not ok %d\n", res);
|
||||||
if (res == CURLE_OPERATION_TIMEDOUT) {
|
|
||||||
lastRequestError = RequestError::timeout;
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,36 +25,6 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* json_object_get_string_value(json_t* obj, const char* key) {
|
char* json_object_get_string_value(json_t* obj, const char* key) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
std::string urlencode(std::string str);
|
std::string urlencode(std::string str);
|
||||||
|
|
||||||
Result httpcDownloadDataTimeout(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize, u64 timeout);
|
|
||||||
|
|
||||||
char* json_object_get_string_value(json_t* obj, const char* key);
|
char* json_object_get_string_value(json_t* obj, const char* key);
|
||||||
|
|
||||||
#endif // _UTIL_H_
|
#endif // _UTIL_H_
|
||||||
|
|
Loading…
Reference in a new issue