fallback if httpc is unavailable

This commit is contained in:
Sorunome 2019-10-27 19:55:05 +01:00
parent b99305ca82
commit 4f37d6b23a
No known key found for this signature in database
GPG key ID: 63E31F7B5993A9C4
2 changed files with 60 additions and 12 deletions

View file

@ -38,6 +38,12 @@ enum struct RequestError : u8 {
timeout, timeout,
}; };
enum struct ForceRequest : u8 {
none,
curl,
httpc,
};
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);
@ -65,7 +71,7 @@ public:
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);
void syncLoop(); void syncLoop();
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, ForceRequest forceRequest = ForceRequest::none);
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);
json_t* doRequestHttpc(const char* method, std::string url, json_t* body, u32 timeout); json_t* doRequestHttpc(const char* method, std::string url, json_t* body, u32 timeout);
public: public:
@ -73,7 +79,7 @@ public:
std::string getToken(); std::string getToken();
bool login(std::string username, std::string password); bool login(std::string username, std::string password);
void logout(); void logout();
std::string getUserId(); std::string getUserId(ForceRequest forceRequest = ForceRequest::none);
std::string resolveRoom(std::string alias); std::string resolveRoom(std::string alias);
std::vector<std::string> getJoinedRooms(); std::vector<std::string> getJoinedRooms();
RoomInfo getRoomInfo(std::string roomId); RoomInfo getRoomInfo(std::string roomId);

View file

@ -41,6 +41,7 @@ namespace Matrix {
static u32 *SOC_buffer = NULL; static u32 *SOC_buffer = NULL;
bool HTTPC_inited = false; bool HTTPC_inited = false;
bool haveHttpcSupport = false;
Client::Client(std::string homeserverUrl, std::string matrixToken, Store* clientStore) { Client::Client(std::string homeserverUrl, std::string matrixToken, Store* clientStore) {
hsUrl = homeserverUrl; hsUrl = homeserverUrl;
@ -91,11 +92,22 @@ void Client::logout() {
} }
} }
std::string Client::getUserId() { std::string Client::getUserId(ForceRequest forceRequest) {
if (forceRequest == ForceRequest::none) {
if (userIdCache != "") { if (userIdCache != "") {
return userIdCache; return userIdCache;
} }
json_t* ret = doRequest("GET", "/_matrix/client/r0/account/whoami"); std::string userIdHttpc = getUserId(ForceRequest::httpc);
std::string userIdCurl = getUserId(ForceRequest::curl);
haveHttpcSupport = userIdHttpc == userIdCurl;
if (haveHttpcSupport) {
printf_top("httpc support present\n");
} else {
printf_top("httpc support not present\n");
}
return userIdCurl;
}
json_t* ret = doRequest("GET", "/_matrix/client/r0/account/whoami", NULL, 5, forceRequest);
const char* userIdCStr = json_object_get_string_value(ret, "user_id"); const char* userIdCStr = json_object_get_string_value(ret, "user_id");
if (!userIdCStr) { if (!userIdCStr) {
if (ret) json_decref(ret); if (ret) json_decref(ret);
@ -721,22 +733,50 @@ 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, ForceRequest forceRequest) {
std::string url = hsUrl + path; std::string url = hsUrl + path;
requestId++; requestId++;
if (forceRequest == ForceRequest::curl) {
while(doingCurlRequest) {
svcSleepThread((u64)1000000ULL);
}
doingCurlRequest = true;
json_t* ret = doRequestCurl(method, url, body, timeout);
doingCurlRequest = false;
return ret;
}
if (forceRequest == ForceRequest::httpc) {
while(doingHttpcRequest) {
svcSleepThread((u64)1000000ULL);
}
doingHttpcRequest = true;
json_t* ret = doRequestHttpc(method, url, body, timeout);
doingHttpcRequest = false;
return ret;
}
if (haveHttpcSupport) {
while(doingCurlRequest && doingHttpcRequest) {
svcSleepThread((u64)1000000ULL);
}
if (!doingCurlRequest) { if (!doingCurlRequest) {
doingCurlRequest = true; doingCurlRequest = true;
json_t* ret = doRequestCurl(method, url, body, timeout); json_t* ret = doRequestCurl(method, url, body, timeout);
doingCurlRequest = false; doingCurlRequest = false;
return ret; return ret;
} else if (!doingHttpcRequest) { } else {
doingHttpcRequest = true; doingHttpcRequest = true;
json_t* ret = doRequestHttpc(method, url, body, timeout); json_t* ret = doRequestHttpc(method, url, body, timeout);
doingHttpcRequest = false; doingHttpcRequest = false;
return ret; return ret;
}
} else { } else {
return doRequestCurl(method, url, body, timeout); while(doingCurlRequest) {
svcSleepThread((u64)1000000ULL);
}
doingCurlRequest = true;
json_t* ret = doRequestCurl(method, url, body, timeout);
doingCurlRequest = false;
return ret;
} }
} }
@ -851,7 +891,7 @@ json_t* Client::doRequestHttpc(const char* method, std::string url, json_t* body
ret = httpcBeginRequest(&context); ret = httpcBeginRequest(&context);
if (bodyStr) free(bodyStr); if (bodyStr) free(bodyStr);
if (ret) { if (ret) {
printf_top("Failed to perform request %ld\n", ret); printf_top("Failed to perform request %lu\n", ret);
httpcCloseContext(&context); httpcCloseContext(&context);
return NULL; return NULL;
} }
@ -862,8 +902,10 @@ 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));
// printf_top("Status code: %lu\n", statusCode);
ret = httpcGetDownloadSizeState(&context, NULL, &contentSize); ret = httpcGetDownloadSizeState(&context, NULL, &contentSize);
if (ret != 0) { if (ret != 0) {
printf_top("Failed getDownloadSizeState %lu\n", ret);
httpcCloseContext(&context); httpcCloseContext(&context);
return NULL; return NULL;
} }