midori_http_parser 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.gitmodules +6 -0
  4. data/.travis.yml +33 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE-MIT +20 -0
  7. data/README.md +90 -0
  8. data/Rakefile +6 -0
  9. data/bench/standalone.rb +23 -0
  10. data/bench/thin.rb +58 -0
  11. data/ext/ruby_http_parser/.gitignore +1 -0
  12. data/ext/ruby_http_parser/RubyHttpParserService.java +18 -0
  13. data/ext/ruby_http_parser/ext_help.h +18 -0
  14. data/ext/ruby_http_parser/extconf.rb +24 -0
  15. data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +495 -0
  16. data/ext/ruby_http_parser/ruby_http_parser.c +516 -0
  17. data/ext/ruby_http_parser/vendor/.gitkeep +0 -0
  18. data/ext/ruby_http_parser/vendor/http-parser-java/AUTHORS +32 -0
  19. data/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT +48 -0
  20. data/ext/ruby_http_parser/vendor/http-parser-java/README.md +183 -0
  21. data/ext/ruby_http_parser/vendor/http-parser-java/TODO +28 -0
  22. data/ext/ruby_http_parser/vendor/http-parser-java/build.xml +74 -0
  23. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +2175 -0
  24. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.gyp +79 -0
  25. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +304 -0
  26. data/ext/ruby_http_parser/vendor/http-parser-java/src/Http-parser.java.iml +22 -0
  27. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/FieldData.java +41 -0
  28. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java +8 -0
  29. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java +34 -0
  30. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java +12 -0
  31. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java +9 -0
  32. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +113 -0
  33. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java +36 -0
  34. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParserUrl.java +76 -0
  35. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java +256 -0
  36. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java +13 -0
  37. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/Util.java +111 -0
  38. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java +5 -0
  39. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java +25 -0
  40. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java +7 -0
  41. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +2171 -0
  42. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +83 -0
  43. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java +374 -0
  44. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/ParseUrl.java +51 -0
  45. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java +69 -0
  46. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java +52 -0
  47. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java +16 -0
  48. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java +48 -0
  49. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java +212 -0
  50. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java +62 -0
  51. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java +117 -0
  52. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java +27 -0
  53. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Url.java +127 -0
  54. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java +236 -0
  55. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java +59 -0
  56. data/ext/ruby_http_parser/vendor/http-parser-java/test.c +3425 -0
  57. data/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped +845 -0
  58. data/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 +17 -0
  59. data/ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb +6 -0
  60. data/ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb +13 -0
  61. data/ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb +15 -0
  62. data/ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb +33 -0
  63. data/ext/ruby_http_parser/vendor/http-parser/AUTHORS +68 -0
  64. data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +23 -0
  65. data/ext/ruby_http_parser/vendor/http-parser/README.md +246 -0
  66. data/ext/ruby_http_parser/vendor/http-parser/bench.c +111 -0
  67. data/ext/ruby_http_parser/vendor/http-parser/contrib/parsertrace.c +160 -0
  68. data/ext/ruby_http_parser/vendor/http-parser/contrib/url_parser.c +47 -0
  69. data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +2470 -0
  70. data/ext/ruby_http_parser/vendor/http-parser/http_parser.gyp +111 -0
  71. data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +432 -0
  72. data/ext/ruby_http_parser/vendor/http-parser/test.c +4226 -0
  73. data/ext/ruby_http_parser/vendor/http-parser/test_fast +0 -0
  74. data/ext/ruby_http_parser/vendor/http-parser/test_g +0 -0
  75. data/lib/http/parser.rb +1 -0
  76. data/lib/http_parser.rb +21 -0
  77. data/midori_http_parser.gemspec +24 -0
  78. data/spec/parser_spec.rb +376 -0
  79. data/spec/spec_helper.rb +1 -0
  80. data/spec/support/requests.json +631 -0
  81. data/spec/support/responses.json +375 -0
  82. data/tasks/compile.rake +42 -0
  83. data/tasks/fixtures.rake +71 -0
  84. data/tasks/spec.rake +5 -0
  85. data/tasks/submodules.rake +7 -0
  86. metadata +206 -0
