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,62 @@
1
+ package http_parser.lolevel;
2
+
3
+ import java.nio.*;
4
+
5
+ import static http_parser.lolevel.Util.*;
6
+
7
+ public class TestNoOverflowLongBody {
8
+
9
+ public static void test (http_parser.ParserType type, int len) {
10
+ HTTPParser parser = new HTTPParser(type);
11
+ ByteBuffer buf = getBytes(type, len);
12
+
13
+ int buflen = buf.limit();
14
+
15
+ parser.execute(Util.SETTINGS_NULL, buf);
16
+
17
+ check(buflen == buf.position());
18
+
19
+ buf = buffer("a");
20
+ buflen = buf.limit();
21
+
22
+ for (int i = 0; i!= len; ++i) {
23
+ parser.execute(Util.SETTINGS_NULL, buf);
24
+ check(buflen == buf.position());
25
+ buf.rewind();
26
+ }
27
+
28
+ buf = getBytes(type, len);
29
+ buflen = buf.limit();
30
+
31
+ parser.execute(Util.SETTINGS_NULL, buf);
32
+
33
+ check(buflen == buf.position());
34
+
35
+ }
36
+
37
+ static ByteBuffer getBytes (http_parser.ParserType type, int length) {
38
+ if (http_parser.ParserType.HTTP_BOTH == type) {
39
+ throw new RuntimeException("only HTTP_REQUEST and HTTP_RESPONSE");
40
+ }
41
+
42
+ String template = "%s\r\nConnection: Keep-Alive\r\nContent-Length: %d\r\n\r\n";
43
+ String str = null;
44
+ if (http_parser.ParserType.HTTP_REQUEST == type) {
45
+ str = String.format(template, "GET / HTTP/1.1", length);
46
+ } else {
47
+ str = String.format(template, "HTTP/1.0 200 OK", length);
48
+ }
49
+ return buffer(str);
50
+ }
51
+
52
+ public static void test () {
53
+ p(TestNoOverflowLongBody.class);
54
+ test(http_parser.ParserType.HTTP_REQUEST, 1000);
55
+ test(http_parser.ParserType.HTTP_REQUEST, 100000);
56
+ test(http_parser.ParserType.HTTP_RESPONSE, 1000);
57
+ test(http_parser.ParserType.HTTP_RESPONSE, 100000);
58
+ }
59
+
60
+
61
+
62
+ }
@@ -0,0 +1,117 @@
1
+ package http_parser.lolevel;
2
+
3
+ import java.nio.ByteBuffer;
4
+ import http_parser.HTTPException;
5
+ import http_parser.Util;
6
+
7
+ public class UnitTest {
8
+
9
+ static void p(Object o) {System.out.println(o);}
10
+
11
+ public static void testErrorFormat() {
12
+ String bla = "This has an error in position 10 (the n in 'an')";
13
+ ByteBuffer buf = ByteBuffer.wrap(bla.getBytes());
14
+ buf.position(10);
15
+
16
+ String mes =
17
+ "This has an error in position 10 (the n in 'an')\n" +
18
+ "..........^";
19
+
20
+ check_equals(mes, Util.error ("test error", buf, 0));
21
+
22
+
23
+ bla = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J";
24
+ buf = ByteBuffer.wrap(bla.getBytes());
25
+ buf.position(50);
26
+ mes =
27
+ "56789B123456789C123456789D123456789E123456789F123456789G123456789H123456\n"+
28
+ "....................................^";
29
+ check_equals(mes, Util.error("test trim right and left", buf, 0));
30
+
31
+
32
+ buf.position(5);
33
+ mes =
34
+ "123456789A123456789B123456789C123456789D123456789E123456789F123456789G12\n"+
35
+ ".....^";
36
+ check_equals(mes, Util.error("test trim right", buf, 0));
37
+
38
+
39
+ int limit = buf.limit();
40
+ buf.limit(10);
41
+ mes =
42
+ "123456789A\n"+
43
+ ".....^";
44
+ check_equals(mes, Util.error("all before, not enough after", buf, 0));
45
+
46
+
47
+
48
+ buf.limit(limit);
49
+ buf.position(90);
50
+ mes =
51
+ "9C123456789D123456789E123456789F123456789G123456789H123456789I123456789J\n"+
52
+ "..............................................................^";
53
+ check_equals(mes, Util.error("test trim left", buf, 10));
54
+ }
55
+
56
+
57
+ // Test that the error callbacks are properly called.
58
+ public static void testErrorCallback () {
59
+ String nothttp = "THis is certainly not valid HTTP";
60
+ ByteBuffer buf = ByteBuffer.wrap(nothttp.getBytes());
61
+
62
+ ParserSettings s = new ParserSettings();
63
+ s.on_error = new HTTPErrorCallback() {
64
+ public void cb (HTTPParser p, String mes, ByteBuffer buf, int pos) {
65
+ throw new HTTPException(mes);
66
+ }
67
+ }; // err callback
68
+
69
+
70
+ HTTPParser p = new HTTPParser();
71
+ try {
72
+ p.execute(s, buf);
73
+ } catch (HTTPException e) {
74
+ check_equals("Invalid HTTP method", e.getMessage());
75
+ }
76
+
77
+ buf = ByteBuffer.wrap("GET / HTTP 1.10000".getBytes());
78
+ p = new HTTPParser();
79
+ try {
80
+ p.execute(s, buf);
81
+ } catch (HTTPException e) {
82
+ check_equals("ridiculous http minor", e.getMessage());
83
+ }
84
+
85
+ // if no error handler is defined, behave just like the above...
86
+ ParserSettings s0 = new ParserSettings();
87
+
88
+ buf = ByteBuffer.wrap("THis is certainly not valid HTTP".getBytes());
89
+ p = new HTTPParser();
90
+ try {
91
+ p.execute(s0, buf);
92
+ } catch (HTTPException e) {
93
+ check_equals("Invalid HTTP method", e.getMessage());
94
+ }
95
+
96
+ buf = ByteBuffer.wrap("GET / HTTP 1.10000".getBytes());
97
+ p = new HTTPParser();
98
+ try {
99
+ p.execute(s0, buf);
100
+ } catch (HTTPException e) {
101
+ check_equals("ridiculous http minor", e.getMessage());
102
+ }
103
+ }
104
+
105
+ static void check_equals(Object supposed2be, Object is) {
106
+ if (!supposed2be.equals(is)) {
107
+ throw new RuntimeException(is + " is supposed to be "+supposed2be);
108
+ }
109
+ }
110
+
111
+
112
+ public static void test () {
113
+ p(UnitTest.class);
114
+ testErrorFormat();
115
+ testErrorCallback();
116
+ }
117
+ }
@@ -0,0 +1,27 @@
1
+ package http_parser.lolevel;
2
+
3
+ import java.nio.*;
4
+ import java.util.*;
5
+
6
+ import http_parser.ParserType;
7
+
8
+ import static http_parser.lolevel.Util.*;
9
+
10
+ public class Upgrade {
11
+ static final String upgrade = "GET /demo HTTP/1.1\r\n" +
12
+ "Connection: Upgrade\r\n" +
13
+ "Upgrade: WebSocket\r\n\r\n" +
14
+ "third key data";
15
+ static void test () {
16
+ p(Upgrade.class);
17
+ HTTPParser parser = new HTTPParser(ParserType.HTTP_REQUEST);
18
+ ByteBuffer buf = buffer(upgrade);
19
+
20
+ int read = parser.execute(Util.SETTINGS_NULL, buf);
21
+ check (63 == read);
22
+ String s = str(buf);
23
+ check ("third key data".equals(str(buf)));
24
+
25
+ }
26
+
27
+ }
@@ -0,0 +1,127 @@
1
+ package http_parser.lolevel;
2
+
3
+ import http_parser.FieldData;
4
+ import http_parser.HTTPParserUrl;
5
+
6
+ import static http_parser.HTTPParserUrl.*;
7
+ import static http_parser.lolevel.HTTPParser.*;
8
+
9
+ /**
10
+ */
11
+ public class Url {
12
+
13
+ public static Url[] URL_TESTS = new Url[]{
14
+ new Url("proxy request", "http://hostname/", false,
15
+ new HTTPParserUrl(
16
+ (1 << UrlFields.UF_SCHEMA.getIndex()) | (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PATH.getIndex()),
17
+ 0,
18
+ new FieldData[]{
19
+ new FieldData(0,4),
20
+ new FieldData(7,8),
21
+ new FieldData(0,0),
22
+ new FieldData(15,1),
23
+ new FieldData(0,0),
24
+ new FieldData(0,0)
25
+ }),
26
+ 0),
27
+ new Url("CONNECT request", "hostname:443", true,
28
+ new HTTPParserUrl(
29
+ (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PORT.getIndex()),
30
+ 443,
31
+ new FieldData[]{
32
+ new FieldData(0,0),
33
+ new FieldData(0,8),
34
+ new FieldData(9,3),
35
+ new FieldData(0,0),
36
+ new FieldData(0,0),
37
+ new FieldData(0,0)
38
+ }),
39
+ 0),
40
+ new Url("proxy ipv6 request", "http://[1:2::3:4]/", false,
41
+ new HTTPParserUrl(
42
+ (1 << UrlFields.UF_SCHEMA.getIndex()) | (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PATH.getIndex()),
43
+ 0,
44
+ new FieldData[]{
45
+ new FieldData(0,4),
46
+ new FieldData(8,8),
47
+ new FieldData(0,0),
48
+ new FieldData(17,1),
49
+ new FieldData(0,0),
50
+ new FieldData(0,0)
51
+ }),
52
+ 0),
53
+ new Url("CONNECT ipv6 address", "[1:2::3:4]:443", true,
54
+ new HTTPParserUrl(
55
+ (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PORT.getIndex()),
56
+ 443,
57
+ new FieldData[]{
58
+ new FieldData(0,0),
59
+ new FieldData(1,8),
60
+ new FieldData(11,3),
61
+ new FieldData(0,0),
62
+ new FieldData(0,0),
63
+ new FieldData(0,0)
64
+ }),
65
+ 0),
66
+ new Url("extra ? in query string",
67
+ "http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css,fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css,fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css",
68
+ false,
69
+ new HTTPParserUrl(
70
+ (1 << UrlFields.UF_SCHEMA.getIndex()) |
71
+ (1 << UrlFields.UF_HOST.getIndex()) |
72
+ (1 << UrlFields.UF_PATH.getIndex()) |
73
+ (1 << UrlFields.UF_QUERY.getIndex()),
74
+ 0,
75
+ new FieldData[]{
76
+ new FieldData(0,4),
77
+ new FieldData(7,10),
78
+ new FieldData(0,0),
79
+ new FieldData(17,12),
80
+ new FieldData(30,187),
81
+ new FieldData(0,0)
82
+ }),
83
+ 0),
84
+ new Url("proxy empty host",
85
+ "http://:443/",
86
+ false,
87
+ null,
88
+ 1),
89
+ new Url("proxy empty port",
90
+ "http://hostname:/",
91
+ false,
92
+ null,
93
+ 1),
94
+ new Url("CONNECT empty host",
95
+ ":443",
96
+ true,
97
+ null,
98
+ 1),
99
+ new Url("CONNECT empty port",
100
+ "hostname:",
101
+ true,
102
+ null,
103
+ 1),
104
+ new Url("CONNECT with extra bits",
105
+ "hostname:443/",
106
+ true,
107
+ null,
108
+ 1),
109
+
110
+ };
111
+
112
+ String name;
113
+ String url;
114
+ boolean is_connect;
115
+ HTTPParserUrl u;
116
+ int rv;
117
+
118
+ public Url(String name, String url, boolean is_connect, HTTPParserUrl u, int rv) {
119
+ this.name = name;
120
+ this.url = url;
121
+ this.is_connect = is_connect;
122
+ this.u = u;
123
+ this.rv = rv;
124
+ }
125
+
126
+
127
+ }
@@ -0,0 +1,236 @@
1
+ package http_parser.lolevel;
2
+
3
+ import java.nio.*;
4
+ import java.util.*;
5
+
6
+ import primitive.collection.ByteList;
7
+
8
+ import http_parser.*;
9
+
10
+ public class Util {
11
+
12
+ static final ParserSettings SETTINGS_NULL = new ParserSettings();
13
+
14
+ static String str (ByteBuffer b, int pos, int len) {
15
+ byte [] by = new byte[len];
16
+ int saved = b.position();
17
+ b.position(pos);
18
+ b.get(by);
19
+ b.position(saved);
20
+ return new String(by);
21
+ }
22
+ static String str (ByteBuffer b) {
23
+ int len = b.limit() - b.position();
24
+ byte [] by = new byte[len];
25
+ int saved = b.position();
26
+ b.get(by);
27
+ b.position(saved);
28
+ return new String(by);
29
+ }
30
+
31
+ static ByteBuffer buffer(String str) {
32
+ return ByteBuffer.wrap(str.getBytes());
33
+ }
34
+
35
+ static ByteBuffer empty() {
36
+ return ByteBuffer.wrap(new byte[0]);
37
+ }
38
+
39
+ static void check(boolean betterBtrue) {
40
+ if (!betterBtrue) {
41
+ throw new RuntimeException("!");
42
+ }
43
+ }
44
+ static void check (int should, int is) {
45
+ if (should != is) {
46
+ throw new RuntimeException("should be: "+should+" is:"+is);
47
+ }
48
+ }
49
+
50
+ static void test_message(Message mes) {
51
+ int raw_len = mes.raw.length;
52
+ for (int msg1len = 0; msg1len != raw_len; ++msg1len) {
53
+ mes.reset();
54
+ ByteBuffer msg1 = ByteBuffer.wrap(mes.raw, 0, msg1len);
55
+ ByteBuffer msg2 = ByteBuffer.wrap(mes.raw, msg1len, mes.raw.length - msg1len);
56
+
57
+ HTTPParser parser = new HTTPParser(mes.type);
58
+ ParserSettings settings = mes.settings();
59
+
60
+ int read = 0;
61
+ if (msg1len !=0) {
62
+ read = parser.execute(settings, msg1);
63
+ if (mes.upgrade() && parser.upgrade) {
64
+ // Messages have a settings() that checks itself...
65
+ check(1 == mes.num_called);
66
+ continue;
67
+ }
68
+ check(read == msg1len);
69
+ }
70
+
71
+ read = parser.execute(settings, msg2);
72
+ if (mes.upgrade() && parser.upgrade) {
73
+ check(1 == mes.num_called);
74
+ continue;
75
+ }
76
+
77
+ check( mes.raw.length - msg1len, read);
78
+
79
+ ByteBuffer empty = Util.empty();
80
+ read = parser.execute(settings, empty);
81
+
82
+ if (mes.upgrade() && parser.upgrade) {
83
+ check(1 == mes.num_called);
84
+ continue;
85
+ }
86
+ check(empty.position() == empty.limit());
87
+ check(0 == read);
88
+ check(1 == mes.num_called);
89
+
90
+ }
91
+ }
92
+
93
+ static void test_multiple3(Message r1, Message r2, Message r3) {
94
+ int message_count = 1;
95
+ if (!r1.upgrade()) {
96
+ message_count++;
97
+ if (!r2.upgrade()) {
98
+ message_count++;
99
+ }
100
+ }
101
+ boolean has_upgrade = (message_count < 3 || r3.upgrade());
102
+
103
+ ByteList blist = new ByteList();
104
+ blist.addAll(r1.raw);
105
+ blist.addAll(r2.raw);
106
+ blist.addAll(r3.raw);
107
+
108
+ byte [] raw = blist.toArray();
109
+ ByteBuffer buf = ByteBuffer.wrap(raw);
110
+
111
+ Util.Settings settings = Util.settings();
112
+ HTTPParser parser = new HTTPParser(r1.type);
113
+
114
+ int read = parser.execute(settings, buf);
115
+ if (has_upgrade && parser.upgrade) {
116
+ raw = upgrade_message_fix(raw, read, r1,r2,r3);
117
+ check(settings.numCalled == message_count);
118
+ return;
119
+ }
120
+
121
+ check(read == raw.length);
122
+
123
+ buf = Util.empty();
124
+ read = parser.execute(settings, buf);
125
+ if (has_upgrade && parser.upgrade) {
126
+ check(settings.numCalled == message_count);
127
+ return;
128
+ }
129
+
130
+ check(0 == read);
131
+ check(settings.numCalled == message_count);
132
+ }
133
+
134
+ /* Given a sequence of bytes and the number of these that we were able to
135
+ * parse, verify that upgrade bodies are correct.
136
+ */
137
+ static byte [] upgrade_message_fix(byte[] body, int nread, Message... msgs) {
138
+ int off = 0;
139
+ for (Message m : msgs) {
140
+ off += m.raw.length;
141
+ if (m.upgrade()) {
142
+ off -= m.upgrade.length;
143
+ // Original C:
144
+ // Check the portion of the response after its specified upgrade
145
+ // if (!check_str_eq(m, "upgrade", body + off, body + nread)) {
146
+ // abort();
147
+ // }
148
+ // to me, this seems to be equivalent to comparing off and nread ...
149
+ check (off, nread);
150
+
151
+ // Original C:
152
+ // Fix up the response so that message_eq() will verify the beginning
153
+ // of the upgrade */
154
+ //
155
+ // *(body + nread + strlen(m->upgrade)) = '\0';
156
+ // This only shortens body so the strlen check passes.
157
+ return new byte[off];
158
+
159
+ }
160
+ }
161
+ return null;
162
+ }
163
+ //upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) {
164
+ // va_list ap;
165
+ // size_t i;
166
+ // size_t off = 0;
167
+ //
168
+ // va_start(ap, nmsgs);
169
+ //
170
+ // for (i = 0; i < nmsgs; i++) {
171
+ // struct message *m = va_arg(ap, struct message *);
172
+ //
173
+ // off += strlen(m->raw);
174
+ //
175
+ // if (m->upgrade) {
176
+ // off -= strlen(m->upgrade);
177
+ //
178
+ // /* Check the portion of the response after its specified upgrade */
179
+ // if (!check_str_eq(m, "upgrade", body + off, body + nread)) {
180
+ // abort();
181
+ // }
182
+ //
183
+ // /* Fix up the response so that message_eq() will verify the beginning
184
+ // * of the upgrade */
185
+ // *(body + nread + strlen(m->upgrade)) = '\0';
186
+ // messages[num_messages -1 ].upgrade = body + nread;
187
+ //
188
+ // va_end(ap);
189
+ // return;
190
+ // }
191
+ // }
192
+ //
193
+ // va_end(ap);
194
+ // printf("\n\n*** Error: expected a message with upgrade ***\n");
195
+ //
196
+ // abort();
197
+ //}
198
+ static void p (Object o) {
199
+ System.out.println(o);
200
+ }
201
+
202
+ static Settings settings() {
203
+ return new Settings();
204
+ }
205
+ static Message find(List<Message> list, String name) {
206
+ for (Message m : list) {
207
+ if (name.equals(m.name)) {
208
+ return m;
209
+ }
210
+ }
211
+ return null;
212
+ }
213
+
214
+ static class Settings extends ParserSettings {
215
+ public int numCalled;
216
+ public int bodyCount;
217
+ Settings() {
218
+ this.on_message_complete = new HTTPCallback() {
219
+ public int cb (HTTPParser parser) {
220
+ numCalled++;
221
+ return 0;
222
+ }
223
+ };
224
+ this.on_body = new HTTPDataCallback() {
225
+ public int cb (HTTPParser p, ByteBuffer b, int pos, int len) {
226
+ bodyCount += len;
227
+ return 0;
228
+ }
229
+ };
230
+ }
231
+
232
+ int numCalled () {
233
+ return this.numCalled;
234
+ }
235
+ }
236
+ }