mechanize 2.7.6 → 2.8.2

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 (119) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/ci-test.yml +53 -0
  4. data/.yardopts +8 -0
  5. data/{CHANGELOG.rdoc → CHANGELOG.md} +136 -87
  6. data/EXAMPLES.rdoc +1 -24
  7. data/Gemfile +1 -4
  8. data/{LICENSE.rdoc → LICENSE.txt} +4 -0
  9. data/README.md +77 -0
  10. data/Rakefile +18 -3
  11. data/examples/rubygems.rb +2 -2
  12. data/lib/mechanize.rb +3 -2
  13. data/lib/mechanize/chunked_termination_error.rb +1 -0
  14. data/lib/mechanize/content_type_error.rb +1 -0
  15. data/lib/mechanize/cookie.rb +1 -13
  16. data/lib/mechanize/cookie_jar.rb +4 -12
  17. data/lib/mechanize/directory_saver.rb +1 -0
  18. data/lib/mechanize/download.rb +2 -1
  19. data/lib/mechanize/element_matcher.rb +1 -0
  20. data/lib/mechanize/element_not_found_error.rb +1 -0
  21. data/lib/mechanize/file.rb +2 -1
  22. data/lib/mechanize/file_connection.rb +5 -3
  23. data/lib/mechanize/file_request.rb +1 -0
  24. data/lib/mechanize/file_response.rb +4 -1
  25. data/lib/mechanize/file_saver.rb +1 -0
  26. data/lib/mechanize/form.rb +2 -10
  27. data/lib/mechanize/form/button.rb +1 -0
  28. data/lib/mechanize/form/check_box.rb +1 -0
  29. data/lib/mechanize/form/field.rb +1 -0
  30. data/lib/mechanize/form/file_upload.rb +1 -0
  31. data/lib/mechanize/form/hidden.rb +1 -0
  32. data/lib/mechanize/form/image_button.rb +1 -0
  33. data/lib/mechanize/form/keygen.rb +1 -0
  34. data/lib/mechanize/form/multi_select_list.rb +1 -0
  35. data/lib/mechanize/form/option.rb +1 -0
  36. data/lib/mechanize/form/radio_button.rb +1 -0
  37. data/lib/mechanize/form/reset.rb +1 -0
  38. data/lib/mechanize/form/select_list.rb +1 -0
  39. data/lib/mechanize/form/submit.rb +1 -0
  40. data/lib/mechanize/form/text.rb +1 -0
  41. data/lib/mechanize/form/textarea.rb +1 -0
  42. data/lib/mechanize/headers.rb +1 -0
  43. data/lib/mechanize/history.rb +1 -0
  44. data/lib/mechanize/http.rb +1 -0
  45. data/lib/mechanize/http/agent.rb +16 -8
  46. data/lib/mechanize/http/auth_challenge.rb +1 -0
  47. data/lib/mechanize/http/auth_realm.rb +1 -0
  48. data/lib/mechanize/http/auth_store.rb +1 -0
  49. data/lib/mechanize/http/content_disposition_parser.rb +14 -2
  50. data/lib/mechanize/http/www_authenticate_parser.rb +3 -3
  51. data/lib/mechanize/image.rb +1 -0
  52. data/lib/mechanize/page.rb +4 -3
  53. data/lib/mechanize/page/base.rb +1 -0
  54. data/lib/mechanize/page/frame.rb +1 -0
  55. data/lib/mechanize/page/image.rb +1 -0
  56. data/lib/mechanize/page/label.rb +1 -0
  57. data/lib/mechanize/page/link.rb +8 -1
  58. data/lib/mechanize/page/meta_refresh.rb +1 -0
  59. data/lib/mechanize/parser.rb +1 -0
  60. data/lib/mechanize/pluggable_parsers.rb +1 -0
  61. data/lib/mechanize/prependable.rb +1 -0
  62. data/lib/mechanize/redirect_limit_reached_error.rb +1 -0
  63. data/lib/mechanize/redirect_not_get_or_head_error.rb +1 -0
  64. data/lib/mechanize/response_code_error.rb +2 -1
  65. data/lib/mechanize/response_read_error.rb +1 -0
  66. data/lib/mechanize/robots_disallowed_error.rb +1 -0
  67. data/lib/mechanize/test_case.rb +34 -29
  68. data/lib/mechanize/test_case/bad_chunking_servlet.rb +1 -0
  69. data/lib/mechanize/test_case/basic_auth_servlet.rb +1 -0
  70. data/lib/mechanize/test_case/content_type_servlet.rb +1 -0
  71. data/lib/mechanize/test_case/digest_auth_servlet.rb +1 -0
  72. data/lib/mechanize/test_case/file_upload_servlet.rb +1 -0
  73. data/lib/mechanize/test_case/form_servlet.rb +1 -0
  74. data/lib/mechanize/test_case/gzip_servlet.rb +4 -3
  75. data/lib/mechanize/test_case/header_servlet.rb +1 -0
  76. data/lib/mechanize/test_case/http_refresh_servlet.rb +1 -0
  77. data/lib/mechanize/test_case/infinite_redirect_servlet.rb +1 -0
  78. data/lib/mechanize/test_case/infinite_refresh_servlet.rb +1 -0
  79. data/lib/mechanize/test_case/many_cookies_as_string_servlet.rb +1 -0
  80. data/lib/mechanize/test_case/many_cookies_servlet.rb +1 -0
  81. data/lib/mechanize/test_case/modified_since_servlet.rb +1 -0
  82. data/lib/mechanize/test_case/ntlm_servlet.rb +1 -0
  83. data/lib/mechanize/test_case/one_cookie_no_spaces_servlet.rb +1 -0
  84. data/lib/mechanize/test_case/one_cookie_servlet.rb +1 -0
  85. data/lib/mechanize/test_case/quoted_value_cookie_servlet.rb +1 -0
  86. data/lib/mechanize/test_case/redirect_servlet.rb +1 -0
  87. data/lib/mechanize/test_case/referer_servlet.rb +1 -0
  88. data/lib/mechanize/test_case/refresh_with_empty_url.rb +1 -0
  89. data/lib/mechanize/test_case/refresh_without_url.rb +1 -0
  90. data/lib/mechanize/test_case/response_code_servlet.rb +1 -0
  91. data/lib/mechanize/test_case/robots_txt_servlet.rb +1 -0
  92. data/lib/mechanize/test_case/send_cookies_servlet.rb +1 -0
  93. data/lib/mechanize/test_case/server.rb +1 -0
  94. data/lib/mechanize/test_case/servlets.rb +1 -0
  95. data/lib/mechanize/test_case/verb_servlet.rb +5 -6
  96. data/lib/mechanize/unauthorized_error.rb +1 -0
  97. data/lib/mechanize/unsupported_scheme_error.rb +1 -0
  98. data/lib/mechanize/util.rb +2 -1
  99. data/lib/mechanize/version.rb +2 -1
  100. data/lib/mechanize/xml_file.rb +1 -0
  101. data/mechanize.gemspec +45 -35
  102. data/test/htdocs/dir with spaces/foo.html +1 -0
  103. data/test/htdocs/tc_links.html +1 -1
  104. data/test/test_mechanize.rb +19 -7
  105. data/test/test_mechanize_cookie.rb +19 -19
  106. data/test/test_mechanize_cookie_jar.rb +85 -53
  107. data/test/test_mechanize_download.rb +13 -1
  108. data/test/test_mechanize_file.rb +10 -0
  109. data/test/test_mechanize_file_connection.rb +21 -3
  110. data/test/test_mechanize_file_response.rb +25 -1
  111. data/test/test_mechanize_form.rb +12 -0
  112. data/test/test_mechanize_form_keygen.rb +1 -0
  113. data/test/test_mechanize_http_agent.rb +53 -8
  114. data/test/test_mechanize_http_content_disposition_parser.rb +27 -0
  115. data/test/test_mechanize_link.rb +24 -0
  116. data/test/test_mechanize_page_encoding.rb +28 -1
  117. metadata +117 -71
  118. data/.travis.yml +0 -36
  119. data/README.rdoc +0 -77
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class BadChunkingServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET req, res
3
4
  res.keep_alive = false if res.respond_to? :keep_alive=
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class BasicAuthServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req,res)
3
4
  htpd = nil
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class ContentTypeServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  ct = req.query['ct'] || "text/html; charset=utf-8"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'logger'
2
3
 
