mechanize 2.14.1 → 2.14.2

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/lib/mechanize/directory_saver.rb +2 -1
  4. data/lib/mechanize/file_saver.rb +2 -0
  5. data/lib/mechanize/parser.rb +33 -3
  6. data/lib/mechanize/test_case.rb +2 -9
  7. data/lib/mechanize/version.rb +1 -1
  8. metadata +3 -172
  9. data/.autotest +0 -6
  10. data/.github/dependabot.yml +0 -11
  11. data/.github/workflows/ci.yml +0 -43
  12. data/.github/workflows/upstream.yml +0 -51
  13. data/.gitignore +0 -15
  14. data/.yardopts +0 -8
  15. data/Gemfile +0 -12
  16. data/Rakefile +0 -56
  17. data/examples/flickr_upload.rb +0 -22
  18. data/examples/latest_user_agents.rb +0 -100
  19. data/examples/mech-dump.rb +0 -5
  20. data/examples/proxy_req.rb +0 -7
  21. data/examples/rubygems.rb +0 -23
  22. data/examples/spider.rb +0 -22
  23. data/examples/wikipedia_links_to_philosophy.rb +0 -158
  24. data/mechanize.gemspec +0 -74
  25. data/test/data/htpasswd +0 -1
  26. data/test/data/server.crt +0 -16
  27. data/test/data/server.csr +0 -12
  28. data/test/data/server.key +0 -15
  29. data/test/data/server.pem +0 -15
  30. data/test/test_mechanize.rb +0 -1382
  31. data/test/test_mechanize_cookie.rb +0 -559
  32. data/test/test_mechanize_cookie_jar.rb +0 -615
  33. data/test/test_mechanize_directory_saver.rb +0 -60
  34. data/test/test_mechanize_download.rb +0 -102
  35. data/test/test_mechanize_element_not_found_error.rb +0 -16
  36. data/test/test_mechanize_file.rb +0 -118
  37. data/test/test_mechanize_file_connection.rb +0 -40
  38. data/test/test_mechanize_file_request.rb +0 -26
  39. data/test/test_mechanize_file_response.rb +0 -48
  40. data/test/test_mechanize_file_saver.rb +0 -22
  41. data/test/test_mechanize_form.rb +0 -1025
  42. data/test/test_mechanize_form_check_box.rb +0 -49
  43. data/test/test_mechanize_form_encoding.rb +0 -110
  44. data/test/test_mechanize_form_field.rb +0 -78
  45. data/test/test_mechanize_form_file_upload.rb +0 -21
  46. data/test/test_mechanize_form_image_button.rb +0 -13
  47. data/test/test_mechanize_form_keygen.rb +0 -34
  48. data/test/test_mechanize_form_multi_select_list.rb +0 -98
  49. data/test/test_mechanize_form_option.rb +0 -60
  50. data/test/test_mechanize_form_radio_button.rb +0 -96
  51. data/test/test_mechanize_form_select_list.rb +0 -81
  52. data/test/test_mechanize_form_textarea.rb +0 -53
  53. data/test/test_mechanize_headers.rb +0 -36
  54. data/test/test_mechanize_history.rb +0 -104
  55. data/test/test_mechanize_http_agent.rb +0 -2145
  56. data/test/test_mechanize_http_auth_challenge.rb +0 -64
  57. data/test/test_mechanize_http_auth_realm.rb +0 -56
  58. data/test/test_mechanize_http_auth_store.rb +0 -233
  59. data/test/test_mechanize_http_content_disposition_parser.rb +0 -167
  60. data/test/test_mechanize_http_www_authenticate_parser.rb +0 -204
  61. data/test/test_mechanize_image.rb +0 -9
  62. data/test/test_mechanize_link.rb +0 -171
  63. data/test/test_mechanize_page.rb +0 -295
  64. data/test/test_mechanize_page_encoding.rb +0 -215
  65. data/test/test_mechanize_page_frame.rb +0 -17
  66. data/test/test_mechanize_page_image.rb +0 -191
  67. data/test/test_mechanize_page_link.rb +0 -377
  68. data/test/test_mechanize_page_meta_refresh.rb +0 -151
  69. data/test/test_mechanize_parser.rb +0 -316
  70. data/test/test_mechanize_pluggable_parser.rb +0 -68
  71. data/test/test_mechanize_redirect_limit_reached_error.rb +0 -25
  72. data/test/test_mechanize_redirect_not_get_or_head_error.rb +0 -15
  73. data/test/test_mechanize_response_read_error.rb +0 -29
  74. data/test/test_mechanize_subclass.rb +0 -23
  75. data/test/test_mechanize_util.rb +0 -144
  76. data/test/test_mechanize_xml_file.rb +0 -30
  77. data/test/test_multi_select.rb +0 -120
