http_parser.rb 0.6.0.beta.1 → 0.8.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/linux.yml +23 -0
- data/.github/workflows/windows.yml +23 -0
- data/.gitignore +5 -4
- data/.gitmodules +2 -2
- data/README.md +2 -2
- data/Rakefile +4 -2
- data/ext/ruby_http_parser/extconf.rb +1 -1
- data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +86 -52
- data/ext/ruby_http_parser/ruby_http_parser.c +53 -7
- data/ext/ruby_http_parser/vendor/http-parser/AUTHORS +37 -1
- data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +1 -5
- data/ext/ruby_http_parser/vendor/http-parser/Makefile +110 -8
- data/ext/ruby_http_parser/vendor/http-parser/README.md +105 -37
- data/ext/ruby_http_parser/vendor/http-parser/bench.c +128 -0
- data/ext/ruby_http_parser/vendor/http-parser/contrib/parsertrace.c +157 -0
- data/ext/ruby_http_parser/vendor/http-parser/contrib/url_parser.c +47 -0
- data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +892 -510
- data/ext/ruby_http_parser/vendor/http-parser/http_parser.gyp +34 -2
- data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +198 -77
- data/ext/ruby_http_parser/vendor/http-parser/test.c +1781 -201
- data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +271 -154
- data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +48 -61
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +5 -3
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java +37 -104
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +116 -101
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +9 -5
- data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java +1 -1
- data/ext/ruby_http_parser/vendor/http-parser-java/test.c +579 -153
- data/http_parser.rb.gemspec +14 -9
- data/spec/parser_spec.rb +177 -99
- data/spec/support/requests.json +2 -2
- data/spec/support/responses.json +20 -0
- data/tasks/spec.rake +1 -1
- metadata +131 -162
- data/Gemfile.lock +0 -39
- data/ext/ruby_http_parser/vendor/http-parser/CONTRIBUTIONS +0 -4
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPHeadersCompleteCallback.java +0 -13
- data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPHeadersCompleteCallback.java +0 -12
data/http_parser.rb.gemspec
CHANGED
@@ -1,27 +1,32 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "http_parser.rb"
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.8.0"
|
4
4
|
s.summary = "Simple callback-based HTTP request/response parser"
|
5
|
-
s.description = "Ruby bindings to
|
5
|
+
s.description = "Ruby bindings to https://github.com/joyent/http-parser and https://github.com/http-parser/http-parser.java"
|
6
6
|
|
7
7
|
s.authors = ["Marc-Andre Cournoyer", "Aman Gupta"]
|
8
8
|
s.email = ["macournoyer@gmail.com", "aman@tmm1.net"]
|
9
|
+
s.license = 'MIT'
|
9
10
|
|
10
|
-
s.homepage = "
|
11
|
+
s.homepage = "https://github.com/tmm1/http_parser.rb"
|
11
12
|
s.files = `git ls-files`.split("\n") + Dir['ext/ruby_http_parser/vendor/**/*']
|
12
13
|
|
13
14
|
s.require_paths = ["lib"]
|
14
15
|
s.extensions = ["ext/ruby_http_parser/extconf.rb"]
|
15
16
|
|
16
|
-
s.add_development_dependency 'rake-compiler', '
|
17
|
-
s.add_development_dependency 'rspec', '
|
18
|
-
s.add_development_dependency 'json', '
|
19
|
-
s.add_development_dependency 'benchmark_suite'
|
20
|
-
s.add_development_dependency 'ffi'
|
17
|
+
s.add_development_dependency 'rake-compiler', '~> 1.0'
|
18
|
+
s.add_development_dependency 'rspec', '~> 3'
|
19
|
+
s.add_development_dependency 'json', '~> 2.1'
|
20
|
+
s.add_development_dependency 'benchmark_suite', '~> 1.0'
|
21
|
+
s.add_development_dependency 'ffi', '~> 1.9'
|
21
22
|
|
22
23
|
if RUBY_PLATFORM =~ /java/
|
23
24
|
s.add_development_dependency 'jruby-openssl'
|
24
25
|
else
|
25
|
-
|
26
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
27
|
+
s.add_development_dependency 'yajl-ruby', '~> 1.3'
|
28
|
+
else
|
29
|
+
s.add_development_dependency 'yajl-ruby', '= 1.2.1'
|
30
|
+
end
|
26
31
|
end
|
27
32
|
end
|
data/spec/parser_spec.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
if defined?(Encoding)
|
2
|
+
Encoding.default_external = "UTF-8"
|
3
|
+
end
|
1
4
|
require "spec_helper"
|
2
5
|
require "json"
|
3
6
|
|
@@ -17,24 +20,46 @@ describe HTTP::Parser do
|
|
17
20
|
end
|
18
21
|
|
19
22
|
it "should have initial state" do
|
20
|
-
@parser.headers.
|
23
|
+
expect(@parser.headers).to be_nil
|
21
24
|
|
22
|
-
@parser.http_version.
|
23
|
-
@parser.http_method.
|
24
|
-
@parser.status_code.
|
25
|
+
expect(@parser.http_version).to be_nil
|
26
|
+
expect(@parser.http_method).to be_nil
|
27
|
+
expect(@parser.status_code).to be_nil
|
25
28
|
|
26
|
-
@parser.request_url.
|
29
|
+
expect(@parser.request_url).to be_nil
|
27
30
|
|
28
|
-
@parser.header_value_type.
|
31
|
+
expect(@parser.header_value_type).to eq(:mixed)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should be able to run in non-main ractors" do
|
35
|
+
skip unless Kernel.const_defined?(:Ractor)
|
36
|
+
default_header_value_type = HTTP::Parser.default_header_value_type
|
37
|
+
r = Ractor.new(default_header_value_type) { |type|
|
38
|
+
parser = HTTP::Parser.new(default_header_value_type: type)
|
39
|
+
done = false
|
40
|
+
parser.on_message_complete = proc {
|
41
|
+
done = true
|
42
|
+
}
|
43
|
+
parser <<
|
44
|
+
"GET /ractor HTTP/1.1\r\n" +
|
45
|
+
"Content-Length: 5\r\n" +
|
46
|
+
"\r\n" +
|
47
|
+
"World"
|
48
|
+
done
|
49
|
+
}
|
50
|
+
expect(r.take).to be true
|
29
51
|
end
|
30
52
|
|
31
53
|
it "should allow us to set the header value type" do
|
32
54
|
[:mixed, :arrays, :strings].each do |type|
|
33
55
|
@parser.header_value_type = type
|
34
|
-
@parser.header_value_type.
|
56
|
+
expect(@parser.header_value_type).to eq(type)
|
35
57
|
|
36
58
|
parser_tmp = HTTP::Parser.new(nil, type)
|
37
|
-
parser_tmp.header_value_type.
|
59
|
+
expect(parser_tmp.header_value_type).to eq(type)
|
60
|
+
|
61
|
+
parser_tmp2 = HTTP::Parser.new(default_header_value_type: type)
|
62
|
+
expect(parser_tmp2.header_value_type).to eq(type)
|
38
63
|
end
|
39
64
|
end
|
40
65
|
|
@@ -43,16 +68,16 @@ describe HTTP::Parser do
|
|
43
68
|
HTTP::Parser.default_header_value_type = type
|
44
69
|
|
45
70
|
parser = HTTP::Parser.new
|
46
|
-
parser.header_value_type.
|
71
|
+
expect(parser.header_value_type).to eq(type)
|
47
72
|
end
|
48
73
|
end
|
49
74
|
|
50
75
|
it "should throw an Argument Error if header value type is invalid" do
|
51
|
-
|
76
|
+
expect{ @parser.header_value_type = 'bob' }.to raise_error(ArgumentError)
|
52
77
|
end
|
53
78
|
|
54
79
|
it "should throw an Argument Error if default header value type is invalid" do
|
55
|
-
|
80
|
+
expect{ HTTP::Parser.default_header_value_type = 'bob' }.to raise_error(ArgumentError)
|
56
81
|
end
|
57
82
|
|
58
83
|
it "should implement basic api" do
|
@@ -65,29 +90,29 @@ describe HTTP::Parser do
|
|
65
90
|
"\r\n" +
|
66
91
|
"World"
|
67
92
|
|
68
|
-
@started.
|
69
|
-
@done.
|
93
|
+
expect(@started).to be true
|
94
|
+
expect(@done).to be true
|
70
95
|
|
71
|
-
@parser.http_major.
|
72
|
-
@parser.http_minor.
|
73
|
-
@parser.http_version.
|
74
|
-
@parser.http_method.
|
75
|
-
@parser.status_code.
|
96
|
+
expect(@parser.http_major).to eq(1)
|
97
|
+
expect(@parser.http_minor).to eq(1)
|
98
|
+
expect(@parser.http_version).to eq([1,1])
|
99
|
+
expect(@parser.http_method).to eq('GET')
|
100
|
+
expect(@parser.status_code).to be_nil
|
76
101
|
|
77
|
-
@parser.request_url.
|
102
|
+
expect(@parser.request_url).to eq('/test?ok=1')
|
78
103
|
|
79
|
-
@parser.headers.
|
80
|
-
@parser.headers['User-Agent'].
|
81
|
-
@parser.headers['Host'].
|
104
|
+
expect(@parser.headers).to eq(@headers)
|
105
|
+
expect(@parser.headers['User-Agent']).to eq('curl/7.18.0')
|
106
|
+
expect(@parser.headers['Host']).to eq('0.0.0.0:5000')
|
82
107
|
|
83
|
-
@body.
|
108
|
+
expect(@body).to eq("World")
|
84
109
|
end
|
85
110
|
|
86
111
|
it "should raise errors on invalid data" do
|
87
|
-
|
112
|
+
expect{ @parser << "BLAH" }.to raise_error(HTTP::Parser::Error)
|
88
113
|
end
|
89
114
|
|
90
|
-
it "should abort parser via callback" do
|
115
|
+
it "should abort parser via header complete callback with a body" do
|
91
116
|
@parser.on_headers_complete = proc { |e| @headers = e; :stop }
|
92
117
|
|
93
118
|
data =
|
@@ -98,33 +123,90 @@ describe HTTP::Parser do
|
|
98
123
|
|
99
124
|
bytes = @parser << data
|
100
125
|
|
101
|
-
bytes.
|
102
|
-
data[bytes..-1].
|
126
|
+
expect(bytes).to eq(37)
|
127
|
+
expect(data[bytes..-1]).to eq('World')
|
128
|
+
|
129
|
+
expect(@headers).to eq({'Content-Length' => '5'})
|
130
|
+
expect(@body).to be_empty
|
131
|
+
expect(@done).to be false
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should abort parser via header complete callback without a body" do
|
135
|
+
@parser.on_headers_complete = proc { |e| @headers = e; :stop }
|
136
|
+
|
137
|
+
data =
|
138
|
+
"GET / HTTP/1.0\r\n" +
|
139
|
+
"Content-Length: 0\r\n" +
|
140
|
+
"\r\n"
|
141
|
+
|
142
|
+
bytes = @parser << data
|
143
|
+
|
144
|
+
expect(bytes).to eq(37)
|
145
|
+
expect(data[bytes..-1]).to eq('')
|
146
|
+
|
147
|
+
expect(@headers).to eq({'Content-Length' => '0'})
|
148
|
+
expect(@body).to be_empty
|
149
|
+
expect(@done).to be false
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should abort parser via message complete callback with a body" do
|
153
|
+
@parser.on_message_complete = proc { :stop }
|
154
|
+
|
155
|
+
data =
|
156
|
+
"CONNECT www.example.com:443 HTTP/1.0\r\n" +
|
157
|
+
"Connection: keep-alive\r\n" +
|
158
|
+
"\r\n" +
|
159
|
+
"World"
|
160
|
+
|
161
|
+
bytes = @parser << data
|
162
|
+
|
163
|
+
expect(bytes).to eq(64)
|
164
|
+
expect(data[bytes..-1]).to eq('World')
|
103
165
|
|
104
|
-
@headers.
|
105
|
-
@
|
106
|
-
@
|
166
|
+
expect(@headers).to eq({'Connection' => 'keep-alive'})
|
167
|
+
expect(@parser.upgrade_data).to eq('World')
|
168
|
+
expect(@body).to be_empty
|
169
|
+
expect(@done).to be false
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should abort parser via message complete callback without a body" do
|
173
|
+
@parser.on_message_complete = proc { :stop }
|
174
|
+
|
175
|
+
data =
|
176
|
+
"CONNECT www.example.com:443 HTTP/1.0\r\n" +
|
177
|
+
"Connection: keep-alive\r\n" +
|
178
|
+
"\r\n"
|
179
|
+
|
180
|
+
bytes = @parser << data
|
181
|
+
|
182
|
+
expect(bytes).to eq(64)
|
183
|
+
expect(data[bytes..-1]).to eq('')
|
184
|
+
|
185
|
+
expect(@headers).to eq({'Connection' => 'keep-alive'})
|
186
|
+
expect(@parser.upgrade_data).to eq('')
|
187
|
+
expect(@body).to be_empty
|
188
|
+
expect(@done).to be false
|
107
189
|
end
|
108
190
|
|
109
191
|
it "should reset to initial state" do
|
110
192
|
@parser << "GET / HTTP/1.0\r\n\r\n"
|
111
193
|
|
112
|
-
@parser.http_method.
|
113
|
-
@parser.http_version.
|
194
|
+
expect(@parser.http_method).to eq('GET')
|
195
|
+
expect(@parser.http_version).to eq([1,0])
|
114
196
|
|
115
|
-
@parser.request_url.
|
197
|
+
expect(@parser.request_url).to eq('/')
|
116
198
|
|
117
|
-
@parser.reset
|
199
|
+
expect(@parser.reset!).to be true
|
118
200
|
|
119
|
-
@parser.http_version.
|
120
|
-
@parser.http_method.
|
121
|
-
@parser.status_code.
|
201
|
+
expect(@parser.http_version).to be_nil
|
202
|
+
expect(@parser.http_method).to be_nil
|
203
|
+
expect(@parser.status_code).to be_nil
|
122
204
|
|
123
|
-
@parser.request_url.
|
205
|
+
expect(@parser.request_url).to be_nil
|
124
206
|
end
|
125
207
|
|
126
208
|
it "should optionally reset parser state on no-body responses" do
|
127
|
-
@parser.reset
|
209
|
+
expect(@parser.reset!).to be true
|
128
210
|
|
129
211
|
@head, @complete = 0, 0
|
130
212
|
@parser.on_headers_complete = proc {|h| @head += 1; :reset }
|
@@ -134,21 +216,21 @@ describe HTTP::Parser do
|
|
134
216
|
head_response = "HTTP/1.1 200 OK\r\nContent-Length:10\r\n\r\n"
|
135
217
|
|
136
218
|
@parser << head_response
|
137
|
-
@head.
|
138
|
-
@complete.
|
219
|
+
expect(@head).to eq(1)
|
220
|
+
expect(@complete).to eq(1)
|
139
221
|
|
140
222
|
@parser << head_response
|
141
|
-
@head.
|
142
|
-
@complete.
|
223
|
+
expect(@head).to eq(2)
|
224
|
+
expect(@complete).to eq(2)
|
143
225
|
end
|
144
226
|
|
145
227
|
it "should retain callbacks after reset" do
|
146
|
-
@parser.reset
|
228
|
+
expect(@parser.reset!).to be true
|
147
229
|
|
148
230
|
@parser << "GET / HTTP/1.0\r\n\r\n"
|
149
|
-
@started.
|
150
|
-
@headers.
|
151
|
-
@done.
|
231
|
+
expect(@started).to be true
|
232
|
+
expect(@headers).to eq({})
|
233
|
+
expect(@done).to be true
|
152
234
|
end
|
153
235
|
|
154
236
|
it "should parse headers incrementally" do
|
@@ -162,10 +244,10 @@ describe HTTP::Parser do
|
|
162
244
|
@parser << chunk
|
163
245
|
end
|
164
246
|
|
165
|
-
@parser.headers.
|
247
|
+
expect(@parser.headers).to eq({
|
166
248
|
'Header1' => 'value 1',
|
167
249
|
'Header2' => 'value 2'
|
168
|
-
}
|
250
|
+
})
|
169
251
|
end
|
170
252
|
|
171
253
|
it "should handle multiple headers using strings" do
|
@@ -177,7 +259,7 @@ describe HTTP::Parser do
|
|
177
259
|
"Set-Cookie: NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly\r\n" +
|
178
260
|
"\r\n"
|
179
261
|
|
180
|
-
@parser.headers["Set-Cookie"].
|
262
|
+
expect(@parser.headers["Set-Cookie"]).to eq("PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com, NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly")
|
181
263
|
end
|
182
264
|
|
183
265
|
it "should handle multiple headers using strings" do
|
@@ -189,10 +271,10 @@ describe HTTP::Parser do
|
|
189
271
|
"Set-Cookie: NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly\r\n" +
|
190
272
|
"\r\n"
|
191
273
|
|
192
|
-
@parser.headers["Set-Cookie"].
|
274
|
+
expect(@parser.headers["Set-Cookie"]).to eq([
|
193
275
|
"PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com",
|
194
276
|
"NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly"
|
195
|
-
]
|
277
|
+
])
|
196
278
|
end
|
197
279
|
|
198
280
|
it "should handle multiple headers using mixed" do
|
@@ -204,10 +286,10 @@ describe HTTP::Parser do
|
|
204
286
|
"Set-Cookie: NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly\r\n" +
|
205
287
|
"\r\n"
|
206
288
|
|
207
|
-
@parser.headers["Set-Cookie"].
|
289
|
+
expect(@parser.headers["Set-Cookie"]).to eq([
|
208
290
|
"PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com",
|
209
291
|
"NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly"
|
210
|
-
]
|
292
|
+
])
|
211
293
|
end
|
212
294
|
|
213
295
|
it "should handle a single cookie using mixed" do
|
@@ -218,23 +300,23 @@ describe HTTP::Parser do
|
|
218
300
|
"Set-Cookie: PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com\r\n" +
|
219
301
|
"\r\n"
|
220
302
|
|
221
|
-
@parser.headers["Set-Cookie"].
|
303
|
+
expect(@parser.headers["Set-Cookie"]).to eq("PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com")
|
222
304
|
end
|
223
305
|
|
224
306
|
it "should support alternative api" do
|
225
307
|
callbacks = double('callbacks')
|
226
|
-
callbacks.
|
227
|
-
callbacks.
|
228
|
-
callbacks.
|
229
|
-
callbacks.
|
308
|
+
allow(callbacks).to receive(:on_message_begin){ @started = true }
|
309
|
+
allow(callbacks).to receive(:on_headers_complete){ |e| @headers = e }
|
310
|
+
allow(callbacks).to receive(:on_body){ |chunk| @body << chunk }
|
311
|
+
allow(callbacks).to receive(:on_message_complete){ @done = true }
|
230
312
|
|
231
313
|
@parser = HTTP::Parser.new(callbacks)
|
232
314
|
@parser << "GET / HTTP/1.0\r\n\r\n"
|
233
315
|
|
234
|
-
@started.
|
235
|
-
@headers.
|
236
|
-
@body.
|
237
|
-
@done.
|
316
|
+
expect(@started).to be true
|
317
|
+
expect(@headers).to eq({})
|
318
|
+
expect(@body).to eq('')
|
319
|
+
expect(@done).to be true
|
238
320
|
end
|
239
321
|
|
240
322
|
it "should ignore extra content beyond specified length" do
|
@@ -245,8 +327,8 @@ describe HTTP::Parser do
|
|
245
327
|
"hello" +
|
246
328
|
" \n"
|
247
329
|
|
248
|
-
@body.
|
249
|
-
@done.
|
330
|
+
expect(@body).to eq('hello')
|
331
|
+
expect(@done).to be true
|
250
332
|
end
|
251
333
|
|
252
334
|
it 'sets upgrade_data if available' do
|
@@ -256,8 +338,8 @@ describe HTTP::Parser do
|
|
256
338
|
"Upgrade: WebSocket\r\n\r\n" +
|
257
339
|
"third key data"
|
258
340
|
|
259
|
-
@parser.upgrade
|
260
|
-
@parser.upgrade_data.
|
341
|
+
expect(@parser.upgrade?).to be true
|
342
|
+
expect(@parser.upgrade_data).to eq('third key data')
|
261
343
|
end
|
262
344
|
|
263
345
|
it 'sets upgrade_data to blank if un-available' do
|
@@ -266,8 +348,8 @@ describe HTTP::Parser do
|
|
266
348
|
"Connection: Upgrade\r\n" +
|
267
349
|
"Upgrade: WebSocket\r\n\r\n"
|
268
350
|
|
269
|
-
@parser.upgrade
|
270
|
-
@parser.upgrade_data.
|
351
|
+
expect(@parser.upgrade?).to be true
|
352
|
+
expect(@parser.upgrade_data).to eq('')
|
271
353
|
end
|
272
354
|
|
273
355
|
it 'should stop parsing headers when instructed' do
|
@@ -281,13 +363,13 @@ describe HTTP::Parser do
|
|
281
363
|
|
282
364
|
@parser.on_headers_complete = proc { |e| :stop }
|
283
365
|
offset = (@parser << request)
|
284
|
-
@parser.upgrade
|
285
|
-
@parser.upgrade_data.
|
286
|
-
offset.
|
366
|
+
expect(@parser.upgrade?).to be true
|
367
|
+
expect(@parser.upgrade_data).to eq('')
|
368
|
+
expect(offset).to eq(request.length)
|
287
369
|
end
|
288
370
|
|
289
371
|
it "should execute on_body on requests with no content-length" do
|
290
|
-
@parser.reset
|
372
|
+
expect(@parser.reset!).to be true
|
291
373
|
|
292
374
|
@head, @complete, @body = 0, 0, 0
|
293
375
|
@parser.on_headers_complete = proc {|h| @head += 1 }
|
@@ -298,52 +380,48 @@ describe HTTP::Parser do
|
|
298
380
|
|
299
381
|
@parser << head_response
|
300
382
|
@parser << ''
|
301
|
-
@head.
|
302
|
-
@complete.
|
303
|
-
@body.
|
383
|
+
expect(@head).to eq(1)
|
384
|
+
expect(@complete).to eq(1)
|
385
|
+
expect(@body).to eq(1)
|
304
386
|
end
|
305
387
|
|
306
388
|
|
307
389
|
%w[ request response ].each do |type|
|
308
390
|
JSON.parse(File.read(File.expand_path("../support/#{type}s.json", __FILE__))).each do |test|
|
309
391
|
test['headers'] ||= {}
|
310
|
-
next
|
392
|
+
next if !defined?(JRUBY_VERSION) and HTTP::Parser.strict? != test['strict']
|
311
393
|
|
312
394
|
it "should parse #{type}: #{test['name']}" do
|
313
395
|
@parser << test['raw']
|
314
396
|
|
315
|
-
@parser.http_method.
|
316
|
-
@parser.keep_alive
|
397
|
+
expect(@parser.http_method).to eq(test['method'])
|
398
|
+
expect(@parser.keep_alive?).to eq(test['should_keep_alive'])
|
317
399
|
|
318
400
|
if test.has_key?('upgrade') and test['upgrade'] != 0
|
319
|
-
@parser.upgrade
|
320
|
-
@parser.upgrade_data.
|
401
|
+
expect(@parser.upgrade?).to be true
|
402
|
+
expect(@parser.upgrade_data).to eq(test['upgrade'])
|
321
403
|
end
|
322
404
|
|
323
|
-
|
324
|
-
|
325
|
-
http_minor
|
326
|
-
]
|
405
|
+
expect(@parser.send("http_major")).to eq(test["http_major"])
|
406
|
+
expect(@parser.send("http_minor")).to eq(test["http_minor"])
|
327
407
|
|
328
408
|
if test['type'] == 'HTTP_REQUEST'
|
329
|
-
|
330
|
-
request_url
|
331
|
-
|
409
|
+
if defined?(JRUBY_VERSION)
|
410
|
+
expect(@parser.send("request_url")).to eq(test["request_url"])
|
411
|
+
else
|
412
|
+
# It's created by rb_str_new(), so that encoding is Encoding::ASCII_8BIT a.k.a Encoding::BINARY
|
413
|
+
expect(@parser.send("request_url")).to eq(test["request_url"].force_encoding(Encoding::ASCII_8BIT))
|
414
|
+
end
|
332
415
|
else
|
333
|
-
|
334
|
-
|
335
|
-
]
|
336
|
-
end
|
337
|
-
|
338
|
-
fields.each do |field|
|
339
|
-
@parser.send(field).should == test[field]
|
416
|
+
expect(@parser.send("status_code")).to eq(test["status_code"])
|
417
|
+
expect(@parser.send("status")).to eq(test["status"].force_encoding(Encoding::ASCII_8BIT)) if !defined?(JRUBY_VERSION)
|
340
418
|
end
|
341
419
|
|
342
|
-
@headers.size.
|
343
|
-
@headers.
|
420
|
+
expect(@headers.size).to eq(test['num_headers'])
|
421
|
+
expect(@headers).to eq(test['headers'])
|
344
422
|
|
345
|
-
@body.
|
346
|
-
@body.size.
|
423
|
+
expect(@body).to eq(test['body'])
|
424
|
+
expect(@body.size).to eq(test['body_size']) if test['body_size']
|
347
425
|
end
|
348
426
|
end
|
349
427
|
end
|