3
4
  class DigestAuthServlet < WEBrick::HTTPServlet::AbstractServlet
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class FileUploadServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_POST req, res
3
4
  res.body = req.body
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class FormServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res.content_type = 'text/html'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'stringio'
2
3
  require 'zlib'
3
4
 
@@ -13,8 +14,8 @@ class GzipServlet < WEBrick::HTTPServlet::AbstractServlet
13
14
  end
14
15
 
15
16
  if name = req.query['file'] then
16
- open "#{TEST_DIR}/htdocs/#{name}" do |io|
17
- string = ""
17
+ ::File.open("#{TEST_DIR}/htdocs/#{name}") do |io|
18
+ string = String.new
18
19
  zipped = StringIO.new string, 'w'
19
20
  Zlib::GzipWriter.wrap zipped do |gz|
20
21
  gz.write io.read
@@ -22,7 +23,7 @@ class GzipServlet < WEBrick::HTTPServlet::AbstractServlet
22
23
  res.body = string
23
24
  end
24
25
  else
25
- res.body = ''
26
+ res.body = String.new
26
27
  end
27
28
 
28
29
  res['Content-Encoding'] = req['X-ResponseContentEncoding'] || 'gzip'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class HeaderServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res.content_type = "text/plain"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class HttpRefreshServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res['Content-Type'] = req.query['ct'] || "text/html"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class InfiniteRedirectServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res['Content-Type'] = req.query['ct'] || "text/html"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class InfiniteRefreshServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  address = "#{req.host}:#{req.port}"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class ManyCookiesAsStringServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  cookies = []
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class ManyCookiesServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  name_cookie = WEBrick::Cookie.new("name", "Aaron")
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class ModifiedSinceServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  s_time = 'Fri, 04 May 2001 00:00:38 GMT'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class NTLMServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
 
3
4
  def do_GET(req, res)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class OneCookieNoSpacesServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  cookie = WEBrick::Cookie.new("foo", "bar")
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class OneCookieServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  cookie = WEBrick::Cookie.new("foo", "bar")
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class QuotedValueCookieServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  cookie = WEBrick::Cookie.new("quoted", "\"value\"")
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class RedirectServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res['Content-Type'] = req.query['ct'] || 'text/html'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class RefererServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res['Content-Type'] = "text/html"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class RefreshWithEmptyUrl < WEBrick::HTTPServlet::AbstractServlet
2
3
  @@count = 0
3
4
  def do_GET(req, res)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class RefreshWithoutUrl < WEBrick::HTTPServlet::AbstractServlet
2
3
  @@count = 0
3
4
  def do_GET(req, res)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class ResponseCodeServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res['Content-Type'] = req.query['ct'] || "text/html"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class RobotsTxtServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  if /301/ === req['Host'] && req.path == '/robots.txt'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class SendCookiesServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  def do_GET(req, res)
3
4
  res.content_type = 'text/html'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'webrick'
2
3
  require 'mechanize/test_case/servlets'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'mechanize/test_case/bad_chunking_servlet'
2
3
  require 'mechanize/test_case/basic_auth_servlet'
3
4
  require 'mechanize/test_case/content_type_servlet'
@@ -1,11 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  class VerbServlet < WEBrick::HTTPServlet::AbstractServlet
2
3
  %w[HEAD GET POST PUT DELETE].each do |verb|
3
- eval <<-METHOD
4
- def do_#{verb}(req, res)
5
- res.header['X-Request-Method'] = #{verb.dump}
6
- res.body = #{verb.dump}
7
- end
8
- METHOD
4
+ define_method "do_#{verb}" do |req, res|
5
+ res.header['X-Request-Method'] = verb
6
+ res.body = verb
7
+ end
9
8
  end
10
9
  end
11
10
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::UnauthorizedError < Mechanize::ResponseCodeError
2
3
 
3
4
  attr_reader :challenges
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::UnsupportedSchemeError < Mechanize::Error
2
3
  attr_accessor :scheme, :uri
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'cgi'
2
3
  require 'nkf'
3
4
 
@@ -15,7 +16,7 @@ class Mechanize::Util
15
16
  def build_query_string(parameters, enc = nil)