@@ -1,2145 +0,0 @@
1
- # coding: utf-8
2
- # frozen_string_literal: true
3
-
4
- require 'mechanize/test_case'
5
- unless RUBY_PLATFORM == 'java'
6
- require 'brotli'
7
- require 'zstd-ruby'
8
- end
9
-
10
- class TestMechanizeHttpAgent < Mechanize::TestCase
11
-
12
- def setup
13
- super
14
-
15
- @agent = @mech.agent
16
-
17
- @uri = URI.parse 'http://example/'
18
-
19
- @req = Net::HTTP::Get.new '/'
20
- @res = Net::HTTPOK.allocate
21
- @res.instance_variable_set :@code, 200
22
- @res.instance_variable_set :@header, {}
23
-
24
- @headers = %w[accept accept-encoding user-agent]
25
- end
26
-
27
- def auth_realm uri, scheme, type
28
- base_uri = uri + '/'
29
- realm = Mechanize::HTTP::AuthRealm.new scheme, base_uri, 'r'
30
- @agent.authenticate_methods[base_uri][type] << realm
31
-
32
- realm
33
- end
34
-
35
- def skip_if_jruby_zlib
36
- if RUBY_ENGINE == 'jruby'
37
- meth = caller_locations(1,1).first.base_label
38
- skip "#{meth}: skipped because how Zlib handles error is different in JRuby"
39
- end
40
- end
41
-
42
- def test_agent_is_named
43
- assert_equal 'mechanize', Mechanize::HTTP::Agent.new.http.name
44
- assert_equal 'unique', Mechanize::HTTP::Agent.new('unique').http.name
45
- end
46
-
47
- def test_auto_io
48
- Tempfile.open 'input' do |input_io|
49
- input_io.binmode
50
- input_io.write '12345'
51
- input_io.rewind
52
-
53
- out_io = @agent.auto_io @NAME, 1024, input_io
54
-
55
- assert_equal '12345', out_io.string
56
-
57
- assert_equal Encoding::BINARY, out_io.string.encoding if
58
- Object.const_defined? :Encoding
59
- end
60
- end
61
-
62
- def test_auto_io_chunk
63
- Tempfile.open 'input' do |input_io|
64
- chunks = []
65
-
66
- input_io.binmode
67
- input_io.write '12345'
68
- input_io.rewind
69
-
70
- @agent.auto_io @NAME, 1, input_io do |chunk|
71
- chunks << chunk
72
- end
73
-
74
- assert_equal %w[1 2 3 4 5], chunks
75
- end
76
- end
77
-
78
- def test_auto_io_tempfile
79
- @agent.max_file_buffer = 3
80
-
81
- Tempfile.open 'input' do |input_io|
82
- input_io.binmode
83
- input_io.write '12345'
84
- input_io.rewind
85
-
86
- out_io = @agent.auto_io @NAME, 1, input_io
87
-
88
- result = out_io.read
89
- assert_equal '12345', result
90
-
91
- assert_equal Encoding::BINARY, result.encoding if
92
- Object.const_defined? :Encoding
93
- end
94
- end
95
-
96
- def test_auto_io_yield
97
- Tempfile.open 'input' do |input_io|
98
- input_io.binmode
99
- input_io.write '12345'
100
- input_io.rewind
101
-
102
- out_io = @agent.auto_io @NAME, 1024, input_io do |chunk|
103
- "x#{chunk}"
104
- end
105
-
106
- assert_equal 'x12345', out_io.string
107
- end
108
- end
109
-
110
- def test_certificate_equals
111
- cert_path = File.expand_path '../data/server.crt', __FILE__
112
- cert = OpenSSL::X509::Certificate.new File.read cert_path
113
-
114
- @agent.certificate = cert
115
-
116
- assert_equal cert.to_pem, @agent.certificate.to_pem
117
- end
118
-
119
- def test_certificate_equals_file
120
- cert_path = File.expand_path '../data/server.crt', __FILE__
121
-
122
- cert = OpenSSL::X509::Certificate.new File.read cert_path
123
-
124
- @agent.certificate = cert_path
125
-
126
- assert_equal cert.to_pem, @agent.certificate.to_pem
127
- end
128
-
129
- def test_connection_for_file
130
- uri = URI.parse 'file:///nonexistent'
131
- conn = @agent.connection_for uri
132
-
133
- assert_equal Mechanize::FileConnection.new, conn
134
- end
135
-
136
- def test_connection_for_http
137
- conn = @agent.connection_for @uri
138
-
139
- assert_equal @agent.http, conn
140
- end
141
-
142
- def test_disable_keep_alive
143
- @agent.disable_keep_alive @req
144
-
145
- refute @req['connection']
146
- end
147
-
148
- def test_disable_keep_alive_no
149
- @agent.keep_alive = false
150
-
151
- @agent.disable_keep_alive @req
152
-
153
- assert_equal 'close', @req['connection']
154
- end
155
-
156
- def test_enable_gzip
157
- @agent.enable_gzip @req
158
-
159
- assert_equal 'gzip,deflate,identity', @req['accept-encoding']
160
- end
161
-
162
- def test_enable_gzip_no
163
- @agent.gzip_enabled = false
164
-
165
- @agent.enable_gzip @req
166
-
167
- assert_equal 'identity', @req['accept-encoding']
168
- end
169
-
170
- def test_fetch_file_nonexistent
171
- in_tmpdir do
172
- nonexistent = File.join Dir.pwd, 'nonexistent'
173
-
174
- uri = URI.parse "file:///#{nonexistent}"
175
-
176
- e = assert_raises Mechanize::ResponseCodeError do
177
- @agent.fetch uri
178
- end
179
-
180
- assert_match "404 => Net::HTTPNotFound for #{uri}", e.message
181
- end
182
- end
183
-
184
- def test_fetch_file_plus
185
- Tempfile.open '++plus++' do |io|
186
- content = 'plusses +++'
187
- io.write content
188
- io.rewind
189
-
190
- uri = URI.parse "file://#{Mechanize::Util.uri_escape io.path}"
191
-
192
- page = @agent.fetch uri
193
-
194
- assert_equal content, page.body
195
- assert_kind_of Mechanize::File, page
196
- end
197
- end
198
-
199
- def test_fetch_file_space
200
- foo = File.expand_path("../htdocs/dir with spaces/foo.html", __FILE__)
201
-
202
- uri = URI.parse "file://#{Mechanize::Util.uri_escape foo}"
203
-
204
- page = @agent.fetch uri
205
-
206
- assert_equal File.read(foo), page.body.gsub(/\r\n/, "\n")
207
- assert_kind_of Mechanize::Page, page
208
- end
209
-
210
- def test_fetch_head_gzip
211
- uri = @uri + '/gzip?file=index.html'
212
-
213
- page = @agent.fetch uri, :head
214
-
215
- assert_kind_of Mechanize::Page, page
216
- end
217
-
218
- def test_fetch_hooks
219
- @agent.pre_connect_hooks << proc do |agent, request|
220
- assert_equal '/index.html', request.path
221
- assert_equal @agent, agent
222
- end
223
-
224
- @agent.post_connect_hooks << proc do |agent, uri, response, body|
225
- assert_equal @agent, agent
226
- assert_equal URI('http://example/index.html'), uri
227
- assert_equal '200', response.code
228
- assert_kind_of String, body
229
- end
230
-
231
- @agent.fetch URI 'http://example/index.html'
232
- end
233
-
234
- def test_fetch_ignore_bad_chunking
235
- @agent.ignore_bad_chunking = true
236
-
237
- file = @agent.fetch 'http://example/bad_chunking'
238
-
239
- assert_equal '0123456789', file.content
240
- end
241
-
242
- def test_fetch_post_connect_hook
243
- response = nil
244
- @agent.post_connect_hooks << lambda { |_, _, res, _| response = res }
245
-
246
- @agent.fetch 'http://localhost/'
247
-
248
- assert response
249
- end
250
-
251
- def test_fetch_redirect_header
252
- page = @agent.fetch('http://example/redirect', :get,
253
- 'X-Location' => '/http_headers',
254
- 'Range' => 'bytes=0-99999')
255
-
256
- assert_match 'range|bytes=0-999', page.body
257
- end
258
-
259
- def test_fetch_server_error
260
- e = assert_raises Mechanize::ResponseCodeError do
261
- @mech.get 'http://localhost/response_code?code=500'
262
- end
263
-
264
- assert_equal '500', e.response_code
265
- end
266
-
267
- def test_fetch_allowed_error_codes
268
- @agent.allowed_error_codes = ['500']
269
-
270
- page = @mech.get 'http://localhost/response_code?code=500'
271
-
272
- assert_equal '500', page.code
273
- end
274
-
275
- def test_fetch_allowed_error_codes_int
276
- @agent.allowed_error_codes = [500]
277
-
278
- page = @mech.get 'http://localhost/response_code?code=500'
279
-
280
- assert_equal '500', page.code
281
- end
282
-
283
- def test_get_meta_refresh_header_follow_self
284
- @agent.follow_meta_refresh = true
285
- @agent.follow_meta_refresh_self = true
286
-
287
- page = Mechanize::Page.new(@uri, nil, '', 200, @mech)
288
- @res.instance_variable_set :@header, 'refresh' => ['0']
289
-
290
- refresh = @agent.get_meta_refresh @res, @uri, page
291
-
292
- assert_equal [0.0, URI('http://example/')], refresh
293
- end
294
-
295
- def test_get_meta_refresh_header_no_follow
296
- page = Mechanize::Page.new(@uri, nil, '', 200, @mech)
297
- @res.instance_variable_set :@header, 'refresh' => ['0']
298
-
299
- refresh = @agent.get_meta_refresh @res, @uri, page
300
-
301
- assert_nil refresh
302
- end
303
-
304
- def test_get_meta_refresh_header_no_follow_self
305
- @agent.follow_meta_refresh = true
306
-
307
- page = Mechanize::Page.new(@uri, nil, '', 200, @mech)
308
- @res.instance_variable_set :@header, 'refresh' => ['0']
309
-
310
- refresh = @agent.get_meta_refresh @res, @uri, page
311
-
312
- assert_nil refresh
313
- end
314
-
315
- def test_get_meta_refresh_meta_follow_self
316
- @agent.follow_meta_refresh = true
317
- @agent.follow_meta_refresh_self = true
318
-
319
- body = <<-BODY
320
- <title></title>
321
- <meta http-equiv="refresh" content="0">
322
- BODY
323
-
324
- page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
325
-
326
- refresh = @agent.get_meta_refresh @res, @uri, page
327
-
328
- assert_equal [0, nil], refresh
329
- end
330
-
331
- def test_get_meta_refresh_meta_no_follow
332
- body = <<-BODY
333
- <title></title>
334
- <meta http-equiv="refresh" content="0">
335
- BODY
336
-
337
- page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
338
-
339
- refresh = @agent.get_meta_refresh @res, @uri, page
340
-
341
- assert_nil refresh
342
- end
343
-
344
- def test_get_meta_refresh_meta_no_follow_self
345
- @agent.follow_meta_refresh = true
346
-
347
- body = <<-BODY
348
- <title></title>
349
- <meta http-equiv="refresh" content="0">
350
- BODY
351
-
352
- page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
353
-
354
- refresh = @agent.get_meta_refresh @res, @uri, page
355
-
356
- assert_nil refresh
357
- end
358
-
359
- def test_get_robots
360
- robotstxt = @agent.get_robots 'http://localhost/robots.txt'
361
- refute_equal '', robotstxt
362
-
363
- robotstxt = @agent.get_robots 'http://localhost/response_code?code=404'
364
- assert_equal '', robotstxt
365
- end
366
-
367
- def test_hook_content_encoding_response
368
- @mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io|
369
- response['content-encoding'] = 'gzip' if response['content-encoding'] == 'agzip'}
370
-
371
- @res.instance_variable_set :@header, 'content-encoding' => %w[agzip]
372
- body_io = StringIO.new 'part'
373
- @agent.hook_content_encoding @res, @uri, body_io
374
-
375
- assert_equal 'gzip', @res['content-encoding']
376
- end
377
-
378
- def test_http_request_file
379
- uri = URI.parse 'file:///nonexistent'
380
- request = @agent.http_request uri, :get
381
-
382
- assert_kind_of Mechanize::FileRequest, request
383
- assert_equal '/nonexistent', request.path
384
- end
385
-
386
- def test_http_request_get
387
- request = @agent.http_request @uri, :get
388
-
389
- assert_kind_of Net::HTTP::Get, request
390
- assert_equal '/', request.path
391
- end
392
-
393
- def test_http_request_post
394
- request = @agent.http_request @uri, :post
395
-
396
- assert_kind_of Net::HTTP::Post, request
397
- assert_equal '/', request.path
398
- end
399
-
400
- def test_idle_timeout_equals
401
- @agent.idle_timeout = 1
402
-
403
- assert_equal 1, @agent.http.idle_timeout
404
- end
405
-
406
- def test_inflate
407
- body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
408
-
409
- result = @agent.inflate body_io
410
-
411
- assert_equal 'part', result.read
412
- end
413
-
414
- def test_post_connect
415
- @agent.post_connect_hooks << proc { |agent, uri, response, body|
416
- assert_equal @agent, agent
417
- assert_equal @res, response
418
- assert_equal 'body', body
419
- throw :called
420
- }
421
-
422
- io = StringIO.new 'body'
423
-
424
- assert_throws :called do
425
- @agent.post_connect @uri, @res, io
426
- end
427
-
428
- assert_equal 0, io.pos
429
- end
430
-
431
- def test_pre_connect
432
- @agent.pre_connect_hooks << proc { |agent, request|
433
- assert_equal @agent, agent
434
- assert_equal @req, request
435
- throw :called
436
- }
437
-
438
- assert_throws :called do
439
- @agent.pre_connect @req
440
- end
441
- end
442
-
443
- def test_request_add_headers
444
- @agent.request_add_headers @req, 'Content-Length' => 300
445
-
446
- assert_equal '300', @req['content-length']
447
- end
448
-
449
- def test_request_add_headers_etag
450
- @agent.request_add_headers @req, :etag => '300'
451
-
452
- assert_equal '300', @req['etag']
453
- end
454
-
455
- def test_request_add_headers_if_modified_since
456
- @agent.request_add_headers @req, :if_modified_since => 'some_date'
457
-
458
- assert_equal 'some_date', @req['if-modified-since']
459
- end
460
-
461
- def test_request_add_headers_none
462
- @agent.request_add_headers @req
463
-
464
- assert_equal @headers, @req.to_hash.keys.sort
465
- end
466
-
467
- def test_fetch_accepts_symbol_names_in_request_headers
468
- @agent.request_headers = { Authorization: 'Bearer tokensecret' }
469
-
470
- page = @agent.fetch 'http://example/http_headers'
471
-
472
- assert_match 'authorization|Bearer tokensecret', page.body
473
- end
474
-
475
- def test_fetch_lets_a_request_header_override_any_spelling_of_an_agent_header
476
- @agent.request_headers = { 'Authorization' => 'agent-one', 'authorization' => 'agent-two' }
477
-
478
- page = @agent.fetch 'http://example/http_headers', :get,
479
- { 'Authorization' => 'per-request' }
480
-
481
- assert_match 'authorization|per-request', page.body
482
- end
483
-
484
- def test_meta_refresh_drops_entity_headers
485
- @agent.follow_meta_refresh = true
486
-
487
- uri = URI 'http://example/session'
488
- response = Net::HTTPOK.new '1.1', '200', 'OK'
489
- response['Refresh'] = '0;url=/http_headers'
490
- page = Mechanize::Page.new uri, response, '', 200, @mech
491
-
492
- @agent.response_follow_meta_refresh(response, uri, page, 0,
493
- { 'Content-Length' => '7',
494
- 'Content-Type' => 'text/plain',
495
- 'Content-MD5' => 'deadbeef' })
496
-
497
- request = requests.last
498
-
499
- assert_equal 'GET', request.method
500
- assert_nil request['Content-Length']
501
- assert_nil request['Content-Type']
502
- assert_nil request['Content-MD5']
503
- end
504
-
505
- def test_fetch_applies_request_headers
506
- @agent.request_headers['X-Foo'] = 'bar'
507
-
508
- page = @agent.fetch 'http://example/http_headers'
509
-
510
- assert_match 'x-foo|bar', page.body
511
- end
512
-
513
- def test_request_add_headers_symbol
514
- e = assert_raises ArgumentError do
515
- @agent.request_add_headers @req, :content_length => 300
516
- end
517
-
518
- assert_equal 'unknown header symbol content_length', e.message
519
- end
520
-
521
- def test_request_auth_basic
522
- @agent.add_auth @uri, 'user', 'password'
523
-
524
- auth_realm @uri, 'Basic', :basic
525
-
526
- @agent.request_auth @req, @uri
527
-
528
- assert_match %r%^Basic %, @req['Authorization']
529
- end
530
-
531
- def test_request_auth_digest
532
- @agent.add_auth @uri, 'user', 'password'
533
-
534
- realm = auth_realm @uri, 'Digest', :digest
535
- @agent.digest_challenges[realm] = 'Digest realm=r, qop="auth"'
536
-
537
- @agent.request_auth @req, @uri
538
-
539
- assert_match %r%^Digest %, @req['Authorization']
540
- assert_match %r%qop=auth%, @req['Authorization']
541
-
542
- @req['Authorization'] = nil
543
- @agent.request_auth @req, @uri
544
-
545
- assert_match %r%^Digest %, @req['Authorization']
546
- assert_match %r%qop=auth%, @req['Authorization']
547
- end
548
-
549
- def test_request_auth_iis_digest
550
- @agent.add_auth @uri, 'user', 'password'
551
-
552
- realm = auth_realm @uri, 'Digest', :digest
553
- @agent.digest_challenges[realm] = 'Digest realm=r, qop="auth"'
554
-
555
- @agent.request_auth @req, @uri
556
-
557
- assert_match %r%^Digest %, @req['Authorization']
558
- assert_match %r%qop=auth%, @req['Authorization']
559
- end
560
-
561
- def test_request_auth_none
562
- @agent.request_auth @req, @uri
563
-
564
- assert_nil @req['Authorization']
565
- end
566
-
567
- def test_request_cookies
568
- uri = URI.parse 'http://host.example.com'
569
- @agent.cookie_jar.parse 'hello=world domain=.example.com', uri
570
-
571
- @agent.request_cookies @req, uri
572
-
573
- assert_equal 'hello="world domain=.example.com"', @req['Cookie']
574
- end
575
-
576
- def test_request_cookies_many
577
- uri = URI.parse 'http://host.example.com'
578
- cookie_str = 'a=b domain=.example.com, c=d domain=.example.com'
579
- @agent.cookie_jar.parse cookie_str, uri
580
-
581
- @agent.request_cookies @req, uri
582
-
583
- expected_variant1 = /a="b domain=\.example\.com"; c="d domain=\.example\.com"/
584
- expected_variant2 = /c="d domain=\.example\.com"; a="b domain=\.example\.com"/
585
-
586
- assert_match(/^(#{expected_variant1}|#{expected_variant2})$/, @req['Cookie'])
587
- end
588
-
589
- def test_request_cookies_none
590
- @agent.request_cookies @req, @uri
591
-
592
- assert_nil @req['Cookie']
593
- end
594
-
595
- def test_request_cookies_wrong_domain
596
- uri = URI.parse 'http://host.example.com'
597
- @agent.cookie_jar.parse 'hello=world domain=.example.com', uri
598
-
599
- @agent.request_cookies @req, @uri
600
-
601
- assert_nil @req['Cookie']
602
- end
603
-
604
- def test_request_host
605
- @agent.request_host @req, @uri
606
-
607
- assert_equal 'example', @req['host']
608
- end
609
-
610
- def test_request_host_nonstandard
611
- @uri.port = 81
612
-
613
- @agent.request_host @req, @uri
614
-
615
- assert_equal 'example:81', @req['host']
616
- end
617
-
618
- def test_request_language_charset
619
- @agent.request_language_charset @req
620
-
621
- assert_equal('en-us,en;q=0.5', @req['accept-language'])
622
- assert_nil(@req['accept-charset'])
623
- end
624
-
625
- def test_request_referer
626
- referer = URI.parse 'http://old.example'
627
-
628
- @agent.request_referer @req, @uri, referer
629
-
630
- assert_equal 'http://old.example', @req['referer']
631
- end
632
-
633
- def test_request_referer_https
634
- uri = URI.parse 'https://example'
635
- referer = URI.parse 'https://old.example'
636
-
637
- @agent.request_referer @req, uri, referer
638
-
639
- assert_equal 'https://old.example', @req['referer']
640
- end
641
-
642
- def test_request_referer_https_downgrade
643
- referer = URI.parse 'https://old.example'
644
-
645
- @agent.request_referer @req, @uri, referer
646
-
647
- assert_nil @req['referer']
648
- end
649
-
650
- def test_request_referer_https_downgrade_case
651
- uri = URI.parse 'http://example'
652
- referer = URI.parse 'httpS://old.example'
653
-
654
- @agent.request_referer @req, uri, referer
655
-
656
- assert_nil @req['referer']
657
- end
658
-
659
- def test_request_referer_https_upgrade
660
- uri = URI.parse 'https://example'
661
- referer = URI.parse 'http://old.example'
662
-
663
- @agent.request_referer @req, uri, referer
664
-
665
- assert_equal 'http://old.example', @req['referer']
666
- end
667
-
668
- def test_request_referer_none
669
- @agent.request_referer @req, @uri, nil
670
-
671
- assert_nil @req['referer']
672
- end
673
-
674
- def test_request_referer_strip
675
- uri = URI.parse 'http://example.com/index.html'
676
-
677
- host_path = "old.example/page.html?q=x"
678
- referer = "http://#{host_path}"
679
-
680
- [
681
- "",
682
- "@",
683
- "user1@",
684
- ":@",
685
- "user1:@",
686
- ":password1@",
687
- "user1:password1@",
688
- ].each { |userinfo|
689
- ['', '#frag'].each { |frag|
690
- url = URI.parse "http://#{userinfo}#{host_path}#{frag}"
691
-
692
- @agent.request_referer @req, uri, url
693
-
694
- assert_equal referer, @req['referer'], url
695
- }
696
- }
697
- end
698
-
699
- def test_request_user_agent
700
- @agent.request_user_agent @req
701
-
702
- assert_match %r%^Mechanize/#{Mechanize::VERSION}%, @req['user-agent']
703
-
704
- ruby_version = if RUBY_PATCHLEVEL >= 0 then
705
- "#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
706
- else
707
- "#{RUBY_VERSION}dev#{RUBY_REVISION}"
708
- end
709
-
710
- assert_match %r%Ruby/#{ruby_version}%, @req['user-agent']
711
- end
712
-
713
- def test_resolve_bad_uri
714
- e = assert_raises ArgumentError do
715
- @agent.resolve 'google'
716
- end
717
-
718
- assert_equal 'absolute URL needed (not google)', e.message
719
- end
720
-
721
- def test_resolve_uri_without_path
722
- e = assert_raises ArgumentError do
723
- @agent.resolve 'http:%5C%5Cfoo'
724
- end
725
-
726
- assert_equal 'hierarchical URL needed (not http:%5C%5Cfoo)', e.message
727
- end
728
-
729
- def test_resolve_utf8
730
- uri = 'http://example?q=ü'
731
-
732
- resolved = @agent.resolve uri
733
-
734
- assert_equal '/?q=%C3%BC', resolved.request_uri
735
- end
736
-
737
- def test_resolve_parameters_body
738
- input_params = { :q => 'hello' }
739
-
740
- uri, params = @agent.resolve_parameters @uri, :post, input_params
741
-
742
- assert_equal 'http://example/', uri.to_s
743
- assert_equal input_params, params
744
- end
745
-
746
- def test_resolve_parameters_query
747
- uri, params = @agent.resolve_parameters @uri, :get, :q => 'hello'
748
-
749
- assert_equal 'http://example/?q=hello', uri.to_s
750
- assert_nil params
751
- end
752
-
753
- def test_resolve_parameters_query_append
754
- input_params = { :q => 'hello' }
755
- @uri.query = 'a=b'
756
-
757
- uri, params = @agent.resolve_parameters @uri, :get, input_params
758
-
759
- assert_equal 'http://example/?a=b&q=hello', uri.to_s
760
- assert_nil params
761
- end
762
-
763
- def test_resolve_slashes
764
- page = Mechanize::Page.new URI('http://example/foo/'), nil, '', 200, @mech
765
- uri = '/bar/http://example/test/'
766
-
767
- resolved = @agent.resolve uri, page
768
-
769
- assert_equal 'http://example/bar/http://example/test/', resolved.to_s
770
- end
771
-
772
- def test_response_authenticate
773
- @agent.add_auth @uri, 'user', 'password'
774
-
775
- @res.instance_variable_set :@header, 'www-authenticate' => ['Basic realm=r']
776
-
777
- @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
778
-
779
- base_uri = @uri + '/'
780
- realm = Mechanize::HTTP::AuthRealm.new 'Basic', base_uri, 'r'
781
- assert_equal [realm], @agent.authenticate_methods[base_uri][:basic]
782
- end
783
-
784
- def test_response_authenticate_digest
785
- @agent.add_auth @uri, 'user', 'password'
786
-
787
- @res.instance_variable_set(:@header,
788
- 'www-authenticate' => ['Digest realm=r'])
789
-
790
- @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
791
-
792
- base_uri = @uri + '/'
793
- realm = Mechanize::HTTP::AuthRealm.new 'Digest', base_uri, 'r'
794
- assert_equal [realm], @agent.authenticate_methods[base_uri][:digest]
795
-
796
- challenge = Mechanize::HTTP::AuthChallenge.new('Digest',
797
- { 'realm' => 'r' },
798
- 'Digest realm=r')
799
-
800
- assert_equal challenge, @agent.digest_challenges[realm]
801
- end
802
-
803
- def test_response_authenticate_digest_iis
804
- @agent.add_auth @uri, 'user', 'password'
805
-
806
- @res.instance_variable_set(:@header,
807
- 'www-authenticate' => ['Digest realm=r'],
808
- 'server' => ['Microsoft-IIS'])
809
- @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
810
-
811
- base_uri = @uri + '/'
812
- realm = Mechanize::HTTP::AuthRealm.new 'Digest', base_uri, 'r'
813
- assert_equal [realm], @agent.authenticate_methods[base_uri][:iis_digest]
814
- end
815
-
816
- def test_response_authenticate_multiple
817
- @agent.add_auth @uri, 'user', 'password'
818
-
819
- @res.instance_variable_set(:@header,
820
- 'www-authenticate' =>
821
- ['Basic realm=r, Digest realm=r'])
822
-
823
- @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
824
-
825
- base_uri = @uri + '/'
826
- realm = Mechanize::HTTP::AuthRealm.new 'Digest', base_uri, 'r'
827
- assert_equal [realm], @agent.authenticate_methods[base_uri][:digest]
828
-
829
- assert_empty @agent.authenticate_methods[base_uri][:basic]
830
- end
831
-
832
- def test_response_authenticate_no_credentials
833
- @res.instance_variable_set :@header, 'www-authenticate' => ['Basic realm=r']
834
-
835
- e = assert_raises Mechanize::UnauthorizedError do
836
- @agent.response_authenticate @res, fake_page, @uri, @req, {}, nil, nil
837
- end
838
-
839
- assert_match 'no credentials', e.message
840
- assert_match 'available realms: r', e.message
841
- end
842
-
843
- def test_response_authenticate_no_www_authenticate
844
- @agent.add_auth @uri, 'user', 'password'
845
-
846
- denied_uri = URI('http://example/denied')
847
-
848
- denied = page denied_uri, 'text/html', '', 401
849
-
850
- e = assert_raises Mechanize::UnauthorizedError do
851
- @agent.response_authenticate @res, denied, @uri, @req, {}, nil, nil
852
- end
853
-
854
- assert_equal "401 => Net::HTTPUnauthorized for #{denied_uri} -- " \
855
- "WWW-Authenticate header missing in response",
856
- e.message
857
- end
858
-
859
- def test_response_authenticate_ntlm
860
- @uri += '/ntlm'
861
- @agent.add_auth @uri, 'user', 'password'
862
-
863
- @res.instance_variable_set(:@header,
864
- 'www-authenticate' => ['Negotiate, NTLM'])
865
-
866
- begin
867
- page = @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
868
- rescue OpenSSL::Digest::DigestError
869
- skip "It looks like OpenSSL is not configured to support MD4"
870
- end
871
-
872
- assert_equal 'ok', page.body # lame test
873
- end
874
-
875
- def test_response_authenticate_unknown
876
- @agent.add_auth @uri, 'user', 'password'
877
-
878
- page = Mechanize::File.new nil, nil, nil, 401
879
- @res.instance_variable_set(:@header,
880
- 'www-authenticate' => ['Unknown realm=r'])
881
-
882
- assert_raises Mechanize::UnauthorizedError do
883
- @agent.response_authenticate @res, page, @uri, @req, nil, nil, nil
884
- end
885
- end
886
-
887
- def test_response_content_encoding_7_bit
888
- @res.instance_variable_set :@header, 'content-encoding' => %w[7bit]
889
-
890
- body = @agent.response_content_encoding @res, StringIO.new('part')
891
-
892
- assert_equal 'part', body.read
893
- end
894
-
895
- def test_response_content_encoding_deflate
896
- @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
897
- body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
898
-
899
- body = @agent.response_content_encoding @res, body_io
900
-
901
- assert_equal 'part', body.read
902
-
903
- assert body_io.closed?
904
- end
905
-
906
- def test_response_content_encoding_deflate_chunked
907
- @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
908
- body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
909
-
910
- body = @agent.response_content_encoding @res, body_io
911
-
912
- assert_equal 'part', body.read
913
- end
914
-
915
- def test_response_content_encoding_deflate_corrupt
916
- @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
917
- body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01" # missing 1 byte
918
-
919
- e = assert_raises Mechanize::Error do
920
- @agent.response_content_encoding @res, body_io
921
- end
922
-
923
- assert_match %r%error handling content-encoding deflate:%, e.message
924
- assert_match %r%Zlib%, e.message
925
-
926
- assert body_io.closed?
927
- end
928
-
929
- def test_response_content_encoding_deflate_empty
930
- @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
931
-
932
- body = @agent.response_content_encoding @res, StringIO.new
933
-
934
- assert_equal '', body.read
935
- end
936
-
937
- # IIS/6.0 ASP.NET/2.0.50727 does not wrap deflate with zlib, WTF?
938
- def test_response_content_encoding_deflate_no_zlib
939
- @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
940
-
941
- body = @agent.response_content_encoding @res, StringIO.new("+H,*\001\000")
942
-
943
- assert_equal 'part', body.read
944
- end
945
-
946
- def test_response_content_encoding_gzip
947
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
948
- body_io = StringIO.new \
949
- "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
950
-
951
- body = @agent.response_content_encoding @res, body_io
952
-
953
- assert_equal 'part', body.read
954
-
955
- assert body_io.closed?
956
- end
957
-
958
- def test_response_content_encoding_gzip_chunked
959
- def @res.content_length() nil end
960
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
961
- body_io = StringIO.new \
962
- "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
963
-
964
- body = @agent.response_content_encoding @res, body_io
965
-
966
- assert_equal 'part', body.read
967
- end
968
-
969
- def test_response_content_encoding_brotli_when_brotli_not_loaded
970
- skip("only test this on jruby which doesn't have brotli support") unless RUBY_ENGINE == 'jruby'
971
-
972
- @res.instance_variable_set :@header, 'content-encoding' => %w[br]
973
- body_io = StringIO.new("content doesn't matter for this test")
974
-
975
- e = assert_raises(Mechanize::Error) do
976
- @agent.response_content_encoding(@res, body_io)
977
- end
978
- assert_includes(e.message, "cannot deflate brotli-encoded response")
979
-
980
- assert(body_io.closed?)
981
- end
982
-
983
- def test_response_content_encoding_brotli
984
- skip("jruby does not have brotli support") if RUBY_ENGINE == 'jruby'
985
-
986
- @res.instance_variable_set :@header, 'content-encoding' => %w[br]
987
- body_io = StringIO.new(Brotli.deflate("this is compressed by brotli"))
988
-
989
- body = @agent.response_content_encoding(@res, body_io)
990
-
991
- assert_equal("this is compressed by brotli", body.read)
992
- assert(body_io.closed?)
993
- end
994
-
995
- def test_response_content_encoding_brotli_corrupt
996
- skip("jruby does not have brotli support") if RUBY_ENGINE == 'jruby'
997
-
998
- @res.instance_variable_set :@header, 'content-encoding' => %w[br]
999
- body_io = StringIO.new("not a brotli payload")
1000
-
1001
- e = assert_raises(Mechanize::Error) do
1002
- @agent.response_content_encoding(@res, body_io)
1003
- end
1004
- assert_includes(e.message, "error inflating brotli-encoded response")
1005
- assert_kind_of(Brotli::Error, e.cause)
1006
- assert(body_io.closed?)
1007
- end
1008
-
1009
- def test_response_content_encoding_zstd_when_zstd_not_loaded
1010
- skip("only test this on jruby which doesn't have zstd support") unless RUBY_ENGINE == 'jruby'
1011
-
1012
- @res.instance_variable_set :@header, 'content-encoding' => %w[zstd]
1013
- body_io = StringIO.new("content doesn't matter for this test")
1014
-
1015
- e = assert_raises(Mechanize::Error) do
1016
- @agent.response_content_encoding(@res, body_io)
1017
- end
1018
- assert_includes(e.message, 'cannot deflate zstd-encoded response')
1019
-
1020
- assert(body_io.closed?)
1021
- end
1022
-
1023
- def test_response_content_encoding_zstd
1024
- skip('jruby does not have zstd support') if RUBY_ENGINE == 'jruby'
1025
-
1026
- @res.instance_variable_set :@header, 'content-encoding' => %w[zstd]
1027
- body_io = StringIO.new(Zstd.compress('this is compressed by zstd'))
1028
-
1029
- body = @agent.response_content_encoding(@res, body_io)
1030
-
1031
- assert_equal('this is compressed by zstd', body.read)
1032
- assert(body_io.closed?)
1033
- end
1034
-
1035
- def test_response_content_encoding_zstd_corrupt
1036
- skip('jruby does not have zstd support') if RUBY_ENGINE == 'jruby'
1037
-
1038
- @res.instance_variable_set :@header, 'content-encoding' => %w[zstd]
1039
- body_io = StringIO.new('not a zstd payload')
1040
-
1041
- e = assert_raises(Mechanize::Error) do
1042
- @agent.response_content_encoding(@res, body_io)
1043
- end
1044
- assert_includes(e.message, 'error decompressing zstd-encoded response')
1045
- assert_kind_of(RuntimeError, e.cause)
1046
- assert(body_io.closed?)
1047
- end
1048
-
1049
- def test_response_content_encoding_gzip_corrupt
1050
- log = StringIO.new
1051
- logger = Logger.new log
1052
- @agent.context.log = logger
1053
-
1054
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
1055
- body_io = StringIO.new \
1056
- "\037\213\b\0002\002\225M\000\003+H,*\001"
1057
-
1058
- skip_if_jruby_zlib
1059
-
1060
- e = assert_raises Mechanize::Error do
1061
- @agent.response_content_encoding @res, body_io
1062
- end
1063
-
1064
- assert_match %r%error handling content-encoding gzip:%, e.message
1065
- assert_match %r%Zlib%, e.message
1066
-
1067
- assert_match %r%unable to gunzip response: unexpected end of file%,
1068
- log.string
1069
- assert_match %r%unable to inflate response: buffer error%,
1070
- log.string
1071
-
1072
- assert body_io.closed?
1073
- end
1074
-
1075
- def test_response_content_encoding_gzip_checksum_corrupt_crc
1076
- log = StringIO.new
1077
- logger = Logger.new log
1078
- @agent.context.log = logger
1079
-
1080
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
1081
- body_io = StringIO.new \
1082
- "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017J\004\000\000\000"
1083
-
1084
- body = @agent.response_content_encoding @res, body_io
1085
-
1086
- assert_equal 'part', body.read
1087
-
1088
- assert body_io.closed?
1089
-
1090
- assert_match %r%invalid compressed data -- crc error%, log.string
1091
- rescue IOError
1092
- skip_if_jruby_zlib
1093
- raise
1094
- end
1095
-
1096
- def test_response_content_encoding_gzip_checksum_corrupt_length
1097
- log = StringIO.new
1098
- logger = Logger.new log
1099
- @agent.context.log = logger
1100
-
1101
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
1102
- body_io = StringIO.new \
1103
- "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\005\000\000\000"
1104
-
1105
- @agent.response_content_encoding @res, body_io
1106
-
1107
- assert body_io.closed?
1108
-
1109
- assert_match %r%invalid compressed data -- length error%, log.string
1110
- rescue IOError
1111
- skip_if_jruby_zlib
1112
- raise
1113
- end
1114
-
1115
- def test_response_content_encoding_gzip_checksum_truncated
1116
- log = StringIO.new
1117
- logger = Logger.new log
1118
- @agent.context.log = logger
1119
-
1120
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
1121
- body_io = StringIO.new \
1122
- "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000"
1123
-
1124
- @agent.response_content_encoding @res, body_io
1125
-
1126
- assert body_io.closed?
1127
-
1128
- assert_match %r%unable to gunzip response: footer is not found%, log.string
1129
- rescue IOError
1130
- skip_if_jruby_zlib
1131
- raise
1132
- end
1133
-
1134
- def test_response_content_encoding_gzip_empty
1135
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
1136
-
1137
- body = @agent.response_content_encoding @res, StringIO.new
1138
-
1139
- assert_equal '', body.read
1140
- end
1141
-
1142
- def test_response_content_encoding_gzip_encoding_bad
1143
- @res.instance_variable_set(:@header,
1144
- 'content-encoding' => %w[gzip],
1145
- 'content-type' => 'text/html; charset=UTF-8')
1146
-
1147
- # "test\xB2"
1148
- body_io = StringIO.new \
1149
- "\037\213\b\000*+\314N\000\003+I-.\331\004\000x\016\003\376\005\000\000\000"
1150
-
1151
- body = @agent.response_content_encoding @res, body_io
1152
-
1153
- expected = +"test\xB2"
1154
- expected.force_encoding Encoding::BINARY if have_encoding?
1155
-
1156
- content = body.read
1157
- assert_equal expected, content
1158
- assert_equal Encoding::BINARY, content.encoding if have_encoding?
1159
- end
1160
-
1161
- def test_response_content_encoding_gzip_no_footer
1162
- @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
1163
- body_io = StringIO.new \
1164
- "\037\213\b\0002\002\225M\000\003+H,*\001\000"
1165
-
1166
- body = @agent.response_content_encoding @res, body_io
1167
-
1168
- assert_equal 'part', body.read
1169
-
1170
- assert body_io.closed?
1171
- rescue IOError
1172
- skip_if_jruby_zlib
1173
- raise
1174
- end
1175
-
1176
- def test_response_content_encoding_none
1177
- @res.instance_variable_set :@header, 'content-encoding' => %w[none]
1178
-
1179
- body = @agent.response_content_encoding @res, StringIO.new('part')
1180
-
1181
- assert_equal 'part', body.read
1182
- end
1183
-
1184
- def test_response_content_encoding_empty_string
1185
- @res.instance_variable_set :@header, 'content-encoding' => %w[]
1186
-
1187
- body = @agent.response_content_encoding @res, StringIO.new('part')
1188
-
1189
- assert_equal 'part', body.read
1190
- end
1191
-
1192
- def test_response_content_encoding_identity
1193
- @res.instance_variable_set :@header, 'content-encoding' => %w[identity]
1194
-
1195
- body = @agent.response_content_encoding @res, StringIO.new('part')
1196
-
1197
- assert_equal 'part', body.read
1198
- end
1199
-
1200
- def test_response_content_encoding_tempfile_7_bit
1201
- body_io = tempfile 'part'
1202
-
1203
- @res.instance_variable_set :@header, 'content-encoding' => %w[7bit]
1204
-
1205
- body = @agent.response_content_encoding @res, body_io
1206
-
1207
- assert_equal 'part', body.read
1208
- refute body_io.closed?
1209
- ensure
1210
- begin
1211
- body_io.close! if body_io and not body_io.closed?
1212
- rescue IOError
1213
- # HACK for ruby 1.8
1214
- end
1215
- end
1216
-
1217
- def test_response_content_encoding_tempfile_gzip
1218
- body_io = tempfile "x\x9C+H,*\x01\x00\x04?\x01\xB8"
1219
- @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
1220
-
1221
- body = @agent.response_content_encoding @res, body_io
1222
-
1223
- assert_equal 'part', body.read
1224
- assert body_io.closed?
1225
- ensure
1226
- body_io.close! if body_io and not body_io.closed?
1227
- end
1228
-
1229
- def test_response_content_encoding_unknown
1230
- @res.instance_variable_set :@header, 'content-encoding' => %w[unknown]
1231
- body = StringIO.new 'part'
1232
-
1233
- e = assert_raises Mechanize::Error do
1234
- @agent.response_content_encoding @res, body
1235
- end
1236
-
1237
- assert_equal 'unsupported content-encoding: unknown', e.message
1238
- end
1239
-
1240
- def test_response_content_encoding_x_gzip
1241
- @res.instance_variable_set :@header, 'content-encoding' => %w[x-gzip]
1242
- body_io = StringIO.new \
1243
- "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
1244
-
1245
- body = @agent.response_content_encoding @res, body_io
1246
-
1247
- assert_equal 'part', body.read
1248
- end
1249
-
1250
- def test_response_cookies
1251
- uri = URI.parse 'http://host.example.com'
1252
- cookie_str = 'a=b domain=.example.com'
1253
- @res.instance_variable_set(:@header,
1254
- 'set-cookie' => [cookie_str],
1255
- 'content-type' => %w[text/html])
1256
- page = Mechanize::Page.new uri, @res, '', 200, @mech
1257
-
1258
- @agent.response_cookies @res, uri, page
1259
-
1260
- assert_equal ['a="b domain=.example.com"'],
1261
- @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
1262
- end
1263
-
1264
- def test_response_cookies_many
1265
- uri = URI.parse 'http://host.example.com'
1266
- cookie1 = 'a=b domain=.example.com'
1267
- cookie2 = 'c=d domain=.example.com'
1268
- cookies = [cookie1, cookie2]
1269
- @res.instance_variable_set(:@header,
1270
- 'set-cookie' => cookies,
1271
- 'content-type' => %w[text/html])
1272
- page = Mechanize::Page.new uri, @res, '', 200, @mech
1273
-
1274
- @agent.response_cookies @res, uri, page
1275
-
1276
- cookies_from_jar = @agent.cookie_jar.cookies(uri)
1277
-
1278
- assert_equal 2, cookies_from_jar.length
1279
- assert_equal [
1280
- 'a="b domain=.example.com"',
1281
- 'c="d domain=.example.com"',
1282
- ], cookies_from_jar.sort_by { |c| c.name }.map(&:to_s)
1283
- end
1284
-
1285
- def test_response_cookies_meta
1286
- uri = URI.parse 'http://host.example.com'
1287
- cookie_str = 'a=b domain=.example.com'
1288
-
1289
- body = <<-BODY
1290
- <head>
1291
- <meta http-equiv="Set-Cookie" content="#{cookie_str}">
1292
- </head>"
1293
- BODY
1294
-
1295
- @res.instance_variable_set(:@header,
1296
- 'content-type' => %w[text/html])
1297
- page = Mechanize::Page.new uri, @res, body, 200, @mech
1298
-
1299
- @agent.response_cookies @res, uri, page
1300
-
1301
- assert_equal ['a="b domain=.example.com"'],
1302
- @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
1303
- end
1304
-
1305
- def test_response_cookies_meta_bogus
1306
- uri = URI.parse 'http://host.example.com'
1307
-
1308
- body = <<-BODY
1309
- <head>
1310
- <meta http-equiv="Set-Cookie">
1311
- </head>"
1312
- BODY
1313
-
1314
- @res.instance_variable_set(:@header,
1315
- 'content-type' => %w[text/html])
1316
- page = Mechanize::Page.new uri, @res, body, 200, @mech
1317
-
1318
- @agent.response_cookies @res, uri, page
1319
-
1320
- assert_empty @agent.cookie_jar.cookies(uri)
1321
- end
1322
-
1323
- def test_response_follow_meta_refresh
1324
- uri = URI.parse 'http://example/#id+1'
1325
-
1326
- body = <<-BODY
1327
- <title></title>
1328
- <meta http-equiv="refresh" content="0">
1329
- BODY
1330
-
1331
- page = Mechanize::Page.new(uri, nil, body, 200, @mech)
1332
-
1333
- @agent.follow_meta_refresh = true
1334
- @agent.follow_meta_refresh_self = true
1335
-
1336
- page = @agent.response_follow_meta_refresh @res, uri, page, 0
1337
-
1338
- assert_equal uri, page.uri
1339
- end
1340
-
1341
- def test_response_follow_meta_refresh_to_cross_origin_drops_agent_request_headers
1342
- uri = URI.parse 'http://example/'
1343
-
1344
- body = <<-BODY
1345
- <title></title>
1346
- <meta http-equiv="refresh" content="0;url=http://trap/http_headers">
1347
- BODY
1348
-
1349
- page = Mechanize::Page.new(uri, nil, body, 200, @mech)
1350
-
1351
- @agent.follow_meta_refresh = true
1352
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1353
-
1354
- page = @agent.response_follow_meta_refresh @res, uri, page, 0
1355
-
1356
- refute_match("authorization|Bearer tokensecret", page.body)
1357
- end
1358
-
1359
- def test_meta_refresh_to_same_origin_keeps_agent_request_headers
1360
- @agent.follow_meta_refresh = true
1361
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1362
-
1363
- page = @agent.fetch 'http://example/http_refresh?refresh_url=/http_headers'
1364
-
1365
- assert_match("authorization|Bearer tokensecret", page.body)
1366
- end
1367
-
1368
- def test_response_follow_meta_refresh_limit
1369
- uri = URI.parse 'http://example/#id+1'
1370
-
1371
- body = <<-BODY
1372
- <title></title>
1373
- <meta http-equiv="refresh" content="0">
1374
- BODY
1375
-
1376
- page = Mechanize::Page.new(uri, nil, body, 200, @mech)
1377
-
1378
- @agent.follow_meta_refresh = true
1379
- @agent.follow_meta_refresh_self = true
1380
-
1381
- assert_raises Mechanize::RedirectLimitReachedError do
1382
- @agent.response_follow_meta_refresh(@res, uri, page,
1383
- @agent.redirection_limit)
1384
- end
1385
- end
1386
-
1387
- def test_response_meta_refresh_with_insecure_url
1388
- uri = URI.parse 'http://example/#id+1'
1389
-
1390
- body = <<-BODY
1391
- <title></title>
1392
- <meta http-equiv="refresh" content="0; url=file:///dev/zero">
1393
- BODY
1394
-
1395
- page = Mechanize::Page.new(uri, nil, body, 200, @mech)
1396
-
1397
- @agent.follow_meta_refresh = true
1398
-
1399
- assert_raises Mechanize::Error do
1400
- @agent.response_follow_meta_refresh(@res, uri, page,
1401
- @agent.redirection_limit)
1402
- end
1403
- end
1404
-
1405
- def test_response_parse
1406
- body = '<title>hi</title>'
1407
- @res.instance_variable_set :@header, 'content-type' => %w[text/html]
1408
-
1409
- page = @agent.response_parse @res, body, @uri
1410
-
1411
- assert_instance_of Mechanize::Page, page
1412
- assert_equal @mech, page.mech
1413
- end
1414
-
1415
- def test_response_parse_content_type_case
1416
- body = '<title>hi</title>'
1417
- @res.instance_variable_set(:@header, 'content-type' => %w[text/HTML])
1418
-
1419
- page = @agent.response_parse @res, body, @uri
1420
-
1421
- assert_instance_of Mechanize::Page, page
1422
-
1423
- assert_equal 'text/HTML', page.content_type
1424
- end
1425
-
1426
- def test_response_parse_content_type_encoding
1427
- body = '<title>hi</title>'
1428
- @res.instance_variable_set(:@header,
1429
- 'content-type' =>
1430
- %w[text/html;charset=ISO-8859-1])
1431
-
1432
- page = @agent.response_parse @res, body, @uri
1433
-
1434
- assert_instance_of Mechanize::Page, page
1435
- assert_equal @mech, page.mech
1436
-
1437
- assert_equal 'ISO-8859-1', page.encoding
1438
- assert_equal 'ISO-8859-1', page.parser.encoding
1439
- end
1440
-
1441
- def test_response_parse_content_type_encoding_broken_iso_8859_1
1442
- body = '<title>hi</title>'
1443
- @res.instance_variable_set(:@header,
1444
- 'content-type' =>
1445
- %w[text/html; charset=ISO_8859-1])
1446
-
1447
- page = @agent.response_parse @res, body, @uri
1448
-
1449
- assert_instance_of Mechanize::Page, page
1450
- assert_equal 'ISO_8859-1', page.encoding
1451
- end
1452
-
1453
- def test_response_parse_content_type_encoding_broken_utf_8
1454
- body = '<title>hi</title>'
1455
- @res.instance_variable_set(:@header,
1456
- 'content-type' =>
1457
- %w[text/html; charset=UTF8])
1458
-
1459
- page = @agent.response_parse @res, body, @uri
1460
-
1461
- assert_instance_of Mechanize::Page, page
1462
-
1463
- # as of libxml 2.12.0, the result is dependent on how libiconv is built (which aliases are supported)
1464
- # if the alias "UTF8" is defined, then the result will be "UTF-8".
1465
- # if the alias "UTF8" is not defined, then the result will be "UTF8".
1466
- # note that this alias may be defined by Nokogiri itself in its EncodingHandler class.
1467
- assert_includes ["UTF8", "UTF-8"], page.encoding
1468
- assert_includes ["UTF8", "UTF-8"], page.parser.encoding
1469
- end
1470
-
1471
- def test_response_parse_content_type_encoding_garbage
1472
- body = '<title>hi</title>'
1473
- @res.instance_variable_set(:@header,
1474
- 'content-type' =>
1475
- %w[text/html; charset=garbage_charset])
1476
-
1477
- page = @agent.response_parse @res, body, @uri
1478
-
1479
- assert_instance_of Mechanize::Page, page
1480
- assert_equal @mech, page.mech
1481
- end
1482
-
1483
- def test_response_parse_content_type_encoding_semicolon
1484
- body = '<title>hi</title>'
1485
- @res.instance_variable_set(:@header,
1486
- 'content-type' =>
1487
- %w[text/html;charset=UTF-8;])
1488
-
1489
- page = @agent.response_parse @res, body, @uri
1490
-
1491
- assert_instance_of Mechanize::Page, page
1492
-
1493
- assert_equal 'UTF-8', page.encoding
1494
- end
1495
-
1496
- def test_response_read
1497
- def @res.read_body() yield 'part' end
1498
- def @res.content_length() 4 end
1499
-
1500
- io = @agent.response_read @res, @req, @uri
1501
-
1502
- body = io.read
1503
-
1504
- assert_equal 'part', body
1505
- assert_equal Encoding::BINARY, body.encoding
1506
- end
1507
-
1508
- def test_response_read_chunked_no_trailer
1509
- @res['Transfer-Encoding'] = 'chunked'
1510
- def @res.content_length() end
1511
- def @res.read_body
1512
- yield 'a' * 10
1513
- raise EOFError
1514
- end
1515
-
1516
- e = assert_raises Mechanize::ChunkedTerminationError do
1517
- @agent.response_read @res, @req, @uri
1518
- end
1519
-
1520
- assert_equal 'aaaaaaaaaa', e.body_io.read
1521
- end
1522
-
1523
- def test_response_read_content_length_head
1524
- req = Net::HTTP::Head.new '/'
1525
-
1526
- def @res.content_length() end
1527
- def @res.read_body() end
1528
-
1529
- io = @agent.response_read @res, req, @uri
1530
-
1531
- assert_equal '', io.read
1532
- end
1533
-
1534
- def test_response_read_content_length_mismatch
1535
- def @res.content_length() 5 end
1536
- def @res.read_body() yield 'part' end
1537
-
1538
- e = assert_raises Mechanize::ResponseReadError do
1539
- @agent.response_read @res, @req, @uri
1540
- end
1541
-
1542
- assert_equal 'Content-Length (5) does not match response body length (4)' \
1543
- ' (Mechanize::ResponseReadError)', e.message
1544
- end
1545
-
1546
- def test_response_read_content_length_redirect
1547
- res = Net::HTTPFound.allocate
1548
- def res.content_length() 5 end
1549
- def res.code() 302 end
1550
- def res.read_body() yield 'part' end
1551
- res.instance_variable_set :@header, {}
1552
-
1553
- io = @agent.response_read res, @req, @uri
1554
-
1555
- assert_equal 'part', io.read
1556
- end
1557
-
1558
- def test_response_read_error
1559
- def @res.read_body()
1560
- yield 'part'
1561
- raise Net::HTTP::Persistent::Error
1562
- end
1563
-
1564
- e = assert_raises Mechanize::ResponseReadError do
1565
- @agent.response_read @res, @req, @uri
1566
- end
1567
-
1568
- assert_equal @res, e.response
1569
- assert_equal 'part', e.body_io.read
1570
- assert_kind_of Net::HTTP::Persistent::Error, e.error
1571
- end
1572
-
1573
- def test_response_read_file
1574
- Tempfile.open 'pi.txt' do |tempfile|
1575
- tempfile.write "π\n"
1576
- tempfile.flush
1577
- tempfile.rewind
1578
-
1579
- uri = URI.parse "file://#{tempfile.path}"
1580
- req = Mechanize::FileRequest.new uri
1581
- res = Mechanize::FileResponse.new tempfile.path
1582
-
1583
- io = @agent.response_read res, req, uri
1584
-
1585
- expected = "π\n".dup.force_encoding(Encoding::BINARY)
1586
-
1587
- # Ruby 1.8.7 doesn't let us set the write mode of the tempfile to binary,
1588
- # so we should expect an inserted carriage return on some platforms
1589
- expected_with_carriage_return = "π\r\n".dup.force_encoding(Encoding::BINARY)
1590
-
1591
- body = io.read
1592
- assert_match(/^(#{expected}|#{expected_with_carriage_return})$/m, body)
1593
- assert_equal Encoding::BINARY, body.encoding
1594
- end
1595
- end
1596
-
1597
- def test_response_read_large
1598
- @agent.max_file_buffer = 10240
1599
-
1600
- def @res.read_body() yield 'a' * 10241 end
1601
- def @res.content_length() 10241 end
1602
-
1603
- io = @agent.response_read @res, @req, @uri
1604
-
1605
- assert_kind_of Tempfile, io
1606
- assert_equal 10241, io.stat.size
1607
- end
1608
-
1609
- def test_response_read_large_chunked
1610
- @agent.max_file_buffer = 10240
1611
-
1612
- def @res.read_body
1613
- 11.times do yield 'a' * 1024 end
1614
- end
1615
- def @res.content_length() end
1616
-
1617
- io = @agent.response_read @res, @req, @uri
1618
-
1619
- assert_kind_of Tempfile, io
1620
- assert_equal 11264, io.stat.size
1621
- end
1622
-
1623
- def test_response_read_no_body
1624
- req = Net::HTTP::Options.new '/'
1625
-
1626
- def @res.content_length() end
1627
- def @res.read_body() end
1628
-
1629
- io = @agent.response_read @res, req, @uri
1630
-
1631
- assert_equal '', io.read
1632
- end
1633
-
1634
- def test_response_read_unknown_code
1635
- res = Net::HTTPUnknownResponse.allocate
1636
- res.instance_variable_set :@code, 9999
1637
- res.instance_variable_set :@header, {}
1638
- def res.read_body() yield 'part' end
1639
-
1640
- e = assert_raises Mechanize::ResponseCodeError do
1641
- @agent.response_read res, @req, @uri
1642
- end
1643
-
1644
- assert_equal res, e.page
1645
- end
1646
-
1647
- def test_response_redirect
1648
- @agent.redirect_ok = true
1649
- referer = page 'http://example/referer'
1650
-
1651
- page = fake_page
1652
- page = @agent.response_redirect({ 'Location' => '/index.html' }, :get,
1653
- page, 0, {}, referer)
1654
-
1655
- assert_equal URI('http://fake.example/index.html'), page.uri
1656
-
1657
- assert_equal 'http://example/referer', requests.first['Referer']
1658
- end
1659
-
1660
- def test_response_redirect_header
1661
- @agent.redirect_ok = true
1662
- referer = page 'http://example/referer'
1663
-
1664
- headers = {
1665
- 'Range' => 'bytes=0-9999',
1666
- 'Content-Type' => 'application/x-www-form-urlencoded',
1667
- 'CONTENT-LENGTH' => '9999',
1668
- 'content-md5' => '14758f1afd44c09b7992073ccf00b43d',
1669
- }
1670
-
1671
- page = fake_page
1672
- page = @agent.response_redirect({ 'Location' => '/http_headers' }, :get,
1673
- page, 0, headers, referer)
1674
-
1675
- assert_equal URI('http://fake.example/http_headers'), page.uri
1676
-
1677
- assert_match 'range|bytes=0-9999', page.body
1678
- refute_match 'content-type|application/x-www-form-urlencoded', page.body
1679
- refute_match 'content-length|9999', page.body
1680
- refute_match 'content-md5|14758f1afd44c09b7992073ccf00b43d', page.body
1681
- end
1682
-
1683
- def test_response_redirect_malformed
1684
- @agent.redirect_ok = true
1685
- referer = page 'http://example/referer'
1686
-
1687
- page = fake_page
1688
- page = @agent.response_redirect({ 'Location' => '/index.html?q=あ' }, :get,
1689
- page, 0, {}, referer)
1690
-
1691
- assert_equal URI('http://fake.example/index.html?q=%E3%81%82'), page.uri
1692
-
1693
- assert_equal 'http://example/referer', requests.first['Referer']
1694
- end
1695
-
1696
- def test_response_redirect_insecure
1697
- @agent.redirect_ok = true
1698
- referer = page 'http://example/referer'
1699
-
1700
- assert_raises Mechanize::Error do
1701
- @agent.response_redirect({ 'Location' => 'file:///etc/passwd' }, :get,
1702
- fake_page, 0, {}, referer)
1703
- end
1704
- end
1705
-
1706
- def test_response_redirect_limit
1707
- @agent.redirect_ok = true
1708
- referer = page 'http://example/referer'
1709
-
1710
- assert_raises Mechanize::RedirectLimitReachedError do
1711
- @agent.response_redirect({ 'Location' => '/index.html' }, :get,
1712
- fake_page, @agent.redirection_limit, {}, referer)
1713
- end
1714
- end
1715
-
1716
- def test_response_redirect_to_cross_site_with_credential
1717
- @agent.redirect_ok = true
1718
-
1719
- headers = {
1720
- 'Range' => 'bytes=0-9999',
1721
- 'AUTHORIZATION' => 'Basic xxx',
1722
- 'cookie' => 'name=value',
1723
- }
1724
-
1725
- page = html_page ''
1726
- page = @agent.response_redirect({ 'Location' => 'http://trap/http_headers' }, :get,
1727
- page, 0, headers)
1728
-
1729
- refute_includes(headers.keys, "AUTHORIZATION")
1730
- refute_includes(headers.keys, "cookie")
1731
-
1732
- assert_match("range|bytes=0-9999", page.body)
1733
- refute_match("authorization|Basic xxx", page.body)
1734
- refute_match("cookie|name=value", page.body)
1735
- end
1736
-
1737
- def test_response_redirect_to_cross_site_strips_all_credential_headers
1738
- @agent.redirect_ok = true
1739
-
1740
- headers = {
1741
- 'Range' => 'bytes=0-9999',
1742
- 'Proxy-Authorization' => 'Basic proxysecret',
1743
- 'Cookie2' => 'version=1',
1744
- }
1745
-
1746
- page = html_page ''
1747
- page = @agent.response_redirect({ 'Location' => 'http://trap/http_headers' }, :get,
1748
- page, 0, headers)
1749
-
1750
- refute_includes(headers.keys, "Proxy-Authorization")
1751
- refute_includes(headers.keys, "Cookie2")
1752
-
1753
- refute_match("proxy-authorization|Basic proxysecret", page.body)
1754
- refute_match("cookie2|version=1", page.body)
1755
- end
1756
-
1757
- def test_response_redirect_to_same_site_keeps_all_credential_headers
1758
- @agent.redirect_ok = true
1759
-
1760
- headers = {
1761
- 'Proxy-Authorization' => 'Basic proxysecret',
1762
- 'Cookie2' => 'version=1',
1763
- }
1764
-
1765
- page = html_page ''
1766
- page = @agent.response_redirect({ 'Location' => '/http_headers' }, :get,
1767
- page, 0, headers)
1768
-
1769
- assert_match("proxy-authorization|Basic proxysecret", page.body)
1770
- assert_match("cookie2|version=1", page.body)
1771
- end
1772
-
1773
- def test_response_redirect_to_cross_site_drops_agent_request_headers
1774
- @agent.redirect_ok = true
1775
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret', 'Cookie' => 'name=value' }
1776
-
1777
- page = html_page ''
1778
- page = @agent.response_redirect({ 'Location' => 'http://trap/http_headers' }, :get,
1779
- page, 0, {})
1780
-
1781
- refute_match("authorization|Bearer tokensecret", page.body)
1782
- refute_match("cookie|name=value", page.body)
1783
- end
1784
-
1785
- def test_redirect_to_cross_site_keeps_insensitive_agent_request_headers
1786
- @agent.redirect_ok = true
1787
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret', 'X-Api-Key' => 'apikey' }
1788
-
1789
- page = @agent.fetch 'http://example/redirect', :get,
1790
- { 'X-Location' => 'http://trap/http_headers' }
1791
-
1792
- refute_match("authorization|Bearer tokensecret", page.body)
1793
- assert_match("x-api-key|apikey", page.body)
1794
- end
1795
-
1796
- def test_redirect_to_same_site_keeps_agent_request_headers
1797
- @agent.redirect_ok = true
1798
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1799
-
1800
- page = @agent.fetch 'http://example/redirect', :get, { 'X-Location' => '/http_headers' }
1801
-
1802
- assert_match("authorization|Bearer tokensecret", page.body)
1803
- end
1804
-
1805
- def test_response_redirect_to_downgraded_scheme_strips_credential
1806
- @agent.redirect_ok = true
1807
-
1808
- headers = { 'AUTHORIZATION' => 'Basic xxx', 'cookie' => 'name=value' }
1809
-
1810
- page = page 'https://example:8443/', 'text/html'
1811
- page = @agent.response_redirect({ 'Location' => 'http://example:8443/http_headers' }, :get,
1812
- page, 0, headers)
1813
-
1814
- refute_includes(headers.keys, "AUTHORIZATION")
1815
- refute_includes(headers.keys, "cookie")
1816
-
1817
- refute_match("authorization|Basic xxx", page.body)
1818
- refute_match("cookie|name=value", page.body)
1819
- end
1820
-
1821
- def test_response_redirect_to_downgraded_scheme_drops_agent_request_headers
1822
- @agent.redirect_ok = true
1823
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1824
-
1825
- page = page 'https://example:8443/', 'text/html'
1826
- page = @agent.response_redirect({ 'Location' => 'http://example:8443/http_headers' }, :get,
1827
- page, 0, {})
1828
-
1829
- refute_match("authorization|Bearer tokensecret", page.body)
1830
- end
1831
-
1832
- def test_response_redirect_to_different_port_strips_cookie
1833
- @agent.redirect_ok = true
1834
-
1835
- headers = { 'cookie' => 'name=value' }
1836
-
1837
- page = html_page ''
1838
- page = @agent.response_redirect({ 'Location' => 'http://example:81/http_headers' }, :get,
1839
- page, 0, headers)
1840
-
1841
- refute_match("cookie|name=value", page.body)
1842
- end
1843
-
1844
- # Every request the agent made to a host other than the one the credential
1845
- # was set for.
1846
- def foreign_requests
1847
- requests.reject { |request| request['host'] == 'example' }
1848
- end
1849
-
1850
- def test_second_redirect_hop_on_a_foreign_origin_does_not_restore_credentials
1851
- @agent.redirect_ok = true
1852
- @agent.redirection_limit = 2
1853
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1854
-
1855
- assert_raises Mechanize::RedirectLimitReachedError do
1856
- @agent.fetch 'http://example/redirect', :get,
1857
- { 'X-Location' => 'http://trap/redirect' }
1858
- end
1859
-
1860
- assert_operator foreign_requests.length, :>, 1
1861
- assert_empty foreign_requests.select { |r| r['Authorization'] }
1862
- end
1863
-
1864
- def test_authentication_retry_on_a_foreign_origin_does_not_restore_credentials
1865
- @agent.redirect_ok = true
1866
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1867
- @agent.add_auth URI('http://trap/'), 'user', 'pass'
1868
-
1869
- begin
1870
- @agent.fetch 'http://example/redirect', :get,
1871
- { 'X-Location' => 'http://trap/basic_auth' }
1872
- rescue Mechanize::UnauthorizedError
1873
- # a leaked bearer token overwrites the Basic credential and the retry fails
1874
- end
1875
-
1876
- assert_operator foreign_requests.length, :>, 1
1877
- assert_empty foreign_requests.select { |r| r['Authorization'] == 'Bearer tokensecret' }
1878
- end
1879
-
1880
- def test_meta_refresh_to_a_second_foreign_origin_does_not_restore_credentials
1881
- @agent.redirect_ok = true
1882
- @agent.follow_meta_refresh = true
1883
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1884
-
1885
- @agent.fetch 'http://example/redirect', :get,
1886
- { 'X-Location' => 'http://trap/http_refresh?refresh_url=/http_headers' }
1887
-
1888
- assert_nil requests.find { |r| r.path == '/http_headers' }['Authorization']
1889
- end
1890
-
1891
- def test_robots_lookup_on_a_foreign_origin_does_not_send_credentials
1892
- @agent.redirect_ok = true
1893
- @agent.robots = true
1894
- @agent.request_headers = { 'Authorization' => 'Bearer tokensecret' }
1895
-
1896
- @agent.fetch 'http://example/redirect', :get,
1897
- { 'X-Location' => 'http://trap/http_headers' }
1898
-
1899
- assert_nil requests.find { |r| r.path == '/robots.txt' }['Authorization']
1900
- end
1901
-
1902
- def test_response_redirect_to_same_site_with_credential
1903
- @agent.redirect_ok = true
1904
-
1905
- headers = {
1906
- 'Range' => 'bytes=0-9999',
1907
- 'AUTHORIZATION' => 'Basic xxx',
1908
- 'cookie' => 'name=value',
1909
- }
1910
-
1911
- page = html_page ''
1912
- page = @agent.response_redirect({ 'Location' => '/http_headers' }, :get,
1913
- page, 0, headers)
1914
-
1915
- assert_includes(headers.keys, "AUTHORIZATION")
1916
- assert_includes(headers.keys, "cookie")
1917
-
1918
- assert_match("range|bytes=0-9999", page.body)
1919
- assert_match("authorization|Basic xxx", page.body)
1920
- assert_match("cookie|name=value", page.body)
1921
- end
1922
-
1923
- def test_response_redirect_to_same_site_diff_port_with_credential
1924
- @agent.redirect_ok = true
1925
-
1926
- headers = {
1927
- 'Range' => 'bytes=0-9999',
1928
- 'AUTHORIZATION' => 'Basic xxx',
1929
- 'cookie' => 'name=value',
1930
- }
1931
-
1932
- page = html_page ''
1933
- page = @agent.response_redirect({ 'Location' => 'http://example:81/http_headers' }, :get,
1934
- page, 0, headers)
1935
-
1936
- refute_includes(headers.keys, "AUTHORIZATION")
1937
- refute_includes(headers.keys, "cookie")
1938
-
1939
- assert_match("range|bytes=0-9999", page.body)
1940
- refute_match("authorization|Basic xxx", page.body)
1941
- refute_match("cookie|name=value", page.body)
1942
- end
1943
-
1944
- def test_response_redirect_not_ok
1945
- @agent.redirect_ok = false
1946
-
1947
- page = fake_page
1948
- page = @agent.response_redirect({ 'Location' => '/other' }, :get, page, 0,
1949
- {}, page)
1950
-
1951
- assert_equal URI('http://fake.example'), page.uri
1952
- end
1953
-
1954
- def test_response_redirect_permanent
1955
- @agent.redirect_ok = :permanent
1956
-
1957
- response = Net::HTTPMovedPermanently.allocate
1958
- response.instance_variable_set :@header, { 'location' => %w[/index.html] }
1959
-
1960
- page = fake_page
1961
- page = @agent.response_redirect response, :get, page, 0, {}, page
1962
-
1963
- assert_equal URI('http://fake.example/index.html'), page.uri
1964
- end
1965
-
1966
- def test_response_redirect_permanent_temporary
1967
- @agent.redirect_ok = :permanent
1968
-
1969
- response = Net::HTTPMovedTemporarily.allocate
1970
- response.instance_variable_set :@header, { 'location' => %w[/index.html] }
1971
-
1972
- page = fake_page
1973
- page = @agent.response_redirect response, :get, page, 0, {}, page
1974
-
1975
- assert_equal URI('http://fake.example/'), page.uri
1976
- end
1977
-
1978
- def test_retry_change_request_equals
1979
- unless Gem::Requirement.new("< 4.0.0").satisfied_by?(Gem::Version.new(Net::HTTP::Persistent::VERSION))
1980
- # see https://github.com/drbrain/net-http-persistent/pull/100
1981
- skip("net-http-persistent 4.0.0 and later does not support retry_change_requests")
1982
- end
1983
-
1984
- refute @agent.http.retry_change_requests
1985
-
1986
- @agent.retry_change_requests = true
1987
-
1988
- assert @agent.http.retry_change_requests
1989
- end
1990
-
1991
- def test_robots_allowed_eh
1992
- allowed = URI 'http://localhost/index.html'
1993
- disallowed = URI 'http://localhost/norobots.html'
1994
-
1995
- assert @agent.robots_allowed? allowed
1996
- refute @agent.robots_allowed? disallowed
1997
-
1998
- refute @agent.robots_disallowed? allowed
1999
- assert @agent.robots_disallowed? disallowed
2000
- end
2001
-
2002
- def test_robots_allowed_eh_noindex
2003
- @agent.robots = true
2004
-
2005
- noindex = URI 'http://localhost/noindex.html'
2006
-
2007
- assert @agent.robots_allowed? noindex
2008
-
2009
- assert_raises Mechanize::RobotsDisallowedError do
2010
- @agent.fetch noindex
2011
- end
2012
- end
2013
-
2014
- def test_robots_infinite_loop
2015
- @agent.robots = true
2016
- @agent.redirect_ok = true
2017
-
2018
- assert_raises Mechanize::RobotsDisallowedError do
2019
- @agent.fetch URI('http://301/norobots.html')
2020
- end
2021
-
2022
- @agent.fetch URI('http://301/robots.html')
2023
- end
2024
-
2025
- def test_set_proxy
2026
- @agent.set_proxy 'www.example.com', 9001, 'joe', 'lol'
2027
-
2028
- assert_equal @agent.proxy_uri.host, 'www.example.com'
2029
- assert_equal @agent.proxy_uri.port, 9001
2030
- assert_equal @agent.proxy_uri.user, 'joe'
2031
- assert_equal @agent.proxy_uri.password, 'lol'
2032
- end
2033
-
2034
- def test_set_proxy_port_string
2035
- @agent.set_proxy 'www.example.com', '9001', 'joe', 'lol'
2036
-
2037
- assert_equal @agent.proxy_uri.host, 'www.example.com'
2038
- assert_equal @agent.proxy_uri.port, 9001
2039
- assert_equal @agent.proxy_uri.user, 'joe'
2040
- assert_equal @agent.proxy_uri.password, 'lol'
2041
- end
2042
-
2043
- def test_set_proxy_service_name
2044
- @agent.set_proxy 'www.example.com', 'http', 'joe', 'lol'
2045
-
2046
- assert_equal @agent.proxy_uri.host, 'www.example.com'
2047
- assert_equal @agent.proxy_uri.port, 80
2048
- assert_equal @agent.proxy_uri.user, 'joe'
2049
- assert_equal @agent.proxy_uri.password, 'lol'
2050
- end
2051
-
2052
- def test_set_proxy_service_name_bad
2053
- e = assert_raises ArgumentError do
2054
- @agent.set_proxy 'www.example.com', 'nonexistent service', 'joe', 'lol'
2055
- end
2056
-
2057
- assert_equal 'invalid value for port: "nonexistent service"', e.message
2058
- end
2059
-
2060
- def test_set_proxy_with_scheme
2061
- @agent.set_proxy 'http://www.example.com', 9001, 'joe', 'lol'
2062
-
2063
- assert_equal @agent.proxy_uri.host, 'www.example.com'
2064
- assert_equal @agent.proxy_uri.port, 9001
2065
- assert_equal @agent.proxy_uri.user, 'joe'
2066
- assert_equal @agent.proxy_uri.password, 'lol'
2067
- end
2068
-
2069
- def test_set_proxy_url
2070
- @agent.set_proxy 'http://joe:lol@www.example.com:9001'
2071
-
2072
- assert_equal @agent.proxy_uri.host, 'www.example.com'
2073
- assert_equal @agent.proxy_uri.port, 9001
2074
- assert_equal @agent.proxy_uri.user, 'joe'
2075
- assert_equal @agent.proxy_uri.password, 'lol'
2076
- end
2077
-
2078
- def test_set_proxy_uri
2079
- @agent.set_proxy URI('http://joe:lol@www.example.com:9001')
2080
-
2081
- assert_equal @agent.proxy_uri.host, 'www.example.com'
2082
- assert_equal @agent.proxy_uri.port, 9001
2083
- assert_equal @agent.proxy_uri.user, 'joe'
2084
- assert_equal @agent.proxy_uri.password, 'lol'
2085
- end
2086
-
2087
- def test_set_proxy_url_and_credentials
2088
- @agent.set_proxy 'http://www.example.com:9001', nil, 'joe', 'lol'
2089
-
2090
- assert_equal @agent.proxy_uri.host, 'www.example.com'
2091
- assert_equal @agent.proxy_uri.port, 9001
2092
- assert_equal @agent.proxy_uri.user, 'joe'
2093
- assert_equal @agent.proxy_uri.password, 'lol'
2094
- end
2095
-
2096
- def test_setting_agent_name
2097
- mech = Mechanize.new 'user-set-name'
2098
- assert_equal 'user-set-name', mech.agent.http.name
2099
- end
2100
-
2101
- def test_ssl
2102
- in_tmpdir do
2103
- store = OpenSSL::X509::Store.new
2104
- @agent.ca_file = '.'
2105
- @agent.cert_store = store
2106
- @agent.certificate = ssl_certificate
2107
- @agent.private_key = ssl_private_key
2108
- @agent.ssl_version = 'SSLv3'
2109
- @agent.verify_callback = proc { |ok, context| }
2110
-
2111
- http = @agent.http
2112
-
2113
- assert_equal '.', http.ca_file
2114
- assert_equal store, http.cert_store
2115
- assert_equal ssl_certificate, http.certificate
2116
- assert_equal ssl_private_key, http.private_key
2117
- assert_equal 'SSLv3', http.ssl_version
2118
- assert_equal OpenSSL::SSL::VERIFY_PEER, http.verify_mode
2119
- assert http.verify_callback
2120
- end
2121
- end
2122
-
2123
- def test_use_tempfile_eh
2124
- refute @agent.use_tempfile? nil
2125
-
2126
- @agent.max_file_buffer = 1
2127
-
2128
- refute @agent.use_tempfile? 0
2129
- assert @agent.use_tempfile? 1
2130
-
2131
- @agent.max_file_buffer = nil
2132
-
2133
- refute @agent.use_tempfile? 1
2134
- end
2135
-
2136
- def test_verify_none_equals
2137
- @agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
2138
-
2139
- http = @agent.http
2140
-
2141
- assert_equal OpenSSL::SSL::VERIFY_NONE, http.verify_mode
2142
- end
2143
-
2144
- end
2145
-