mechanize 2.7.4 → 2.7.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mechanize might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f74b81c4883e990cd6360ee0294a3ff1ae1c8d59
4
- data.tar.gz: 872ab6eeda86c290a94105a730bfec64ee819493
3
+ metadata.gz: f42c3bb7351deeb2a1a68c33b118e666925ed20a
4
+ data.tar.gz: 751d2ffcf39675f4668a7d069a707a3782cafcfe
5
5
  SHA512:
6
- metadata.gz: 96dc6beaa52babf27369eb8548733298782a2409f7a2bb43c9a5e9241445d96e117c54ad5b8c3e445b6b4c4ea1edb37f8b223b0513916f8be7b591fa3e29c598
7
- data.tar.gz: 95e653b7705518a33aa5bbb765be7ddc4603756e0ee24bd5ab6c2979d039ea5b29e94ae9a2b8e478ceaa993b165d83a65d695212fa271ab59889fe7c811c876d
6
+ metadata.gz: c1b85a0469fbdd35bb9ce230cf5752d4cef8f9416eab11f72ca00bc25f0f3b40065a94e31ef63944ecf8ef270a3388bbbab310b190ffbf4582f0305da3d24259
7
+ data.tar.gz: 4e94e81383dccbf49bec0312e1ffe0183eaf7668679f7a77d4d5b42c2ece81337797cc16b8d61fef02dfac9077aa46ece2acce0b2418204f231ef476416b8df8
@@ -6,20 +6,26 @@ notifications:
6
6
  - ljjarvis@gmail.com
7
7
  - knu@idaemons.org
8
8
  sudo: false
9
+ # bundler is missing for jruby-head in travis-ci
10
+ # https://github.com/travis-ci/travis-ci/issues/5861
11
+ before_install: gem query -i -n ^bundler$ >/dev/null || gem install bundler
9
12
  rvm:
10
13
  - 1.9.3
11
14
  - 2.0.0
12
15
  - 2.1
13
16
  - 2.2
14
- - 2.3
17
+ - 2.3.1
15
18
  - ruby-head
16
- - jruby-19mode
19
+ - jruby-1.7.25
20
+ - jruby-9.1.2.0
17
21
  - jruby-head
18
22
  - rbx-19mode
19
23
  script: rake test
20
24
  matrix:
21
25
  allow_failures:
26
+ - rvm: 2.3
22
27
  - rvm: ruby-head
23
- - rvm: jruby-19mode
28
+ - rvm: jruby-1.7.25
29
+ - rvm: jruby-9.1.2.0
24
30
  - rvm: jruby-head
25
31
  - rvm: rbx-19mode
@@ -1,5 +1,16 @@
1
1
  = Mechanize CHANGELOG
2
2
 