16
17
  each_parameter(parameters).inject(nil) { |s, (k, v)|
17
18
  # WEBrick::HTTP.escape* has some problems about m17n on ruby-1.9.*.
18
- (s.nil? ? '' : s << '&') << [CGI.escape(k.to_s), CGI.escape(v.to_s)].join('=')
19
+ (s.nil? ? String.new : s << '&') << [CGI.escape(k.to_s), CGI.escape(v.to_s)].join('=')
19
20
  } || ''
20
21
  end
21
22
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize
2
- VERSION = "2.7.6"
3
+ VERSION = "2.8.2"
3
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class encapsulates an XML file. If Mechanize finds a content-type
3
4
  # of 'text/xml' or 'application/xml' this class will be instantiated and
data/mechanize.gemspec CHANGED
@@ -1,20 +1,19 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'mechanize/version'
2
+ # frozen_string_literal: true
3
+ require_relative 'lib/mechanize/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "mechanize"
8
- spec.version = Mechanize::VERSION
9
- spec.homepage = "http://docs.seattlerb.org/mechanize/"
10
- spec.summary = %q{The Mechanize library is used for automating interaction with websites}
11
- spec.description =
6
+ spec.name = "mechanize"
7
+ spec.version = Mechanize::VERSION
8
+ spec.homepage = "https://github.com/sparklemotion/mechanize"
9
+ spec.summary = 'The Mechanize library is used for automating interaction with websites'
10
+ spec.description =
12
11
  [
13
12
  "The Mechanize library is used for automating interaction with websites.",
14
13
  "Mechanize automatically stores and sends cookies, follows redirects,",
15
14
  "and can follow links and submit forms. Form fields can be populated and",
16
15
  "submitted. Mechanize also keeps track of the sites that you have visited as",
17
- "a history."
16
+ "a history.",
18
17
  ].join("\n")
19
18
 
20
19
  spec.authors =
@@ -23,44 +22,55 @@ Gem::Specification.new do |spec|
23
22
  'Aaron Patterson',
24
23
  'Mike Dalessio',
25
24
  'Akinori MUSHA',
26
- 'Lee Jarvis'
25
+ 'Lee Jarvis',
27
26
  ]
28
27
  spec.email =
29
28
  [
30
29
  'drbrain@segment7.net',
31
- 'aaronp@rubyforge.org',
30
+ 'aaron.patterson@gmail.com',
32
31
  'mike.dalessio@gmail.com',
33
32
  'knu@idaemons.org',
34
- 'ljjarvis@gmail.com'
33
+ 'ljjarvis@gmail.com',
35
34
  ]
36
35
 
37
- spec.license = "MIT"
36
+ spec.metadata = {
37
+ 'yard.run' => 'yard',
38
+ 'bug_tracker_uri' => 'https://github.com/sparklemotion/mechanize/issues',
39
+ 'changelog_uri' => 'https://github.com/sparklemotion/mechanize/blob/main/CHANGELOG.md',
40
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/mechanize',
41
+ 'homepage_uri' => 'https://github.com/sparklemotion/mechanize',
42
+ 'source_code_uri' => 'https://github.com/sparklemotion/mechanize'
43
+ }
44
+
45
+ spec.license = "MIT"
38
46
 
39
47
  spec.require_paths = ["lib"]
40
- spec.files = `git ls-files`.split($/)
41
- spec.test_files = spec.files.grep(%r{^test/})
48
+ spec.files = %x(git ls-files).split($/)
49
+ spec.test_files = spec.files.grep(%r{^test/})
50
+
51
+ spec.extra_rdoc_files += Dir['*.rdoc', '*.md']
52
+ spec.rdoc_options = ["--main", "README.md"]
53
+
54
+ spec.required_ruby_version = ">= 2.5.0"
42
55
 
43
- spec.extra_rdoc_files += Dir['*.rdoc']
44
- spec.rdoc_options = ["--main", "README.rdoc"]
56
+ spec.add_runtime_dependency("addressable", "~> 2.8")
57
+ spec.add_runtime_dependency("domain_name", ">= 0.5.20190701", "~> 0.5")
58
+ spec.add_runtime_dependency("http-cookie", ">= 1.0.3", "~> 1.0")
59
+ spec.add_runtime_dependency("mime-types", "~> 3.0")
60
+ spec.add_runtime_dependency("net-http-digest_auth", ">= 1.4.1", "~> 1.4")
45
61
 
