diff --git a/TODO.txt b/TODO.txt index 82410dd..d6f627d 100644 --- a/TODO.txt +++ b/TODO.txt @@ -25,6 +25,7 @@ Milestone: v0.3.0 [ ] Document JsonEncode() and JsonEncodeValue() [ ] Update man page for td [ ] Document Telodendria and Main +[ ] Document tt and http-debug-server [~] Simple command line tool to make matrix requests [x] Built on HTTP client API diff --git a/src/HttpServer.c b/src/HttpServer.c index 10d76d0..4d95a94 100644 --- a/src/HttpServer.c +++ b/src/HttpServer.c @@ -444,8 +444,8 @@ HttpServerWorkerThread(void *args) * Every once in a while, we're too fast for the client. When this * happens, UtilGetLine() sets errno to EAGAIN. If we get * EAGAIN, then clear the error on the stream and try again - * after a few ms. This is typically more than enough time for the - * client to send data. */ + * after a few ms. This is typically more than enough time for + * the client to send data. */ firstRead = UtilServerTs(); while ((lineLen = UtilGetLine(&line, &lineSize, fp)) == -1 && errno == EAGAIN) diff --git a/src/Json.c b/src/Json.c index 4f6704d..41b3ea8 100644 --- a/src/Json.c +++ b/src/Json.c @@ -706,6 +706,7 @@ static int JsonConsumeWhitespace(JsonParserState * state) { int c; + while (1) { c = fgetc(state->stream); diff --git a/src/Util.c b/src/Util.c index 129a340..9bf20d9 100644 --- a/src/Util.c +++ b/src/Util.c @@ -302,7 +302,7 @@ UtilGetLine(char **linePtr, size_t * n, FILE * stream) } size_t -UtilStreamCopy(FILE *in, FILE *out) +UtilStreamCopy(FILE * in, FILE * out) { size_t bytes = 0; int c; diff --git a/src/include/Util.h b/src/include/Util.h index 0476cd1..8006fbc 100644 --- a/src/include/Util.h +++ b/src/include/Util.h @@ -51,6 +51,6 @@ extern ssize_t UtilGetLine(char **, size_t *, FILE *); extern size_t -UtilStreamCopy(FILE *, FILE *); + UtilStreamCopy(FILE *, FILE *); #endif /* TELODENDRIA_UTIL_H */ diff --git a/tools/bin/tt b/tools/bin/tt new file mode 100755 index 0000000..e2ada05 --- /dev/null +++ b/tools/bin/tt @@ -0,0 +1,48 @@ +#!/usr/bin/env sh + +BASE="http://localhost:8008" +USERNAME="tt_user" +PASSWORD=$(json -e 'p@s$w0rd') + +ENDPOINT="$1" + +# Check if user is available. If it is, register it. +user_available=$(http "$BASE/_matrix/client/v3/register/available?username=$USERNAME" | json -s "available") +if [ "$user_available" = "true" ]; then + session=$(echo '{}' | http -X POST "$BASE/_matrix/client/v3/register" | json -s "session->@decode") + ( + printf '{' + printf ' "auth": {' + printf ' "type": "m.login.dummy",' + printf ' "session": %s' "$(json -e "$session")" + printf ' },' + printf ' "username": %s,' "$(json -e "$USERNAME")" + printf ' "password": %s,' "$PASSWORD" + printf ' "inhibit_login": true ' + printf '}' + ) | http -X POST "$BASE/_matrix/client/v3/register" > /dev/null +fi + +# Log in +ACCESS_TOKEN=$(( + printf '{' + printf ' "identifier": {' + printf ' "type": "m.id.user",' + printf ' "user": %s' "$(json -e "$USERNAME")" + printf ' },' + printf ' "type": "m.login.password",' + printf ' "password": %s' "$PASSWORD" + printf '}' +) | http -X POST "$BASE/_matrix/client/v3/login" | json -s "access_token->@decode") + +if [ -z "$ACCESS_TOKEN" ]; then + echo "Unable to log in." + exit 1 +fi + +# Make request +http -X POST -H "Authorization: Bearer $ACCESS_TOKEN" "$BASE$ENDPOINT" | json + +# Log out +http -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \ + "$BASE/_matrix/client/v3/logout" > /dev/null diff --git a/tools/src/http-debug-server.c b/tools/src/http-debug-server.c new file mode 100644 index 0000000..af77a50 --- /dev/null +++ b/tools/src/http-debug-server.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include +#include + +#include +#include + +static HttpServer *server = NULL; + +static void +SignalHandle(int signal) +{ + (void) signal; + HttpServerStop(server); +} + +static void +HttpHandle(HttpServerContext * cx, void *args) +{ + HashMap *headers = HttpRequestHeaders(cx); + HttpRequestMethod method = HttpRequestMethodGet(cx); + + char *key; + char *val; + + size_t bytes; + + printf("%s %s\n", HttpRequestMethodToString(method), + HttpRequestPath(cx)); + + while (HashMapIterate(headers, &key, (void **) &val)) + { + printf("%s: %s\n", key, val); + } + + printf("\n"); + + bytes = UtilStreamCopy(HttpStream(cx), stdout); + + printf("\n"); + printf("(%lu bytes)\n", bytes); + + HttpSendHeaders(cx); + + fprintf(HttpStream(cx), "{}\n"); +} + +int +main(void) +{ + struct sigaction sa; + + server = HttpServerCreate(8008, 1, 1, HttpHandle, NULL); + if (!HttpServerStart(server)) + { + fprintf(stderr, "Unable to start HTTP server.\n"); + HttpServerFree(server); + return 1; + } + + printf("Listening on port 8008.\n"); + + sa.sa_handler = SignalHandle; + sigfillset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + if (sigaction(SIGINT, &sa, NULL) < 0) + { + fprintf(stderr, "Unable to install signal handler.\n"); + HttpServerStop(server); + HttpServerJoin(server); + HttpServerFree(server); + return 1; + } + + HttpServerJoin(server); + + printf("Shutting down.\n"); + HttpServerStop(server); + return 0; +}