3
+ === 2.7.5
4
+
5
+ * New Features
6
+ * All 4xx responses and RedirectLimitReachedError when fetching robots.txt are treated as full allow just like Googlebot does.
7
+ * Enable support for mime-types > 3.
8
+
9
+ * Bug fix
10
+ * Don't cause infinite loop when `GET /robots.txt` redirects. (#457)
11
+ * Fix basic authentication for a realm that contains uppercase characters. (#458, #459)
12
+ * Fix encoding error when uploading a file which name is non-ASCII. (#333)
13
+
3
14
  === 2.7.4
4
15
 
5
16
  * New Features
@@ -10,7 +21,7 @@
10
21
  Rawlins.
11
22
  * Capture link when scheme is unsupported. #362 by Jon Rowe.
12
23
  * Pre-defined User-Agent stings are updated to those of more recent versions, and new aliases for IE 10/11 and Edge are added.
13
- * Support for mime-types 1.x is restored while keeping compatible with mime-types 2.x and adding support for 3.0.
24
+ * Support for mime-types 1.x is restored while keeping compatible with mime-types 2.x.
14
25
  * Mechanize::Page now responds to #xpath, #css, #at_xpath, #at_css, and #%.
15
26
  * element(s)_with methods now accept :xpath and :css options for doing xpath/css
16
27
  selector searching.
data/Rakefile CHANGED
@@ -25,7 +25,7 @@ end
25
25
  RDoc::Task.new do |rdoc|
26
26
  rdoc.main = "README.rdoc"
27
27
  rdoc.rdoc_dir = 'doc'
28
- rdoc.rdoc_files.include( "CHANGELOG.rdoc", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.rdoc", "Manifest.txt", "README.rdoc", "lib/**/*.rb")
28
+ rdoc.rdoc_files.include( "CHANGELOG.rdoc", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.rdoc", "README.rdoc", "lib/**/*.rb")
29
29
  end
30
30
 
31
31
  desc "Run tests"
@@ -67,12 +67,12 @@ class Mechanize::Form
67
67
 
68
68
  # Returns all field names (keys) for this form
69
69
  def keys
70
- fields.map { |f| f.name }
70
+ fields.map(&:name)
71
71
  end
72
72
 
73
73
  # Returns all field values for this form
74
74
  def values
75
- fields.map { |f| f.value }
75
+ fields.map(&:value)
76
76
  end
77
77
 
78
78
  # Returns all buttons of type Submit
@@ -278,10 +278,10 @@ class Mechanize::Form
278
278
 
279
279
  # take one radio button from each group
280
280
  radio_groups.each_value do |g|
281
- checked = g.select {|f| f.checked}
281
+ checked = g.select(&:checked)
282
282
 
283
283
  if checked.uniq.size > 1 then
284
- values = checked.map { |button| button.value }.join(', ').inspect
284
+ values = checked.map(&:value).join(', ').inspect
285
285
  name = checked.first.name.inspect
286
286
  raise Mechanize::Error,
287
287
  "radiobuttons #{values} are checked in the #{name} group, " \
@@ -337,6 +337,8 @@ class Mechanize::Form
337
337
  @clicked_buttons = []
338
338
  end
339
339
 
340
+ CRLF = "\r\n".freeze
341
+
340
342
  # This method calculates the request data to be sent back to the server
341
343
  # for this form, depending on if this is a regular post, get, or a
342
344
  # multi-part post,
@@ -348,16 +350,23 @@ class Mechanize::Form
348
350
  boundary = rand_string(20)
349
351
  @enctype = "multipart/form-data; boundary=#{boundary}"
350
352
 
351
- params = query_params.map do |k,v|
352
- param_to_multipart(k, v) if k
353
- end.compact
353
+ delimiter = "--#{boundary}\r\n"
354
+
355
+ data = ::String.new
354
356
 
355
- params.concat @file_uploads.map { |f| file_to_multipart(f) }
357
+ query_params.each do |k,v|
358
+ if k
359
+ data << delimiter
360
+ param_to_multipart(k, v, data)
361
+ end
362
+ end
356
363
 
357
- params.map do |part|
358
- "--#{boundary}\r\n#{part.force_encoding(Encoding::ASCII_8BIT)}"
359
- end.join('') +
360
- "--#{boundary}--\r\n"
364
+ @file_uploads.each do |f|
365
+ data << delimiter
366
+ file_to_multipart(f, data)
367
+ end
368
+
369
+ data << "--#{boundary}--\r\n"
361
370
  else
362
371
  Mechanize::Util.build_query_string(query_params)
363
372
  end
@@ -586,49 +595,67 @@ class Mechanize::Form
586
595
  end
587
596
  end
588
597
 
598
+ unless ::String.method_defined?(:b)
599
+ # Define String#b for Ruby < 2.0
600
+ class ::String
601
+ def b
602
+ dup.force_encoding(Encoding::ASCII_8BIT)
603
+ end
604
+ end
605
+ end
606
+
589
607
  def rand_string(len = 10)
590
608
  chars = ("a".."z").to_a + ("A".."Z").to_a
591
- string = ""
609
+ string = ::String.new
592
610
  1.upto(len) { |i| string << chars[rand(chars.size-1)] }
593
611
  string
594
612
  end
595
613
 
596
614
  def mime_value_quote(str)
597
- str.gsub(/(["\r\\])/){|s| '\\' + s}
615
+ str.b.gsub(/(["\r\\])/, '\\\\\1')
598
616
  end
599
617
 
600
- def param_to_multipart(name, value)
601
- return "Content-Disposition: form-data; name=\"" +
602
- "#{mime_value_quote(name)}\"\r\n" +
603
- "\r\n#{value}\r\n"
618
+ def param_to_multipart(name, value, buf = ::String.new)
619
+ buf <<
620
+ "Content-Disposition: form-data; name=\"".freeze <<
621
+ mime_value_quote(name) <<
622
+ "\"\r\n\r\n".freeze <<
623
+ value.b <<
624
+ CRLF
604
625
  end
605
626
 
606
- def file_to_multipart(file)
627
+ def file_to_multipart(file, buf = ::String.new)
607
628
  file_name = file.file_name ? ::File.basename(file.file_name) : ''
608
- body = "Content-Disposition: form-data; name=\"" +
609
- "#{mime_value_quote(file.name)}\"; " +
610
- "filename=\"#{mime_value_quote(file_name)}\"\r\n" +
611
- "Content-Transfer-Encoding: binary\r\n"
629
+
630
+ body = buf <<
631
+ "Content-Disposition: form-data; name=\"".freeze <<
632
+ mime_value_quote(file.name) <<
633
+ "\"; filename=\"".freeze <<
634
+ mime_value_quote(file_name) <<
635
+ "\"\r\nContent-Transfer-Encoding: binary\r\n".freeze
612
636
 
613
637
  if file.file_data.nil? and file.file_name
614
- file.file_data = open(file.file_name, "rb") { |f| f.read }
638
+ file.file_data = File.binread(file.file_name)
615
639
  file.mime_type =
616
640
  WEBrick::HTTPUtils.mime_type(file.file_name,
617
641
  WEBrick::HTTPUtils::DefaultMimeTypes)
618
642
  end
619
643
 
620
644
  if file.mime_type
621
- body << "Content-Type: #{file.mime_type}\r\n"
645
+ body << "Content-Type: ".freeze << file.mime_type << CRLF
622
646
  end
623
647
 
624
- body <<
625
- if file.file_data.respond_to? :read
626
- "\r\n#{file.file_data.read}\r\n"
648
+ body << CRLF
649
+
650
+ if file_data = file.file_data
651
+ if file_data.respond_to? :read
652
+ body << file_data.read.force_encoding(Encoding::ASCII_8BIT)
627
653
  else
628
- "\r\n#{file.file_data}\r\n"
654
+ body << file_data.b
629
655
  end
656
+ end
630
657
 
631
- body
658
+ body << CRLF
632
659
  end
633
660
  end
634
661
 
@@ -64,18 +64,18 @@ class Mechanize::Form::MultiSelectList < Mechanize::Form::Field
64
64
  # Select no options
65
65
  def select_none
66
66
  @value = []
67
- options.each { |o| o.untick }
67
+ options.each(&:untick)
68
68
  end
69
69
 
70
70
  # Select all options
71
71
  def select_all
72
72
  @value = []
73
- options.each { |o| o.tick }
73
+ options.each(&:tick)
74
74
  end
75
75
 
76
76
  # Get a list of all selected options
77
77
  def selected_options
78
- @options.find_all { |o| o.selected? }
78
+ @options.find_all(&:selected?)
79
79
  end
80
80
 
81
81
  def value=(values)
@@ -91,10 +91,7 @@ class Mechanize::Form::MultiSelectList < Mechanize::Form::Field
91
91
  end
92
92
 
93
93
  def value
94
- value = []
95
- value.concat @value
96
- value.concat selected_options.map { |o| o.value }
97
- value
94
+ @value + selected_options.map(&:value)
98
95
  end
99
96
 
100
97
  end
@@ -16,7 +16,7 @@ class Mechanize::History < Array
16
16
  end
17
17
 
18
18
  def inspect # :nodoc:
19
- uris = map { |page| page.uri }.join ', '
19
+ uris = map(&:uri).join ', '
20
20
 
21
21
  "[#{uris}]"
22
22
  end
@@ -71,7 +71,10 @@ class Mechanize::HTTP::Agent
71
71
 
72
72
  # :section: Allowed error codes
73
73
 
74
- # List of error codes to handle without raising an exception.
74
+ # List of error codes (in String or Integer) to handle without
75
+ # raising Mechanize::ResponseCodeError, defaulted to an empty array.
76
+ # Note that 2xx, 3xx and 401 status codes will be handled without
77
+ # checking this list.
75
78
 
76
79
  attr_accessor :allowed_error_codes
77
80
 
@@ -80,6 +83,9 @@ class Mechanize::HTTP::Agent
80
83
  # When true, this agent will consult the site's robots.txt for each access.
81
84
  attr_reader :robots
82
85
 
86
+ # Mutex used when fetching robots.txt
87
+ attr_reader :robots_mutex
88
+
83
89
  # :section: SSL
84
90
 
85
91
  # OpenSSL key password
@@ -148,6 +154,7 @@ class Mechanize::HTTP::Agent
148
154
  @redirection_limit = 20
149
155
  @request_headers = {}
150
156
  @robots = false
157
+ @robots_mutex = Mutex.new
151
158
  @user_agent = nil
152
159
  @webrobots = nil
153
160
 
@@ -988,11 +995,26 @@ class Mechanize::HTTP::Agent
988
995
 
989
996
  # :section: Robots
990
997
 
998
+ RobotsKey = :__mechanize_get_robots__
999
+
991
1000
  def get_robots(uri) # :nodoc:
992
- fetch(uri).body
993
- rescue Mechanize::ResponseCodeError => e
994
- return '' if e.response_code == '404'
995
- raise e
1001
+ robots_mutex.synchronize do
1002
+ Thread.current[RobotsKey] = true
1003
+ begin
1004
+ fetch(uri).body
1005
+ rescue Mechanize::ResponseCodeError => e
1006
+ case e.response_code
1007
+ when /\A4\d\d\z/
1008
+ ''
1009
+ else
1010
+ raise e
1011
+ end
1012
+ rescue Mechanize::RedirectLimitReachedError
1013
+ ''
1014
+ ensure
1015
+ Thread.current[RobotsKey] = false
1016
+ end
1017
+ end
996
1018
  end
997
1019
 
998
1020
  def robots= value
@@ -1006,7 +1028,7 @@ class Mechanize::HTTP::Agent
1006
1028
  # robots.txt.
1007
1029
 
1008
1030
  def robots_allowed? uri
1009
- return true if uri.request_uri == '/robots.txt'
1031
+ return true if Thread.current[RobotsKey]
1010
1032
 
1011
1033
  webrobots.allowed? uri
1012
1034
  end
@@ -7,7 +7,7 @@ class Mechanize::HTTP::AuthRealm
7
7
  def initialize scheme, uri, realm
8
8
  @scheme = scheme
9
9
  @uri = uri
10
- @realm = realm.downcase if realm
10
+ @realm = realm if realm
11
11
  end
12
12
 
13
13
  def == other
@@ -1,4 +1,4 @@
1
- # A Frame object wrapse a frame HTML element. Frame objects can be treated
1
+ # A Frame object wraps a frame HTML element. Frame objects can be treated
2
2
  # just like Link objects. They contain #src, the #link they refer to and a
3
3
  # #name, the name of the frame they refer to. #src and #name are aliased to
4
4
  # #href and #text respectively so that a Frame object can be treated just like
@@ -0,0 +1,14 @@
1
+ class RobotsTxtServlet < WEBrick::HTTPServlet::AbstractServlet
2
+ def do_GET(req, res)
3
+ if /301/ === req['Host'] && req.path == '/robots.txt'
4
+ res['Location'] = 'http://301/robots_txt'
5
+ res.code = 301
6
+ else
7
+ res['Content-Type'] = 'text/plain'
8
+ res.body = <<-'EOF'
9
+ User-Agent: *
10
+ Disallow: /norobots
11
+ EOF
12
+ end
13
+ end
14
+ end
@@ -21,6 +21,7 @@ require 'mechanize/test_case/referer_servlet'
21
21
  require 'mechanize/test_case/refresh_with_empty_url'
22
22
  require 'mechanize/test_case/refresh_without_url'
23
23
  require 'mechanize/test_case/response_code_servlet'
24
+ require 'mechanize/test_case/robots_txt_servlet'
24
25
  require 'mechanize/test_case/send_cookies_servlet'
25
26
  require 'mechanize/test_case/verb_servlet'
26
27
 
@@ -49,6 +50,8 @@ MECHANIZE_TEST_CASE_SERVLETS = {
49
50
  '/refresh_with_empty_url' => RefreshWithEmptyUrl,
50
51
  '/refresh_without_url' => RefreshWithoutUrl,
51
52
  '/response_code' => ResponseCodeServlet,
53
+ '/robots.txt' => RobotsTxtServlet,
54
+ '/robots_txt' => RobotsTxtServlet,
52
55
  '/send_cookies' => SendCookiesServlet,
53
56
  '/verb' => VerbServlet,
54
57
  }
@@ -11,7 +11,7 @@ class Mechanize::UnauthorizedError < Mechanize::ResponseCodeError
11
11
  out = super
12
12
 
13
13
  if @challenges then
14
- realms = @challenges.map { |challenge| challenge.realm_name }.join ', '
14
+ realms = @challenges.map(&:realm_name).join ', '
15
15
  out << " -- available realms: #{realms}"
16
16
  end
17
17
 
@@ -102,10 +102,11 @@ class Mechanize::Util
102
102
  case NKF::BINARY
103
103
  when Encoding
104
104
  def self.guess_encoding(src)
105
- NKF.guess(src)
105
+ # NKF.guess of JRuby may return nil
106
+ NKF.guess(src) || Encoding::US_ASCII
106
107
  end
107
108
  else
108
- # Old NKF from 1.8, still bundled with JRuby and Rubinius
109
+ # Old NKF from 1.8, still bundled with Rubinius
109
110
  NKF_ENCODING_MAP = {
110
111
  NKF::UNKNOWN => Encoding::US_ASCII,
111
112
  NKF::BINARY => Encoding::ASCII_8BIT,
@@ -1,3 +1,3 @@
1
1
  class Mechanize
2
- VERSION = "2.7.4"
2
+ VERSION = "2.7.5"
3
3
  end
@@ -47,7 +47,11 @@ Gem::Specification.new do |spec|
47
47
 
48
48
  spec.add_runtime_dependency "net-http-digest_auth", [ ">= 1.1.1", "~> 1.1" ]
49
49
  spec.add_runtime_dependency "net-http-persistent", [ ">= 2.5.2", "~> 2.5" ]
50
- spec.add_runtime_dependency "mime-types", [ ">= 1.17.2", "< 3" ]
50
+ if RUBY_VERSION >= "2.0"
51
+ spec.add_runtime_dependency "mime-types", [ ">= 1.17.2" ]
52
+ else
53
+ spec.add_runtime_dependency "mime-types", [ ">= 1.17.2", "< 3" ]
54
+ end
51
55
  spec.add_runtime_dependency "http-cookie", [ "~> 1.0" ]
52
56
  spec.add_runtime_dependency "nokogiri", [ "~> 1.6" ]
53
57
  spec.add_runtime_dependency "ntlm-http", [ ">= 0.1.1", "~> 0.1" ]
@@ -92,7 +92,7 @@ class TestMechanize < Mechanize::TestCase
92
92
 
93
93
  assert_equal("http://localhost/form_test.html",
94
94
  @mech.history.last.uri.to_s)
95
- end
95
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
96
96
 
97
97
  def test_click_bogus_link_with_cookies
98
98
  @mech.cookie_jar = cookie_jar("a=b")
@@ -149,7 +149,7 @@ class TestMechanize < Mechanize::TestCase
149
149
 
150
150
  assert_equal("http://localhost/form_test.html",
151
151
  @mech.history.last.uri.to_s)
152
- end
152
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
153
153
 
154
154
  def test_click_link
155
155
  link = node 'a', 'href' => '/index.html'
@@ -374,6 +374,14 @@ but not <a href="/" rel="me nofollow">this</a>!
374
374
  end
375
375
  end
376
376
 
377
+ def test_get_auth
378
+ @mech.add_auth @uri, 'user', 'pass'
379
+
380
+ page = @mech.get @uri + '/basic_auth'
381
+
382
+ assert_equal 'You are authenticated', page.body
383
+ end
384
+
377
385
  def test_get_auth_bad
378
386
  @mech.add_auth(@uri, 'aaron', 'aaron')
379
387
 
@@ -392,6 +400,14 @@ but not <a href="/" rel="me nofollow">this</a>!
392
400
  assert_equal("401", e.response_code)
393
401
  end
394
402
 
403
+ def test_get_auth_realm
404
+ @mech.add_auth @uri, 'user', 'pass', 'Blah'
405
+
406
+ page = @mech.get @uri + '/basic_auth'
407
+
408
+ assert_equal 'You are authenticated', page.body
409
+ end
410
+
395
411
  def test_get_conditional
396
412
  assert_empty @mech.history
397
413
 
@@ -927,7 +943,26 @@ but not <a href="/" rel="me nofollow">this</a>!
927
943
  "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"",
928
944
  page.body
929
945
  )
930
- assert page.body.length > File.read(__FILE__).length
946
+ assert_send [page.body.bytesize, :>, File.size(__FILE__)]
947
+ end
948
+
949
+ def test_post_file_upload_nonascii
950
+ name = 'ユーザファイル1'
951
+ file_upload = Mechanize::Form::FileUpload.new({'name' => 'userfile1'}, name)
952
+ file_upload.file_data = File.read(__FILE__)
953
+ file_upload.mime_type = 'application/zip'
954
+
955
+ page = @mech.post('http://localhost/file_upload', {
956
+ :name => 'Some file',
957
+ :userfile1 => file_upload
958
+ })
959
+
960
+ assert_match(
961
+ "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"".force_encoding(Encoding::ASCII_8BIT),
962
+ page.body
963
+ )
964
+ assert_match("Content-Type: application/zip", page.body)
965
+ assert_send [page.body.bytesize, :>, File.size(__FILE__)]
931
966
  end
932
967
 
933
968
  def test_post_file_upload
@@ -946,7 +981,7 @@ but not <a href="/" rel="me nofollow">this</a>!
946
981
  page.body
947
982
  )
948
983
  assert_match("Content-Type: application/zip", page.body)
949
- assert page.body.length > File.read(__FILE__).length
984
+ assert_send [page.body.bytesize, :>, File.size(__FILE__)]
950
985
  end
951
986
 
952
987
  def test_post_redirect
@@ -1140,7 +1175,7 @@ but not <a href="/" rel="me nofollow">this</a>!
1140
1175
 
1141
1176
  page = @mech.submit(form)
1142
1177
 
1143
- contents = File.read __FILE__
1178
+ contents = File.binread __FILE__
1144
1179
  basename = File.basename __FILE__
1145
1180
 
1146
1181
  assert_match(
@@ -1160,7 +1195,7 @@ but not <a href="/" rel="me nofollow">this</a>!
1160
1195
 
1161
1196
  page = @mech.submit(form)
1162
1197
 
1163
- contents = File.read __FILE__
1198
+ contents = File.binread __FILE__
1164
1199
  basename = File.basename __FILE__
1165
1200
  assert_match(
1166
1201
  "Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"",
@@ -1604,6 +1604,17 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
1604
1604
  end
1605
1605
  end
1606
1606
 
1607
+ def test_robots_infinite_loop
1608
+ @agent.robots = true
1609
+ @agent.redirect_ok = true
1610
+
1611
+ assert_raises Mechanize::RobotsDisallowedError do
1612
+ @agent.fetch URI('http://301/norobots.html')
1613
+ end
1614
+
1615
+ @agent.fetch URI('http://301/robots.html')
1616
+ end
1617
+
1607
1618
  def test_set_proxy
1608
1619
  @agent.set_proxy 'www.example.com', 9001, 'joe', 'lol'
1609
1620
 
@@ -25,6 +25,14 @@ class TestMechanizeHttpAuthChallenge < Mechanize::TestCase
25
25
  assert_equal expected, @challenge.realm(@uri + '/foo')
26
26
  end
27
27
 
28
+ def test_realm_digest_case
29
+ challenge = @AC.new 'Digest', { 'realm' => 'R' }, 'Digest realm=R'
30
+
31
+ expected = @AR.new 'Digest', @uri, 'R'
32
+
33
+ assert_equal expected, challenge.realm(@uri + '/foo')
34
+ end
35
+
28
36
  def test_realm_unknown
29
37
  @challenge.scheme = 'Unknown'
30
38
 
@@ -39,6 +47,12 @@ class TestMechanizeHttpAuthChallenge < Mechanize::TestCase
39
47
  assert_equal 'r', @challenge.realm_name
40
48
  end
41
49
 
50
+ def test_realm_name_case
51
+ challenge = @AC.new 'Digest', { 'realm' => 'R' }, 'Digest realm=R'
52
+
53
+ assert_equal 'R', challenge.realm_name
54
+ end
55
+
42
56
  def test_realm_name_ntlm
43
57
  challenge = @AC.new 'Negotiate, NTLM'
44
58
 
@@ -14,7 +14,10 @@ class TestMechanizeHttpAuthRealm < Mechanize::TestCase
14
14
  assert_equal 'r', @realm.realm
15
15
 
16
16
  realm = @AR.new 'Digest', @uri, 'R'
17
- assert_equal 'r', realm.realm
17
+ refute_equal 'r', realm.realm
18
+
19
+ realm = @AR.new 'Digest', @uri, 'R'
20
+ assert_equal 'R', realm.realm
18
21
 
19
22
  realm = @AR.new 'Digest', @uri, nil
20
23
  assert_nil realm.realm
@@ -30,6 +33,9 @@ class TestMechanizeHttpAuthRealm < Mechanize::TestCase
30
33
  other = @AR.new 'Digest', URI('http://other.example/'), 'r'
31
34
  refute_equal @realm, other
32
35
 
36
+ other = @AR.new 'Digest', @uri, 'R'
37
+ refute_equal @realm, other
38
+
33
39
  other = @AR.new 'Digest', @uri, 's'
34
40
  refute_equal @realm, other
35
41
  end
@@ -57,6 +57,20 @@ class TestMechanizeHttpAuthStore < Mechanize::TestCase
57
57
  assert_equal expected, @store.auth_accounts
58
58
  end
59
59
 
60
+ def test_add_auth_realm_case
61
+ @store.add_auth @uri, 'user1', 'pass', 'realm'
62
+ @store.add_auth @uri, 'user2', 'pass', 'Realm'
63
+
64
+ expected = {
65
+ @uri => {
66
+ 'realm' => ['user1', 'pass', nil],
67
+ 'Realm' => ['user2', 'pass', nil],
68
+ }
69
+ }
70
+
71
+ assert_equal expected, @store.auth_accounts
72
+ end
73
+
60
74
  def test_add_auth_string
61
75
  @store.add_auth "#{@uri}/path", 'user', 'pass'
62
76
 
@@ -143,6 +157,14 @@ class TestMechanizeHttpAuthStore < Mechanize::TestCase
143
157
  assert_equal ['user1', 'pass', nil], @store.credentials_for(@uri, 'other')
144
158
  end
145
159
 
160
+ def test_credentials_for_realm_case
161
+ @store.add_auth @uri, 'user1', 'pass', 'realm'
162
+ @store.add_auth @uri, 'user2', 'pass', 'Realm'
163
+
164
+ assert_equal ['user1', 'pass', nil], @store.credentials_for(@uri, 'realm')
165
+ assert_equal ['user2', 'pass', nil], @store.credentials_for(@uri, 'Realm')
166
+ end
167
+
146
168
  def test_credentials_for_path
147
169
  @store.add_auth @uri, 'user', 'pass', 'realm'
148
170
 
@@ -183,6 +205,21 @@ class TestMechanizeHttpAuthStore < Mechanize::TestCase
183
205
  assert_equal expected, @store.auth_accounts
184
206
  end
185
207
 
208
+ def test_remove_auth_realm_case
209
+ @store.add_auth @uri, 'user1', 'pass', 'realm'
210
+ @store.add_auth @uri, 'user2', 'pass', 'Realm'
211
+
212
+ @store.remove_auth @uri, 'Realm'
213
+
214
+ expected = {
215
+ @uri => {
216
+ 'realm' => ['user1', 'pass', nil]
217
+ }
218
+ }
219
+
220
+ assert_equal expected, @store.auth_accounts
221
+ end
222
+
186
223
  def test_remove_auth_string
187
224
  @store.add_auth @uri, 'user1', 'pass'
188
225
 
@@ -109,6 +109,14 @@ class TestMechanizeHttpWwwAuthenticateParser < Mechanize::TestCase
109
109
  assert_equal expected, @parser.parse('Basic ReAlM=foo')
110
110
  end
111
111
 
112
+ def test_parse_realm_value_case
113
+ expected = [
114
+ challenge('Basic', { 'realm' => 'Foo' }, 'Basic realm=Foo'),
115
+ ]
116
+
117
+ assert_equal expected, @parser.parse('Basic realm=Foo')
118
+ end
119
+
112
120
  def test_parse_scheme_uppercase
113
121
  expected = [
114
122
  challenge('Basic', { 'realm' => 'foo' }, 'BaSiC realm=foo'),
@@ -10,7 +10,7 @@ class TestMechanizeLink < Mechanize::TestCase
10
10
  page = link.click
11
11
  assert_equal("http://localhost/form_test.html",
12
12
  @mech.history.last.uri.to_s)
13
- end
13
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
14
14
 
15
15
  def test_click_bang
16
16
  page = @mech.get("http://localhost/frame_test.html")
@@ -20,7 +20,7 @@ class TestMechanizeLink < Mechanize::TestCase
20
20
  page = link.click
21
21
  assert_equal("http://localhost/form_test.html",
22
22
  @mech.history.last.uri.to_s)
23
- end
23
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
24
24
 
25
25
  def test_click_base
26
26
  page = @mech.get("http://google.com/tc_base_link.html")
@@ -103,7 +103,7 @@ class TestMechanizeLink < Mechanize::TestCase
103
103
  page = page.link_with(:text => 'just the query string').click
104
104
  assert_equal('http://localhost/relative/tc_relative_links.html?a=b',
105
105
  page.uri.to_s)
106
- end
106
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse IFRAME
107
107
 
108
108
  def test_uri_weird
109
109
  doc = Nokogiri::HTML::Document.new
@@ -122,6 +122,6 @@ class TestMechanizeLink < Mechanize::TestCase
122
122
 
123
123
  assert_equal "/form_test.html", link.uri.to_s
124
124
  assert_equal "http://localhost/form_test.html", link.resolved_uri.to_s
125
- end
125
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
126
126
  end
127
127
 
@@ -123,7 +123,7 @@ class TestMechanizePage < Mechanize::TestCase
123
123
  assert_equal "frame4", page.iframes.first.name
124
124
  assert_equal "/file_upload.html", page.iframes.first.src
125
125
  assert_equal "File Upload Form", page.iframes.first.content.title
126
- end
126
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse IFRAME
127
127
 
128
128
  def test_image_with
129
129
  page = html_page <<-BODY
@@ -290,7 +290,7 @@ class TestMechanizePageLink < Mechanize::TestCase
290
290
  def test_links
291
291
  page = @mech.get("http://localhost/find_link.html")
292
292
  assert_equal(18, page.links.length)
293
- end
293
+ end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse FRAME outside of FRAMESET
294
294
 
295
295
  def test_links_with_bold
296
296
  page = @mech.get("http://localhost/tc_links.html")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mechanize
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.4
4
+ version: 2.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Hodel
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-12-31 00:00:00.000000000 Z
15
+ date: 2016-08-22 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: net-http-digest_auth
@@ -61,9 +61,6 @@ dependencies:
61
61
  - - ">="
62
62
  - !ruby/object:Gem::Version
63
63
  version: 1.17.2
64
- - - "<"
65
- - !ruby/object:Gem::Version
66
- version: '3'
67
64
  type: :runtime
68
65
  prerelease: false
69
66
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,9 +68,6 @@ dependencies:
71
68
  - - ">="
72
69
  - !ruby/object:Gem::Version
73
70
  version: 1.17.2
74
- - - "<"
75
- - !ruby/object:Gem::Version
76
- version: '3'
77
71
  - !ruby/object:Gem::Dependency
78
72
  name: http-cookie
79
73
  requirement: !ruby/object:Gem::Requirement
@@ -247,7 +241,6 @@ files:
247
241
  - GUIDE.rdoc
248
242
  - Gemfile
249
243
  - LICENSE.rdoc
250
- - Manifest.txt
251
244
  - README.rdoc
252
245
  - Rakefile
253
246
  - examples/flickr_upload.rb
@@ -336,6 +329,7 @@ files:
336
329
  - lib/mechanize/test_case/refresh_with_empty_url.rb
337
330
  - lib/mechanize/test_case/refresh_without_url.rb
338
331
  - lib/mechanize/test_case/response_code_servlet.rb
332
+ - lib/mechanize/test_case/robots_txt_servlet.rb
339
333
  - lib/mechanize/test_case/send_cookies_servlet.rb
340
334
  - lib/mechanize/test_case/server.rb
341
335
  - lib/mechanize/test_case/servlets.rb
@@ -378,7 +372,6 @@ files:
378
372
  - test/htdocs/rails_3_encoding_hack_form_test.html
379
373
  - test/htdocs/relative/tc_relative_links.html
380
374
  - test/htdocs/robots.html
381
- - test/htdocs/robots.txt
382
375
  - test/htdocs/tc_bad_charset.html
383
376
  - test/htdocs/tc_bad_links.html
384
377
  - test/htdocs/tc_base_link.html
@@ -469,7 +462,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
469
462
  version: '0'
470
463
  requirements: []
471
464
  rubyforge_project:
472
- rubygems_version: 2.4.6
465
+ rubygems_version: 2.5.1
473
466
  signing_key:
474
467
  specification_version: 4
475
468
  summary: The Mechanize library is used for automating interaction with websites
@@ -506,7 +499,6 @@ test_files:
506
499
  - test/htdocs/rails_3_encoding_hack_form_test.html
507
500
  - test/htdocs/relative/tc_relative_links.html
508
501
  - test/htdocs/robots.html
509
- - test/htdocs/robots.txt
510
502
  - test/htdocs/tc_bad_charset.html
511
503
  - test/htdocs/tc_bad_links.html
512
504
  - test/htdocs/tc_base_link.html
@@ -575,4 +567,3 @@ test_files:
575
567
  - test/test_mechanize_util.rb
576
568
  - test/test_mechanize_xml_file.rb
577
569
  - test/test_multi_select.rb
578
- has_rdoc:
@@ -1,204 +0,0 @@
1
- .autotest
2
- .travis.yml
3
- CHANGELOG.rdoc
4
- EXAMPLES.rdoc
5
- GUIDE.rdoc
6
- LICENSE.rdoc
7
- Manifest.txt
8
- README.rdoc
9
- Rakefile
10
- examples/flickr_upload.rb
11
- examples/mech-dump.rb
12
- examples/proxy_req.rb
13
- examples/rubyforge.rb
14
- examples/spider.rb
15
- examples/wikipedia_links_to_philosophy.rb
16
- lib/mechanize.rb
17
- lib/mechanize/chunked_termination_error.rb
18
- lib/mechanize/content_type_error.rb
19
- lib/mechanize/cookie.rb
20
- lib/mechanize/cookie_jar.rb
21
- lib/mechanize/directory_saver.rb
22
- lib/mechanize/download.rb
23
- lib/mechanize/element_matcher.rb
24
- lib/mechanize/element_not_found_error.rb
25
- lib/mechanize/file.rb
26
- lib/mechanize/file_connection.rb
27
- lib/mechanize/file_request.rb
28
- lib/mechanize/file_response.rb
29
- lib/mechanize/file_saver.rb
30
- lib/mechanize/form.rb
31
- lib/mechanize/form/button.rb
32
- lib/mechanize/form/check_box.rb
33
- lib/mechanize/form/field.rb
34
- lib/mechanize/form/file_upload.rb
35
- lib/mechanize/form/hidden.rb
36
- lib/mechanize/form/image_button.rb
37
- lib/mechanize/form/keygen.rb
38
- lib/mechanize/form/multi_select_list.rb
39
- lib/mechanize/form/option.rb
40
- lib/mechanize/form/radio_button.rb
41
- lib/mechanize/form/reset.rb
42
- lib/mechanize/form/select_list.rb
43
- lib/mechanize/form/submit.rb
44
- lib/mechanize/form/text.rb
45
- lib/mechanize/form/textarea.rb
46
- lib/mechanize/headers.rb
47
- lib/mechanize/history.rb
48
- lib/mechanize/http.rb
49
- lib/mechanize/http/agent.rb
50
- lib/mechanize/http/auth_challenge.rb
51
- lib/mechanize/http/auth_realm.rb
52
- lib/mechanize/http/auth_store.rb
53
- lib/mechanize/http/content_disposition_parser.rb
54
- lib/mechanize/http/www_authenticate_parser.rb
55
- lib/mechanize/image.rb
56
- lib/mechanize/page.rb
57
- lib/mechanize/page/base.rb
58
- lib/mechanize/page/frame.rb
59
- lib/mechanize/page/image.rb
60
- lib/mechanize/page/label.rb
61
- lib/mechanize/page/link.rb
62
- lib/mechanize/page/meta_refresh.rb
63
- lib/mechanize/parser.rb
64
- lib/mechanize/pluggable_parsers.rb
65
- lib/mechanize/prependable.rb
66
- lib/mechanize/redirect_limit_reached_error.rb
67
- lib/mechanize/redirect_not_get_or_head_error.rb
68
- lib/mechanize/response_code_error.rb
69
- lib/mechanize/response_read_error.rb
70
- lib/mechanize/robots_disallowed_error.rb
71
- lib/mechanize/test_case.rb
72
- lib/mechanize/test_case/.document
73
- lib/mechanize/test_case/bad_chunking_servlet.rb
74
- lib/mechanize/test_case/basic_auth_servlet.rb
75
- lib/mechanize/test_case/content_type_servlet.rb
76
- lib/mechanize/test_case/digest_auth_servlet.rb
77
- lib/mechanize/test_case/file_upload_servlet.rb
78
- lib/mechanize/test_case/form_servlet.rb
79
- lib/mechanize/test_case/gzip_servlet.rb
80
- lib/mechanize/test_case/header_servlet.rb
81
- lib/mechanize/test_case/http_refresh_servlet.rb
82
- lib/mechanize/test_case/infinite_redirect_servlet.rb
83
- lib/mechanize/test_case/infinite_refresh_servlet.rb
84
- lib/mechanize/test_case/many_cookies_as_string_servlet.rb
85
- lib/mechanize/test_case/many_cookies_servlet.rb
86
- lib/mechanize/test_case/modified_since_servlet.rb
87
- lib/mechanize/test_case/ntlm_servlet.rb
88
- lib/mechanize/test_case/one_cookie_no_spaces_servlet.rb
89
- lib/mechanize/test_case/one_cookie_servlet.rb
90
- lib/mechanize/test_case/quoted_value_cookie_servlet.rb
91
- lib/mechanize/test_case/redirect_servlet.rb
92
- lib/mechanize/test_case/referer_servlet.rb
93
- lib/mechanize/test_case/refresh_with_empty_url.rb
94
- lib/mechanize/test_case/refresh_without_url.rb
95
- lib/mechanize/test_case/response_code_servlet.rb
96
- lib/mechanize/test_case/send_cookies_servlet.rb
97
- lib/mechanize/test_case/server.rb
98
- lib/mechanize/test_case/servlets.rb
99
- lib/mechanize/test_case/verb_servlet.rb
100
- lib/mechanize/unauthorized_error.rb
101
- lib/mechanize/unsupported_scheme_error.rb
102
- lib/mechanize/util.rb
103
- lib/mechanize/xml_file.rb
104
- test/data/htpasswd
105
- test/data/server.crt
106
- test/data/server.csr
107
- test/data/server.key
108
- test/data/server.pem
109
- test/htdocs/alt_text.html
110
- test/htdocs/bad_form_test.html
111
- test/htdocs/button.jpg
112
- test/htdocs/canonical_uri.html
113
- test/htdocs/dir with spaces/foo.html
114
- test/htdocs/empty_form.html
115
- test/htdocs/file_upload.html
116
- test/htdocs/find_link.html
117
- test/htdocs/form_multi_select.html
118
- test/htdocs/form_multival.html
119
- test/htdocs/form_no_action.html
120
- test/htdocs/form_no_input_name.html
121
- test/htdocs/form_order_test.html
122
- test/htdocs/form_select.html
123
- test/htdocs/form_set_fields.html
124
- test/htdocs/form_test.html
125
- test/htdocs/frame_referer_test.html
126
- test/htdocs/frame_test.html
127
- test/htdocs/google.html
128
- test/htdocs/index.html
129
- test/htdocs/link with space.html
130
- test/htdocs/meta_cookie.html
131
- test/htdocs/no_title_test.html
132
- test/htdocs/noindex.html
133
- test/htdocs/rails_3_encoding_hack_form_test.html
134
- test/htdocs/relative/tc_relative_links.html
135
- test/htdocs/robots.html
136
- test/htdocs/robots.txt
137
- test/htdocs/tc_bad_charset.html
138
- test/htdocs/tc_bad_links.html
139
- test/htdocs/tc_base_link.html
140
- test/htdocs/tc_blank_form.html
141
- test/htdocs/tc_charset.html
142
- test/htdocs/tc_checkboxes.html
143
- test/htdocs/tc_encoded_links.html
144
- test/htdocs/tc_field_precedence.html
145
- test/htdocs/tc_follow_meta.html
146
- test/htdocs/tc_follow_meta_loop_1.html
147
- test/htdocs/tc_follow_meta_loop_2.html
148
- test/htdocs/tc_form_action.html
149
- test/htdocs/tc_links.html
150
- test/htdocs/tc_meta_in_body.html
151
- test/htdocs/tc_pretty_print.html
152
- test/htdocs/tc_referer.html
153
- test/htdocs/tc_relative_links.html
154
- test/htdocs/tc_textarea.html
155
- test/htdocs/test_click.html
156
- test/htdocs/unusual______.html
157
- test/test_mechanize.rb
158
- test/test_mechanize_cookie.rb
159
- test/test_mechanize_cookie_jar.rb
160
- test/test_mechanize_directory_saver.rb
161
- test/test_mechanize_download.rb
162
- test/test_mechanize_element_not_found_error.rb
163
- test/test_mechanize_file.rb
164
- test/test_mechanize_file_connection.rb
165
- test/test_mechanize_file_request.rb
166
- test/test_mechanize_file_response.rb
167
- test/test_mechanize_file_saver.rb
168
- test/test_mechanize_form.rb
169
- test/test_mechanize_form_check_box.rb
170
- test/test_mechanize_form_encoding.rb
171
- test/test_mechanize_form_field.rb
172
- test/test_mechanize_form_file_upload.rb
173
- test/test_mechanize_form_image_button.rb
174
- test/test_mechanize_form_keygen.rb
175
- test/test_mechanize_form_multi_select_list.rb
176
- test/test_mechanize_form_option.rb
177
- test/test_mechanize_form_radio_button.rb
178
- test/test_mechanize_form_select_list.rb
179
- test/test_mechanize_form_textarea.rb
180
- test/test_mechanize_headers.rb
181
- test/test_mechanize_history.rb
182
- test/test_mechanize_http_agent.rb
183
- test/test_mechanize_http_auth_challenge.rb
184
- test/test_mechanize_http_auth_realm.rb
185
- test/test_mechanize_http_auth_store.rb
186
- test/test_mechanize_http_content_disposition_parser.rb
187
- test/test_mechanize_http_www_authenticate_parser.rb
188
- test/test_mechanize_image.rb
189
- test/test_mechanize_link.rb
190
- test/test_mechanize_page.rb
191
- test/test_mechanize_page_encoding.rb
192
- test/test_mechanize_page_frame.rb
193
- test/test_mechanize_page_image.rb
194
- test/test_mechanize_page_link.rb
195
- test/test_mechanize_page_meta_refresh.rb
196
- test/test_mechanize_parser.rb
197
- test/test_mechanize_pluggable_parser.rb
198
- test/test_mechanize_redirect_limit_reached_error.rb
199
- test/test_mechanize_redirect_not_get_or_head_error.rb
200
- test/test_mechanize_response_read_error.rb
201
- test/test_mechanize_subclass.rb
202
- test/test_mechanize_util.rb
203
- test/test_mechanize_xml_file.rb
204
- test/test_multi_select.rb
@@ -1,2 +0,0 @@
1
- User-Agent: *
2
- Disallow: /norobots