Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
typedef void (*notify_callback_t)();
typedef void (*result_callback_t)(const char *str, size_t n);
struct callbacks_t {
notify_callback_t request_begin, request_end;
result_callback_t request_method, request_url, request_protocol;
notify_callback_t header_begin, header_end;
result_callback_t header_name, header_value;
};
#define CALLBACK(p, callback) (((callbacks_t *) (p)->userdata)->callback)
bool tokentable[256] = { true };
void init_tokentable() {
static const char nontokens[] = "()<>@,;:\\\"/[]?={} \t";
for (int i = 0; i < 32; i++)
tokentable[i] = false;
for (int i = 128; i < 256; i++)
tokentable[i] = false;
for (int i = 0; i < sizeof(nontokens); i++)
tokentable[nontokens[i]] = false;
}
bool istoken(char c) {
return tokentable[c];
}
bool iseol(char c) {
return c == 13 || c == 10;
}
bool ishspace(char c) {
return c == 9 || c == 32;
}
bool ishttpversion(char c) {
return c == 46 || c == 48 || c == 49;
}
void requestline(parser_t *p) {
CALLBACK(p, request_begin)();
const char *method = p->cursor;
SKIPWHILE1(p, istoken);
CALLBACK(p, request_method)(method, p->cursor - method);
SKIPWHILE1(p, ishspace);
const char *url = p->cursor;
SKIPWHILE1(p, !ishspace);
SKIPWHILE1(p, ishspace);
match(p, "HTTP/");
CALLBACK(p, request_url)(url, p->cursor - url);
const char *protocol = p->cursor;
SKIPWHILE1(p, ishttpversion);
CALLBACK(p, request_protocol)(protocol, p->cursor - protocol);
SKIP(p, iseol);
CALLBACK(p, request_end)();
}
void header(parser_t *p) {
CALLBACK(p, header_begin)();
const char *name = p->cursor;
SKIPWHILE1(p, istoken);
MATCH(p, ':');
CALLBACK(p, header_name)(name, p->cursor - name);
SKIPWHILE1(p, ishspace);
const char *body = p->cursor;
SKIPWHILE(p, !iseol);
CALLBACK(p, header_value)(body, p->cursor - body);
NEXT(p);
while (ishspace(HEAD(p))) {
SKIPWHILE1(p, ishspace);
const char *value = p->cursor;
SKIPWHILE(p, !iseol);
CALLBACK(p, header_value)(value, p->cursor - value);
NEXT(p);
}
CALLBACK(p, header_end)();
}
void request(parser_t *p) {
requestline(p);
while (istoken(HEAD(p)))
header(p);
SKIP(p, iseol);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment