mechanize 2.1.pre.1 → 2.1
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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG.rdoc +10 -9
- data/lib/mechanize.rb +2 -2
- data/lib/mechanize/cookie.rb +24 -10
- data/lib/mechanize/download.rb +1 -1
- data/lib/mechanize/http/agent.rb +15 -16
- data/lib/mechanize/test_case.rb +4 -0
- data/test/test_mechanize.rb +14 -0
- data/test/test_mechanize_cookie.rb +41 -0
- data/test/test_mechanize_cookie_jar.rb +9 -3
- data/test/test_mechanize_http_agent.rb +20 -0
- data/test/test_mechanize_page_encoding.rb +2 -2
- metadata +4 -6
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Mechanize CHANGELOG
|
2
2
|
|
3
|
-
=== 2.1 /
|
3
|
+
=== 2.1 / 2011-12-20
|
4
4
|
|
5
5
|
* Deprecations
|
6
6
|
* Mechanize#get no longer accepts an options hash.
|
@@ -9,8 +9,9 @@
|
|
9
9
|
* Minor enhancements
|
10
10
|
* Mechanize now depends on net-http-persistent 2.3+. This new version
|
11
11
|
brings idle timeouts to help with the dreaded "too many connection resets"
|
12
|
-
issue when POSTing to a closed connection.
|
13
|
-
|
12
|
+
issue when POSTing to a closed connection. Issue #123
|
13
|
+
* SSL connections will be verified against the system certificate store by
|
14
|
+
default.
|
14
15
|
* Added Mechanize#retry_change_requests to allow mechanize to retry POST and
|
15
16
|
other non-idempotent requests when you know it is safe to do so. Issue
|
16
17
|
#123
|
@@ -39,8 +40,8 @@
|
|
39
40
|
by Jo Hund.
|
40
41
|
* Updated 'Mac Safari' User-Agent alias to Safari 5.1.1. 'Mac Safari 4' can
|
41
42
|
be used for the old 'Mac Safari' alias.
|
42
|
-
* When given multiple HTTP authentication options mechanize
|
43
|
-
|
43
|
+
* When given multiple HTTP authentication options mechanize now picks the
|
44
|
+
strongest method.
|
44
45
|
* Improvements to HTTP authorization:
|
45
46
|
* mechanize raises Mechanize::UnathorizedError for 401 responses which is
|
46
47
|
a sublcass of Mechanize::ResponseCodeError.
|
@@ -52,10 +53,6 @@
|
|
52
53
|
Issue #167
|
53
54
|
|
54
55
|
* Bug fixes
|
55
|
-
* Mechanize takes more care to avoid saving files with certain unsafe names.
|
56
|
-
You should still take care not to use mechanize to save files into your
|
57
|
-
home directory. Issue #163.
|
58
|
-
* Mechanize#cookie_jar= works again. Issue #126
|
59
56
|
* Mechanize now handles cookies just as most modern browsers do,
|
60
57
|
roughly based on RFC 6265.
|
61
58
|
* domain=.example.com (which is invalid) is considered identical to
|
@@ -75,6 +72,10 @@
|
|
75
72
|
* It is recommended that you clear out existing cookie jars for
|
76
73
|
regeneration because previously saved cookies may not have been
|
77
74
|
parsed correctly.
|
75
|
+
* Mechanize takes more care to avoid saving files with certain unsafe names.
|
76
|
+
You should still take care not to use mechanize to save files directly
|
77
|
+
into your home directory ($HOME). Issue #163.
|
78
|
+
* Mechanize#cookie_jar= works again. Issue #126
|
78
79
|
* The original Referer value persists on redirection. Issue #150
|
79
80
|
* Do not send a referer on a Refresh header based redirection.
|
80
81
|
* Fixed encoding error in tests when LANG=C. Patch #142 by jinschoi.
|
data/lib/mechanize.rb
CHANGED
@@ -308,7 +308,7 @@ class Mechanize
|
|
308
308
|
# FIXME: Huge hack so that using a URI as a referer works. I need to
|
309
309
|
# refactor everything to pass around URIs but still support
|
310
310
|
# Mechanize::Page#base
|
311
|
-
unless
|
311
|
+
unless Mechanize::Parser === referer then
|
312
312
|
referer = referer.is_a?(String) ?
|
313
313
|
Page.new(URI.parse(referer), {'content-type' => 'text/html'}) :
|
314
314
|
Page.new(referer, {'content-type' => 'text/html'})
|
@@ -975,7 +975,7 @@ class Mechanize
|
|
975
975
|
# Find our pluggable parser
|
976
976
|
parser_klass = @pluggable_parser.parser content_type
|
977
977
|
|
978
|
-
unless Mechanize::Download
|
978
|
+
unless parser_klass <= Mechanize::Download then
|
979
979
|
body = case body
|
980
980
|
when IO, Tempfile, StringIO then
|
981
981
|
body.read
|
data/lib/mechanize/cookie.rb
CHANGED
@@ -74,6 +74,9 @@ class Mechanize::Cookie
|
|
74
74
|
alias for_domain? for_domain
|
75
75
|
|
76
76
|
class << self
|
77
|
+
# Parses a Set-Cookie header line +str+ sent from +uri+ into an
|
78
|
+
# array of Cookie objects. Note that this array may contain
|
79
|
+
# nil's when some of the cookie-pairs are malformed.
|
77
80
|
def parse(uri, str, log = Mechanize.log)
|
78
81
|
return str.split(/,(?=[^;,]*=)|,$/).map { |c|
|
79
82
|
cookie_elem = c.split(/;+/)
|
@@ -96,8 +99,12 @@ class Mechanize::Cookie
|
|
96
99
|
|
97
100
|
case key.downcase
|
98
101
|
when 'domain'
|
99
|
-
|
100
|
-
|
102
|
+
begin
|
103
|
+
cookie.domain = value
|
104
|
+
cookie.for_domain = true
|
105
|
+
rescue
|
106
|
+
log.warn("Couldn't parse domain: #{value}") if log
|
107
|
+
end
|
101
108
|
when 'path'
|
102
109
|
cookie.path = value
|
103
110
|
when 'expires'
|
@@ -147,15 +154,22 @@ class Mechanize::Cookie
|
|
147
154
|
# Sets the domain attribute. A leading dot in +domain+ implies
|
148
155
|
# turning the +for_domain?+ flag on.
|
149
156
|
def domain=(domain)
|
150
|
-
if domain
|
151
|
-
@
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
domain
|
157
|
+
if DomainName === domain
|
158
|
+
@domain_name = domain
|
159
|
+
else
|
160
|
+
domain.is_a?(String) or
|
161
|
+
(domain.respond_to?(:to_str) && (domain = domain.to_str).is_a?(String)) or
|
162
|
+
raise TypeError, "#{domain.class} is not a String"
|
163
|
+
if domain.start_with?('.')
|
164
|
+
@for_domain = true
|
165
|
+
domain = domain[1..-1]
|
166
|
+
end
|
167
|
+
# Do we really need to support this?
|
168
|
+
if domain.match(/\A([^:]+):[0-9]+\z/)
|
169
|
+
domain = $1
|
170
|
+
end
|
171
|
+
@domain_name = DomainName.new(domain)
|
157
172
|
end
|
158
|
-
@domain_name = DomainName.new(domain)
|
159
173
|
set_domain(@domain_name.hostname)
|
160
174
|
end
|
161
175
|
|
data/lib/mechanize/download.rb
CHANGED
data/lib/mechanize/http/agent.rb
CHANGED
@@ -695,6 +695,7 @@ class Mechanize::HTTP::Agent
|
|
695
695
|
begin
|
696
696
|
zio = Zlib::GzipReader.new body_io
|
697
697
|
out_io = Tempfile.new 'mechanize-decode'
|
698
|
+
out_io.binmode
|
698
699
|
|
699
700
|
until zio.eof? do
|
700
701
|
out_io.write zio.read 16384
|
@@ -723,16 +724,9 @@ class Mechanize::HTTP::Agent
|
|
723
724
|
end
|
724
725
|
|
725
726
|
def response_cookies response, uri, page
|
726
|
-
log = log() # reduce method calls
|
727
727
|
if Mechanize::Page === page and page.body =~ /Set-Cookie/n
|
728
728
|
page.search('//head/meta[@http-equiv="Set-Cookie"]').each do |meta|
|
729
|
-
|
730
|
-
if @cookie_jar.add(uri, c)
|
731
|
-
log.debug("saved cookie: #{c}") if log
|
732
|
-
else
|
733
|
-
log.debug("rejected cookie: #{c}") if log
|
734
|
-
end
|
735
|
-
}
|
729
|
+
save_cookies(uri, meta['content'])
|
736
730
|
end
|
737
731
|
end
|
738
732
|
|
@@ -740,17 +734,22 @@ class Mechanize::HTTP::Agent
|
|
740
734
|
|
741
735
|
return unless header_cookies
|
742
736
|
|
743
|
-
header_cookies.each do |
|
744
|
-
|
745
|
-
if @cookie_jar.add(uri, c)
|
746
|
-
log.debug("saved cookie: #{c}") if log
|
747
|
-
else
|
748
|
-
log.debug("rejected cookie: #{c}") if log
|
749
|
-
end
|
750
|
-
}
|
737
|
+
header_cookies.each do |set_cookie|
|
738
|
+
save_cookies(uri, set_cookie)
|
751
739
|
end
|
752
740
|
end
|
753
741
|
|
742
|
+
def save_cookies(uri, set_cookie)
|
743
|
+
log = log() # reduce method calls
|
744
|
+
Mechanize::Cookie.parse(uri, set_cookie, log) { |c|
|
745
|
+
if @cookie_jar.add(uri, c)
|
746
|
+
log.debug("saved cookie: #{c}") if log
|
747
|
+
else
|
748
|
+
log.debug("rejected cookie: #{c}") if log
|
749
|
+
end
|
750
|
+
}
|
751
|
+
end
|
752
|
+
|
754
753
|
def response_follow_meta_refresh response, uri, page, redirects
|
755
754
|
delay, new_url = get_meta_refresh(response, uri, page)
|
756
755
|
return nil unless new_url
|
data/lib/mechanize/test_case.rb
CHANGED
@@ -43,6 +43,10 @@ class Mechanize::TestCase < MiniTest::Unit::TestCase
|
|
43
43
|
Mechanize::Page.new uri, response, html, 200, agent
|
44
44
|
end
|
45
45
|
|
46
|
+
def have_encoding?
|
47
|
+
Object.const_defined? :Encoding
|
48
|
+
end
|
49
|
+
|
46
50
|
def html_page body
|
47
51
|
uri = URI 'http://example/'
|
48
52
|
Mechanize::Page.new uri, { 'content-type' => 'text/html' }, body, 200, @mech
|
data/test/test_mechanize.rb
CHANGED
@@ -452,6 +452,19 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
452
452
|
assert_nil requests.last['referer']
|
453
453
|
end
|
454
454
|
|
455
|
+
def test_get_referer_download
|
456
|
+
download = Mechanize::Download.new URI 'http://example/prev'
|
457
|
+
|
458
|
+
uri = URI 'http://example'
|
459
|
+
|
460
|
+
page = @mech.get uri, { :q => 'h' }, download, { 'X-H' => 'v' }
|
461
|
+
|
462
|
+
assert_equal URI('http://example/?q=h'), page.uri
|
463
|
+
assert_equal URI('http://example'), uri
|
464
|
+
|
465
|
+
assert_equal 'http://example/prev', requests.first['referer']
|
466
|
+
end
|
467
|
+
|
455
468
|
def test_get_robots
|
456
469
|
@mech.robots = true
|
457
470
|
|
@@ -791,6 +804,7 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
791
804
|
download = @mech.parse @uri, response, StringIO.new('raw')
|
792
805
|
|
793
806
|
assert_kind_of Mechanize::Download, download
|
807
|
+
assert_kind_of StringIO, download.content
|
794
808
|
end
|
795
809
|
|
796
810
|
def test_parse_html
|
@@ -406,5 +406,46 @@ class TestMechanizeCookie < Mechanize::TestCase
|
|
406
406
|
end
|
407
407
|
end
|
408
408
|
end
|
409
|
+
|
410
|
+
def test_new
|
411
|
+
cookie = Mechanize::Cookie.new('key', 'value')
|
412
|
+
assert_equal 'key', cookie.name
|
413
|
+
assert_equal 'value', cookie.value
|
414
|
+
assert_equal nil, cookie.expires
|
415
|
+
|
416
|
+
# Minimum unit for the expires attribute is second
|
417
|
+
expires = Time.at((Time.now + 3600).to_i)
|
418
|
+
|
419
|
+
cookie = Mechanize::Cookie.new('key', 'value', :expires => expires.dup)
|
420
|
+
assert_equal 'key', cookie.name
|
421
|
+
assert_equal 'value', cookie.value
|
422
|
+
assert_equal expires, cookie.expires
|
423
|
+
|
424
|
+
cookie = Mechanize::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup)
|
425
|
+
assert_equal 'key', cookie.name
|
426
|
+
assert_equal 'value', cookie.value
|
427
|
+
assert_equal expires, cookie.expires
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_domain=
|
431
|
+
url = URI.parse('http://host.dom.example.com:8080/')
|
432
|
+
|
433
|
+
cookie_str = 'a=b; domain=Example.Com'
|
434
|
+
cookie = Mechanize::Cookie.parse(url, cookie_str).first
|
435
|
+
assert 'example.com', cookie.domain
|
436
|
+
|
437
|
+
cookie.domain = DomainName(url.host)
|
438
|
+
assert 'host.dom.example.com', cookie.domain
|
439
|
+
|
440
|
+
cookie.domain = 'Dom.example.com'
|
441
|
+
assert 'dom.example.com', cookie.domain
|
442
|
+
|
443
|
+
cookie.domain = Object.new.tap { |o|
|
444
|
+
def o.to_str
|
445
|
+
'Example.com'
|
446
|
+
end
|
447
|
+
}
|
448
|
+
assert 'example.com', cookie.domain
|
449
|
+
end
|
409
450
|
end
|
410
451
|
|
@@ -47,13 +47,19 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
47
47
|
assert_equal(2, @jar.cookies(url2).length)
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
51
|
-
url = URI.parse('http://
|
50
|
+
def test_host_only
|
51
|
+
url = URI.parse('http://rubyforge.org/')
|
52
52
|
|
53
53
|
@jar.add(url, Mechanize::Cookie.new(
|
54
54
|
cookie_values(:domain => 'rubyforge.org', :for_domain => false)))
|
55
55
|
|
56
|
-
assert_equal(
|
56
|
+
assert_equal(1, @jar.cookies(url).length)
|
57
|
+
|
58
|
+
assert_equal(1, @jar.cookies(URI('http://RubyForge.org/')).length)
|
59
|
+
|
60
|
+
assert_equal(1, @jar.cookies(URI('https://RubyForge.org/')).length)
|
61
|
+
|
62
|
+
assert_equal(0, @jar.cookies(URI('http://www.rubyforge.org/')).length)
|
57
63
|
end
|
58
64
|
|
59
65
|
def test_empty_value
|
@@ -601,6 +601,26 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
601
601
|
assert_equal 'part', body.read
|
602
602
|
end
|
603
603
|
|
604
|
+
def test_response_content_encoding_gzip_encoding_bad
|
605
|
+
def @res.content_length() 24 end
|
606
|
+
@res.instance_variable_set(:@header,
|
607
|
+
'content-encoding' => %w[gzip],
|
608
|
+
'content-type' => 'text/html; charset=UTF-8')
|
609
|
+
|
610
|
+
# "test\xB2"
|
611
|
+
body_io = StringIO.new \
|
612
|
+
"\037\213\b\000*+\314N\000\003+I-.\331\004\000x\016\003\376\005\000\000\000"
|
613
|
+
|
614
|
+
body = @agent.response_content_encoding @res, body_io
|
615
|
+
|
616
|
+
expected = "test\xB2"
|
617
|
+
expected.force_encoding Encoding::BINARY if have_encoding?
|
618
|
+
|
619
|
+
content = body.read
|
620
|
+
assert_equal expected, content
|
621
|
+
assert_equal Encoding::BINARY, content.encoding if have_encoding?
|
622
|
+
end
|
623
|
+
|
604
624
|
def test_response_content_encoding_none
|
605
625
|
def @res.content_length() 4 end
|
606
626
|
@res.instance_variable_set :@header, 'content-encoding' => %w[none]
|
@@ -168,8 +168,8 @@ class TestMechanizePageEncoding < Mechanize::TestCase
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def test_parser_encoding_when_searching_elements
|
171
|
-
skip "Encoding not implemented" unless
|
172
|
-
|
171
|
+
skip "Encoding not implemented" unless have_encoding?
|
172
|
+
|
173
173
|
body = '<span id="latin1">hi</span>'
|
174
174
|
page = util_page body, 'content-type' => 'text/html,charset=ISO-8859-1'
|
175
175
|
|
metadata
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mechanize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 1
|
9
|
-
|
10
|
-
- 1
|
11
|
-
version: 2.1.pre.1
|
9
|
+
version: "2.1"
|
12
10
|
platform: ruby
|
13
11
|
authors:
|
14
12
|
- Eric Hodel
|
@@ -40,7 +38,7 @@ cert_chain:
|
|
40
38
|
x52qPcexcYZR7w==
|
41
39
|
-----END CERTIFICATE-----
|
42
40
|
|
43
|
-
date: 2011-
|
41
|
+
date: 2011-12-20 00:00:00 Z
|
44
42
|
dependencies:
|
45
43
|
- !ruby/object:Gem::Dependency
|
46
44
|
name: net-http-digest_auth
|
@@ -418,7 +416,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
418
416
|
requirements: []
|
419
417
|
|
420
418
|
rubyforge_project: mechanize
|
421
|
-
rubygems_version: 1.8.
|
419
|
+
rubygems_version: 1.8.12
|
422
420
|
signing_key:
|
423
421
|
specification_version: 3
|
424
422
|
summary: The Mechanize library is used for automating interaction with websites
|
metadata.gz.sig
CHANGED
Binary file
|