chibipub

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 5687941b116a63dc2d0528948beb2423ed01450e
parent a063e39067588c7ec8d75a4528a8ad3a5e6b499b
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 19 Nov 2020 12:10:46 -0800

move http code to its own file

Diffstat:
ACOPYING | 1+
MMakefile | 2+-
Asrc/http.c | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/http.h | 27+++++++++++++++++++++++++++
Msrc/wolfsocks.c | 164+------------------------------------------------------------------------------
5 files changed, 166 insertions(+), 164 deletions(-)

diff --git a/COPYING b/COPYING @@ -0,0 +1 @@ +GPLv3 diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ CFLAGS = -Wall -Werror -std=c89 -Isrc -OBJS = src/cursor.o +OBJS = src/cursor.o src/http.o wolfsocks: src/wolfsocks.c $(OBJS) $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ diff --git a/src/http.c b/src/http.c @@ -0,0 +1,136 @@ +#include "http.h" +#include <stdio.h> +#include <assert.h> + +static int parse_segment_with(struct parser *p, char **seg, char delim) +{ + char c; + + *seg = (char*)p->arena.p; + + while (1) { + if (!pull_byte(&p->cur, (unsigned char*)&c)) + return 0; + + if (c == delim) { + if (!push_byte(&p->arena, 0)) + return 0; + return 1; + } + + if (!push_byte(&p->arena, c)) + return 0; + } + + return 1; +} + +static int consume_char(struct cursor *cur, char match) +{ + char c; + return pull_byte(cur, (unsigned char*)&c) && c == match; +} + +static int parse_segment(struct parser *p, char **seg) +{ + return parse_segment_with(p, seg, ' '); +} + +static int parse_last_segment(struct parser *p, char **seg) +{ + if (!parse_segment_with(p, seg, '\r')) + return 0; + + /* don't consume crlf yet */ + p->cur.p--; + + return 1; +} + +static int parse_header_name(struct parser *p, char **name) +{ + if (!parse_segment_with(p, name, ':')) + return 0; + + return consume_char(&p->cur, ' '); +} + +static int consume_crlf(struct cursor *cur) +{ + return consume_char(cur, '\r') && consume_char(cur, '\n'); +} + +static int parse_request_line(struct http_req *req, struct parser *p) +{ + if (!parse_segment(p, &req->method)) + return 0; + + if (!parse_segment(p, &req->path)) + return 0; + + if (!parse_last_segment(p, &req->ver)) + return 0; + + return consume_crlf(&p->cur); +} + +static int parse_header(struct http_header **prev, struct parser *p) +{ + struct http_header next; + struct http_header *next_p; + next.next = NULL; + + assert(prev); + assert(*prev == NULL || (*prev)->next == NULL); + + if (!parse_header_name(p, &next.name)) + return 0; + + if (!parse_last_segment(p, &next.value)) + return 0; + + next_p = (struct http_header *)p->arena.p; + + if (!push_data(&p->arena, (unsigned char*)&next, sizeof(next))) + return 0; + + if (*prev == NULL) + *prev = next_p; + else + (*prev)->next = next_p; + + return consume_crlf(&p->cur); +} + + +int parse_http_request(struct http_req *req, struct parser *p) +{ + struct http_header **header; + struct cursor back; + + if (!parse_request_line(req, p)) + return 0; + + header = &req->headers; + + while (1) { + copy_cursor(&p->cur, &back); + if (!parse_header(header, p)) { + copy_cursor(&back, &p->cur); + break; + } + header = &(*header)->next; + } + + return consume_crlf(&p->cur); +} + +void print_http_request(struct http_req *req) +{ + struct http_header *header; + printf("%s %s %s\r\n", req->method, req->path, req->ver); + header = req->headers; + for (; header; header = header->next) { + printf("%s: %s\n", header->name, header->value); + } +} diff --git a/src/http.h b/src/http.h @@ -0,0 +1,27 @@ +#ifndef WOLFSOCKS_HTTP +#define WOLFSOCKS_HTTP + +#include "cursor.h" + +struct parser { + struct cursor cur; + struct cursor arena; +}; + +struct http_header { + char *name; + char *value; + struct http_header *next; +}; + +struct http_req { + char *method; + char *path; + char *ver; + struct http_header *headers; +}; + +int parse_http_request(struct http_req *req, struct parser *p); +void print_http_request(struct http_req *req); + +#endif /* WOLFSOCKS_HTTP */ diff --git a/src/wolfsocks.c b/src/wolfsocks.c @@ -11,29 +11,11 @@ #include <ctype.h> #include <assert.h> -#include "cursor.h" +#include "http.h" #define BUF_SIZE 4096 #define ARENA_SIZE 8192 -struct parser { - struct cursor cur; - struct cursor arena; -}; - -struct http_header { - char *name; - char *value; - struct http_header *next; -}; - -struct http_req { - char *method; - char *path; - char *ver; - struct http_header *headers; -}; - static void error(char *msg) { perror(msg); @@ -41,150 +23,6 @@ static void error(char *msg) } -static int parse_segment_with(struct parser *p, char **seg, char delim) -{ - char c; - - *seg = (char*)p->arena.p; - - while (1) { - if (!pull_byte(&p->cur, (unsigned char*)&c)) - return 0; - - if (c == delim) { - if (!push_byte(&p->arena, 0)) - return 0; - return 1; - } - - if (!push_byte(&p->arena, c)) - return 0; - } - - return 1; -} - -static int consume_char(struct cursor *cur, char match) -{ - char c; - return pull_byte(cur, (unsigned char*)&c) && c == match; -} - -static int parse_segment(struct parser *p, char **seg) -{ - return parse_segment_with(p, seg, ' '); -} - -static int parse_last_segment(struct parser *p, char **seg) -{ - if (!parse_segment_with(p, seg, '\r')) - return 0; - - /* don't consume crlf yet */ - p->cur.p--; - - return 1; -} - -static int parse_header_name(struct parser *p, char **name) -{ - if (!parse_segment_with(p, name, ':')) - return 0; - - return consume_char(&p->cur, ' '); -} - -static int consume_crlf(struct cursor *cur) -{ - return consume_char(cur, '\r') && consume_char(cur, '\n'); -} - -static int parse_request_line(struct http_req *req, struct parser *p) -{ - if (!parse_segment(p, &req->method)) - return 0; - - if (!parse_segment(p, &req->path)) - return 0; - - if (!parse_last_segment(p, &req->ver)) - return 0; - - return consume_crlf(&p->cur); -} - -static int parse_header(struct http_header **prev, struct parser *p) -{ - struct http_header next; - struct http_header *next_p; - next.next = NULL; - - assert(*prev == NULL || !(*prev)->next); - - printf("parsing header name...\n"); - - if (!parse_header_name(p, &next.name)) - return 0; - - printf("got header name: %s\n", next.name); - - if (!parse_last_segment(p, &next.value)) - return 0; - - printf("got header value: %s\n", next.value); - - next_p = (struct http_header *)p->arena.p; - - if (!push_data(&p->arena, (unsigned char*)&next, sizeof(next))) - return 0; - - if (*prev == NULL) - *prev = next_p; - else - (*prev)->next = next_p; - - printf("consuming crlf: %.*s\n", 2, p->cur.p); - - return consume_crlf(&p->cur); -} - - -static int parse_http_request(struct http_req *req, struct parser *p) -{ - struct http_header **header; - struct cursor back; - - if (!parse_request_line(req, p)) - return 0; - - printf("got request line\n"); - - header = &req->headers; - - while (1) { - copy_cursor(&p->cur, &back); - if (!parse_header(header, p)) { - copy_cursor(&back, &p->cur); - break; - } - header = &(*header)->next; - } - - printf("after headers: %.*s\n", 5, p->cur.p); - - return consume_crlf(&p->cur); -} - -static void print_http_request(struct http_req *req) -{ - struct http_header *header; - printf("%s %s %s\r\n", req->method, req->path, req->ver); - header = req->headers; - for (; header; header = header->next) { - printf("%s: %s\n", header->name, header->value); - } -} - void run_http_server() { static unsigned char arena[ARENA_SIZE];