add support for HTTP_BOTH

This is good for analyzing raw streams of data when one is not sure
which direction it will be in.
event_stream
Cliff Frey 15 years ago committed by Ryan Dahl
parent c2acc213ac
commit b8c3336f5d

@ -132,6 +132,8 @@ static const uint32_t usual[] = {
enum state enum state
{ s_dead = 1 /* important that this is > 0 */ { s_dead = 1 /* important that this is > 0 */
, s_start_res_or_resp
, s_res_or_resp_H
, s_start_res , s_start_res
, s_res_H , s_res_H
, s_res_HT , s_res_HT
@ -326,6 +328,42 @@ size_t http_parser_execute (http_parser *parser,
*/ */
goto error; goto error;
case s_start_res_or_resp:
{
if (ch == CR || ch == LF)
break;
parser->flags = 0;
parser->content_length = -1;
CALLBACK2(message_begin);
if (ch == 'H')
state = s_res_or_resp_H;
else {
parser->type = HTTP_REQUEST;
if (ch < 'A' || 'Z' < ch) goto error;
parser->buffer[0] = ch;
index = 0;
state = s_req_method;
}
break;
}
case s_res_or_resp_H:
if (ch == 'T') {
parser->type = HTTP_RESPONSE;
state = s_res_HT;
} else {
if (ch < 'A' || 'Z' < ch) goto error;
parser->type = HTTP_REQUEST;
parser->method = (enum http_method) 0;
parser->buffer[0] = 'H';
parser->buffer[1] = ch;
index = 1;
state = s_req_method;
}
break;
case s_start_res: case s_start_res:
{ {
parser->flags = 0; parser->flags = 0;
@ -1547,7 +1585,7 @@ void
http_parser_init (http_parser *parser, enum http_parser_type t) http_parser_init (http_parser *parser, enum http_parser_type t)
{ {
parser->type = t; parser->type = t;
parser->state = (t == HTTP_REQUEST ? s_start_req : s_start_res); parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_res_or_resp));
parser->nread = 0; parser->nread = 0;
parser->upgrade = 0; parser->upgrade = 0;

@ -89,7 +89,7 @@ enum http_method
}; };
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE }; enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
struct http_parser { struct http_parser {

134
test.c

@ -1207,82 +1207,84 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess
int total_len = strlen(total); int total_len = strlen(total);
int total_ops = (total_len - 1) * (total_len - 2) / 2; int total_ops = 2 * (total_len - 1) * (total_len - 2) / 2;
int ops = 0 ; int ops = 0 ;
size_t buf1_len, buf2_len, buf3_len; size_t buf1_len, buf2_len, buf3_len;
int i,j; int i,j,type_both;
for (j = 2; j < total_len; j ++ ) { for (type_both = 0; type_both < 2; type_both ++ ) {
for (i = 1; i < j; i ++ ) { for (j = 2; j < total_len; j ++ ) {
for (i = 1; i < j; i ++ ) {
if (ops % 1000 == 0) {
printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops); if (ops % 1000 == 0) {
fflush(stdout); printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops);
} fflush(stdout);
ops += 1; }
ops += 1;
parser_init(r1->type);
parser_init(type_both ? HTTP_BOTH : r1->type);
buf1_len = i;
strncpy(buf1, total, buf1_len); buf1_len = i;
buf1[buf1_len] = 0; strncpy(buf1, total, buf1_len);
buf1[buf1_len] = 0;
buf2_len = j - i;
strncpy(buf2, total+i, buf2_len); buf2_len = j - i;
buf2[buf2_len] = 0; strncpy(buf2, total+i, buf2_len);
buf2[buf2_len] = 0;
buf3_len = total_len - j;
strncpy(buf3, total+j, buf3_len); buf3_len = total_len - j;
buf3[buf3_len] = 0; strncpy(buf3, total+j, buf3_len);
buf3[buf3_len] = 0;
read = parse(buf1, buf1_len);
if (read != buf1_len) { read = parse(buf1, buf1_len);
print_error(buf1, read); if (read != buf1_len) {
goto error; print_error(buf1, read);
} goto error;
}
read = parse(buf2, buf2_len);
if (read != buf2_len) { read = parse(buf2, buf2_len);
print_error(buf2, read); if (read != buf2_len) {
goto error; print_error(buf2, read);
} goto error;
}
read = parse(buf3, buf3_len);
if (read != buf3_len) { read = parse(buf3, buf3_len);
print_error(buf3, read); if (read != buf3_len) {
goto error; print_error(buf3, read);
goto error;
}
parse(NULL, 0);
if (3 != num_messages) {
fprintf(stderr, "\n\nParser didn't see 3 messages only %d\n", num_messages);
goto error;
}
if (!message_eq(0, r1)) {
fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n");
goto error;
}
if (!message_eq(1, r2)) {
fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n");
goto error;
}
if (!message_eq(2, r3)) {
fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n");
goto error;
}
parser_free();
} }
parse(NULL, 0);
if (3 != num_messages) {
fprintf(stderr, "\n\nParser didn't see 3 messages only %d\n", num_messages);
goto error;
}
if (!message_eq(0, r1)) {
fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n");
goto error;
}
if (!message_eq(1, r2)) {
fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n");
goto error;
}
if (!message_eq(2, r3)) {
fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n");
goto error;
}
parser_free();
} }
} }
puts("\b\b\b\b100%"); puts("\b\b\b\b100%");
return; return;
error: error:
fprintf(stderr, "i=%d j=%d\n", i, j); fprintf(stderr, "i=%d j=%d\n", i, j);
fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1); fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1);
fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2); fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2);

Loading…
Cancel
Save