46
- spec.required_ruby_version = ">= 1.9.2"
62
+ # careful! some folks are relying on older versions of net-http-persistent
63
+ # - see the socks proxy patch in use at #507 and #464
64
+ # - see use of retry_change_requests that was removed at #558
65
+ spec.add_runtime_dependency("net-http-persistent", ">= 2.5.2", "< 5.0.dev")
47
66
 
48
- spec.add_runtime_dependency "net-http-digest_auth", [ ">= 1.1.1", "~> 1.1" ]
49
- if RUBY_VERSION >= "2.0"
50
- spec.add_runtime_dependency "mime-types", [ ">= 1.17.2" ]
51
- spec.add_runtime_dependency "net-http-persistent", [ ">= 2.5.2"]
52
- else
53
- spec.add_runtime_dependency "mime-types", [ ">= 1.17.2", "< 3" ]
54
- spec.add_runtime_dependency "net-http-persistent", [ ">= 2.5.2", "~> 2.5" ]
55
- end
56
- spec.add_runtime_dependency "http-cookie", [ "~> 1.0" ]
57
- spec.add_runtime_dependency "nokogiri", [ "~> 1.6" ]
58
- spec.add_runtime_dependency "ntlm-http", [ ">= 0.1.1", "~> 0.1" ]
59
- spec.add_runtime_dependency "webrobots", [ "< 0.2", ">= 0.0.9" ]
60
- spec.add_runtime_dependency "domain_name", [ ">= 0.5.1", "~> 0.5" ]
67
+ spec.add_runtime_dependency("nokogiri", ">= 1.11.2", "~> 1.11")
68
+ spec.add_runtime_dependency("rubyntlm", ">= 0.6.3", "~> 0.6")
69
+ spec.add_runtime_dependency("webrick", "~> 1.7")
70
+ spec.add_runtime_dependency("webrobots", "~> 0.1.2")
61
71
 
62
- spec.add_development_dependency "rake"
63
- spec.add_development_dependency "bundler", "~> 1.3"
64
- spec.add_development_dependency "rdoc", "~> 4.0"
65
- spec.add_development_dependency "minitest", "~> 5.0"
72
+ spec.add_development_dependency("minitest", "~> 5.14")
73
+ spec.add_development_dependency("rake", "~> 13.0")
74
+ spec.add_development_dependency("rdoc", "~> 6.3")
75
+ spec.add_development_dependency("rubocop", "~> 1.12")
66
76
  end
@@ -1 +1,2 @@
1
1
  HELLO
2
+
@@ -7,7 +7,7 @@
7
7
  <a href="thing.html" class="thing_link">Thing!</a>
8
8
  <a href="thing.html">Ruby <b>Rocks!</b></a>
9
9
  <!-- Testing a bug with escaped stuff in links:
10
- http://rubyforge.org/pipermail/mechanize-users/2006-September/000002.html
10
+ http://rubygems.org/pipermail/mechanize-users/2006-September/000002.html
11
11
  -->
12
12
  <a href="link%20with%20space.html">encoded space</a>
13
13
  <a href="link with space.html">not encoded space</a>
@@ -345,6 +345,15 @@ but not <a href="/" rel="me nofollow">this</a>!
345
345
  end
346
346
  end
347
347
 
348
+ def test_download_does_not_allow_command_injection
349
+ skip if windows?
350
+ in_tmpdir do
351
+ @mech.download('http://example', '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'')
352
+
353
+ refute_operator(File, :exist?, "vul.txt")
354
+ end
355
+ end
356
+
348
357
  def test_get
349
358
  uri = URI 'http://localhost'
350
359
 
@@ -689,9 +698,7 @@ but not <a href="/" rel="me nofollow">this</a>!
689
698
  end
690
699
 
691
700
  def test_get_space
692
- page = nil
693
-
694
- page = @mech.get("http://localhost/tc_bad_links.html ")
701
+ @mech.get("http://localhost/tc_bad_links.html ")
695
702
 
696
703
  assert_match(/tc_bad_links.html$/, @mech.history.last.uri.to_s)
697
704
 
@@ -943,7 +950,7 @@ but not <a href="/" rel="me nofollow">this</a>!
943
950
  "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"",
944
951
  page.body
945
952
  )
