mechanize 2.7.7 → 2.8.3

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.

Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/ci-test.yml +36 -8
  4. data/.yardopts +8 -0
  5. data/{CHANGELOG.rdoc → CHANGELOG.md} +117 -88
  6. data/Gemfile +1 -6
  7. data/{LICENSE.rdoc → LICENSE.txt} +4 -0
  8. data/README.md +77 -0
  9. data/Rakefile +18 -3
  10. data/lib/mechanize/chunked_termination_error.rb +1 -0
  11. data/lib/mechanize/content_type_error.rb +1 -0
  12. data/lib/mechanize/cookie.rb +1 -13
  13. data/lib/mechanize/cookie_jar.rb +2 -10
  14. data/lib/mechanize/directory_saver.rb +1 -0
  15. data/lib/mechanize/download.rb +1 -0
  16. data/lib/mechanize/element_matcher.rb +1 -0
  17. data/lib/mechanize/element_not_found_error.rb +1 -0
  18. data/lib/mechanize/file.rb +1 -0
  19. data/lib/mechanize/file_connection.rb +5 -3
  20. data/lib/mechanize/file_request.rb +1 -0
  21. data/lib/mechanize/file_response.rb +3 -0
  22. data/lib/mechanize/file_saver.rb +1 -0
  23. data/lib/mechanize/form/button.rb +1 -0
  24. data/lib/mechanize/form/check_box.rb +1 -0
  25. data/lib/mechanize/form/field.rb +1 -0
  26. data/lib/mechanize/form/file_upload.rb +1 -0
  27. data/lib/mechanize/form/hidden.rb +1 -0
  28. data/lib/mechanize/form/image_button.rb +1 -0
  29. data/lib/mechanize/form/keygen.rb +1 -0
  30. data/lib/mechanize/form/multi_select_list.rb +1 -0
  31. data/lib/mechanize/form/option.rb +1 -0
  32. data/lib/mechanize/form/radio_button.rb +1 -0
  33. data/lib/mechanize/form/reset.rb +1 -0
  34. data/lib/mechanize/form/select_list.rb +1 -0
  35. data/lib/mechanize/form/submit.rb +1 -0
  36. data/lib/mechanize/form/text.rb +1 -0
  37. data/lib/mechanize/form/textarea.rb +1 -0
  38. data/lib/mechanize/form.rb +1 -9
  39. data/lib/mechanize/headers.rb +1 -0
  40. data/lib/mechanize/history.rb +1 -0
  41. data/lib/mechanize/http/agent.rb +16 -8
  42. data/lib/mechanize/http/auth_challenge.rb +1 -0
  43. data/lib/mechanize/http/auth_realm.rb +1 -0
  44. data/lib/mechanize/http/auth_store.rb +1 -0
  45. data/lib/mechanize/http/content_disposition_parser.rb +14 -2
  46. data/lib/mechanize/http/www_authenticate_parser.rb +3 -3
  47. data/lib/mechanize/http.rb +1 -0
  48. data/lib/mechanize/image.rb +1 -0
  49. data/lib/mechanize/page/base.rb +1 -0
  50. data/lib/mechanize/page/frame.rb +1 -0
  51. data/lib/mechanize/page/image.rb +1 -0
  52. data/lib/mechanize/page/label.rb +1 -0
  53. data/lib/mechanize/page/link.rb +8 -1
  54. data/lib/mechanize/page/meta_refresh.rb +1 -0
  55. data/lib/mechanize/page.rb +4 -3
  56. data/lib/mechanize/parser.rb +1 -0
  57. data/lib/mechanize/pluggable_parsers.rb +1 -0
  58. data/lib/mechanize/prependable.rb +1 -0
  59. data/lib/mechanize/redirect_limit_reached_error.rb +1 -0
  60. data/lib/mechanize/redirect_not_get_or_head_error.rb +1 -0
  61. data/lib/mechanize/response_code_error.rb +2 -1
  62. data/lib/mechanize/response_read_error.rb +1 -0
  63. data/lib/mechanize/robots_disallowed_error.rb +1 -0
  64. data/lib/mechanize/test_case/bad_chunking_servlet.rb +1 -0
  65. data/lib/mechanize/test_case/basic_auth_servlet.rb +1 -0
  66. data/lib/mechanize/test_case/content_type_servlet.rb +1 -0
  67. data/lib/mechanize/test_case/digest_auth_servlet.rb +1 -0
  68. data/lib/mechanize/test_case/file_upload_servlet.rb +1 -0
  69. data/lib/mechanize/test_case/form_servlet.rb +1 -0
  70. data/lib/mechanize/test_case/gzip_servlet.rb +1 -0
  71. data/lib/mechanize/test_case/header_servlet.rb +1 -0
  72. data/lib/mechanize/test_case/http_refresh_servlet.rb +1 -0
  73. data/lib/mechanize/test_case/infinite_redirect_servlet.rb +1 -0
  74. data/lib/mechanize/test_case/infinite_refresh_servlet.rb +1 -0
  75. data/lib/mechanize/test_case/many_cookies_as_string_servlet.rb +1 -0
  76. data/lib/mechanize/test_case/many_cookies_servlet.rb +1 -0
  77. data/lib/mechanize/test_case/modified_since_servlet.rb +1 -0
  78. data/lib/mechanize/test_case/ntlm_servlet.rb +1 -0
  79. data/lib/mechanize/test_case/one_cookie_no_spaces_servlet.rb +1 -0
  80. data/lib/mechanize/test_case/one_cookie_servlet.rb +1 -0
  81. data/lib/mechanize/test_case/quoted_value_cookie_servlet.rb +1 -0
  82. data/lib/mechanize/test_case/redirect_servlet.rb +1 -0
  83. data/lib/mechanize/test_case/referer_servlet.rb +1 -0
  84. data/lib/mechanize/test_case/refresh_with_empty_url.rb +1 -0
  85. data/lib/mechanize/test_case/refresh_without_url.rb +1 -0
  86. data/lib/mechanize/test_case/response_code_servlet.rb +1 -0
  87. data/lib/mechanize/test_case/robots_txt_servlet.rb +1 -0
  88. data/lib/mechanize/test_case/send_cookies_servlet.rb +1 -0
  89. data/lib/mechanize/test_case/server.rb +1 -0
  90. data/lib/mechanize/test_case/servlets.rb +1 -0
  91. data/lib/mechanize/test_case/verb_servlet.rb +1 -0
  92. data/lib/mechanize/test_case.rb +32 -27
  93. data/lib/mechanize/unauthorized_error.rb +1 -0
  94. data/lib/mechanize/unsupported_scheme_error.rb +1 -0
  95. data/lib/mechanize/util.rb +2 -1
  96. data/lib/mechanize/version.rb +2 -1
  97. data/lib/mechanize/xml_file.rb +1 -0
  98. data/lib/mechanize.rb +2 -1
  99. data/mechanize.gemspec +48 -34
  100. data/test/htdocs/dir with spaces/foo.html +1 -0
  101. data/test/test_mechanize.rb +5 -4
  102. data/test/test_mechanize_cookie_jar.rb +2 -0
  103. data/test/test_mechanize_download.rb +1 -0
  104. data/test/test_mechanize_file.rb +1 -0
  105. data/test/test_mechanize_file_connection.rb +21 -3
  106. data/test/test_mechanize_file_response.rb +6 -0
  107. data/test/test_mechanize_http_agent.rb +47 -7
  108. data/test/test_mechanize_http_content_disposition_parser.rb +27 -0
  109. data/test/test_mechanize_link.rb +24 -0
  110. data/test/test_mechanize_page_encoding.rb +28 -1
  111. metadata +145 -56
  112. data/README.rdoc +0 -77
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Mechanize
2
+
3
+ * https://www.rubydoc.info/gems/mechanize/
4
+ * https://github.com/sparklemotion/mechanize
5
+
6
+ [![Test suite](https://github.com/sparklemotion/mechanize/actions/workflows/ci-test.yml/badge.svg)](https://github.com/sparklemotion/mechanize/actions/workflows/ci-test.yml)
7
+
8
+
9
+ ## Description
10
+
11
+ The Mechanize library is used for automating interaction with websites. Mechanize automatically stores and sends cookies, follows redirects, and can follow links and submit forms. Form fields can be populated and submitted. Mechanize also keeps track of the sites that you have visited as a history.
12
+
13
+
14
+ ## Dependencies
15
+
16
+ * Ruby >= 2.5
17
+ * Gems:
18
+ * `addressable`
19
+ * `domain_name`
20
+ * `http-cookie`
21
+ * `mime-types`
22
+ * `net-http-digest_auth`
23
+ * `net-http-persistent`
24
+ * `nokogiri`
25
+ * `rubyntlm`
26
+ * `webrick`
27
+ * `webrobots`
28
+
29
+
30
+ ## Support:
31
+
32
+ The bug tracker is available here:
33
+
34
+ * https://github.com/sparklemotion/mechanize/issues
35
+
36
+
37
+ ## Examples
38
+
39
+ If you are just starting, check out [GUIDE.rdoc](https://github.com/sparklemotion/mechanize/blob/main/GUIDE.rdoc) or [EXAMPLES.rdoc](https://github.com/sparklemotion/mechanize/blob/main/EXAMPLES.rdoc).
40
+
41
+
42
+ ## Developers
43
+
44
+ Use bundler to install dependencies:
45
+
46
+ ```
47
+ bundle install
48
+ ```
49
+
50
+ Run all tests with:
51
+
52
+ ```
53
+ bundle exec rake test
54
+ ```
55
+
56
+ See also Mechanize::TestCase to read about the built-in testing infrastructure.
57
+
58
+
59
+ ## Authors
60
+
61
+ * Eric Hodel
62
+ * Akinori MUSHA
63
+ * Aaron Patterson
64
+ * Lee Jarvis
65
+ * Mike Dalessio
66
+
67
+
68
+ ## Acknowledgments
69
+
70
+ This library was heavily influenced by its namesake in the Perl world. A big
71
+ thanks goes to [Andy Lester](http://petdance.com), the author of the original Perl module WWW::Mechanize which is available [here](http://search.cpan.org/dist/WWW-Mechanize/). Ruby Mechanize would not be around without you!
72
+
73
+ Thank you to Michael Neumann for starting the Ruby version. Thanks to everyone who's helped out in various ways. Finally, thank you to the people using this library!
74
+
75
+ ## License
76
+
77
+ This library is distributed under the MIT license. Please see [LICENSE.txt](https://github.com/sparklemotion/mechanize/blob/main/LICENSE.txt).
data/Rakefile CHANGED
@@ -23,9 +23,9 @@ task('ssl_cert') do |p|
23
23
  end
24
24
 
25
25
  RDoc::Task.new do |rdoc|
26
- rdoc.main = "README.rdoc"
26
+ rdoc.main = "README.md"
27
27
  rdoc.rdoc_dir = 'doc'
28
- rdoc.rdoc_files.include( "CHANGELOG.rdoc", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.rdoc", "README.rdoc", "lib/**/*.rb")
28
+ rdoc.rdoc_files.include( "CHANGELOG.md", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.txt", "README.md", "lib/**/*.rb")
29
29
  end
30
30
 
31
31
  desc "Run tests"
@@ -38,4 +38,19 @@ task publish_docs: %w[rdoc] do
38
38
  sh 'rsync', '-avzO', '--delete', 'doc/', 'docs-push.seattlerb.org:/data/www/docs.seattlerb.org/mechanize/'
39
39
  end
40
40
 
41
- task default: :test
41
+ desc "Run rubocop checks"
42
+ task :rubocop => ["rubocop:security", "rubocop:frozen_string_literals"]
43
+
44
+ namespace "rubocop" do
45
+ desc "Run rubocop security check"
46
+ task :security do
47
+ sh "rubocop lib --only Security"
48
+ end
49
+
50
+ desc "Run rubocop string literals check"
51
+ task :frozen_string_literals do
52
+ sh "rubocop lib --auto-correct-all --only Style/FrozenStringLiteralComment"
53
+ end
54
+ end
55
+
56
+ task default: [:rubocop, :test]
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Raised when Mechanize detects the chunked transfer-encoding may be
3
4
  # incorrectly terminated.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This error is raised when a pluggable parser tries to parse a content type
3
4
  # that it does not know how to handle. For example if Mechanize::Page were to
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  warn 'mechanize/cookie will be deprecated. Please migrate to the http-cookie APIs.' if $VERBOSE
2
3
 
3
4
  require 'http/cookie'
@@ -50,19 +51,6 @@ class Mechanize
50
51
 
51
52
  Cookie = ::HTTP::Cookie
52
53
 
53
- # Compatibility for Ruby 1.8/1.9
54
- unless Cookie.respond_to?(:prepend, true)
55
- require 'mechanize/prependable'
56
-
57
- class Cookie
58
- extend Prependable
59
-
60
- class << self
61
- extend Prependable
62
- end
63
- end
64
- end
65
-
66
54
  class Cookie
67
55
  prepend CookieIMethods
68
56
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  warn 'mechanize/cookie_jar will be deprecated. Please migrate to the http-cookie APIs.' if $VERBOSE
2
3
 
3
4
  require 'http/cookie_jar'
@@ -148,7 +149,7 @@ class Mechanize
148
149
  return super(input, opthash) if opthash[:format] != :yaml
149
150
 
150
151
  begin
151
- data = YAML.load(input)
152
+ data = YAML.load(input) # rubocop:disable Security/YAMLLoad
152
153
  rescue ArgumentError
153
154
  @logger.warn "unloadable YAML cookie data discarded" if @logger
154
155
  return self
@@ -175,15 +176,6 @@ class Mechanize
175
176
  end
176
177
  end
177
178
 
178
- # Compatibility for Ruby 1.8/1.9
179
- unless ::HTTP::CookieJar.respond_to?(:prepend, true)
180
- require 'mechanize/prependable'
181
-
182
- class ::HTTP::CookieJar
183
- extend Prependable
184
- end
185
- end
186
-
187
179
  class ::HTTP::CookieJar
188
180
  prepend CookieJarIMethods
189
181
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Unlike Mechanize::FileSaver, the directory saver places all downloaded files
3
4
  # in a single pre-specified directory.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Download is a pluggable parser for downloading files without loading them
3
4
  # into memory first. You may subclass this class to handle content types you
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Mechanize::ElementMatcher
2
3
 
3
4
  def elements_with singular, plural = "#{singular}s"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Raised when an an element was not found on the Page
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This is the base class for the Pluggable Parsers. If Mechanize cannot find
3
4
  # an appropriate class to use for the content type, this class will be used.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Wrapper to make a file URI work like an http URI
3
4
 
@@ -10,8 +11,9 @@ class Mechanize::FileConnection
10
11
  end
11
12
 
12
13
  def request uri, request
13
- yield Mechanize::FileResponse.new Mechanize::Util.uri_unescape uri.path
14
+ file_path = uri.select(:host, :path)
15
+ .select { |part| part && (part.length > 0) }
16
+ .join(":")
17
+ yield Mechanize::FileResponse.new(Mechanize::Util.uri_unescape(file_path))
14
18
  end
15
-
16
19
  end
17
-
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A wrapper for a file URI that makes a request that works like a
3
4
  # Net::HTTPRequest
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Fake response for dealing with file:/// requests
3
4
 
4
5
  class Mechanize::FileResponse
5
6
 
7
+ attr_reader :file_path
8
+
6
9
  def initialize(file_path)
7
10
  @file_path = file_path
8
11
  @uri = nil
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This is a pluggable parser that automatically saves every file it
3
4
  # encounters. Unlike Mechanize::DirectorySaver, the file saver saves the
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A Submit button in a Form
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a check box found in a Form. To activate the CheckBox
3
4
  # in the Form, set the checked method to true.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a field in a form. It handles the following input
3
4
  # tags found in a form:
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # This class represents a file upload field found in a form. To use this
2
3
  # class, set FileUpload#file_data= to the data of the file you want to upload
3
4
  # and FileUpload#mime_type= to the appropriate mime type of the file.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Hidden < Mechanize::Form::Field
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents an image button in a form. Use the x and y methods to
3
4
  # set the x and y positions for where the mouse "clicked".
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a keygen (public / private key generator) found in a
3
4
  # Form. The field will automatically generate a key pair and compute its own
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a select list where multiple values can be selected.
3
4
  # MultiSelectList#value= accepts an array, and those values are used as
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class contains an option found within SelectList. A SelectList can
3
4
  # have many Option classes associated with it. An option can be selected by
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class represents a radio button found in a Form. To activate the
3
4
  # RadioButton in the Form, set the checked method to true.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Reset < Mechanize::Form::Button
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # This class represents a select list or drop down box in a Form. Set the
2
3
  # value for the list by calling SelectList#value=. SelectList contains a list
3
4
  # of Option that were found. After finding the correct option, set the select
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Submit < Mechanize::Form::Button
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Text < Mechanize::Form::Field
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Form::Textarea < Mechanize::Form::Field
2
3
  end
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'mechanize/element_matcher'
2
3
 
3
4
  # This class encapsulates a form parsed out of an HTML page. Each type of
@@ -643,15 +644,6 @@ class Mechanize::Form
643
644
  end
644
645
  end
645
646
 
646
- unless ::String.method_defined?(:b)
647
- # Define String#b for Ruby < 2.0
648
- class ::String
649
- def b
650
- dup.force_encoding(Encoding::ASCII_8BIT)
651
- end
652
- end
653
- end
654
-
655
647
  def rand_string(len = 10)
656
648
  chars = ("a".."z").to_a + ("A".."Z").to_a
657
649
  string = ::String.new
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::Headers < Hash
2
3
  def [](key)
3
4
  super(key.downcase)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class manages history for your mechanize object.
3
4
 
@@ -1,6 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'tempfile'
2
3
  require 'net/ntlm'
3
- require 'kconv'
4
4
  require 'webrobots'
5
5
 
6
6
  ##
@@ -9,6 +9,9 @@ require 'webrobots'
9
9
 
10
10
  class Mechanize::HTTP::Agent
11
11
 
12
+ CREDENTIAL_HEADERS = ['Authorization', 'Cookie']
13
+ POST_HEADERS = ['Content-Length', 'Content-MD5', 'Content-Type']
14
+
12
15
  # :section: Headers
13
16
 
14
17
  # Disables If-Modified-Since conditional requests (enabled by default)
@@ -838,7 +841,7 @@ class Mechanize::HTTP::Agent
838
841
 
839
842
  out_io
840
843
  rescue Zlib::Error => e
841
- message = "error handling content-encoding #{response['Content-Encoding']}:"
844
+ message = String.new("error handling content-encoding #{response['Content-Encoding']}:")
842
845
  message << " #{e.message} (#{e.class})"
843
846
  raise Mechanize::Error, message
844
847
  ensure
@@ -986,14 +989,20 @@ class Mechanize::HTTP::Agent
986
989
 
987
990
  redirect_method = method == :head ? :head : :get
988
991
 
992
+ new_uri = secure_resolve!(response['Location'].to_s, page)
993
+ @history.push(page, page.uri)
994
+
989
995
  # Make sure we are not copying over the POST headers from the original request
990
- ['Content-Length', 'Content-MD5', 'Content-Type'].each do |key|
991
- headers.delete key
996
+ POST_HEADERS.each do |key|
997
+ headers.delete_if { |h| h.casecmp?(key) }
992
998
  end
993
999
 
994
- new_uri = secure_resolve! response['Location'].to_s, page
995
-
996
- @history.push(page, page.uri)
1000
+ # Make sure we clear credential headers if being redirected to another site
1001
+ if new_uri.host != page.uri.host
1002
+ CREDENTIAL_HEADERS.each do |ch|
1003
+ headers.delete_if { |h| h.casecmp?(ch) }
1004
+ end
1005
+ end
997
1006
 
998
1007
  fetch new_uri, redirect_method, headers, [], referer, redirects + 1
999
1008
  end
@@ -1278,4 +1287,3 @@ class Mechanize::HTTP::Agent
1278
1287
  end
1279
1288
 
1280
1289
  require 'mechanize/http/auth_store'
1281
-
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::HTTP
2
3
 
3
4
  AuthChallenge = Struct.new :scheme, :params, :raw
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::HTTP::AuthRealm
2
3
 
3
4
  attr_reader :scheme
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A credential store for HTTP authentication.
3
4
  #
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # coding: BINARY
2
3
 
3
4
  require 'strscan'
@@ -16,6 +17,7 @@ end
16
17
  # * Missing disposition-type
17
18
  # * Multiple semicolons
18
19
  # * Whitespace around semicolons
20
+ # * Dates in ISO 8601 format
19
21
 
20
22
  class Mechanize::HTTP::ContentDispositionParser
21
23
 
@@ -93,7 +95,17 @@ class Mechanize::HTTP::ContentDispositionParser
93
95
  when /^filename$/ then
94
96
  rfc_2045_value
95
97
  when /^(creation|modification|read)-date$/ then
96
- Time.rfc822 rfc_2045_quoted_string
98
+ date = rfc_2045_quoted_string
99
+
100
+ begin
101
+ Time.rfc822 date
102
+ rescue ArgumentError
103
+ begin
104
+ Time.iso8601 date
105
+ rescue ArgumentError
106
+ nil
107
+ end
108
+ end
97
109
  when /^size$/ then
98
110
  rfc_2045_value.to_i(10)
99
111
  else
@@ -125,7 +137,7 @@ class Mechanize::HTTP::ContentDispositionParser
125
137
  def rfc_2045_quoted_string
126
138
  return nil unless @scanner.scan(/"/)
127
139
 
128
- text = ''
140
+ text = String.new
129
141
 
130
142
  while true do
131
143
  chunk = @scanner.scan(/[\000-\014\016-\041\043-\133\135-\177]+/) # not \r "
@@ -1,4 +1,4 @@
1
- # coding: BINARY
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'strscan'
4
4
 
@@ -151,10 +151,10 @@ class Mechanize::HTTP::WWWAuthenticateParser
151
151
  def quoted_string
152
152
  return nil unless @scanner.scan(/"/)
153
153
 
154
- text = ''
154
+ text = String.new
155
155
 
156
156
  while true do
157
- chunk = @scanner.scan(/[\r\n \t\041\043-\176\200-\377]+/) # not "
157
+ chunk = @scanner.scan(/[\r\n \t\x21\x23-\x7e\u0080-\u00ff]+/) # not " which is \x22
158
158
 
159
159
  if chunk then
160
160
  text << chunk
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Mechanize::HTTP contains classes for communicated with HTTP servers. All
3
4
  # API under this namespace is considered private and is subject to change at
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # An Image holds downloaded data for an image/* response.
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A base element on an HTML page. Mechanize treats base tags just like 'a'
3
4
  # tags. Base objects will contain links, but most likely will have no text.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # A Frame object wraps a frame HTML element. Frame objects can be treated
2
3
  # just like Link objects. They contain #src, the #link they refer to and a
3
4
  # #name, the name of the frame they refer to. #src and #name are aliased to
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # An image element on an HTML page
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A form label on an HTML page
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class encapsulates links. It contains the text and the URI for
3
4
  # 'a' tags parsed out of an HTML page. If the link contains an image,
@@ -8,6 +9,8 @@
8
9
  # <a href="http://example">Hello World</a>
9
10
  # <a href="http://example"><img src="test.jpg" alt="Hello World"></a>
10
11
 
12
+ require 'addressable/uri'
13
+
11
14
  class Mechanize::Page::Link
12
15
  attr_reader :node
13
16
  attr_reader :href
@@ -94,7 +97,11 @@ class Mechanize::Page::Link
94
97
  begin
95
98
  URI.parse @href
96
99
  rescue URI::InvalidURIError
97
- URI.parse WEBrick::HTTPUtils.escape @href
100
+ begin
101
+ URI.parse(Addressable::URI.escape(@href))
102
+ rescue Addressable::URI::InvalidURIError
103
+ raise URI::InvalidURIError
104
+ end
98
105
  end
99
106
  end
100
107
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class encapsulates a meta element with a refresh http-equiv. Mechanize
3
4
  # treats meta refresh elements just like 'a' tags. MetaRefresh objects will
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class encapsulates an HTML page. If Mechanize finds a content
3
4
  # type of 'text/html', this class will be instantiated and returned.
@@ -103,9 +104,9 @@ class Mechanize::Page < Mechanize::File
103
104
  parser = self.parser unless parser
104
105
  return false if parser.errors.empty?
105
106
  parser.errors.any? do |error|
106
- error.message =~ /(indicate\ encoding)|
107
- (Invalid\ char)|
108
- (input\ conversion\ failed)/x
107
+ error.message.scrub =~ /(indicate\ encoding)|
108
+ (Invalid\ char)|
109
+ (input\ conversion\ failed)/x
109
110
  end
110
111
  end
111
112
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # The parser module provides standard methods for accessing the headers and
3
4
  # content of a response that are shared across pluggable parsers.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'mechanize/file'
2
3
  require 'mechanize/file_saver'
3
4
  require 'mechanize/page'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Fake implementation of prepend(), which does not support overriding
2
3
  # inherited methods nor methods that are formerly overridden by
3
4
  # another invocation of prepend().
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Raised when too many redirects are sent
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # Raised when a POST, PUT, or DELETE request results in a redirect
3
4
  # see RFC 2616 10.3.2, 10.3.3 http://www.ietf.org/rfc/rfc2616.txt
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # This error is raised when Mechanize encounters a response code it does not
2
3
  # know how to handle. Currently, this exception will be thrown if Mechanize
3
4
  # encounters response codes other than 200, 301, or 302. Any other response
@@ -16,7 +17,7 @@ class Mechanize::ResponseCodeError < Mechanize::Error
16
17
 
17
18
  def to_s
18
19
  response_class = Net::HTTPResponse::CODE_TO_OBJ[@response_code]
19
- out = "#{@response_code} => #{response_class} "
20
+ out = String.new("#{@response_code} => #{response_class} ")
20
21
  out << "for #{@page.uri} " if @page.respond_to? :uri # may be HTTPResponse
21
22
  out << "-- #{super}"
22
23
  end