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:
A | COPYING | | | 1 | + |
M | Makefile | | | 2 | +- |
A | src/http.c | | | 136 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/http.h | | | 27 | +++++++++++++++++++++++++++ |
M | src/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];