diff --git a/src/AS/Ping.c b/src/AS/Ping.c index 88ac7cb..3a8ffb7 100644 --- a/src/AS/Ping.c +++ b/src/AS/Ping.c @@ -10,15 +10,16 @@ #include -void +bool ASPing(const ParseeConfig *conf) { HttpClientContext *ctx = NULL; HashMap *json = NULL; char *path; + bool ret; if (!conf) { - return; + return false; } path = StrConcat(3, @@ -33,7 +34,9 @@ ASPing(const ParseeConfig *conf) Free(path); json = HashMapCreate(); ASAuthenticateRequest(conf, ctx); - ParseeSetRequestJSON(ctx, json); + ret = ParseeSetRequestJSON(ctx, json) == HTTP_OK; HttpClientContextFree(ctx); JsonFree(json); + + return ret; } diff --git a/src/Main.c b/src/Main.c index cebb055..a9b0a50 100644 --- a/src/Main.c +++ b/src/Main.c @@ -58,6 +58,34 @@ static const Argument arguments[] = #undef Argument }; +void +ParseeCheckMatrix(void *datp) +{ + static volatile uint64_t streak = 0; + ParseeData *data = datp; + if (!ASPing(data->config)) + { + Log(LOG_ERR, "Cannot reach '%s' properly...", data->config->homeserver_host); + if (++streak >= 5) + { + Log(LOG_ERR, "This has been at least the fifth time in a row."); + Log(LOG_ERR, "Please check if your homeserver is active."); + Log(LOG_ERR, "%s shall now exit...", NAME); + + pthread_mutex_lock(&data->halt_lock); + data->halted = true; + pthread_mutex_unlock(&data->halt_lock); + + XMPPFinishCompStream(data->jabber); + pthread_join(xmpp_thr, NULL); + Log(LOG_INFO, "Stopping server..."); + HttpServerStop(data->server); + } + return; + } + streak = 0; +} + int Main(Array *args, HashMap *env) { @@ -259,6 +287,7 @@ Main(Array *args, HashMap *env) Log(LOG_NOTICE, "Starting up local cronjobs..."); cron = CronCreate(10 SECONDS); CronEvery(cron, 5 MINUTES, ParseeCleanup, conf.handlerArgs); + CronEvery(cron, 10 SECONDS, ParseeCheckMatrix, conf.handlerArgs); ParseeCleanup(conf.handlerArgs); CronStart(cron); diff --git a/src/Routes/Ping.c b/src/Routes/Ping.c new file mode 100644 index 0000000..a508336 --- /dev/null +++ b/src/Routes/Ping.c @@ -0,0 +1,38 @@ +#include + +#include + +#include +#include + +RouteHead(RoutePing, arr, argp) +{ + ParseeHttpArg *args = argp; + HashMap *request = NULL; + HashMap *response = NULL; + Array *events; + size_t i; + + response = ASVerifyRequest(args); + if (response) + { + goto end; + } + if (HttpRequestMethodGet(args->ctx) != HTTP_POST) + { + HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED); + response = MatrixCreateError( + "M_UNRECOGNIZED", + "Path /ping only accepts POST as a valid method." + ); + goto end; + } + + RequestJSON(); + + response = HashMapCreate(); +end: + (void) arr; + JsonFree(request); + return response; +} diff --git a/src/include/AS.h b/src/include/AS.h index 8afef6f..562d172 100644 --- a/src/include/AS.h +++ b/src/include/AS.h @@ -29,7 +29,7 @@ extern void ASAuthenticateRequest(const ParseeConfig *, HttpClientContext *); extern bool ASRegisterUser(const ParseeConfig *, char *); /* Pings the homeserver to get attention. */ -extern void ASPing(const ParseeConfig *); +extern bool ASPing(const ParseeConfig *); /** Joins a room from an {id} and a given {user} we want to masquerade * as. diff --git a/src/include/Routes.h b/src/include/Routes.h index 369a0d7..8d233e6 100644 --- a/src/include/Routes.h +++ b/src/include/Routes.h @@ -74,6 +74,7 @@ typedef struct ParseeCmdArg { X_ROUTE("/_matrix/app/v1/transactions/(.*)", RouteTxns) \ X_ROUTE("/_matrix/app/v1/users/(.*)", RouteUserAck) \ X_ROUTE("/_matrix/app/v1/rooms/(.*)", RouteRoomAck) \ + X_ROUTE("/_matrix/app/v1/ping", RoutePing) \ X_ROUTE("/_matrix/client/v1/media/download/(.*)/(.*)", RouteMedia) #define X_ROUTE(path, name) extern void * name(Array *, void *);