From 5dcc4c8bf768e78abaa35004db25a0f09f90a6a5 Mon Sep 17 00:00:00 2001 From: Kevin Jerebica Date: Thu, 12 Sep 2024 19:31:01 +0200 Subject: [PATCH] proxy: finish re-writing all proxy states Also fix some new bugs that showed up. Proxying now works with HTTP websites but only the ones which serve their content through the content-length HTTP header field --- Makefile | 2 +- parslib | 2 +- proxlib | Bin 138120 -> 139312 bytes proxlib.c | 175 +++++++++++++++++++++++++++++++++++++++++++----------- proxlib.h | 5 ++ 5 files changed, 148 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 912d294..c368cf2 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC=bear --append -- gcc -CFLAGS= -g3 -Wall -Werror +CFLAGS=-g3 CFILES=proxlib.c CFILES_PARSLIB=parslib/parslib.final.o OUT=proxlib diff --git a/parslib b/parslib index 678a442..5583508 160000 --- a/parslib +++ b/parslib @@ -1 +1 @@ -Subproject commit 678a44228fe0c5b24b2d1b96576da0e44211c364 +Subproject commit 55835087d359f77d00030b3dffb1cd43980722ee diff --git a/proxlib b/proxlib index 9657c200e5b6215a05caf6af6bdaa50d3d1e80b2..f37cdbe83635eea3953accd74fe399e7d9dba400 100755 GIT binary patch delta 41218 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 HK$ZKyt3eB@ delta 37987 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 { + ret = write(conn->cltfd, conn->srvbuff+bytes, conn->srvbuff_len-bytes); if (ret < 0) return -1; bytes += ret; - }*/ + } return 0; } -// TODO: add parsing ability -int do_prs_srv(void) { - int ret = 0; - return ret; -} +int do_rcv_srv(struct conn *conn) { + int ret = 0; + char *line = NULL; + char *msgbuff = NULL; + int line_len = 0; + int msgbuff_len = 0; -int do_rcv_srv(void) { - /*int bytes = 0; - int ret = 0; - while (bytes < PROXY_MAX_MSGLEN) { - ret = recv(srv_sock, srv_msg+bytes, PROXY_MAX_MSGLEN-bytes, MSG_PEEK); - if (ret < 0) - return -1; - if (!ret) - break; - ret = recv(srv_sock, srv_msg+bytes, PROXY_MAX_MSGLEN-bytes, 0); - - bytes += ret; + // response line + ret = read_line(conn->srvfd, &line_len, &line, &msgbuff_len, &msgbuff); + if (ret < 0) { + fprintf(stderr, "Failed receiving response line from upstream\n"); + return -1; } - srv_msg_len = bytes; + if (debug == 1) { + fprintf(stdout, "debug - [upstream] received line: %s\n", line); + } - if (debug == 1) - fprintf(stdout, "[%d] Received server message of size %d bytes\n", statem, srv_msg_len); - */ + ret = parestitl(line, line_len, &(conn->srvres.titl)); + if (ret < 0) { + fprintf(stderr, "Failed parsing response line\n"); + return -1; + } + + if (debug == 1) { + fprintf(stdout, "debug - [upstream] parsed response line\n"); + } + + free(line); + + // headers + int next_header = 1; + while (next_header) { + ret = read_line(conn->srvfd, &line_len, &line, &msgbuff_len, &msgbuff); + if (ret < 0) { + fprintf(stderr, "Failed receiving header line\n"); + return -1; + } + + if (line_len == 0) { + if (debug == 1) { + fprintf(stdout, "debug - [upstream] reached end of headers\n"); + } + next_header = 0; + continue; + } + + if (debug == 1) { + fprintf(stdout, "debug - [upstream] received line: %s\n", line); + } + + ret = parshfield(line, line_len, conn->srvres.hentries); + if (ret < 0) { + fprintf(stderr, "Failed parsing header field\n"); + return -1; + } + + if (debug == 1) { + fprintf(stdout, "debug - parsed header field\n"); + } + + free(line); + } + + // body +body: + struct httpares *res = &conn->srvres; + struct point *content_length_entry = &res->hentries[header_content_length]; + if (content_length_entry->er == NULL) { + fprintf(stderr, "[upstream] no content length header\n"); + return -1; + } + + int content_length = 0; + ret = stoin(content_length_entry->er, content_length_entry->len, &content_length); + if (ret < 0) { + fprintf(stderr, "[upstream] failed parsing content length header\n"); + return -1; + } + + line_len = content_length; + line = (char *) calloc(1, line_len); + if (!line) { + fprintf(stderr, "[upstream] not enough dynamic memory\n"); + return -1; + } + + int bytes = 0; + do { + ret = recv(conn->srvfd, line+bytes, line_len-bytes, MSG_WAITALL); + if (ret < 0) { + fprintf(stderr, "[upstream] failed reading body from response\n"); + return -1; + } + bytes += ret; + } while (bytes < line_len); + + msgbuff = (char *) realloc(msgbuff, msgbuff_len+line_len); + if (!msgbuff) { + fprintf(stderr, "[upstream] not enough dynamic memory\n"); + return -1; + } + + memcpy(msgbuff+msgbuff_len, line, line_len); + msgbuff_len += line_len; + + if (debug <= 2) { + fprintf(stdout, "------------------------------\n"); + fprintf(stdout, "debug - [upstream] received body %d: %.*s\n", line_len, line_len, line); + fprintf(stdout, "------------------------------\n"); + } + + if (debug <= 2) { + fprintf(stdout, "printing parsed response\n"); + printfpares(&conn->srvres); + } + + conn->srvbuff = msgbuff; + conn->srvbuff_len = msgbuff_len; return 0; } -// TODO int do_con_srv(struct conn *conn) { int ret = 0; struct httpareq *req = &conn->cltreq; @@ -209,16 +302,16 @@ _exit: return ret; } -int do_fwd_srv(void) { - /*int bytes = 0; +int do_fwd_srv(struct conn *conn) { + int bytes = 0; int ret = 0; - while (bytes < clt_msg_len) { - ret = write(srv_sock, clt_msg+bytes, clt_msg_len-bytes); + while (bytes < conn->cltbuff_len) { + ret = write(conn->srvfd, conn->cltbuff+bytes, conn->cltbuff_len-bytes); if (ret < 0) return -1; bytes += ret; - }*/ + } return 0; } @@ -295,6 +388,9 @@ int do_rcv_clt(struct conn *conn) { printfpareq(&conn->cltreq); } + conn->cltbuff = msgbuff; + conn->cltbuff_len = msgbuff_len; + return 0; } @@ -302,6 +398,8 @@ void do_clear(struct conn *conn) { statem = STATEM_RCV_CLT; frepareq(&conn->cltreq); frepares(&conn->srvres); + free(conn->cltbuff); + free(conn->srvbuff); } void do_statem(struct conn *conn) { @@ -315,6 +413,15 @@ void do_statem(struct conn *conn) { case STATEM_CON_SRV: ret = do_con_srv(conn); break; + case STATEM_FWD_SRV: + ret = do_fwd_srv(conn); + break; + case STATEM_RCV_SRV: + ret = do_rcv_srv(conn); + break; + case STATEM_FWD_CLT: + ret = do_fwd_clt(conn); + break; } if (ret < 0) diff --git a/proxlib.h b/proxlib.h index 2809d59..a0e8d64 100644 --- a/proxlib.h +++ b/proxlib.h @@ -21,6 +21,11 @@ struct conn { int cltfd; int srvfd; + char *cltbuff; + int cltbuff_len; + char *srvbuff; + int srvbuff_len; + struct httpareq cltreq; struct httpares srvres; };