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
This commit is contained in:
parent
403ecb70b3
commit
5dcc4c8bf7
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
CC=bear --append -- gcc
|
CC=bear --append -- gcc
|
||||||
CFLAGS= -g3 -Wall -Werror
|
CFLAGS=-g3
|
||||||
CFILES=proxlib.c
|
CFILES=proxlib.c
|
||||||
CFILES_PARSLIB=parslib/parslib.final.o
|
CFILES_PARSLIB=parslib/parslib.final.o
|
||||||
OUT=proxlib
|
OUT=proxlib
|
||||||
|
|
2
parslib
2
parslib
|
@ -1 +1 @@
|
||||||
Subproject commit 678a44228fe0c5b24b2d1b96576da0e44211c364
|
Subproject commit 55835087d359f77d00030b3dffb1cd43980722ee
|
183
proxlib.c
183
proxlib.c
|
@ -11,7 +11,7 @@
|
||||||
#include "parslib/parslib.h"
|
#include "parslib/parslib.h"
|
||||||
|
|
||||||
int on = 1;
|
int on = 1;
|
||||||
int debug = 2;
|
int debug = 3;
|
||||||
int statem;
|
int statem;
|
||||||
|
|
||||||
#define SEGMENT_LEN 512
|
#define SEGMENT_LEN 512
|
||||||
|
@ -104,50 +104,143 @@ void do_err(void) {
|
||||||
STATEM_ERR);
|
STATEM_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_fwd_clt(void) {
|
int do_fwd_clt(struct conn *conn) {
|
||||||
/*int bytes = 0;
|
int bytes = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while (bytes < srv_msg_len) {
|
while (bytes < conn->srvbuff_len) {
|
||||||
ret = write(clt_sock, srv_msg+bytes, srv_msg_len-bytes);
|
ret = write(conn->cltfd, conn->srvbuff+bytes, conn->srvbuff_len-bytes);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
bytes += ret;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: add parsing ability
|
|
||||||
int do_prs_srv(void) {
|
|
||||||
int ret = 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
bytes += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_msg_len = bytes;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug == 1)
|
int do_rcv_srv(struct conn *conn) {
|
||||||
fprintf(stdout, "[%d] Received server message of size %d bytes\n", statem, srv_msg_len);
|
int ret = 0;
|
||||||
*/
|
char *line = NULL;
|
||||||
|
char *msgbuff = NULL;
|
||||||
|
int line_len = 0;
|
||||||
|
int msgbuff_len = 0;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug == 1) {
|
||||||
|
fprintf(stdout, "debug - [upstream] received line: %s\n", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
int do_con_srv(struct conn *conn) {
|
int do_con_srv(struct conn *conn) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct httpareq *req = &conn->cltreq;
|
struct httpareq *req = &conn->cltreq;
|
||||||
|
@ -209,16 +302,16 @@ _exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_fwd_srv(void) {
|
int do_fwd_srv(struct conn *conn) {
|
||||||
/*int bytes = 0;
|
int bytes = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while (bytes < clt_msg_len) {
|
while (bytes < conn->cltbuff_len) {
|
||||||
ret = write(srv_sock, clt_msg+bytes, clt_msg_len-bytes);
|
ret = write(conn->srvfd, conn->cltbuff+bytes, conn->cltbuff_len-bytes);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
bytes += ret;
|
bytes += ret;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -295,6 +388,9 @@ int do_rcv_clt(struct conn *conn) {
|
||||||
printfpareq(&conn->cltreq);
|
printfpareq(&conn->cltreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn->cltbuff = msgbuff;
|
||||||
|
conn->cltbuff_len = msgbuff_len;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,6 +398,8 @@ void do_clear(struct conn *conn) {
|
||||||
statem = STATEM_RCV_CLT;
|
statem = STATEM_RCV_CLT;
|
||||||
frepareq(&conn->cltreq);
|
frepareq(&conn->cltreq);
|
||||||
frepares(&conn->srvres);
|
frepares(&conn->srvres);
|
||||||
|
free(conn->cltbuff);
|
||||||
|
free(conn->srvbuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_statem(struct conn *conn) {
|
void do_statem(struct conn *conn) {
|
||||||
|
@ -315,6 +413,15 @@ void do_statem(struct conn *conn) {
|
||||||
case STATEM_CON_SRV:
|
case STATEM_CON_SRV:
|
||||||
ret = do_con_srv(conn);
|
ret = do_con_srv(conn);
|
||||||
break;
|
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)
|
if (ret < 0)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user