version0.2
Ryan 16 years ago
parent 5214fb2524
commit c288a966fe

@ -58,6 +58,7 @@ typedef int (*http_cb) (http_parser*);
#define HTTP_PUT 0x0800 #define HTTP_PUT 0x0800
#define HTTP_TRACE 0x1000 #define HTTP_TRACE 0x1000
#define HTTP_UNLOCK 0x2000 #define HTTP_UNLOCK 0x2000
/* Transfer Encodings */ /* Transfer Encodings */
#define HTTP_IDENTITY 0x01 #define HTTP_IDENTITY 0x01
#define HTTP_CHUNKED 0x02 #define HTTP_CHUNKED 0x02

@ -45,7 +45,7 @@ static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
#define REMAINING (pe - p) #define REMAINING (pe - p)
#define CALLBACK(FOR) \ #define CALLBACK(FOR) \
if(parser->FOR##_mark && parser->on_##FOR) { \ if (parser->FOR##_mark && parser->on_##FOR) { \
parser->on_##FOR( parser \ parser->on_##FOR( parser \
, parser->FOR##_mark \ , parser->FOR##_mark \
, p - parser->FOR##_mark \ , p - parser->FOR##_mark \
@ -71,7 +71,7 @@ static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
parser->body_read = 0; parser->body_read = 0;
#define END_REQUEST \ #define END_REQUEST \
if(parser->on_message_complete) { \ if (parser->on_message_complete) { \
parser->on_message_complete(parser); \ parser->on_message_complete(parser); \
} \ } \
RESET_PARSER(parser); RESET_PARSER(parser);
@ -160,7 +160,7 @@ static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
action skip_chunk_data { action skip_chunk_data {
skip_body(&p, parser, MIN(parser->chunk_size, REMAINING)); skip_body(&p, parser, MIN(parser->chunk_size, REMAINING));
fhold; fhold;
if(parser->chunk_size > REMAINING) { if (parser->chunk_size > REMAINING) {
fbreak; fbreak;
} else { } else {
fgoto chunk_end; fgoto chunk_end;
@ -170,7 +170,7 @@ static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
action end_chunked_body { action end_chunked_body {
END_REQUEST END_REQUEST
//fnext main; //fnext main;
if(parser->type == HTTP_REQUEST) { if (parser->type == HTTP_REQUEST) {
fnext Requests; fnext Requests;
} else { } else {
fnext Responses; fnext Responses;
@ -178,7 +178,7 @@ static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
} }
action body_logic { action body_logic {
if(parser->transfer_encoding == HTTP_CHUNKED) { if (parser->transfer_encoding == HTTP_CHUNKED) {
fnext ChunkedBody; fnext ChunkedBody;
} else { } else {
/* this is pretty stupid. i'd prefer to combine this with skip_chunk_data */ /* this is pretty stupid. i'd prefer to combine this with skip_chunk_data */
@ -295,7 +295,7 @@ static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
main := any >{ main := any >{
fhold; fhold;
if(parser->type == HTTP_REQUEST) { if (parser->type == HTTP_REQUEST) {
fgoto Requests; fgoto Requests;
} else { } else {
fgoto Responses; fgoto Responses;
@ -308,15 +308,15 @@ static int unhex[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
static void static void
skip_body(const char **p, http_parser *parser, size_t nskip) { skip_body(const char **p, http_parser *parser, size_t nskip) {
if(parser->on_body && nskip > 0) { if (parser->on_body && nskip > 0) {
parser->on_body(parser, *p, nskip); parser->on_body(parser, *p, nskip);
} }
parser->body_read += nskip; parser->body_read += nskip;
parser->chunk_size -= nskip; parser->chunk_size -= nskip;
*p += nskip; *p += nskip;
if(0 == parser->chunk_size) { if (0 == parser->chunk_size) {
parser->eating = FALSE; parser->eating = FALSE;
if(parser->transfer_encoding == HTTP_IDENTITY) { if (parser->transfer_encoding == HTTP_IDENTITY) {
END_REQUEST END_REQUEST
} }
} else { } else {
@ -339,7 +339,7 @@ http_parser_init (http_parser *parser, enum http_parser_type type)
/** exec **/ /** exec **/
size_t size_t
http_parser_execute(http_parser *parser, const char *buffer, size_t len) http_parser_execute (http_parser *parser, const char *buffer, size_t len)
{ {
const char *p, *pe; const char *p, *pe;
int cs = parser->cs; int cs = parser->cs;
@ -347,18 +347,18 @@ http_parser_execute(http_parser *parser, const char *buffer, size_t len)
p = buffer; p = buffer;
pe = buffer+len; pe = buffer+len;
if(0 < parser->chunk_size && parser->eating) { if (0 < parser->chunk_size && parser->eating) {
/* eat body */ /* eat body */
size_t eat = MIN(len, parser->chunk_size); size_t eat = MIN(len, parser->chunk_size);
skip_body(&p, parser, eat); skip_body(&p, parser, eat);
} }
if(parser->header_field_mark) parser->header_field_mark = buffer; if (parser->header_field_mark) parser->header_field_mark = buffer;
if(parser->header_value_mark) parser->header_value_mark = buffer; if (parser->header_value_mark) parser->header_value_mark = buffer;
if(parser->fragment_mark) parser->fragment_mark = buffer; if (parser->fragment_mark) parser->fragment_mark = buffer;
if(parser->query_string_mark) parser->query_string_mark = buffer; if (parser->query_string_mark) parser->query_string_mark = buffer;
if(parser->path_mark) parser->path_mark = buffer; if (parser->path_mark) parser->path_mark = buffer;
if(parser->uri_mark) parser->uri_mark = buffer; if (parser->uri_mark) parser->uri_mark = buffer;
%% write exec; %% write exec;
@ -376,18 +376,20 @@ http_parser_execute(http_parser *parser, const char *buffer, size_t len)
return(p - buffer); return(p - buffer);
} }
int http_parser_has_error(http_parser *parser) int
http_parser_has_error (http_parser *parser)
{ {
return parser->cs == http_parser_error; return parser->cs == http_parser_error;
} }
#if 0 #if 0
int http_should_keep_alive(http *request) int
http_should_keep_alive (http *request)
{ {
if(request->keep_alive == -1) if (request->keep_alive == -1)
if(request->version_major == 1) if (request->version_major == 1)
return (request->version_minor != 0); return (request->version_minor != 0);
else if(request->version_major == 0) else if (request->version_major == 0)
return FALSE; return FALSE;
else else
return TRUE; return TRUE;

@ -329,31 +329,36 @@ const struct message responses[] =
, {.name= NULL } /* sentinel */ , {.name= NULL } /* sentinel */
}; };
int request_path_cb(http_parser *_, const char *p, size_t len) int
request_path_cb (http_parser *_, const char *p, size_t len)
{ {
strncat(messages[num_messages].request_path, p, len); strncat(messages[num_messages].request_path, p, len);
return 0; return 0;
} }
int request_uri_cb(http_parser *_, const char *p, size_t len) int
request_uri_cb (http_parser *_, const char *p, size_t len)
{ {
strncat(messages[num_messages].request_uri, p, len); strncat(messages[num_messages].request_uri, p, len);
return 0; return 0;
} }
int query_string_cb(http_parser *_, const char *p, size_t len) int
query_string_cb (http_parser *_, const char *p, size_t len)
{ {
strncat(messages[num_messages].query_string, p, len); strncat(messages[num_messages].query_string, p, len);
return 0; return 0;
} }
int fragment_cb(http_parser *_, const char *p, size_t len) int
fragment_cb (http_parser *_, const char *p, size_t len)
{ {
strncat(messages[num_messages].fragment, p, len); strncat(messages[num_messages].fragment, p, len);
return 0; return 0;
} }
int header_field_cb(http_parser *_, const char *p, size_t len) int
header_field_cb (http_parser *_, const char *p, size_t len)
{ {
struct message *m = &messages[num_messages]; struct message *m = &messages[num_messages];
@ -367,7 +372,8 @@ int header_field_cb(http_parser *_, const char *p, size_t len)
return 0; return 0;
} }
int header_value_cb (http_parser *_, const char *p, size_t len) int
header_value_cb (http_parser *_, const char *p, size_t len)
{ {
struct message *m = &messages[num_messages]; struct message *m = &messages[num_messages];
@ -378,14 +384,16 @@ int header_value_cb (http_parser *_, const char *p, size_t len)
return 0; return 0;
} }
int body_handler (http_parser *_, const char *p, size_t len) int
body_cb (http_parser *_, const char *p, size_t len)
{ {
strncat(messages[num_messages].body, p, len); strncat(messages[num_messages].body, p, len);
// printf("body_handler: '%s'\n", requests[num_messages].body); // printf("body_cb: '%s'\n", requests[num_messages].body);
return 0; return 0;
} }
int message_complete(http_parser *parser) int
message_complete_cb (http_parser *parser)
{ {
messages[num_messages].method = parser->method; messages[num_messages].method = parser->method;
@ -393,7 +401,8 @@ int message_complete(http_parser *parser)
return 0; return 0;
} }
int begin_message (http_parser *_) int
message_begin_cb (http_parser *_)
{ {
return 0; return 0;
} }
@ -407,16 +416,16 @@ parser_init (enum http_parser_type type)
memset(&messages, 0, sizeof messages); memset(&messages, 0, sizeof messages);
parser.on_message_begin = begin_message; parser.on_message_begin = message_begin_cb;
parser.on_header_field = header_field_cb; parser.on_header_field = header_field_cb;
parser.on_header_value = header_value_cb; parser.on_header_value = header_value_cb;
parser.on_path = request_path_cb; parser.on_path = request_path_cb;
parser.on_uri = request_uri_cb; parser.on_uri = request_uri_cb;
parser.on_fragment = fragment_cb; parser.on_fragment = fragment_cb;
parser.on_query_string = query_string_cb; parser.on_query_string = query_string_cb;
parser.on_body = body_handler; parser.on_body = body_cb;
parser.on_headers_complete = NULL; parser.on_headers_complete = NULL;
parser.on_message_complete = message_complete; parser.on_message_complete = message_complete_cb;
} }
void void
@ -432,14 +441,12 @@ request_eq (int index, const struct message *expected)
assert(0 == strcmp(m->request_path, expected->request_path)); assert(0 == strcmp(m->request_path, expected->request_path));
assert(0 == strcmp(m->request_uri, expected->request_uri)); assert(0 == strcmp(m->request_uri, expected->request_uri));
assert(m->num_headers == expected->num_headers); assert(m->num_headers == expected->num_headers);
for(i = 0; i < m->num_headers; i++) { for (i = 0; i < m->num_headers; i++) {
assert(0 == strcmp(m->headers[i][0], expected->headers[i][0])); assert(0 == strcmp(m->headers[i][0], expected->headers[i][0]));
assert(0 == strcmp(m->headers[i][1], expected->headers[i][1])); assert(0 == strcmp(m->headers[i][1], expected->headers[i][1]));
} }
} }
void void
parse_messages (int message_count, const struct message *input_messages[]) parse_messages (int message_count, const struct message *input_messages[])
{ {
@ -495,7 +502,6 @@ test_error (const char *buf)
assert(http_parser_has_error(&parser)); assert(http_parser_has_error(&parser));
} }
void void
test_multiple3 (const struct message *r1, const struct message *r2, const struct message *r3) test_multiple3 (const struct message *r1, const struct message *r2, const struct message *r3)
{ {
@ -544,10 +550,10 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
int ops = 0 ; int ops = 0 ;
int i,j; int i,j;
for(j = 2; j < total_len; j ++ ) { for (j = 2; j < total_len; j ++ ) {
for(i = 1; i < j; i ++ ) { for (i = 1; i < j; i ++ ) {
if(ops % 20 == 0) { if (ops % 20 == 0) {
printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops); printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops);
fflush(stdout); fflush(stdout);
} }
@ -595,7 +601,8 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
printf("\b\b\b\b100%\n"); printf("\b\b\b\b100%\n");
} }
int main() int
main (void)
{ {
test_error("hello world"); test_error("hello world");
test_error("GET / HTP/1.1\r\n\r\n"); test_error("GET / HTP/1.1\r\n\r\n");
@ -690,4 +697,3 @@ int main()
return 0; return 0;
} }

Loading…
Cancel
Save