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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/linux.yml +23 -0
  3. data/.github/workflows/windows.yml +23 -0
  4. data/.gitignore +5 -4
  5. data/.gitmodules +2 -2
  6. data/README.md +2 -2
  7. data/Rakefile +4 -2
  8. data/ext/ruby_http_parser/extconf.rb +1 -1
  9. data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +86 -52
  10. data/ext/ruby_http_parser/ruby_http_parser.c +53 -7
  11. data/ext/ruby_http_parser/vendor/http-parser/AUTHORS +37 -1
  12. data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +1 -5
  13. data/ext/ruby_http_parser/vendor/http-parser/Makefile +110 -8
  14. data/ext/ruby_http_parser/vendor/http-parser/README.md +105 -37
  15. data/ext/ruby_http_parser/vendor/http-parser/bench.c +128 -0
  16. data/ext/ruby_http_parser/vendor/http-parser/contrib/parsertrace.c +157 -0
  17. data/ext/ruby_http_parser/vendor/http-parser/contrib/url_parser.c +47 -0
  18. data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +892 -510
  19. data/ext/ruby_http_parser/vendor/http-parser/http_parser.gyp +34 -2
  20. data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +198 -77
  21. data/ext/ruby_http_parser/vendor/http-parser/test.c +1781 -201
  22. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +271 -154
  23. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +48 -61
  24. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +5 -3
  25. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java +37 -104
  26. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +116 -101
  27. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +9 -5
  28. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java +1 -1
  29. data/ext/ruby_http_parser/vendor/http-parser-java/test.c +579 -153
  30. data/http_parser.rb.gemspec +14 -9
  31. data/spec/parser_spec.rb +177 -99
  32. data/spec/support/requests.json +2 -2
  33. data/spec/support/responses.json +20 -0
  34. data/tasks/spec.rake +1 -1
  35. metadata +131 -162
  36. data/Gemfile.lock +0 -39
  37. data/ext/ruby_http_parser/vendor/http-parser/CONTRIBUTIONS +0 -4
  38. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPHeadersCompleteCallback.java +0 -13
  39. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPHeadersCompleteCallback.java +0 -12
@@ -1,27 +1,32 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "http_parser.rb"
3
- s.version = "0.6.0.beta.1"
3
+ s.version = "0.8.0"
4
4
  s.summary = "Simple callback-based HTTP request/response parser"
5
- s.description = "Ruby bindings to http://github.com/ry/http-parser and http://github.com/a2800276/http-parser.java"
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 = "http://github.com/tmm1/http_parser.rb"
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', '>= 0.7.9'
17
- s.add_development_dependency 'rspec', '>= 2.0.1'
18
- s.add_development_dependency 'json', '>= 1.4.6'
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
- s.add_development_dependency 'yajl-ruby', '>= 0.8.1'
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.should be_nil
23
+ expect(@parser.headers).to be_nil
21
24
 
22
- @parser.http_version.should be_nil
23
- @parser.http_method.should be_nil
24
- @parser.status_code.should be_nil
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.should be_nil
29
+ expect(@parser.request_url).to be_nil
27
30
 
28
- @parser.header_value_type.should == :mixed
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.should == 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.should == 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.should == 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
- proc{ @parser.header_value_type = 'bob' }.should raise_error(ArgumentError)
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
- proc{ HTTP::Parser.default_header_value_type = 'bob' }.should raise_error(ArgumentError)
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.should be_true
69
- @done.should be_true
93
+ expect(@started).to be true
94
+ expect(@done).to be true
70
95
 
71
- @parser.http_major.should == 1
72
- @parser.http_minor.should == 1
73
- @parser.http_version.should == [1,1]
74
- @parser.http_method.should == 'GET'
75
- @parser.status_code.should be_nil
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.should == '/test?ok=1'
102
+ expect(@parser.request_url).to eq('/test?ok=1')
78
103
 
79
- @parser.headers.should == @headers
80
- @parser.headers['User-Agent'].should == 'curl/7.18.0'
81
- @parser.headers['Host'].should == '0.0.0.0:5000'
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.should == "World"
108
+ expect(@body).to eq("World")
84
109
  end
85
110
 
86
111
  it "should raise errors on invalid data" do
87
- proc{ @parser << "BLAH" }.should raise_error(HTTP::Parser::Error)
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.should == 37
102
- data[bytes..-1].should == 'World'
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.should == {'Content-Length' => '5'}
105
- @body.should be_empty
106
- @done.should be_false
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.should == 'GET'
113
- @parser.http_version.should == [1,0]
194
+ expect(@parser.http_method).to eq('GET')
195
+ expect(@parser.http_version).to eq([1,0])
114
196
 
115
- @parser.request_url.should == '/'
197
+ expect(@parser.request_url).to eq('/')
116
198
 
117
- @parser.reset!.should be_true
199
+ expect(@parser.reset!).to be true
118
200
 
119
- @parser.http_version.should be_nil
120
- @parser.http_method.should be_nil
121
- @parser.status_code.should be_nil
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.should be_nil
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!.should be_true
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.should == 1
138
- @complete.should == 1
219
+ expect(@head).to eq(1)
220
+ expect(@complete).to eq(1)
139
221
 
140
222
  @parser << head_response
141
- @head.should == 2
142
- @complete.should == 2
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!.should be_true
228
+ expect(@parser.reset!).to be true
147
229
 
148
230
  @parser << "GET / HTTP/1.0\r\n\r\n"
149
- @started.should be_true
150
- @headers.should == {}
151
- @done.should be_true
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.should == {
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"].should == "PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com, NID=46jSHxPM; path=/; domain=.bob.com; HttpOnly"
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"].should == [
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"].should == [
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"].should == "PREF=ID=a7d2c98; expires=Fri, 05-Apr-2013 05:00:45 GMT; path=/; domain=.bob.com"
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.stub(:on_message_begin){ @started = true }
227
- callbacks.stub(:on_headers_complete){ |e| @headers = e }
228
- callbacks.stub(:on_body){ |chunk| @body << chunk }
229
- callbacks.stub(:on_message_complete){ @done = true }
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.should be_true
235
- @headers.should == {}
236
- @body.should == ''
237
- @done.should be_true
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.should == 'hello'
249
- @done.should be_true
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?.should be_true
260
- @parser.upgrade_data.should == 'third key 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?.should be_true
270
- @parser.upgrade_data.should == ''
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?.should be_true
285
- @parser.upgrade_data.should == ''
286
- offset.should == request.length
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!.should be_true
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.should == 1
302
- @complete.should == 1
303
- @body.should == 1
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 unless HTTP::Parser.strict? == test['strict']
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.should == test['method']
316
- @parser.keep_alive?.should == test['should_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?.should be_true
320
- @parser.upgrade_data.should == test['upgrade']
401
+ expect(@parser.upgrade?).to be true
402
+ expect(@parser.upgrade_data).to eq(test['upgrade'])
321
403
  end
322
404
 
323
- fields = %w[
324
- http_major
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
- fields += %w[
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
- fields += %w[
334
- status_code
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.should == test['num_headers']
343
- @headers.should == test['headers']
420
+ expect(@headers.size).to eq(test['num_headers'])
421
+ expect(@headers).to eq(test['headers'])
344
422
 
345
- @body.should == test['body']
346
- @body.size.should == test['body_size'] if test['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