7 #define assertFalse(x) assert(!(x)); printf(".")
8 #define assertTrue(x) assert(x); printf(".")
9 #define assertEquals(x, y) assert(x == y); printf(".")
11 void assertStrEquals(const char *expected
, const char *given
)
13 int length
= strlen(expected
);
14 assert(strncmp(expected
, given
, length
) == 0);
21 * Definition of test function
25 http_parser_init(&parser
);
26 assertEquals(0, parser
.nread
);
32 void parse_simple_element_cb(void *_
, int type
, const char *at
, size_t length
)
35 case MONGREL_CONTENT_LENGTH
: assertStrEquals("12", at
); break;
36 case MONGREL_CONTENT_TYPE
: assertStrEquals("text/html", at
); break;
37 case MONGREL_HTTP_VERSION
: assertStrEquals("HTTP/1.1", at
); break;
38 case MONGREL_REQUEST_PATH
: assertStrEquals("/", at
); break;
39 case MONGREL_REQUEST_METHOD
: assertStrEquals("GET", at
); break;
40 case MONGREL_REQUEST_URI
: assertStrEquals("/", at
); break;
42 printf("unknown: %d\n", type
);
43 assert(0 && "Got an element that we didn't expect");
47 void parse_simple_field_cb(void *_
, const char *field
, size_t flen
, const char *value
, size_t vlen
)
49 assert(0 && "Shouldn't call field_cb");
52 void parse_simple_test(void)
54 const char *simple
= "GET / HTTP/1.1\r\nconTENT-length: 12\r\ncontent-TYPE: text/html\r\n\r\n";
56 http_parser_init(&parser
);
57 parser
.on_element
= parse_simple_element_cb
;
58 parser
.http_field
= parse_simple_field_cb
;
59 nread
= http_parser_execute(&parser
, simple
, strlen(simple
), 0);
60 assertEquals(nread
, strlen(simple
));
61 assertTrue(http_parser_is_finished(&parser
));
62 assertEquals(parser
.content_length
, 12);
66 /** parse_dumbfuck_headers 1 **/
67 void parse_dumbfuck_element_cb(void *_
, int type
, const char *at
, size_t length
)
70 case MONGREL_HTTP_VERSION
: assertStrEquals("HTTP/1.1", at
); break;
71 case MONGREL_REQUEST_PATH
: assertStrEquals("/", at
); break;
72 case MONGREL_REQUEST_METHOD
: assertStrEquals("GET", at
); break;
73 case MONGREL_REQUEST_URI
: assertStrEquals("/", at
); break;
75 printf("unknown: %d\n", type
);
76 assert(0 && "Got an element that we didn't expect");
80 static int parse_dumbfuck_field_count
= 0;
81 void parse_dumbfuck_field_cb(void *_
, const char *field
, size_t flen
, const char *value
, size_t vlen
)
83 parse_dumbfuck_field_count
++;
84 assertStrEquals("aaaaaaaaaaaaa", field
);
85 assertStrEquals("++++++++++", value
);
86 assertEquals(1, parse_dumbfuck_field_count
);
89 void parse_dumbfuck_test(void)
91 const char *dumbfuck
= "GET / HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n";
92 http_parser_init(&parser
);
93 parser
.on_element
= parse_dumbfuck_element_cb
;
94 parser
.http_field
= parse_dumbfuck_field_cb
;
95 int nread
= http_parser_execute(&parser
, dumbfuck
, strlen(dumbfuck
), 0);
96 assertEquals(nread
, strlen(dumbfuck
));
97 assertTrue(http_parser_is_finished(&parser
));
107 /** parse_dumbfuck_headers 2 **/
108 void donothing_element_cb(void *_
, int type
, const char *at
, size_t length
){;}
110 void parse_dumbfuck2_test(void)
112 const char *dumbfuck2
= "GET / HTTP/1.1\r\nX-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgEBBAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n\tRA==\r\n\t-----END CERTIFICATE-----\r\n\r\n";
113 http_parser_init(&parser
);
114 parser
.on_element
= donothing_element_cb
;
115 parser
.http_field
= 0;
116 http_parser_execute(&parser
, dumbfuck2
, strlen(dumbfuck2
), 0);
117 assertTrue(http_parser_has_error(&parser
));
122 /** test_fragment_in_uri **/
123 void fragment_in_uri_element_cb(void *_
, int type
, const char *at
, size_t length
)
126 case MONGREL_HTTP_VERSION
: assertStrEquals("HTTP/1.1", at
); break;
127 case MONGREL_REQUEST_PATH
: assertStrEquals("/forums/1/topics/2375", at
); break;
128 case MONGREL_REQUEST_METHOD
: assertStrEquals("GET", at
); break;
129 case MONGREL_REQUEST_URI
: assertStrEquals("/forums/1/topics/2375?page=1", at
); break;
130 case MONGREL_FRAGMENT
: assertStrEquals("posts-17408", at
); break;
131 case MONGREL_QUERY_STRING
: assertStrEquals("page=1", at
); break;
133 printf("unknown: %d\n", type
);
134 assert(0 && "Got an element that we didn't expect");
138 void fragment_in_uri_test(void)
140 const char *fragment_in_uri
= "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n";
141 http_parser_init(&parser
);
142 parser
.on_element
= fragment_in_uri_element_cb
;
143 parser
.http_field
= 0;
144 http_parser_execute(&parser
, fragment_in_uri
, strlen(fragment_in_uri
), 0);
145 assertTrue(http_parser_is_finished(&parser
));
152 /* very bad garbage generator */
153 char *rand_data(int min
, int max
, int readable
)
156 int count
= min
+ (int)((rand()/(float)RAND_MAX
) * max
+ 1)*10;
157 char *out
= malloc(count
);
159 for(i
= 0; i
< count
; i
++) {
161 out
[i
] = ((double)rand()/RAND_MAX
)*25+'A';
163 out
[i
] = ((double)rand()/RAND_MAX
)*100+10;
170 void horrible_queries_test(void) {
172 GString
*req
= g_string_new("");
174 for(i
= 0; i
< 10; i
++) {
175 g_string_append_printf(req
, "GET /%s HTTP/1.1\r\nX-%s: Test\r\n\r\n"
176 , rand_data(10, 120, TRUE
)
177 , rand_data(1024, 1024+i
*1024, TRUE
)
179 http_parser_init(&parser
);
180 parser
.on_element
= donothing_element_cb
;
181 parser
.http_field
= 0;
182 http_parser_execute(&parser
, req
->str
, req
->len
, 0);
183 assertTrue(http_parser_has_error(&parser
));
187 /* then that large mangled field values are caught */
188 for(i
= 0; i
< 10; i
++) {
189 g_string_append_printf(req
, "GET /%s HTTP/1.1\r\nX-Test: %s\r\n\r\n"
190 , rand_data(10,120, TRUE
)
191 , rand_data(1024, 1024+(i
*1024), FALSE
)
193 http_parser_init(&parser
);
194 parser
.on_element
= donothing_element_cb
;
195 parser
.http_field
= 0;
196 http_parser_execute(&parser
, req
->str
, req
->len
, 0);
197 assertTrue(http_parser_has_error(&parser
));
201 /* then large headers are rejected too */
202 g_string_append_printf(req
, "GET /%s HTTP/1.1\r\n", rand_data(10,120, TRUE
));
203 for(i
= 0; i
< 80 * 1024; i
++) {
204 g_string_append(req
, "X-Test: test\r\n");
206 http_parser_init(&parser
);
207 parser
.on_element
= donothing_element_cb
;
208 parser
.http_field
= 0;
209 http_parser_execute(&parser
, req
->str
, req
->len
, 0);
210 //assertTrue(http_parser_is_finished(&parser));
211 assertTrue(http_parser_has_error(&parser
));
215 /* finally just that random garbage gets blocked all the time */
216 for(i
= 0; i
< 10; i
++) {
217 g_string_append_printf(req
, "GET %s %s\r\n\r\n"
218 , rand_data(1024, 1024+(i
*1024), FALSE
)
219 , rand_data(1024, 1024+(i
*1024), FALSE
)
221 http_parser_init(&parser
);
222 parser
.on_element
= donothing_element_cb
;
223 parser
.http_field
= 0;
224 http_parser_execute(&parser
, req
->str
, req
->len
, 0);
225 assertTrue(http_parser_has_error(&parser
));
228 g_string_free(req
, TRUE
);
231 int main(int argc
, char *argv
[])
235 parse_dumbfuck_test();
236 parse_dumbfuck2_test();
237 fragment_in_uri_test();
238 horrible_queries_test();
240 printf("\nAll tests passed!\n");