From e0c8530b120057ba0022abe6b9bd719f3712f542 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 1 Apr 2023 02:46:07 +0000 Subject: [PATCH] Clean up http client enough to replace curl in send-patch. --- src/Io/IoFile.c | 10 +++++++++- src/Stream.c | 25 +++++++++++++++++++++++++ src/include/Stream.h | 3 +++ tools/bin/send-patch | 34 +++++++++++++++++++--------------- tools/src/http.c | 17 +++++++++++++++++ 5 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/Io/IoFile.c b/src/Io/IoFile.c index 1783cd0..cdd40ab 100644 --- a/src/Io/IoFile.c +++ b/src/Io/IoFile.c @@ -52,8 +52,16 @@ static off_t IoSeekFile(void *cookie, off_t offset, int whence) { FILE *fp = cookie; + off_t ret = fseeko(fp, offset, whence); - return fseeko(fp, offset, whence); + if (ret > -1) + { + return ftello(fp); + } + else + { + return ret; + } } static int diff --git a/src/Stream.c b/src/Stream.c index cfc0311..fba7f22 100644 --- a/src/Stream.c +++ b/src/Stream.c @@ -521,6 +521,31 @@ StreamGets(Stream * stream, char *str, int size) return str; } +off_t +StreamSeek(Stream *stream, off_t offset, int whence) +{ + off_t result; + + if (!stream) + { + errno = EBADF; + return -1; + } + + result = IoSeek(stream->io, offset, whence); + if (result < 0) + { + return result; + } + + /* Successful seek; clear the buffers */ + stream->rOff = 0; + stream->wLen = 0; + stream->ugLen = 0; + + return result; +} + int StreamEof(Stream * stream) { diff --git a/src/include/Stream.h b/src/include/Stream.h index ec22ee3..8293ace 100644 --- a/src/include/Stream.h +++ b/src/include/Stream.h @@ -75,6 +75,9 @@ extern int extern char * StreamGets(Stream *, char *, int); +extern off_t + StreamSeek(Stream *, off_t, int); + extern int StreamEof(Stream *); diff --git a/tools/bin/send-patch b/tools/bin/send-patch index b8d364b..ca4d416 100755 --- a/tools/bin/send-patch +++ b/tools/bin/send-patch @@ -24,13 +24,13 @@ readpwd() { stty echo ctlecho } -# Calls curl, setting the RETURN variable for the actual -# reply from the server and the ERROR_CODE variable for a -# HTTP error code. -curlec() { - RETURN="$(curl -w "\n%{http_code}" "$@" 2>/dev/null)" - ERROR_CODE="$(echo "$RETURN" | tail -n1)" - RETURN="$(echo "$RETURN" | sed '$d')" +# Makes an HTTP request, setting the RETURN variable for the +# actual reply from the server and the ERROR_CODE variable +# for a HTTP error code. +request() { + RETURN=$(http -i "$@" 2>/dev/null) + ERROR_CODE=$(echo "$RETURN" | head -n1 | awk '{print $2}') + RETURN=$(echo "$RETURN" | sed '1,/^[[:space:]]*$/d') } # Prompts user to login and gives out an access token to use @@ -38,7 +38,7 @@ curlec() { matrix_login() { # Check authentication methods echo "Checking authentication methods..." - curlec "$HS_BASE/_matrix/client/v3/login" + request "$HS_BASE/_matrix/client/v3/login" AUTH_METHODS=$RETURN if [ $ERROR_CODE -ne 200 ]; then echo "Homeserver does not support login." @@ -66,10 +66,11 @@ matrix_login() { printf ' "password": %s' "$(json -e "$MXPW")" printf '}' ) - curlec -X POST -d "$JSON" $HS_BASE/_matrix/client/v3/login - LOGIN=$RETURN + request -X POST -d "$JSON" $HS_BASE/_matrix/client/v3/login + LOGIN="$RETURN" if [ $ERROR_CODE -ne 200 ]; then echo "Login failed." + echo "$RETURN" exit 1 fi ACCESS_TOKEN=$(echo "$LOGIN" | json -s "access_token->@decode") @@ -81,10 +82,11 @@ matrix_logout() { echo "No access token" exit 1 fi - curlec -X POST $HS_BASE/_matrix/client/v3/logout -H "Authorization: Bearer $ACCESS_TOKEN" + request -X POST -H "Authorization: Bearer $ACCESS_TOKEN" "$HS_BASE/_matrix/client/v3/logout" LOGOUT=$RETURN if [ $ERROR_CODE -ne 200 ]; then echo "Logout failed." + echo "$RETURN" exit 1 fi echo "Logged out." @@ -98,13 +100,15 @@ send_patch() { # We are sucessfully logged in as our user, now let's # try to upload and post our patch echo "$PATCHFILE" - curlec -X POST "$HS_BASE/_matrix/media/v3/upload" \ + request -X POST \ -H "Content-Type: text/x-patch" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ - -T "$PATCHFILE" + -d "@$PATCHFILE" \ + "$HS_BASE/_matrix/media/v3/upload" MXCID=$RETURN if [ $ERROR_CODE -ne 200 ]; then echo "Upload failed." + echo "$RETURN" matrix_logout exit 1 fi @@ -123,7 +127,7 @@ send_patch() { printf ' "url": %s' "$(json -e $MXCID)" printf '}' ) - curl -X PUT -d "$JSON" -H "Authorization: Bearer $ACCESS_TOKEN" \ + http -X PUT -d "$JSON" -H "Authorization: Bearer $ACCESS_TOKEN" \ "$HS_BASE/_matrix/client/v3/rooms/$PATCHES_ROOM/send/m.room.message/$(date +%s)" \ 2>/dev/null >/dev/null && echo "Patch sent." @@ -140,7 +144,7 @@ if [ "$(basename "$PATCHFILE" .patch)" = "$PATCHFILE" ] || [ ! -f "$PATCHFILE" ] fi echo "Sending file '$PATCHFILE'" echo "Checking homeserver's real address using .well-known..." -curlec "https://$HS_NAME/.well-known/matrix/client" +request "https://$HS_NAME/.well-known/matrix/client" case "$ERROR_CODE" in "200") WELL_KNOWN=$RETURN diff --git a/tools/src/http.c b/tools/src/http.c index c48855d..19cef82 100644 --- a/tools/src/http.c +++ b/tools/src/http.c @@ -162,6 +162,7 @@ main(int argc, char **argv) if (*data == '@') { Stream *in; + int len; data++; @@ -180,6 +181,22 @@ main(int argc, char **argv) return 1; } + len = StreamSeek(in, 0, SEEK_END); + if (len > -1) + { + char *lenStr; + int nBytes; + + StreamSeek(in, 0, SEEK_SET); + nBytes = snprintf(NULL, 0, "%d", len); + + lenStr = Malloc(nBytes + 1); + snprintf(lenStr, nBytes + 1, "%d", len); + + HttpRequestHeader(cx, "Content-Length", lenStr); + Free(lenStr); + } + HttpRequestSendHeaders(cx); StreamCopy(in, HttpClientStream(cx)); StreamClose(in);