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 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. Also, SSL connections will be
13
- verified against the system certificate store by default. Issue #123
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 can better pick
43
- the strongest method.
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 referer.is_a?(Mechanize::File)
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 === parser_klass then
978
+ unless parser_klass <= Mechanize::Download then
979
979
  body = case body
980
980
  when IO, Tempfile, StringIO then
981
981
  body.read
@@ -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
- cookie.domain = value
100
- cookie.for_domain = true
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.start_with?('.')
151
- @for_domain = true
152
- domain = domain[1..-1]
153
- end
154
- # Do we really need to support this?
155
- if domain.match(/\A([^:]+):[0-9]+\z/)
156
- domain = $1
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
 
@@ -51,7 +51,7 @@ class Mechanize::Download
51
51
  end
52
52
  end
53
53
  else
54
- FileUtils.cp @body_io.path, filename
54
+ FileUtils.mv @body_io.path, filename
55
55
  end
56
56
  end
57
57
 
@@ -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
- Mechanize::Cookie.parse(uri, meta['content'], log) { |c|
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 |cookie|
744
- Mechanize::Cookie.parse(uri, 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
- }
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
@@ -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
@@ -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 test_no_domain_case
51
- url = URI.parse('http://www.rubyforge.org/')
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(0, @jar.cookies(url).length)
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 Object.const_defined? :Encoding
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: 1923831923
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 1
9
- - pre
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-11-09 00:00:00 Z
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.10
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