946
- assert_operator page.body.bytesize, :>, File.size(__FILE__)
953
+ assert_operator page.body.bytesize, :>, file_contents_without_cr(__FILE__).length
947
954
  end
948
955
 
949
956
  def test_post_file_upload_nonascii
@@ -962,7 +969,7 @@ but not <a href="/" rel="me nofollow">this</a>!
962
969
  page.body
963
970
  )
964
971
  assert_match("Content-Type: application/zip", page.body)
965
- assert_operator page.body.bytesize, :>, File.size(__FILE__)
972
+ assert_operator page.body.bytesize, :>, file_contents_without_cr(__FILE__).length
966
973
  end
967
974
 
968
975
  def test_post_file_upload
@@ -981,7 +988,7 @@ but not <a href="/" rel="me nofollow">this</a>!
981
988
  page.body
982
989
  )
983
990
  assert_match("Content-Type: application/zip", page.body)
984
- assert_operator page.body.bytesize, :>, File.size(__FILE__)
991
+ assert_operator page.body.bytesize, :>, file_contents_without_cr(__FILE__).length
985
992
  end
986
993
 
987
994
  def test_post_redirect
@@ -1056,6 +1063,11 @@ but not <a href="/" rel="me nofollow">this</a>!
1056
1063
  end
1057
1064
 
1058
1065
  def test_retry_change_requests_equals
1066
+ unless Gem::Requirement.new("< 4.0.0").satisfied_by?(Gem::Version.new(Net::HTTP::Persistent::VERSION))
1067
+ # see https://github.com/drbrain/net-http-persistent/pull/100
1068
+ skip("net-http-persistent 4.0.0 and later does not support retry_change_requests")
1069
+ end
1070
+
1059
1071
  refute @mech.retry_change_requests
1060
1072
 
1061
1073
  @mech.retry_change_requests = true
@@ -1171,7 +1183,7 @@ but not <a href="/" rel="me nofollow">this</a>!
1171
1183
 
1172
1184
  page = @mech.submit(form)
1173
1185
 
1174
- contents = File.binread __FILE__
1186
+ contents = File.binread(__FILE__).gsub(/\r\n/, "\n")
1175
1187
  basename = File.basename __FILE__
1176
1188
 
