commit 88b7b87269ddeb58c0fe2dfe1e546c30a330f69d
parent 7e273f2e59a9dc7cc7408264e80f19f6c719c6ed
Author: William Casarin <jb55@jb55.com>
Date: Tue, 15 Dec 2020 10:47:07 -0800
refactor errors
Diffstat:
10 files changed, 128 insertions(+), 89 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,6 +5,8 @@ OBJS = src/http.o src/base64.o src/inbox.o src/json.o
HEADERS = $(wildcard src/*.h)
+all: wolfsocks
+
wolfsocks: src/wolfsocks.c $(OBJS) $(HEADERS)
$(CC) $(CFLAGS) $< $(OBJS) $(LDFLAGS) -o $@
diff --git a/src/errors.h b/src/errors.h
@@ -0,0 +1,30 @@
+
+#ifndef WOLFSOCKS_ERRORS
+#define WOLFSOCKS_ERRORS
+
+#include <stdarg.h>
+
+#define note_error(p, msg, ...) note_error_(p, "%s: " msg "\n", __FUNCTION__, ##__VA_ARGS__);
+
+struct errors {
+ int record;
+};
+
+static inline void init_errors(struct errors *errs)
+{
+ errs->record = 1;
+}
+
+static inline void note_error_(struct errors *errs, const char *fmt, ...)
+{
+ if (!errs->record)
+ return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+
+#endif /* WOLFSOCKS_ERRORS */
diff --git a/src/http.c b/src/http.c
@@ -5,6 +5,13 @@
#include <stdio.h>
#include <assert.h>
+
+void init_http_req(struct http_req *req)
+{
+ memset(req, 0, sizeof(*req));
+ init_errors(&req->errs);
+}
+
static int parse_segment_with(struct parser *p, char **seg, char delim)
{
char c;
diff --git a/src/http.h b/src/http.h
@@ -2,6 +2,7 @@
#define WOLFSOCKS_HTTP
#include "cursor.h"
+#include "errors.h"
struct parser {
struct cursor cur;
@@ -19,9 +20,10 @@ struct http_req {
char *path;
char *ver;
struct http_header *headers;
+ struct errors errs;
};
-
+void init_http_req(struct http_req *req);
int get_header(struct http_header *header, const char *match, const char **result);
int parse_http_request(struct http_req *req, struct parser *p);
void print_http_request(struct http_req *req);
diff --git a/src/inbox.c b/src/inbox.c
@@ -33,11 +33,11 @@ static int parse_until(struct cursor *cur, struct cursor *arena, char match,
return 0;
}
-static int parse_kv(struct cursor *cur, struct cursor *arena,
- const char **key, const char **val)
+static int parse_kv(struct errors *errs, struct cursor *cur,
+ struct cursor *arena, const char **key, const char **val)
{
if (!parse_until(cur, arena, '=', key)) {
- note_error(cur, "= not found");
+ note_error(errs, "= not found");
return 0;
}
@@ -49,16 +49,25 @@ static int parse_kv(struct cursor *cur, struct cursor *arena,
return 1;
}
-int parse_signature_header(struct cursor *arena, const char *value, struct sig_header *out)
+int parse_signature_header(struct errors *errs, struct cursor *arena,
+ const char *value, struct sig_header *out)
{
const char *key;
const char *val;
struct cursor cur;
size_t out_len;
make_cursor((unsigned char*)value, (unsigned char*)value + strlen(value), &cur);
+ memset(out, 0, sizeof(*out));
while (1) {
- if (!parse_kv(&cur, arena, &key, &val)) {
+ if (out->key_id && out->headers && out->signature)
+ break;
+
+ if (!parse_kv(errs, &cur, arena, &key, &val)) {
+ note_error(errs, "keyid:%s headers:%s sig:%s",
+ out->key_id,
+ out->headers,
+ out->signature);
break;
}
@@ -72,7 +81,7 @@ int parse_signature_header(struct cursor *arena, const char *value, struct sig_h
if (!base64_decode((const unsigned char*)val, strlen(val),
arena->p, arena->end - arena->p,
&out_len)) {
- note_error(arena, "base64 decode signature");
+ note_error(errs, "base64 decode signature");
return 0;
}
@@ -80,7 +89,7 @@ int parse_signature_header(struct cursor *arena, const char *value, struct sig_h
arena->p += out_len;
if (!push_byte(arena, 0)) {
- note_error(arena, "oom");
+ note_error(errs, "oom");
return 0;
}
}
diff --git a/src/inbox.h b/src/inbox.h
@@ -2,6 +2,7 @@
#define WOLFSOCKS_INBOX
#include "cursor.h"
+#include "errors.h"
struct sig_header {
const char *key_id;
@@ -11,7 +12,7 @@ struct sig_header {
};
-int parse_signature_header(struct cursor *arena, const char *value, struct sig_header *out);
+int parse_signature_header(struct errors *errs, struct cursor *arena, const char *value, struct sig_header *out);
int verify_signature_header(struct sig_header *sig);
#endif
diff --git a/src/json.c b/src/json.c
@@ -5,27 +5,12 @@
#include <ctype.h>
-#define note_error(p, msg, ...) note_error_(p, "%s: " msg "\n", __FUNCTION__, ##__VA_ARGS__);
-
-struct errors {
- int record_errors;
-}
-
struct json_parser {
struct cursor cur;
struct cursor ubjson;
- struct errors errors;
+ struct errors errs;
};
-static void note_error_(struct json_parser *p, const char *fmt, ...)
-{
- if (!p->errors.record_errors)
- return;
-
-
- int record_errors;
-}
-
static void consume_whitespace(struct cursor *cur)
{
for (; cur->p < cur->end; cur->p++) {
@@ -153,7 +138,7 @@ static int push_ubjson_str(struct cursor *ubjson, unsigned char *text,
static int parse_escape(struct json_parser *p)
{
(void)p;
- note_error(p, "implement parse_escape");
+ note_error(&p->errs, "implement parse_escape");
return 0;
}
@@ -168,13 +153,13 @@ static int parse_string(struct json_parser *p)
start = p->cur.p;
if (!parse_char(&p->cur, &c, '"')) {
- note_error(p, "expected '\"', got '%c'", c);
+ note_error(&p->errs, "expected '\"', got '%c'", c);
return 0;
}
while (1) {
if (!parse_utf8_char(&p->cur, &chr)) {
- note_error(p, "invalid utf-8 codepoint");
+ note_error(&p->errs, "invalid utf-8 codepoint");
break;
}
@@ -184,7 +169,7 @@ static int parse_string(struct json_parser *p)
}
if (chr == '\\' && !parse_escape(p)) {
- note_error(p, "invalid escape char '%c'", c);
+ note_error(&p->errs, "invalid escape char '%c'", c);
break;
}
}
@@ -196,7 +181,7 @@ static int parse_string(struct json_parser *p)
static int parse_number(struct json_parser *p)
{
(void)p;
- note_error(p, "not implemented");
+ note_error(&p->errs, "not implemented");
return 0;
}
@@ -208,14 +193,14 @@ static int parse_kv(struct json_parser *p)
c = 0;
if (!parse_string(p)) {
- note_error(p, "key");
+ note_error(&p->errs, "key");
return 0;
}
consume_whitespace(&p->cur);
if (!parse_char(&p->cur, &c, ':')) {
- note_error(p, "expected ':', got %c", c);
+ note_error(&p->errs, "expected ':', got %c", c);
return 0;
}
@@ -235,7 +220,7 @@ static int parse_object(struct json_parser *p)
c = 0;
if (!parse_char(&p->cur, &c, '{')) {
- note_error(p, "expected '{' got '%c'", c);
+ note_error(&p->errs, "expected '{' got '%c'", c);
return 0;
}
@@ -255,7 +240,7 @@ static int parse_object(struct json_parser *p)
consume_whitespace(&p->cur);
if (!peek_char(&p->cur, &c)) {
- note_error(p, "oob");
+ note_error(&p->errs, "oob");
return 0;
}
@@ -265,17 +250,17 @@ static int parse_object(struct json_parser *p)
}
if (c != '"') {
- note_error(p, "expected '\"' or '}', got '%c'", c);
+ note_error(&p->errs, "expected '\"' or '}', got '%c'", c);
return 0;
}
if (!parse_kv(p)) {
- note_error(p, "expected key value pair");
+ note_error(&p->errs, "expected key value pair");
return 0;
}
if (!peek_char(&p->cur, &c)) {
- note_error(p, "oob");
+ note_error(&p->errs, "oob");
return 0;
}
@@ -289,18 +274,18 @@ static int parse_object(struct json_parser *p)
return finalize_object(p, len);
}
- note_error(p, "expected ',' or '}', got '%c'", c);
+ note_error(&p->errs, "expected ',' or '}', got '%c'", c);
return 0;
}
- note_error(p, "impossibru");
+ note_error(&p->errs, "impossibru");
return 0;
}
static int parse_array(struct json_parser *p)
{
(void)p;
- note_error(p, "implement parse_array");
+ note_error(&p->errs, "implement parse_array");
return 0;
}
@@ -327,7 +312,7 @@ static int parse_null(struct json_parser *p)
{
if (!parse_str(&p->cur, "null")) {
fprintf(stderr, "got %.*s instead of null\n", 4, p->cur.p);
- note_error(p, "not null");
+ note_error(&p->errs, "not null");
return 0;
}
@@ -341,7 +326,7 @@ static int parse_value(struct json_parser *p)
consume_whitespace(&p->cur);
- p->record_errors = 0;
+ p->errs.record = 0;
res = parse_string(p) ||
parse_object(p) ||
@@ -350,10 +335,10 @@ static int parse_value(struct json_parser *p)
parse_bool(p) ||
parse_null(p);
- p->record_errors = 1;
+ p->errs.record = 1;
if (!res) {
- note_error(p, "couldn't parse json value");
+ note_error(&p->errs, "couldn't parse json value");
return 0;
}
@@ -369,7 +354,7 @@ static int parse_array_or_object(struct json_parser *p)
consume_whitespace(&p->cur);
if (!peek_char(&p->cur, &c)) {
- note_error(p, "oob");
+ note_error(&p->errs, "oob");
return 0;
}
@@ -380,7 +365,7 @@ static int parse_array_or_object(struct json_parser *p)
if (c == '[')
return parse_array(p);
- note_error(p, "expected '{' or '[', got '%c'", c);
+ note_error(&p->errs, "expected '{' or '[', got '%c'", c);
return 0;
}
@@ -393,29 +378,29 @@ static int parse_ubjson_size(struct ubjson *ubjson, unsigned int *len)
start = ubjson->cur.p;
if (!pull_byte(&ubjson->cur, &byte)) {
- note_error(ubjson->errors, "oob");
+ note_error(&ubjson->errs, "oob");
} else if (byte == 'U' || byte == 'i') {
if (!pull_byte(&ubjson->cur, &byte)) {
- note_error(ubjson->errors, "pull byte after u8 int");
+ note_error(&ubjson->errs, "pull byte after u8 int");
} else {
*len = byte;
return 1;
}
} else if (byte == 'I') {
if (!pull_data(&ubjson->cur, (unsigned char*)&u16, sizeof(u16))) {
- note_error(ubjson->errors, "pull byte after u16 int");
+ note_error(&ubjson->errs, "pull byte after u16 int");
} else {
*len = u16;
return 1;
}
} else if (byte == 'l' || byte == 'L') {
if (!pull_int(&ubjson->cur, (int*)len)) {
- note_error(ubjson->errors, "pull byte after u16 int");
+ note_error(&ubjson->errs, "pull byte after u16 int");
} else {
return 1;
}
} else {
- note_error(ubjson->errors, "unhandled number tag '%c'", byte);
+ note_error(&ubjson->errs, "unhandled number tag '%c'", byte);
}
ubjson->cur.p = start;
@@ -428,12 +413,12 @@ static int parse_ubjson_string(struct ubjson *ubjson, struct json *val)
byte = 0;
if (!parse_char(&ubjson->cur, &byte, 'S')) {
- note_error(ubjson->errors, "expected S tag, got '%c'", byte);
+ note_error(&ubjson->errs, "expected S tag, got '%c'", byte);
return 0;
}
if (!parse_ubjson_size(ubjson, &val->len)) {
- note_error(ubjson->errors, "size");
+ note_error(&ubjson->errs, "size");
return 0;
}
@@ -458,23 +443,23 @@ static int consume_ubjson_value(struct ubjson *u)
c = 0;
if (!pull_byte(&u->cur, &c)) {
- note_error(u->errors, "oob");
+ note_error(&u->errs, "oob");
return 0;
}
if (!valid_ubjson_tag(c)) {
- note_error(u->errors, "invalid value tag '%c'", c);
+ note_error(&u->errs, "invalid value tag '%c'", c);
return 0;
}
if (c == 'Z') {
len = 0;
} else if (!parse_ubjson_size(u, &len)) {
- note_error(u->errors, "value size for tag '%c'", c);
+ note_error(&u->errs, "value size for tag '%c'", c);
return 0;
}
if (u->cur.p + len > u->cur.end) {
- note_error(u->errors, "value size oob");
+ note_error(&u->errs, "value size oob");
return 0;
}
@@ -496,21 +481,21 @@ static int parse_ubjson_object(struct ubjson *ubjson, struct json *val)
copy_ubjson(ubjson, &val->container);
if (!parse_char(&ubjson->cur, &c, '{')) {
- note_error(ubjson->errors, "expected '{' tag, got '%c'", c);
+ note_error(&ubjson->errs, "expected '{' tag, got '%c'", c);
return 0;
}
if (!parse_ubjson_size(ubjson, &val->len)) {
/* reset */
ubjson->cur.p = val->container.cur.p;
- note_error(ubjson->errors, "object len");
+ note_error(&ubjson->errs, "object len");
return 0;
}
if (ubjson->cur.p + val->len >= ubjson->data_end) {
/* reset */
ubjson->cur.p = val->container.cur.p;
- note_error(ubjson->errors, "invalid len %d", val->len);
+ note_error(&ubjson->errs, "invalid len %d", val->len);
return 0;
}
@@ -523,7 +508,7 @@ int parse_ubjson_value(struct ubjson *ubjson, struct json *val)
{
char tag;
if (!peek_char(&ubjson->cur, &tag)) {
- note_error(ubjson->errors, "peek value tag oob");
+ note_error(&ubjson->errs, "peek value tag oob");
return 0;
}
@@ -537,7 +522,7 @@ int parse_ubjson_value(struct ubjson *ubjson, struct json *val)
return parse_ubjson_object(ubjson, val);
}
- note_error(ubjson->errors, "unhandled type '%c'", tag);
+ note_error(&ubjson->errs, "unhandled type '%c'", tag);
return 0;
}
@@ -548,18 +533,18 @@ static int ubjson_obj_lookup(struct ubjson *ubjson, const char *path, struct jso
byte = 0;
if (!parse_char(&ubjson->cur, &byte, '{')) {
- note_error(ubjson->errors, "no object tag, got '%c'", byte);
+ note_error(&ubjson->errs, "no object tag, got '%c'", byte);
return 0;
}
if (!parse_ubjson_size(ubjson, &len)) {
- note_error(ubjson->errors, "object size");
+ note_error(&ubjson->errs, "object size");
return 0;
}
while (1) {
if (!peek_char(&ubjson->cur, &byte)) {
- note_error(ubjson->errors, "oob");
+ note_error(&ubjson->errs, "oob");
break;
}
@@ -568,7 +553,7 @@ static int ubjson_obj_lookup(struct ubjson *ubjson, const char *path, struct jso
}
if (!parse_ubjson_string(ubjson, val)) {
- note_error(ubjson->errors, "string");
+ note_error(&ubjson->errs, "string");
break;
}
@@ -578,7 +563,7 @@ static int ubjson_obj_lookup(struct ubjson *ubjson, const char *path, struct jso
memcmp(path, val->string, val->len)) {
/* skip over value */
if (!consume_ubjson_value(ubjson)) {
- note_error(p, "skip value");
+ note_error(&ubjson->errs, "skip value");
return 0;
}
continue;
@@ -605,13 +590,13 @@ int ubjson_lookup(struct ubjson *ubjson, const char **path, int path_len, struct
seg = path[i];
if (!ubjson_obj_lookup(next, seg, val)) {
- note_error(ubjson->errors, "lookup path segment: '%s'", seg);
+ note_error(&ubjson->errs, "lookup path segment: '%s'", seg);
return 0;
}
/* not at the last segment and don't have an object or array */
if (i != path_len-1 && val->type != JSON_OBJECT) {
- note_error(ubjson->errors,
+ note_error(&ubjson->errs,
"segment '%s' not an object, got '%c'", seg, byte);
return 0;
} else if (val->type == JSON_OBJECT) {
diff --git a/src/json.h b/src/json.h
@@ -3,11 +3,13 @@
#define WOLFSOCKS_JSON
#include "cursor.h"
+#include "errors.h"
#include <stddef.h>
struct ubjson {
struct cursor cur;
unsigned char *data_end;
+ struct errors errs;
};
enum json_value_type {
diff --git a/src/util.h b/src/util.h
@@ -5,8 +5,6 @@
#include <ctype.h>
#include <string.h>
-#define note_error(a, msg) fprintf(stderr, "%s: %s\n", __FUNCTION__, msg)
-
static inline int stricmp(const char *a, const char *b) {
int len, i;
diff --git a/src/wolfsocks.c b/src/wolfsocks.c
@@ -18,8 +18,6 @@
#define BUF_SIZE 4096
#define ARENA_SIZE 134217728 /* 128 MB virtual mem arena */
-#define note_error(a, msg) fprintf(stderr, "%s: %s\n", __FUNCTION__, msg)
-
static void error(char *msg)
{
perror(msg);
@@ -29,29 +27,34 @@ static void error(char *msg)
static int handle_request(struct http_req *req, struct cursor *arena)
{
struct sig_header sig;
+ int inbox_req;
const char *signature;
memset(&sig, 0, sizeof(sig));
- if (!strcmp(req->method, "POST") &&
+ inbox_req = !strcmp(req->method, "POST") &&
(!strcmp(req->path, "/inbox") ||
- !strcmp(req->path, "/inbox/"))) {
+ !strcmp(req->path, "/inbox/"));
- if (!get_header(req->headers, "signature", &signature)) {
- note_error(req, "signature");
- return 0;
- }
+ if (!inbox_req) {
+ note_error(&req->errs, "404");
+ return 0;
+ }
+
+ if (!get_header(req->headers, "signature", &signature)) {
+ note_error(&req->errs, "signature");
+ return 0;
+ }
- printf("signature: %s\n", signature);
+ printf("signature: %s\n", signature);
- if (!parse_signature_header(arena, signature, &sig)) {
- note_error(req, "parse signature header");
- return 0;
- }
+ if (!parse_signature_header(&req->errs, arena, signature, &sig)) {
+ note_error(&req->errs, "parse signature header");
+ return 0;
+ }
- if (!verify_signature_header(&sig)) {
- note_error(req, "verify");
- return 0;
- }
+ if (!verify_signature_header(&sig)) {
+ note_error(&req->errs, "verify");
+ return 0;
}
return 1;
@@ -105,7 +108,7 @@ void run_http_server()
client_len = sizeof(client_addr);
while (1) {
- memset(&req, 0, sizeof(req));
+ init_http_req(&req);
make_cursor(buffer, buffer + BUF_SIZE, &parser.cur);
make_cursor(arena, arena + ARENA_SIZE, &parser.arena);