http_parser.rb 0.5.1-x86-mswin32-60 → 0.5.2-x86-mswin32-60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +16 -16
- data/LICENSE-MIT +20 -0
- data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +68 -11
- data/ext/ruby_http_parser/ruby_http_parser.c +74 -6
- data/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT +26 -1
- data/ext/ruby_http_parser/vendor/http-parser-java/README.md +23 -143
- data/ext/ruby_http_parser/vendor/http-parser-java/TODO +3 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/build.xml +74 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +115 -61
- data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +19 -3
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java +8 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java +34 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java +12 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java +4 -2
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +64 -52
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java +5 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java +323 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/{lolevel/Util.java → Util.java} +27 -28
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +259 -85
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +1 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java +324 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java +69 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java +51 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java +15 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java +47 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java +183 -447
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java +61 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java +2 -1
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java +26 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java +165 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java +58 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/test.c +232 -29
- data/ext/ruby_http_parser/vendor/http-parser-java/test_permutations +1 -1
- data/ext/ruby_http_parser/vendor/http-parser-java/test_unit +1 -1
- data/ext/ruby_http_parser/vendor/http-parser-java/test_utf8 +1 -0
- data/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped +154 -7
- data/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 +17 -0
- data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +1 -1
- data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +52 -10
- data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +3 -1
- data/ext/ruby_http_parser/vendor/http-parser/test.c +89 -3
- data/http_parser.rb.gemspec +8 -2
- data/lib/http_parser.rb +17 -0
- data/spec/parser_spec.rb +97 -6
- data/tasks/compile.rake +3 -1
- metadata +83 -20
- data/ext/ruby_http_parser/vendor/http-parser-java/CONTRIBUTIONS +0 -4
data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java
CHANGED
@@ -33,6 +33,7 @@ public class ParserSettings {
|
|
33
33
|
void call_on_error (HTTPParser p, String mes, ByteBuffer buf, int ini_pos) {
|
34
34
|
if (null != on_error) {
|
35
35
|
on_error.cb(p, mes, buf, ini_pos);
|
36
|
+
return;
|
36
37
|
}
|
37
38
|
// if on_error gets called it MUST throw an exception, else the parser
|
38
39
|
// will attempt to continue parsing, which it can't because it's
|
@@ -0,0 +1,324 @@
|
|
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.ParserType;
|
9
|
+
import http_parser.lolevel.TestLoaderNG.TestSettings;
|
10
|
+
import http_parser.lolevel.TestLoaderNG.Header;
|
11
|
+
import http_parser.lolevel.TestLoaderNG.LastHeader;
|
12
|
+
|
13
|
+
import static http_parser.lolevel.Util.str;
|
14
|
+
|
15
|
+
public class Message {
|
16
|
+
String name;
|
17
|
+
byte [] raw;
|
18
|
+
ParserType type;
|
19
|
+
HTTPMethod method;
|
20
|
+
int status_code;
|
21
|
+
String request_path; // byte [] ?
|
22
|
+
String request_url;
|
23
|
+
String fragment ;
|
24
|
+
String query_string;
|
25
|
+
byte [] body;
|
26
|
+
int body_size;
|
27
|
+
int num_headers;
|
28
|
+
LastHeader last_header_element;
|
29
|
+
Map<String,String> header;
|
30
|
+
List<Header> headers;
|
31
|
+
boolean should_keep_alive;
|
32
|
+
|
33
|
+
boolean upgrade;
|
34
|
+
|
35
|
+
int http_major;
|
36
|
+
int http_minor;
|
37
|
+
|
38
|
+
boolean message_begin_called;
|
39
|
+
boolean headers_complete_called;
|
40
|
+
boolean message_complete_called;
|
41
|
+
boolean message_complete_on_eof;
|
42
|
+
|
43
|
+
|
44
|
+
Map<String,String> parsed_header;
|
45
|
+
String currHField;
|
46
|
+
String currHValue;
|
47
|
+
byte [] pbody;
|
48
|
+
int num_called;
|
49
|
+
|
50
|
+
public String toString() {
|
51
|
+
StringBuilder b = new StringBuilder();
|
52
|
+
b.append("type: "); b.append(type);b.append("\n");
|
53
|
+
b.append("method: "); b.append(method);b.append("\n");
|
54
|
+
b.append("status_code: "); b.append(status_code);b.append("\n");
|
55
|
+
b.append("request_path: "); b.append(request_path);b.append("\n");
|
56
|
+
b.append("request_url: "); b.append(request_url);b.append("\n");
|
57
|
+
b.append("fragment: "); b.append(fragment);b.append("\n");
|
58
|
+
b.append("query_string: "); b.append(query_string);b.append("\n");
|
59
|
+
b.append("body:\n"); b.append(new String(body));b.append("\n");
|
60
|
+
b.append("should_keep_alive: "); b.append(should_keep_alive);b.append("\n");
|
61
|
+
b.append("upgrade: "); b.append(upgrade);b.append("\n");
|
62
|
+
b.append("http_major: "); b.append(http_major);b.append("\n");
|
63
|
+
b.append("http_minor: "); b.append(http_minor);b.append("\n");
|
64
|
+
b.append("message_complete_called: "); b.append(message_complete_called);b.append("\n");
|
65
|
+
return b.toString();
|
66
|
+
}
|
67
|
+
|
68
|
+
Message () {
|
69
|
+
this.header = new HashMap<String, String>();
|
70
|
+
this.headers = new LinkedList<Header>();
|
71
|
+
reset();
|
72
|
+
}
|
73
|
+
/*
|
74
|
+
*prepare this Test Instance for reuse.
|
75
|
+
* */
|
76
|
+
void reset () {
|
77
|
+
this.parsed_header = new HashMap<String, String>();
|
78
|
+
this.pbody = null;
|
79
|
+
this.num_called = 0;
|
80
|
+
|
81
|
+
}
|
82
|
+
void check (boolean val, String mes) {
|
83
|
+
if (!val) {
|
84
|
+
//p(name+" : "+mes);
|
85
|
+
throw new RuntimeException(name+" : "+mes);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
HTTPDataCallback getCB (final String value, final String mes, final TestSettings settings) {
|
91
|
+
return new HTTPDataCallback() {
|
92
|
+
public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
|
93
|
+
// if ("url".equals(mes)){
|
94
|
+
// p("pos"+pos);
|
95
|
+
// p("len"+len);
|
96
|
+
// if (8==pos && 5 == len && "connect request".equals(name)) {
|
97
|
+
// //throw new RuntimeException(name);
|
98
|
+
// }
|
99
|
+
// }
|
100
|
+
String str = str(b, pos, len);
|
101
|
+
String prev_val = settings.map.get(mes);
|
102
|
+
settings.map.put(mes, prev_val + str);
|
103
|
+
//check(value.equals(str), "incorrect "+mes+": "+str);
|
104
|
+
if (-1 == pos) {
|
105
|
+
throw new RuntimeException("he?");
|
106
|
+
}
|
107
|
+
return 0;
|
108
|
+
}
|
109
|
+
};
|
110
|
+
}
|
111
|
+
|
112
|
+
void execute () {
|
113
|
+
p(name);
|
114
|
+
ByteBuffer buf = ByteBuffer.wrap(raw);
|
115
|
+
HTTPParser p = new HTTPParser();
|
116
|
+
TestSettings s = settings();
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
p.execute(s, buf);
|
121
|
+
if (!s.success) {
|
122
|
+
throw new RuntimeException("Test: "+name+"failed");
|
123
|
+
}
|
124
|
+
} // execute
|
125
|
+
|
126
|
+
void execute_permutations() {
|
127
|
+
/*
|
128
|
+
|-|---------------|
|
129
|
+
|--|--------------|
|
130
|
+
|---|-------------|
|
131
|
+
(...)
|
132
|
+
|---------------|-|
|
133
|
+
|-----------------|
|
134
|
+
*/
|
135
|
+
p(name);
|
136
|
+
for (int i = 2; i != raw.length; ++i) {
|
137
|
+
// p(i);
|
138
|
+
HTTPParser p = new HTTPParser();
|
139
|
+
TestSettings s = settings();
|
140
|
+
ByteBuffer buf = ByteBuffer.wrap(raw);
|
141
|
+
int olimit = buf.limit();
|
142
|
+
buf.limit(i);
|
143
|
+
|
144
|
+
parse(p,s,buf);
|
145
|
+
|
146
|
+
buf.position(i);
|
147
|
+
buf.limit(olimit);
|
148
|
+
|
149
|
+
parse(p,s,buf);
|
150
|
+
parse(p,s,buf);
|
151
|
+
|
152
|
+
if (!s.success) {
|
153
|
+
p(this);
|
154
|
+
throw new RuntimeException("Test: "+name+" failed");
|
155
|
+
}
|
156
|
+
reset();
|
157
|
+
}
|
158
|
+
//System.exit(0);
|
159
|
+
} // execute_permutations
|
160
|
+
void parse(HTTPParser p, ParserSettings s, ByteBuffer b) {
|
161
|
+
//p("About to parse: "+b.position() + "->" + b.limit());
|
162
|
+
p.execute(s, b);
|
163
|
+
}
|
164
|
+
|
165
|
+
TestSettings settings() {
|
166
|
+
final TestSettings s = new TestSettings();
|
167
|
+
s.on_path = getCB(request_path, "path", s);
|
168
|
+
s.on_query_string = getCB(query_string, "query_string", s);
|
169
|
+
s.on_url = getCB(request_url, "url", s);
|
170
|
+
s.on_fragment = getCB(fragment, "fragment", s);
|
171
|
+
s.on_message_begin = new HTTPCallback() {
|
172
|
+
public int cb (HTTPParser p) {
|
173
|
+
message_begin_called = true;
|
174
|
+
return -1;
|
175
|
+
}
|
176
|
+
};
|
177
|
+
s.on_header_field = new HTTPDataCallback() {
|
178
|
+
public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
|
179
|
+
if (null != currHValue && null == currHField) {
|
180
|
+
throw new RuntimeException(name+": shouldn't happen");
|
181
|
+
}
|
182
|
+
if (null != currHField) {
|
183
|
+
if (null == currHValue) {
|
184
|
+
currHField += str(b,pos,len);
|
185
|
+
return 0;
|
186
|
+
} else {
|
187
|
+
parsed_header.put(currHField, currHValue);
|
188
|
+
currHField = null;
|
189
|
+
currHValue = null;
|
190
|
+
}
|
191
|
+
}
|
192
|
+
currHField = str(b,pos,len);
|
193
|
+
return 0;
|
194
|
+
}
|
195
|
+
};
|
196
|
+
s.on_header_value = new HTTPDataCallback() {
|
197
|
+
public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
|
198
|
+
if (null == currHField) {
|
199
|
+
throw new RuntimeException(name+" :shouldn't happen field");
|
200
|
+
}
|
201
|
+
if (null == currHValue) {
|
202
|
+
currHValue = str(b,pos,len);
|
203
|
+
} else {
|
204
|
+
currHValue += str(b, pos, len);
|
205
|
+
}
|
206
|
+
return 0;
|
207
|
+
}
|
208
|
+
};
|
209
|
+
s.on_headers_complete = new HTTPCallback() {
|
210
|
+
public int cb (HTTPParser p) {
|
211
|
+
headers_complete_called = true;
|
212
|
+
String parsed_path = s.map.get("path");
|
213
|
+
String parsed_query = s.map.get("query_string");
|
214
|
+
String parsed_url = s.map.get("url");
|
215
|
+
String parsed_frag = s.map.get("fragment");
|
216
|
+
|
217
|
+
if (!request_path.equals(parsed_path)) {
|
218
|
+
throw new RuntimeException(name+": invalid path: "+parsed_path+" should be: "+request_path);
|
219
|
+
}
|
220
|
+
if (!query_string.equals(parsed_query)) {
|
221
|
+
throw new RuntimeException(name+": invalid query: "+parsed_query+" should be: "+query_string);
|
222
|
+
}
|
223
|
+
if (!request_url.equals(parsed_url)) {
|
224
|
+
throw new RuntimeException(">"+name+"<: invalid url: >"+parsed_url+"< should be: >"+request_url+"<");
|
225
|
+
}
|
226
|
+
if (!fragment.equals(parsed_frag)) {
|
227
|
+
throw new RuntimeException(name+": invalid fragement: "+parsed_frag+" should be: "+fragment);
|
228
|
+
}
|
229
|
+
if (null != currHValue || null != currHField) {
|
230
|
+
if (null == currHField || null == currHValue) {
|
231
|
+
throw new RuntimeException("shouldn't happen");
|
232
|
+
}
|
233
|
+
}
|
234
|
+
if (null != currHField) {
|
235
|
+
//p(currHField);
|
236
|
+
//p(">"+currHValue+"<");
|
237
|
+
parsed_header.put(currHField, currHValue);
|
238
|
+
currHField = null;
|
239
|
+
currHValue = null;
|
240
|
+
}
|
241
|
+
|
242
|
+
|
243
|
+
return 0;
|
244
|
+
}
|
245
|
+
};
|
246
|
+
// s.on_headers_complete = new HTTPCallback() {
|
247
|
+
// public int cb (HTTPParser p) {
|
248
|
+
// p("Complete:"+name);
|
249
|
+
// return 0;
|
250
|
+
// }
|
251
|
+
// };
|
252
|
+
|
253
|
+
s.on_body = new HTTPDataCallback() {
|
254
|
+
public int cb (HTTPParser p, ByteBuffer b, int pos, int len){
|
255
|
+
int l = pbody == null ? len : len + pbody.length;
|
256
|
+
int off = pbody == null ? 0 : pbody.length;
|
257
|
+
byte [] nbody = new byte[l];
|
258
|
+
|
259
|
+
if (null != pbody) {
|
260
|
+
System.arraycopy(pbody, 0, nbody, 0, pbody.length);
|
261
|
+
}
|
262
|
+
|
263
|
+
int saved = b.position();
|
264
|
+
b.position(pos);
|
265
|
+
b.get(nbody, off, len);
|
266
|
+
b.position(saved);
|
267
|
+
pbody = nbody;
|
268
|
+
return 0;
|
269
|
+
}
|
270
|
+
};
|
271
|
+
|
272
|
+
s.on_message_complete = new HTTPCallback() {
|
273
|
+
public int cb(HTTPParser p) {
|
274
|
+
message_complete_called = true;
|
275
|
+
num_called += 1;
|
276
|
+
if ( p.http_minor != http_minor
|
277
|
+
|| p.http_major != http_major
|
278
|
+
|| p.status_code != status_code ) {
|
279
|
+
|
280
|
+
throw new RuntimeException("major/minor/status_code mismatch");
|
281
|
+
}
|
282
|
+
|
283
|
+
//check headers
|
284
|
+
|
285
|
+
if (header.keySet().size() != parsed_header.keySet().size()) {
|
286
|
+
p(parsed_header);
|
287
|
+
throw new RuntimeException(name+": different amount of headers");
|
288
|
+
}
|
289
|
+
for (String key : header.keySet()) {
|
290
|
+
String pvalue = parsed_header.get(key);
|
291
|
+
if (!header.get(key).equals(pvalue)) {
|
292
|
+
throw new RuntimeException(name+" : different values for :"+key+" is >"+pvalue+"< should: >"+header.get(key)+"<");
|
293
|
+
}
|
294
|
+
}
|
295
|
+
//check body
|
296
|
+
if (null == pbody && (null == body || body.length == 0 || body.length == 1)) {
|
297
|
+
s.success = true;
|
298
|
+
return 0;
|
299
|
+
}
|
300
|
+
if (null == pbody) {
|
301
|
+
throw new RuntimeException(name+": no body, should be: "+new String(body));
|
302
|
+
}
|
303
|
+
if (pbody.length != body.length) {
|
304
|
+
p(pbody.length);
|
305
|
+
p(body.length);
|
306
|
+
p(new String(pbody));
|
307
|
+
p(new String(body));
|
308
|
+
throw new RuntimeException(name+": incorrect body length");
|
309
|
+
}
|
310
|
+
for (int i = 0 ; i!= body.length; ++i) {
|
311
|
+
if (pbody[i] != body[i]) {
|
312
|
+
throw new RuntimeException("different body");
|
313
|
+
}
|
314
|
+
}
|
315
|
+
s.success = true;
|
316
|
+
return 0;
|
317
|
+
}
|
318
|
+
};
|
319
|
+
return s;
|
320
|
+
} // settings
|
321
|
+
static void p(Object o) {
|
322
|
+
System.out.println(o);
|
323
|
+
}
|
324
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
package http_parser.lolevel;
|
2
|
+
|
3
|
+
import java.nio.*;
|
4
|
+
import java.util.*;
|
5
|
+
|
6
|
+
import static http_parser.lolevel.Util.*;
|
7
|
+
import http_parser.*;
|
8
|
+
|
9
|
+
import primitive.collection.ByteList;
|
10
|
+
|
11
|
+
public class Requests {
|
12
|
+
|
13
|
+
static void test_simple(String req, boolean should_pass) {
|
14
|
+
HTTPParser parser = new HTTPParser(ParserType.HTTP_REQUEST);
|
15
|
+
ByteBuffer buf = buffer(req);
|
16
|
+
boolean passed = false;
|
17
|
+
int read = 0;
|
18
|
+
try {
|
19
|
+
parser.execute(Util.SETTINGS_NULL, buf);
|
20
|
+
passed = (read == req.length());
|
21
|
+
read = parser.execute(Util.SETTINGS_NULL, Util.empty());
|
22
|
+
passed &= (0 == read);
|
23
|
+
} catch (Throwable t) {
|
24
|
+
passed = false;
|
25
|
+
}
|
26
|
+
check(passed == should_pass);
|
27
|
+
}
|
28
|
+
static void simple_tests() {
|
29
|
+
test_simple("hello world", false);
|
30
|
+
test_simple("GET / HTP/1.1\r\n\r\n", false);
|
31
|
+
|
32
|
+
test_simple("ASDF / HTTP/1.1\r\n\r\n", false);
|
33
|
+
test_simple("PROPPATCHA / HTTP/1.1\r\n\r\n", false);
|
34
|
+
test_simple("GETA / HTTP/1.1\r\n\r\n", false);
|
35
|
+
}
|
36
|
+
|
37
|
+
public static void test () {
|
38
|
+
|
39
|
+
simple_tests();
|
40
|
+
|
41
|
+
List<Message> all = TestLoaderNG.load("tests.dumped");
|
42
|
+
List<Message> requests = new LinkedList<Message>();
|
43
|
+
for (Message m : all) {
|
44
|
+
if (ParserType.HTTP_REQUEST == m.type) {
|
45
|
+
requests.add(m);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
for (Message m : requests) {
|
49
|
+
test_message(m);
|
50
|
+
}
|
51
|
+
|
52
|
+
for (int i = 0; i!= requests.size(); ++i) {
|
53
|
+
if (!requests.get(i).should_keep_alive) continue;
|
54
|
+
for (int j = 0; j!=requests.size(); ++j) {
|
55
|
+
if (!requests.get(j).should_keep_alive) continue;
|
56
|
+
for (int k = 0; k!= requests.size(); ++k) {
|
57
|
+
test_multiple3(requests.get(i), requests.get(j), requests.get(k));
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
// postpone test_scan
|
63
|
+
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
package http_parser.lolevel;
|
2
|
+
|
3
|
+
import java.nio.*;
|
4
|
+
import java.util.*;
|
5
|
+
|
6
|
+
import static http_parser.lolevel.Util.*;
|
7
|
+
import http_parser.*;
|
8
|
+
|
9
|
+
import primitive.collection.ByteList;
|
10
|
+
|
11
|
+
public class Responses {
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
public static void test () {
|
16
|
+
List<Message> all = TestLoaderNG.load("tests.dumped");
|
17
|
+
List<Message> responses = new LinkedList<Message>();
|
18
|
+
for (Message m : all) {
|
19
|
+
if (ParserType.HTTP_RESPONSE == m.type) {
|
20
|
+
responses.add(m);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
for (Message m : responses) {
|
24
|
+
test_message(m);
|
25
|
+
}
|
26
|
+
|
27
|
+
for (int i = 0; i!= responses.size(); ++i) {
|
28
|
+
if (!responses.get(i).should_keep_alive) continue;
|
29
|
+
for (int j = 0; j!=responses.size(); ++j) {
|
30
|
+
if (!responses.get(j).should_keep_alive) continue;
|
31
|
+
for (int k = 0; k!= responses.size(); ++k) {
|
32
|
+
test_multiple3(responses.get(i), responses.get(j), responses.get(k));
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
// not sure what test_message_count_body does that test_message doesn't...
|
38
|
+
// Message m = find(responses, "404 no headers no body");
|
39
|
+
// test_message_count_body(m);
|
40
|
+
// m = find(responses, "200 trailing space on chunked body");
|
41
|
+
// test_message_count_body(m);
|
42
|
+
|
43
|
+
// TODO test very large chunked response
|
44
|
+
|
45
|
+
// test_scan is more or less the same as test_permutations, will implement later...
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
}
|