@@ -0,0 +1,83 @@
1
+ package http_parser.lolevel;
2
+ import java.nio.ByteBuffer;
3
+ import http_parser.HTTPException;
4
+ public class ParserSettings {
5
+
6
+ public HTTPCallback on_message_begin;
7
+ public HTTPDataCallback on_path;
8
+ public HTTPDataCallback on_query_string;
9
+ public HTTPDataCallback on_url;
10
+ public HTTPDataCallback on_fragment;
11
+ public HTTPCallback on_status_complete;
12
+ public HTTPDataCallback on_header_field;
13
+ public HTTPDataCallback on_header_value;
14
+ public HTTPCallback on_headers_complete;
15
+ public HTTPDataCallback on_body;
16
+ public HTTPCallback on_message_complete;
17
+ public HTTPErrorCallback on_error;
18
+
19
+ void call_on_message_begin (HTTPParser p) {
20
+ call_on(on_message_begin, p);
21
+ }
22
+
23
+ void call_on_message_complete (HTTPParser p) {
24
+ call_on(on_message_complete, p);
25
+ }
26
+
27
+ // this one is a little bit different:
28
+ // the current `position` of the buffer is the location of the
29
+ // error, `ini_pos` indicates where the position of
30
+ // the buffer when it was passed to the `execute` method of the parser, i.e.
31
+ // using this information and `limit` we'll know all the valid data
32
+ // in the buffer around the error we can use to print pretty error
33
+ // messages.
34
+ void call_on_error (HTTPParser p, String mes, ByteBuffer buf, int ini_pos) {
35
+ if (null != on_error) {
36
+ on_error.cb(p, mes, buf, ini_pos);
37
+ return;
38
+ }
39
+ // if on_error gets called it MUST throw an exception, else the parser
40
+ // will attempt to continue parsing, which it can't because it's
41
+ // in an invalid state.
42
+ throw new HTTPException(mes);
43
+ }
44
+
45
+ void call_on_header_field (HTTPParser p, ByteBuffer buf, int pos, int len) {
46
+ call_on(on_header_field, p, buf, pos, len);
47
+ }
48
+ void call_on_query_string (HTTPParser p, ByteBuffer buf, int pos, int len) {
49
+ call_on(on_query_string, p, buf, pos, len);
50
+ }
51
+ void call_on_fragment (HTTPParser p, ByteBuffer buf, int pos, int len) {
52
+ call_on(on_fragment, p, buf, pos, len);
53
+ }
54
+ void call_on_status_complete(HTTPParser p) {
55
+ call_on(on_status_complete, p);
56
+ }
57
+ void call_on_path (HTTPParser p, ByteBuffer buf, int pos, int len) {
58
+ call_on(on_path, p, buf, pos, len);
59
+ }
60
+ void call_on_header_value (HTTPParser p, ByteBuffer buf, int pos, int len) {
61
+ call_on(on_header_value, p, buf, pos, len);
62
+ }
63
+ void call_on_url (HTTPParser p, ByteBuffer buf, int pos, int len) {
64
+ call_on(on_url, p, buf, pos, len);
65
+ }
66
+ void call_on_body(HTTPParser p, ByteBuffer buf, int pos, int len) {
67
+ call_on(on_body, p, buf, pos, len);
68
+ }
69
+ void call_on_headers_complete(HTTPParser p) {
70
+ call_on(on_headers_complete, p);
71
+ }
72
+ void call_on (HTTPCallback cb, HTTPParser p) {
73
+ // cf. CALLBACK2 macro
74
+ if (null != cb) {
75
+ cb.cb(p);
76
+ }
77
+ }
78
+ void call_on (HTTPDataCallback cb, HTTPParser p, ByteBuffer buf, int pos, int len) {
79
+ if (null != cb && -1 != pos) {
80
+ cb.cb(p,buf,pos,len);
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,374 @@
1
+ package http_parser.lolevel;
2
+
3
+ import java.nio.*;
4
+ import java.io.*;
5
+ import java.util.*;
6
+
7
+ import http_parser.HTTPMethod;
8
+ import http_parser.HTTPParserUrl;
9
+ import http_parser.ParserType;
10
+ import http_parser.lolevel.TestLoaderNG.Header;
11
+ import http_parser.lolevel.TestLoaderNG.LastHeader;
12
+
13
+ import primitive.collection.ByteList;
14
+
15
+ import static http_parser.lolevel.Util.str;
16
+
17
+ public class Message {
18
+ String name;
19
+ byte [] raw;
20
+ ParserType type;
21
+ HTTPMethod method;
22
+ int status_code;
23
+ String request_path; // byte [] ?
24
+ String request_url;
25
+ String fragment ;
26
+ String query_string;
27
+ byte [] body;
28
+ int body_size;
29
+ int num_headers;
30
+ LastHeader last_header_element;
31
+ Map<String,String> header;
32
+ List<Header> headers;
33
+ boolean should_keep_alive;
34
+
35
+ byte[] upgrade;
36
+ boolean upgrade() {
37
+ return null != upgrade;
38
+ }
39
+
40
+ int http_major;
41
+ int http_minor;
42
+
43
+ boolean message_begin_called;
44
+ boolean headers_complete_called;
45
+ boolean message_complete_called;
46
+ boolean message_complete_on_eof;
47
+
48
+
49
+ Map<String,String> parsed_header;
50
+ String currHField;
51
+ String currHValue;
52
+ byte [] pbody;
53
+ int num_called;
54
+
55
+ public String toString() {
56
+ StringBuilder b = new StringBuilder();
57
+ b.append("NAME: "); b.append(name);b.append("\n");
58
+ b.append("type: "); b.append(type);b.append("\n");
59
+ b.append("method: "); b.append(method);b.append("\n");
60
+ b.append("status_code: "); b.append(status_code);b.append("\n");
61
+ b.append("request_path: "); b.append(request_path);b.append("\n");
62
+ b.append("request_url: "); b.append(request_url);b.append("\n");
63
+ b.append("fragment: "); b.append(fragment);b.append("\n");
64
+ b.append("query_string: "); b.append(query_string);b.append("\n");
65
+ b.append("body:\n"); b.append(new String(body));b.append("\n");
66
+ b.append("should_keep_alive: "); b.append(should_keep_alive);b.append("\n");
67
+ b.append("upgrade: "); b.append(upgrade);b.append("\n");
68
+ b.append("http_major: "); b.append(http_major);b.append("\n");
69
+ b.append("http_minor: "); b.append(http_minor);b.append("\n");
70
+ b.append("message_complete_called: "); b.append(message_complete_called);b.append("\n");
71
+ return b.toString();
72
+ }
73
+
74
+ Message () {
75
+ this.header = new HashMap<String, String>();
76
+ this.headers = new LinkedList<Header>();
77
+ reset();
78
+ }
79
+ /*
80
+ *prepare this Test Instance for reuse.
81
+ * */
82
+ void reset () {
83
+ this.parsed_header = new HashMap<String, String>();
84
+ this.pbody = null;
85
+ this.num_called = 0;
86
+
87
+ }
88
+ void check (boolean val, String mes) {
89
+ if (!val) {
90
+ //p(name+" : "+mes);
91
+ throw new RuntimeException(name+" : "+mes);
92
+ }
93
+ }
94
+
95
+
96
+ HTTPDataCallback getCB (final String value, final String mes, final TestSettings settings) {
97
+ return new HTTPDataCallback() {
98
+ public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
99
+ // if ("url".equals(mes)){
100
+ // p("pos"+pos);
101
+ // p("len"+len);
102
+ // if (8==pos && 5 == len && "connect request".equals(name)) {
103
+ // //throw new RuntimeException(name);
104
+ // }
105
+ // }
106
+ //String str = str(b, pos, len);
107
+ ByteList list = settings.map.get(mes);
108
+ for (int i=0; i!=len; ++i) {
109
+ list.add(b.get(pos+i));
110
+ }
111
+ //settings.map.put(mes, prev_val + str);
112
+ //check(value.equals(str), "incorrect "+mes+": "+str);
113
+ if (-1 == pos) {
114
+ throw new RuntimeException("he?");
115
+ }
116
+ return 0;
117
+ }
118
+ };
119
+ }
120
+
121
+ void execute () {
122
+ p(name);
123
+ ByteBuffer buf = ByteBuffer.wrap(raw);
124
+ HTTPParser p = new HTTPParser();
125
+ TestSettings s = settings();
126
+
127
+
128
+
129
+ p.execute(s, buf);
130
+ if (!p.upgrade) {
131
+ // call execute again, else parser can't know message is done
132
+ // if no content length is set.
133
+ p.execute(s, buf);
134
+ }
135
+ if (!s.success) {
136
+ throw new RuntimeException("Test: "+name+" failed");
137
+ }
138
+ } // execute
139
+
140
+ void execute_permutations() {
141
+ /*
142
+ |-|---------------|
143
+ |--|--------------|
144
+ |---|-------------|
145
+ (...)
146
+ |---------------|-|
147
+ |-----------------|
148
+ */
149
+ p(name);
150
+ for (int i = 2; i != raw.length; ++i) {
151
+ // p(i);
152
+ HTTPParser p = new HTTPParser();
153
+ TestSettings s = settings();
154
+ ByteBuffer buf = ByteBuffer.wrap(raw);
155
+ int olimit = buf.limit();
156
+ buf.limit(i);
157
+
158
+ parse(p,s,buf);
159
+ if (!p.upgrade) {
160
+ buf.position(i);
161
+ buf.limit(olimit);
162
+
163
+ parse(p,s,buf);
164
+ if (!p.upgrade) {
165
+ parse(p,s,buf);
166
+ } else {
167
+ if (!upgrade()) {
168
+ throw new RuntimeException("Test:"+name+"parsed as upgrade, is not");
169
+ }
170
+ }
171
+
172
+ } else {
173
+ if (!upgrade()) {
174
+ throw new RuntimeException("Test:"+name+"parsed as upgrade, is not");
175
+ }
176
+ }
177
+ if (!s.success) {
178
+ p(this);
179
+ throw new RuntimeException("Test: "+name+" failed");
180
+ }
181
+ reset();
182
+ }
183
+ //System.exit(0);
184
+ } // execute_permutations
185
+ void parse(HTTPParser p, ParserSettings s, ByteBuffer b) {
186
+ //p("About to parse: "+b.position() + "->" + b.limit());
187
+ p.execute(s, b);
188
+ }
189
+
190
+ TestSettings settings() {
191
+ final TestSettings s = new TestSettings();
192
+ s.on_url = getCB(request_url, "url", s);
193
+ s.on_message_begin = new HTTPCallback() {
194
+ public int cb (HTTPParser p) {
195
+ message_begin_called = true;
196
+ return -1;
197
+ }
198
+ };
199
+ s.on_header_field = new HTTPDataCallback() {
200
+ public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
201
+ if (null != currHValue && null == currHField) {
202
+ throw new RuntimeException(name+": shouldn't happen");
203
+ }
204
+ if (null != currHField) {
205
+ if (null == currHValue) {
206
+ currHField += str(b,pos,len);
207
+ return 0;
208
+ } else {
209
+ parsed_header.put(currHField, currHValue);
210
+ currHField = null;
211
+ currHValue = null;
212
+ }
213
+ }
214
+ currHField = str(b,pos,len);
215
+ return 0;
216
+ }
217
+ };
218
+ s.on_header_value = new HTTPDataCallback() {
219
+ public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
220
+ if (null == currHField) {
221
+ throw new RuntimeException(name+" :shouldn't happen field");
222
+ }
223
+ if (null == currHValue) {
224
+ currHValue = str(b,pos,len);
225
+ } else {
226
+ currHValue += str(b, pos, len);
227
+ }
228
+ return 0;
229
+ }
230
+ };
231
+ s.on_headers_complete = new HTTPCallback() {
232
+ public int cb (HTTPParser p) {
233
+ headers_complete_called = true;
234
+ String parsed_path = null;
235
+ String parsed_query = null;
236
+ String parsed_url = null;
237
+ String parsed_frag = null;
238
+
239
+ try {
240
+ parsed_url = new String(s.map.get("url").toArray(), "UTF8");
241
+
242
+ HTTPParserUrl u = new HTTPParserUrl();
243
+ HTTPParser pp = new HTTPParser();
244
+ ByteBuffer data = Util.buffer(parsed_url);
245
+ pp.parse_url(data,false, u);
246
+
247
+ parsed_path = u.getFieldValue(HTTPParser.UrlFields.UF_PATH, data);
248
+ parsed_query = u.getFieldValue(HTTPParser.UrlFields.UF_QUERY, data);
249
+ parsed_frag = u.getFieldValue(HTTPParser.UrlFields.UF_FRAGMENT, data);
250
+
251
+ } catch (java.io.UnsupportedEncodingException uee) {
252
+ throw new RuntimeException(uee);
253
+ }
254
+
255
+ if (!request_path.equals(parsed_path)) {
256
+ throw new RuntimeException(name+": invalid path: "+parsed_path+" should be: "+request_path);
257
+ }
258
+ if (!query_string.equals(parsed_query)) {
259
+ throw new RuntimeException(name+": invalid query: "+parsed_query+" should be: "+query_string);
260
+ }
261
+ if (!request_url.equals(parsed_url)) {
262
+ throw new RuntimeException(">"+name+"<: invalid url: >"+parsed_url+"< should be: >"+request_url+"<");
263
+ }
264
+ if (!fragment.equals(parsed_frag)) {
265
+ throw new RuntimeException(name+": invalid fragement: "+parsed_frag+" should be: "+fragment);
266
+ }
267
+ if (null != currHValue || null != currHField) {
268
+ if (null == currHField || null == currHValue) {
269
+ throw new RuntimeException("shouldn't happen");
270
+ }
271
+ }
272
+ if (null != currHField) {
273
+ //p(currHField);
274
+ //p(">"+currHValue+"<");
275
+ parsed_header.put(currHField, currHValue);
276
+ currHField = null;
277
+ currHValue = null;
278
+ }
279
+
280
+
281
+ return 0;
282
+ }
283
+ };
284
+ // s.on_headers_complete = new HTTPCallback() {
285
+ // public int cb (HTTPParser p) {
286
+ // p("Complete:"+name);
287
+ // return 0;
288
+ // }
289
+ // };
290
+
291
+ s.on_body = new HTTPDataCallback() {
292
+ public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
293
+ int l = pbody == null ? len : len + pbody.length;
294
+ int off = pbody == null ? 0 : pbody.length;
295
+ byte [] nbody = new byte[l];
296
+
297
+ if (null != pbody) {
298
+ System.arraycopy(pbody, 0, nbody, 0, pbody.length);
299
+ }
300
+
301
+ int saved = b.position();
302
+ b.position(pos);
303
+ b.get(nbody, off, len);
304
+ b.position(saved);
305
+ pbody = nbody;
306
+ return 0;
307
+ }
308
+ };
309
+
310
+ s.on_message_complete = new HTTPCallback() {
311
+ public int cb(HTTPParser p) {
312
+ message_complete_called = true;
313
+ num_called += 1;
314
+ if ( p.http_minor != http_minor
315
+ || p.http_major != http_major
316
+ || p.status_code != status_code ) {
317
+
318
+ throw new RuntimeException("major/minor/status_code mismatch");
319
+ }
320
+
321
+ //check headers
322
+
323
+ if (header.keySet().size() != parsed_header.keySet().size()) {
324
+ p(parsed_header);
325
+ throw new RuntimeException(name+": different amount of headers");
326
+ }
327
+ for (String key : header.keySet()) {
328
+ String pvalue = parsed_header.get(key);
329
+ if (!header.get(key).equals(pvalue)) {
330
+ throw new RuntimeException(name+" : different values for :"+key+" is >"+pvalue+"< should: >"+header.get(key)+"<");
331
+ }
332
+ }
333
+ //check body
334
+ if (null == pbody && (null == body || body.length == 0 || body.length == 1)) {
335
+ s.success = true;
336
+ return 0;
337
+ }
338
+ if (null == pbody) {
339
+ throw new RuntimeException(name+": no body, should be: "+new String(body));
340
+ }
341
+ if (pbody.length != body.length) {
342
+ p(pbody.length);
343
+ p(body.length);
344
+ p(new String(pbody));
345
+ p(new String(body));
346
+ throw new RuntimeException(name+": incorrect body length");
347
+ }
348
+ for (int i = 0 ; i!= body.length; ++i) {
349
+ if (pbody[i] != body[i]) {
350
+ throw new RuntimeException("different body");
351
+ }
352
+ }
353
+ s.success = true;
354
+ return 0;
355
+ }
356
+ };
357
+ return s;
358
+ } // settings
359
+ static void p(Object o) {
360
+ System.out.println(o);
361
+ }
362
+
363
+ static class TestSettings extends ParserSettings {
364
+ public boolean success;
365
+ Map<String, ByteList> map;
366
+ TestSettings () {
367
+ map = new HashMap<String, ByteList>();
368
+ map.put("path", new ByteList());
369
+ map.put("query_string", new ByteList());
370
+ map.put("url", new ByteList());
371
+ map.put("fragment", new ByteList());
372
+ }
373
+ }
374
+ }