1177
1189
  assert_match(
@@ -141,7 +141,7 @@ class TestMechanizeCookie < Mechanize::TestCase
141
141
  def test_parse_date_fail
142
142
  url = URI.parse('http://localhost/')
143
143
 
144
- dates = [
144
+ dates = [
145
145
  "20/06/95 21:07",
146
146
  ]
147
147
 
@@ -290,16 +290,16 @@ class TestMechanizeCookie < Mechanize::TestCase
290
290
  end
291
291
 
292
292
  def test_parse_valid_cookie
293
- url = URI.parse('http://rubyforge.org/')
293
+ url = URI.parse('http://rubygems.org/')
294
294
  cookie_params = {}
295
295
  cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
296
296
  cookie_params['path'] = 'path=/'
297
- cookie_params['domain'] = 'domain=.rubyforge.org'
297
+ cookie_params['domain'] = 'domain=.rubygems.org'
298
298
  cookie_params['httponly'] = 'HttpOnly'
299
299
  cookie_value = '12345%7D=ASDFWEE345%3DASda'
300
300
 
301
301
  expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
302
-
302
+
303
303
  cookie_params.keys.combine.each do |c|
304
304
  cookie_text = "#{cookie_value}; "
305
305
  c.each_with_index do |key, idx|
@@ -325,16 +325,16 @@ class TestMechanizeCookie < Mechanize::TestCase
325
325
  end
326
326
 
327
327
  def test_parse_valid_cookie_empty_value
328
- url = URI.parse('http://rubyforge.org/')
328
+ url = URI.parse('http://rubygems.org/')
329
329
  cookie_params = {}
330
330
  cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
331
331
  cookie_params['path'] = 'path=/'
332
- cookie_params['domain'] = 'domain=.rubyforge.org'
332
+ cookie_params['domain'] = 'domain=.rubygems.org'
333
333
  cookie_params['httponly'] = 'HttpOnly'
334
334
  cookie_value = '12345%7D='
335
335
 
336
336
  expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
337
-
337
+
338
338
  cookie_params.keys.combine.each do |c|
339
339
  cookie_text = "#{cookie_value}; "
340
340
  c.each_with_index do |key, idx|
@@ -361,16 +361,16 @@ class TestMechanizeCookie < Mechanize::TestCase
361
361
 
362
362
  # If no path was given, use the one from the URL
363
363
  def test_cookie_using_url_path
364
- url = URI.parse('http://rubyforge.org/login.php')
364
+ url = URI.parse('http://rubygems.org/login.php')
365
365
  cookie_params = {}
366
366
  cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
367
367
  cookie_params['path'] = 'path=/'
368
- cookie_params['domain'] = 'domain=.rubyforge.org'
368
+ cookie_params['domain'] = 'domain=.rubygems.org'
369
369
  cookie_params['httponly'] = 'HttpOnly'
370
370
  cookie_value = '12345%7D=ASDFWEE345%3DASda'
371
371
 
372
372
  expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
373
-
373
+
374
374
  cookie_params.keys.combine.each do |c|
375
375
  next if c.find { |k| k == 'path' }
376
376
  cookie_text = "#{cookie_value}; "
@@ -398,16 +398,16 @@ class TestMechanizeCookie < Mechanize::TestCase
398
398
 
399
399
  # Test using secure cookies
400
400
  def test_cookie_with_secure
401
- url = URI.parse('http://rubyforge.org/')
401
+ url = URI.parse('http://rubygems.org/')
402
402
  cookie_params = {}
403
403
  cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
404
404
  cookie_params['path'] = 'path=/'
405
- cookie_params['domain'] = 'domain=.rubyforge.org'
405
+ cookie_params['domain'] = 'domain=.rubygems.org'
406
406
  cookie_params['secure'] = 'secure'
407
407
  cookie_value = '12345%7D=ASDFWEE345%3DASda'
408
408
 
409
409
  expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
410
-
410
+
411
411
  cookie_params.keys.combine.each do |c|
412
412
  next unless c.find { |k| k == 'secure' }
413
413
  cookie_text = "#{cookie_value}; "
@@ -435,16 +435,16 @@ class TestMechanizeCookie < Mechanize::TestCase
435
435
  end
436
436
 
437
437
  def test_parse_cookie_no_spaces
438
- url = URI.parse('http://rubyforge.org/')
438
+ url = URI.parse('http://rubygems.org/')
439
439
  cookie_params = {}
440
440
  cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
441
441
  cookie_params['path'] = 'path=/'
442
- cookie_params['domain'] = 'domain=.rubyforge.org'
442
+ cookie_params['domain'] = 'domain=.rubygems.org'
443
443
  cookie_params['httponly'] = 'HttpOnly'
444
444
  cookie_value = '12345%7D=ASDFWEE345%3DASda'
445
445
 
446
446
  expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
447
-
447
+
448
448
  cookie_params.keys.combine.each do |c|
449
449
  cookie_text = "#{cookie_value};"
450
450
  c.each_with_index do |key, idx|
@@ -511,13 +511,13 @@ class TestMechanizeCookie < Mechanize::TestCase
511
511
  end
512
512
 
513
513
  def test_cookie_httponly
514
- url = URI.parse('http://rubyforge.org/')
514
+ url = URI.parse('http://rubygems.org/')
515
515
  cookie_params = {}
516
516
  cookie_params['httponly'] = 'HttpOnly'
517
517
  cookie_value = '12345%7D=ASDFWEE345%3DASda'
518
518
 
519
519
  expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
520
-
520
+
521
521
  cookie_params.keys.combine.each do |c|
522
522
  cookie_text = "#{cookie_value}; "
523
523
  c.each_with_index do |key, idx|
@@ -532,7 +532,7 @@ class TestMechanizeCookie < Mechanize::TestCase
532
532
 
533
533
  assert_equal(true, cookie.httponly)
534
534
 
535
-
535
+
536
536
  # if expires was set, make sure we parsed it
537
537
  if c.find { |k| k == 'expires' }
538
538
  assert_equal(expires, cookie.expires)