mechanize 2.7.7 → 2.8.0
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 +4 -4
- data/.github/workflows/ci-test.yml +24 -4
- data/.yardopts +8 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +81 -66
- data/Gemfile +1 -6
- data/{LICENSE.rdoc → LICENSE.txt} +4 -0
- data/README.md +79 -0
- data/Rakefile +18 -3
- data/lib/mechanize.rb +1 -0
- data/lib/mechanize/chunked_termination_error.rb +1 -0
- data/lib/mechanize/content_type_error.rb +1 -0
- data/lib/mechanize/cookie.rb +1 -13
- data/lib/mechanize/cookie_jar.rb +2 -10
- data/lib/mechanize/directory_saver.rb +1 -0
- data/lib/mechanize/download.rb +1 -0
- data/lib/mechanize/element_matcher.rb +1 -0
- data/lib/mechanize/element_not_found_error.rb +1 -0
- data/lib/mechanize/file.rb +1 -0
- data/lib/mechanize/file_connection.rb +5 -3
- data/lib/mechanize/file_request.rb +1 -0
- data/lib/mechanize/file_response.rb +3 -0
- data/lib/mechanize/file_saver.rb +1 -0
- data/lib/mechanize/form.rb +1 -9
- data/lib/mechanize/form/button.rb +1 -0
- data/lib/mechanize/form/check_box.rb +1 -0
- data/lib/mechanize/form/field.rb +1 -0
- data/lib/mechanize/form/file_upload.rb +1 -0
- data/lib/mechanize/form/hidden.rb +1 -0
- data/lib/mechanize/form/image_button.rb +1 -0
- data/lib/mechanize/form/keygen.rb +1 -0
- data/lib/mechanize/form/multi_select_list.rb +1 -0
- data/lib/mechanize/form/option.rb +1 -0
- data/lib/mechanize/form/radio_button.rb +1 -0
- data/lib/mechanize/form/reset.rb +1 -0
- data/lib/mechanize/form/select_list.rb +1 -0
- data/lib/mechanize/form/submit.rb +1 -0
- data/lib/mechanize/form/text.rb +1 -0
- data/lib/mechanize/form/textarea.rb +1 -0
- data/lib/mechanize/headers.rb +1 -0
- data/lib/mechanize/history.rb +1 -0
- data/lib/mechanize/http.rb +1 -0
- data/lib/mechanize/http/agent.rb +16 -8
- data/lib/mechanize/http/auth_challenge.rb +1 -0
- data/lib/mechanize/http/auth_realm.rb +1 -0
- data/lib/mechanize/http/auth_store.rb +1 -0
- data/lib/mechanize/http/content_disposition_parser.rb +14 -2
- data/lib/mechanize/http/www_authenticate_parser.rb +3 -3
- data/lib/mechanize/image.rb +1 -0
- data/lib/mechanize/page.rb +1 -0
- data/lib/mechanize/page/base.rb +1 -0
- data/lib/mechanize/page/frame.rb +1 -0
- data/lib/mechanize/page/image.rb +1 -0
- data/lib/mechanize/page/label.rb +1 -0
- data/lib/mechanize/page/link.rb +8 -1
- data/lib/mechanize/page/meta_refresh.rb +1 -0
- data/lib/mechanize/parser.rb +1 -0
- data/lib/mechanize/pluggable_parsers.rb +1 -0
- data/lib/mechanize/prependable.rb +1 -0
- data/lib/mechanize/redirect_limit_reached_error.rb +1 -0
- data/lib/mechanize/redirect_not_get_or_head_error.rb +1 -0
- data/lib/mechanize/response_code_error.rb +2 -1
- data/lib/mechanize/response_read_error.rb +1 -0
- data/lib/mechanize/robots_disallowed_error.rb +1 -0
- data/lib/mechanize/test_case.rb +32 -27
- data/lib/mechanize/test_case/bad_chunking_servlet.rb +1 -0
- data/lib/mechanize/test_case/basic_auth_servlet.rb +1 -0
- data/lib/mechanize/test_case/content_type_servlet.rb +1 -0
- data/lib/mechanize/test_case/digest_auth_servlet.rb +1 -0
- data/lib/mechanize/test_case/file_upload_servlet.rb +1 -0
- data/lib/mechanize/test_case/form_servlet.rb +1 -0
- data/lib/mechanize/test_case/gzip_servlet.rb +1 -0
- data/lib/mechanize/test_case/header_servlet.rb +1 -0
- data/lib/mechanize/test_case/http_refresh_servlet.rb +1 -0
- data/lib/mechanize/test_case/infinite_redirect_servlet.rb +1 -0
- data/lib/mechanize/test_case/infinite_refresh_servlet.rb +1 -0
- data/lib/mechanize/test_case/many_cookies_as_string_servlet.rb +1 -0
- data/lib/mechanize/test_case/many_cookies_servlet.rb +1 -0
- data/lib/mechanize/test_case/modified_since_servlet.rb +1 -0
- data/lib/mechanize/test_case/ntlm_servlet.rb +1 -0
- data/lib/mechanize/test_case/one_cookie_no_spaces_servlet.rb +1 -0
- data/lib/mechanize/test_case/one_cookie_servlet.rb +1 -0
- data/lib/mechanize/test_case/quoted_value_cookie_servlet.rb +1 -0
- data/lib/mechanize/test_case/redirect_servlet.rb +1 -0
- data/lib/mechanize/test_case/referer_servlet.rb +1 -0
- data/lib/mechanize/test_case/refresh_with_empty_url.rb +1 -0
- data/lib/mechanize/test_case/refresh_without_url.rb +1 -0
- data/lib/mechanize/test_case/response_code_servlet.rb +1 -0
- data/lib/mechanize/test_case/robots_txt_servlet.rb +1 -0
- data/lib/mechanize/test_case/send_cookies_servlet.rb +1 -0
- data/lib/mechanize/test_case/server.rb +1 -0
- data/lib/mechanize/test_case/servlets.rb +1 -0
- data/lib/mechanize/test_case/verb_servlet.rb +1 -0
- data/lib/mechanize/unauthorized_error.rb +1 -0
- data/lib/mechanize/unsupported_scheme_error.rb +1 -0
- data/lib/mechanize/util.rb +2 -1
- data/lib/mechanize/version.rb +2 -1
- data/lib/mechanize/xml_file.rb +1 -0
- data/mechanize.gemspec +38 -31
- data/test/htdocs/dir with spaces/foo.html +1 -0
- data/test/test_mechanize.rb +5 -4
- data/test/test_mechanize_cookie_jar.rb +2 -0
- data/test/test_mechanize_download.rb +1 -0
- data/test/test_mechanize_file.rb +1 -0
- data/test/test_mechanize_file_connection.rb +21 -3
- data/test/test_mechanize_file_response.rb +6 -0
- data/test/test_mechanize_http_agent.rb +47 -7
- data/test/test_mechanize_http_content_disposition_parser.rb +27 -0
- data/test/test_mechanize_link.rb +24 -0
- metadata +134 -52
- data/README.rdoc +0 -77
data/lib/mechanize/util.rb
CHANGED
@@ -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? ?
|
19
|
+
(s.nil? ? String.new : s << '&') << [CGI.escape(k.to_s), CGI.escape(v.to_s)].join('=')
|
19
20
|
} || ''
|
20
21
|
end
|
21
22
|
|
data/lib/mechanize/version.rb
CHANGED
data/lib/mechanize/xml_file.rb
CHANGED
data/mechanize.gemspec
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'mechanize/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.homepage
|
10
|
-
spec.summary
|
11
|
-
spec.description
|
8
|
+
spec.name = "mechanize"
|
9
|
+
spec.version = Mechanize::VERSION
|
10
|
+
spec.homepage = "http://docs.seattlerb.org/mechanize/"
|
11
|
+
spec.summary = 'The Mechanize library is used for automating interaction with websites'
|
12
|
+
spec.description =
|
12
13
|
[
|
13
14
|
"The Mechanize library is used for automating interaction with websites.",
|
14
15
|
"Mechanize automatically stores and sends cookies, follows redirects,",
|
15
16
|
"and can follow links and submit forms. Form fields can be populated and",
|
16
17
|
"submitted. Mechanize also keeps track of the sites that you have visited as",
|
17
|
-
"a history."
|
18
|
+
"a history.",
|
18
19
|
].join("\n")
|
19
20
|
|
20
21
|
spec.authors =
|
@@ -23,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
23
24
|
'Aaron Patterson',
|
24
25
|
'Mike Dalessio',
|
25
26
|
'Akinori MUSHA',
|
26
|
-
'Lee Jarvis'
|
27
|
+
'Lee Jarvis',
|
27
28
|
]
|
28
29
|
spec.email =
|
29
30
|
[
|
@@ -31,32 +32,38 @@ Gem::Specification.new do |spec|
|
|
31
32
|
'aaron.patterson@gmail.com',
|
32
33
|
'mike.dalessio@gmail.com',
|
33
34
|
'knu@idaemons.org',
|
34
|
-
'ljjarvis@gmail.com'
|
35
|
+
'ljjarvis@gmail.com',
|
35
36
|
]
|
36
37
|
|
37
|
-
spec.license
|
38
|
+
spec.license = "MIT"
|
38
39
|
|
39
40
|
spec.require_paths = ["lib"]
|
40
|
-
spec.files
|
41
|
-
spec.test_files
|
42
|
-
|
43
|
-
spec.extra_rdoc_files += Dir['*.rdoc']
|
44
|
-
spec.rdoc_options
|
45
|
-
|
46
|
-
spec.required_ruby_version = ">=
|
47
|
-
|
48
|
-
spec.add_runtime_dependency
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
spec.add_runtime_dependency "
|
58
|
-
|
59
|
-
spec.add_runtime_dependency
|
60
|
-
spec.add_runtime_dependency
|
61
|
-
spec.add_runtime_dependency
|
41
|
+
spec.files = %x(git ls-files).split($/)
|
42
|
+
spec.test_files = spec.files.grep(%r{^test/})
|
43
|
+
|
44
|
+
spec.extra_rdoc_files += Dir['*.rdoc', '*.md']
|
45
|
+
spec.rdoc_options = ["--main", "README.md"]
|
46
|
+
|
47
|
+
spec.required_ruby_version = ">= 2.5.0"
|
48
|
+
|
49
|
+
spec.add_runtime_dependency("addressable", "~> 2.7")
|
50
|
+
spec.add_runtime_dependency("domain_name", ">= 0.5.20190701", "~> 0.5")
|
51
|
+
spec.add_runtime_dependency("http-cookie", ">= 1.0.3", "~> 1.0")
|
52
|
+
spec.add_runtime_dependency("mime-types", "~> 3.0")
|
53
|
+
spec.add_runtime_dependency("net-http-digest_auth", ">= 1.4.1", "~> 1.4")
|
54
|
+
|
55
|
+
# careful! some folks are relying on older versions of net-http-persistent
|
56
|
+
# - see the socks proxy patch in use at #507 and #464
|
57
|
+
# - see use of retry_change_requests that was removed at #558
|
58
|
+
spec.add_runtime_dependency("net-http-persistent", ">= 2.5.2", "< 5.0.dev")
|
59
|
+
|
60
|
+
spec.add_runtime_dependency("nokogiri", ">= 1.11.2", "~> 1.11")
|
61
|
+
spec.add_runtime_dependency("rubyntlm", ">= 0.6.3", "~> 0.6")
|
62
|
+
spec.add_runtime_dependency("webrick", "~> 1.7")
|
63
|
+
spec.add_runtime_dependency("webrobots", "~> 0.1.2")
|
64
|
+
|
65
|
+
spec.add_development_dependency("minitest", "~> 5.14")
|
66
|
+
spec.add_development_dependency("rake", "~> 13.0")
|
67
|
+
spec.add_development_dependency("rdoc", "~> 6.3")
|
68
|
+
spec.add_development_dependency("rubocop", "~> 1.12")
|
62
69
|
end
|
data/test/test_mechanize.rb
CHANGED
@@ -346,6 +346,7 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
346
346
|
end
|
347
347
|
|
348
348
|
def test_download_does_not_allow_command_injection
|
349
|
+
skip if windows?
|
349
350
|
in_tmpdir do
|
350
351
|
@mech.download('http://example', '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'')
|
351
352
|
|
@@ -949,7 +950,7 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
949
950
|
"Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"",
|
950
951
|
page.body
|
951
952
|
)
|
952
|
-
assert_operator page.body.bytesize, :>,
|
953
|
+
assert_operator page.body.bytesize, :>, file_contents_without_cr(__FILE__).length
|
953
954
|
end
|
954
955
|
|
955
956
|
def test_post_file_upload_nonascii
|
@@ -968,7 +969,7 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
968
969
|
page.body
|
969
970
|
)
|
970
971
|
assert_match("Content-Type: application/zip", page.body)
|
971
|
-
assert_operator page.body.bytesize, :>,
|
972
|
+
assert_operator page.body.bytesize, :>, file_contents_without_cr(__FILE__).length
|
972
973
|
end
|
973
974
|
|
974
975
|
def test_post_file_upload
|
@@ -987,7 +988,7 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
987
988
|
page.body
|
988
989
|
)
|
989
990
|
assert_match("Content-Type: application/zip", page.body)
|
990
|
-
assert_operator page.body.bytesize, :>,
|
991
|
+
assert_operator page.body.bytesize, :>, file_contents_without_cr(__FILE__).length
|
991
992
|
end
|
992
993
|
|
993
994
|
def test_post_redirect
|
@@ -1182,7 +1183,7 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
1182
1183
|
|
1183
1184
|
page = @mech.submit(form)
|
1184
1185
|
|
1185
|
-
contents = File.binread
|
1186
|
+
contents = File.binread(__FILE__).gsub(/\r\n/, "\n")
|
1186
1187
|
basename = File.basename __FILE__
|
1187
1188
|
|
1188
1189
|
assert_match(
|
@@ -502,6 +502,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
502
502
|
end
|
503
503
|
|
504
504
|
def test_prevent_command_injection_when_saving
|
505
|
+
skip if windows?
|
505
506
|
url = URI 'http://rubygems.org/'
|
506
507
|
path = '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\''
|
507
508
|
|
@@ -514,6 +515,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
514
515
|
end
|
515
516
|
|
516
517
|
def test_prevent_command_injection_when_loading
|
518
|
+
skip if windows?
|
517
519
|
url = URI 'http://rubygems.org/'
|
518
520
|
path = '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\''
|
519
521
|
|
data/test/test_mechanize_file.rb
CHANGED
@@ -3,19 +3,37 @@ require 'mechanize/test_case'
|
|
3
3
|
class TestMechanizeFileConnection < Mechanize::TestCase
|
4
4
|
|
5
5
|
def test_request
|
6
|
-
|
6
|
+
file_path = File.expand_path(__FILE__)
|
7
|
+
uri = URI.parse "file://#{file_path}"
|
7
8
|
conn = Mechanize::FileConnection.new
|
8
9
|
|
9
10
|
body = ''
|
10
11
|
|
11
12
|
conn.request uri, nil do |response|
|
13
|
+
assert_equal(file_path, response.file_path)
|
12
14
|
response.read_body do |part|
|
13
15
|
body << part
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
assert_equal File.read(__FILE__), body
|
19
|
+
assert_equal File.read(__FILE__), body.gsub(/\r\n/, "\n")
|
18
20
|
end
|
19
21
|
|
20
|
-
|
22
|
+
def test_request_on_uri_with_windows_drive
|
23
|
+
uri_string = "file://C:/path/to/file.html"
|
24
|
+
expected_file_path = "C:/path/to/file.html"
|
25
|
+
|
26
|
+
uri = URI.parse(uri_string)
|
27
|
+
conn = Mechanize::FileConnection.new
|
21
28
|
|
29
|
+
called = false
|
30
|
+
yielded_file_path = nil
|
31
|
+
conn.request(uri, nil) do |response|
|
32
|
+
called = true
|
33
|
+
yielded_file_path = response.file_path
|
34
|
+
end
|
35
|
+
|
36
|
+
assert(called)
|
37
|
+
assert_equal(expected_file_path, yielded_file_path)
|
38
|
+
end
|
39
|
+
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
require 'mechanize/test_case'
|
2
2
|
|
3
3
|
class TestMechanizeFileResponse < Mechanize::TestCase
|
4
|
+
def test_file_path
|
5
|
+
res = Mechanize::FileResponse.new("/path/to/foo.html")
|
6
|
+
assert_equal("/path/to/foo.html", res.file_path)
|
7
|
+
end
|
8
|
+
|
4
9
|
def test_content_type
|
5
10
|
Tempfile.open %w[pi .nothtml] do |tempfile|
|
6
11
|
res = Mechanize::FileResponse.new tempfile.path
|
@@ -31,6 +36,7 @@ class TestMechanizeFileResponse < Mechanize::TestCase
|
|
31
36
|
end
|
32
37
|
|
33
38
|
def test_read_body_does_not_allow_command_injection
|
39
|
+
skip if windows?
|
34
40
|
in_tmpdir do
|
35
41
|
FileUtils.touch('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'')
|
36
42
|
res = Mechanize::FileResponse.new('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'')
|
@@ -16,11 +16,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
16
16
|
@res.instance_variable_set :@code, 200
|
17
17
|
@res.instance_variable_set :@header, {}
|
18
18
|
|
19
|
-
@headers =
|
20
|
-
%w[accept accept-encoding user-agent]
|
21
|
-
else
|
22
|
-
%w[accept user-agent]
|
23
|
-
end
|
19
|
+
@headers = %w[accept accept-encoding user-agent]
|
24
20
|
end
|
25
21
|
|
26
22
|
def auth_realm uri, scheme, type
|
@@ -205,7 +201,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
205
201
|
|
206
202
|
page = @agent.fetch uri
|
207
203
|
|
208
|
-
assert_equal File.read(foo), page.body
|
204
|
+
assert_equal File.read(foo), page.body.gsub(/\r\n/, "\n")
|
209
205
|
assert_kind_of Mechanize::Page, page
|
210
206
|
end
|
211
207
|
|
@@ -1508,7 +1504,8 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
1508
1504
|
headers = {
|
1509
1505
|
'Range' => 'bytes=0-9999',
|
1510
1506
|
'Content-Type' => 'application/x-www-form-urlencoded',
|
1511
|
-
'
|
1507
|
+
'CONTENT-LENGTH' => '9999',
|
1508
|
+
'content-md5' => '14758f1afd44c09b7992073ccf00b43d',
|
1512
1509
|
}
|
1513
1510
|
|
1514
1511
|
page = fake_page
|
@@ -1520,6 +1517,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
1520
1517
|
assert_match 'range|bytes=0-9999', page.body
|
1521
1518
|
refute_match 'content-type|application/x-www-form-urlencoded', page.body
|
1522
1519
|
refute_match 'content-length|9999', page.body
|
1520
|
+
refute_match 'content-md5|14758f1afd44c09b7992073ccf00b43d', page.body
|
1523
1521
|
end
|
1524
1522
|
|
1525
1523
|
def test_response_redirect_malformed
|
@@ -1555,6 +1553,48 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
1555
1553
|
end
|
1556
1554
|
end
|
1557
1555
|
|
1556
|
+
def test_response_redirect_to_cross_site_with_credential
|
1557
|
+
@agent.redirect_ok = true
|
1558
|
+
|
1559
|
+
headers = {
|
1560
|
+
'Range' => 'bytes=0-9999',
|
1561
|
+
'AUTHORIZATION' => 'Basic xxx',
|
1562
|
+
'cookie' => 'name=value',
|
1563
|
+
}
|
1564
|
+
|
1565
|
+
page = html_page ''
|
1566
|
+
page = @agent.response_redirect({ 'Location' => 'http://trap/http_headers' }, :get,
|
1567
|
+
page, 0, headers)
|
1568
|
+
|
1569
|
+
refute_includes(headers.keys, "AUTHORIZATION")
|
1570
|
+
refute_includes(headers.keys, "cookie")
|
1571
|
+
|
1572
|
+
assert_match 'range|bytes=0-9999', page.body
|
1573
|
+
refute_match("authorization|Basic xxx", page.body)
|
1574
|
+
refute_match("cookie|name=value", page.body)
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
def test_response_redirect_to_same_site_with_credential
|
1578
|
+
@agent.redirect_ok = true
|
1579
|
+
|
1580
|
+
headers = {
|
1581
|
+
'Range' => 'bytes=0-9999',
|
1582
|
+
'AUTHORIZATION' => 'Basic xxx',
|
1583
|
+
'cookie' => 'name=value',
|
1584
|
+
}
|
1585
|
+
|
1586
|
+
page = html_page ''
|
1587
|
+
page = @agent.response_redirect({ 'Location' => '/http_headers' }, :get,
|
1588
|
+
page, 0, headers)
|
1589
|
+
|
1590
|
+
assert_includes(headers.keys, "AUTHORIZATION")
|
1591
|
+
assert_includes(headers.keys, "cookie")
|
1592
|
+
|
1593
|
+
assert_match 'range|bytes=0-9999', page.body
|
1594
|
+
assert_match("authorization|Basic xxx", page.body)
|
1595
|
+
assert_match("cookie|name=value", page.body)
|
1596
|
+
end
|
1597
|
+
|
1558
1598
|
def test_response_redirect_not_ok
|
1559
1599
|
@agent.redirect_ok = false
|
1560
1600
|
|
@@ -30,6 +30,33 @@ class TestMechanizeHttpContentDispositionParser < Mechanize::TestCase
|
|
30
30
|
assert_equal expected, content_disposition.parameters
|
31
31
|
end
|
32
32
|
|
33
|
+
def test_parse_date_iso8601_fallback
|
34
|
+
now = Time.at Time.now.to_i
|
35
|
+
|
36
|
+
content_disposition = @parser.parse \
|
37
|
+
'attachment;' \
|
38
|
+
'filename=value;' \
|
39
|
+
"creation-date=\"#{now.iso8601}\";" \
|
40
|
+
"modification-date=\"#{(now + 1).iso8601}\""
|
41
|
+
|
42
|
+
assert_equal 'attachment', content_disposition.type
|
43
|
+
assert_equal 'value', content_disposition.filename
|
44
|
+
assert_equal now, content_disposition.creation_date
|
45
|
+
assert_equal((now + 1), content_disposition.modification_date)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_parse_date_invalid
|
49
|
+
now = Time.at Time.now.to_i
|
50
|
+
|
51
|
+
content_disposition = @parser.parse \
|
52
|
+
'attachment;' \
|
53
|
+
'filename=value;' \
|
54
|
+
"creation-date=\"#{now.to_s}\";" \
|
55
|
+
"modification-date=\"#{(now + 1).to_s}\""
|
56
|
+
|
57
|
+
assert_nil content_disposition
|
58
|
+
end
|
59
|
+
|
33
60
|
def test_parse_header
|
34
61
|
content_disposition = @parser.parse \
|
35
62
|
'content-disposition: attachment;filename=value', true
|