mechanize 2.2.1 → 2.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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG.rdoc +20 -0
- data/README.rdoc +3 -3
- data/lib/mechanize.rb +29 -14
- data/lib/mechanize/cookie.rb +13 -7
- data/lib/mechanize/download.rb +9 -0
- data/lib/mechanize/http/agent.rb +58 -17
- data/lib/mechanize/page.rb +6 -1
- data/lib/mechanize/pluggable_parsers.rb +4 -0
- data/lib/mechanize/test_case.rb +2 -4
- data/test/test_mechanize.rb +15 -7
- data/test/test_mechanize_cookie.rb +57 -10
- data/test/test_mechanize_download.rb +10 -0
- data/test/test_mechanize_http_agent.rb +104 -16
- data/test/test_mechanize_page.rb +36 -6
- data/test/test_mechanize_page_image.rb +1 -2
- data/test/test_mechanize_page_meta_refresh.rb +3 -6
- metadata +3 -4
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
= Mechanize CHANGELOG
|
2
2
|
|
3
|
+
=== 2.3 / 2012-02-20
|
4
|
+
|
5
|
+
* Minor enhancement
|
6
|
+
* Add support for the Max-Age attribute in the Set-Cookie header.
|
7
|
+
* Added Mechanize::Download#body for compatibility with Mechanize::File when
|
8
|
+
using Mechanize#get_file with Mechanize::Image or other Download-based
|
9
|
+
pluggable parser. Issue #202 by angas
|
10
|
+
* Mechanize#max_file_buffer may be set to nil to disable creation of
|
11
|
+
Tempfiles.
|
12
|
+
|
13
|
+
* Bug fixes
|
14
|
+
* Applied Mechanize#max_file_buffer to the Content-Encoding handlers as well
|
15
|
+
to prevent extra Tempfiles for small gzip or deflate response
|
16
|
+
* Increased the default Mechanize#max_file_buffer to 100,000 bytes. This
|
17
|
+
gives ~5MB of response bodies in memory with the default history setting
|
18
|
+
of 50 pages (depending on GC behavior).
|
19
|
+
* Ignore empty path/domain attributes.
|
20
|
+
* Cookies with an empty Expires attribute value were stored as session
|
21
|
+
cookies but cookies without the Expires attribute were not. Issue #78
|
22
|
+
|
3
23
|
=== 2.2.1 / 2012-02-13
|
4
24
|
|
5
25
|
* Bug fixes
|
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= Mechanize
|
2
2
|
|
3
3
|
* http://mechanize.rubyforge.org
|
4
|
-
*
|
4
|
+
* https://github.com/tenderlove/mechanize
|
5
5
|
|
6
6
|
== DESCRIPTION
|
7
7
|
|
@@ -24,7 +24,7 @@ The mechanize mailing list is available here:
|
|
24
24
|
|
25
25
|
The bug tracker is available here:
|
26
26
|
|
27
|
-
*
|
27
|
+
* https://github.com/tenderlove/mechanize/issues
|
28
28
|
|
29
29
|
== Examples
|
30
30
|
|
@@ -40,7 +40,7 @@ Copyright (c) 2006-2011:
|
|
40
40
|
* {Aaron Patterson}[http://tenderlovemaking.com] (aaronp@rubyforge.org)
|
41
41
|
* {Mike Dalessio}[http://mike.daless.io] (mike@csa.net)
|
42
42
|
|
43
|
-
Copyright (c) 2011:
|
43
|
+
Copyright (c) 2011-2012:
|
44
44
|
|
45
45
|
* {Eric Hodel}[http://blog.segment7.net] (drbrain@segment7.net)
|
46
46
|
* {Akinori MUSHA}[http://blog.akinori.org] (knu@idaemons.org)
|
data/lib/mechanize.rb
CHANGED
@@ -73,7 +73,7 @@ class Mechanize
|
|
73
73
|
##
|
74
74
|
# The version of Mechanize you are using.
|
75
75
|
|
76
|
-
VERSION = '2.
|
76
|
+
VERSION = '2.3'
|
77
77
|
|
78
78
|
##
|
79
79
|
# Base mechanize error class
|
@@ -207,7 +207,9 @@ class Mechanize
|
|
207
207
|
end
|
208
208
|
|
209
209
|
##
|
210
|
-
# Maximum number of items allowed in the history.
|
210
|
+
# Maximum number of items allowed in the history. The default setting is 50
|
211
|
+
# pages. Note that the size of the history multiplied by the maximum
|
212
|
+
# response body size
|
211
213
|
|
212
214
|
def max_history
|
213
215
|
@agent.history.max_size
|
@@ -217,9 +219,11 @@ class Mechanize
|
|
217
219
|
# Sets the maximum number of items allowed in the history to +length+.
|
218
220
|
#
|
219
221
|
# Setting the maximum history length to nil will make the history size
|
220
|
-
# unlimited. Take care when doing this, mechanize stores
|
221
|
-
#
|
222
|
-
# mechanize program this can be quite large.
|
222
|
+
# unlimited. Take care when doing this, mechanize stores response bodies in
|
223
|
+
# memory for pages and in the temporary files directory for other responses.
|
224
|
+
# For a long-running mechanize program this can be quite large.
|
225
|
+
#
|
226
|
+
# See also the discussion under #max_file_buffer=
|
223
227
|
|
224
228
|
def max_history= length
|
225
229
|
@agent.history.max_size = length
|
@@ -295,7 +299,7 @@ class Mechanize
|
|
295
299
|
end
|
296
300
|
if link.noreferrer?
|
297
301
|
href = @agent.resolve(link.href, link.page || current_page)
|
298
|
-
referer = Page.new
|
302
|
+
referer = Page.new
|
299
303
|
else
|
300
304
|
href = link.href
|
301
305
|
end
|
@@ -382,9 +386,9 @@ class Mechanize
|
|
382
386
|
|
383
387
|
referer ||=
|
384
388
|
if uri.to_s =~ %r{\Ahttps?://}
|
385
|
-
Page.new
|
389
|
+
Page.new
|
386
390
|
else
|
387
|
-
current_page || Page.new
|
391
|
+
current_page || Page.new
|
388
392
|
end
|
389
393
|
|
390
394
|
# FIXME: Huge hack so that using a URI as a referer works. I need to
|
@@ -392,9 +396,9 @@ class Mechanize
|
|
392
396
|
# Mechanize::Page#base
|
393
397
|
unless Mechanize::Parser === referer then
|
394
398
|
referer = if referer.is_a?(String) then
|
395
|
-
Page.new URI(referer)
|
399
|
+
Page.new URI(referer)
|
396
400
|
else
|
397
|
-
Page.new referer
|
401
|
+
Page.new referer
|
398
402
|
end
|
399
403
|
end
|
400
404
|
|
@@ -479,7 +483,7 @@ class Mechanize
|
|
479
483
|
# as the request body, if allowed.
|
480
484
|
|
481
485
|
def request_with_entity(verb, uri, entity, headers = {})
|
482
|
-
cur_page = current_page || Page.new
|
486
|
+
cur_page = current_page || Page.new
|
483
487
|
|
484
488
|
headers = {
|
485
489
|
'Content-Type' => 'application/octet-stream',
|
@@ -757,7 +761,9 @@ class Mechanize
|
|
757
761
|
|
758
762
|
##
|
759
763
|
# Responses larger than this will be written to a Tempfile instead of stored
|
760
|
-
# in memory. The default is
|
764
|
+
# in memory. The default is 100,000 bytes.
|
765
|
+
#
|
766
|
+
# A value of nil disables creation of Tempfiles.
|
761
767
|
|
762
768
|
def max_file_buffer
|
763
769
|
@agent.max_file_buffer
|
@@ -765,7 +771,16 @@ class Mechanize
|
|
765
771
|
|
766
772
|
##
|
767
773
|
# Sets the maximum size of a response body that will be stored in memory to
|
768
|
-
# +bytes
|
774
|
+
# +bytes+. A value of nil causes all response bodies to be stored in
|
775
|
+
# memory.
|
776
|
+
#
|
777
|
+
# Note that for Mechanize::Download subclasses, the maximum buffer size
|
778
|
+
# multiplied by the number of pages stored in history (controlled by
|
779
|
+
# #max_history) is an approximate upper limit on the amount of memory
|
780
|
+
# Mechanize will use. By default, Mechanize can use up to ~5MB to store
|
781
|
+
# response bodies for non-File and non-Page (HTML) responses.
|
782
|
+
#
|
783
|
+
# See also the discussion under #max_history=
|
769
784
|
|
770
785
|
def max_file_buffer= bytes
|
771
786
|
@agent.max_file_buffer = bytes
|
@@ -1152,7 +1167,7 @@ class Mechanize
|
|
1152
1167
|
|
1153
1168
|
def post_form(uri, form, headers = {})
|
1154
1169
|
cur_page = form.page || current_page ||
|
1155
|
-
Page.new
|
1170
|
+
Page.new
|
1156
1171
|
|
1157
1172
|
request_data = form.request_data
|
1158
1173
|
|
data/lib/mechanize/cookie.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'time'
|
2
|
-
require 'webrick/
|
2
|
+
require 'webrick/httputils'
|
3
3
|
require 'domain_name'
|
4
4
|
|
5
5
|
# This class is used to represent an HTTP Cookie.
|
@@ -93,12 +93,13 @@ class Mechanize::Cookie
|
|
93
93
|
|
94
94
|
cookie_elem.each do |pair|
|
95
95
|
pair.strip!
|
96
|
-
key, value = pair.split(
|
96
|
+
key, value = pair.split(/=/, 2)
|
97
97
|
next unless key
|
98
98
|
value = WEBrick::HTTPUtils.dequote(value.strip) if value
|
99
99
|
|
100
100
|
case key.downcase
|
101
101
|
when 'domain'
|
102
|
+
next unless value && !value.empty?
|
102
103
|
begin
|
103
104
|
cookie.domain = value
|
104
105
|
cookie.for_domain = true
|
@@ -106,27 +107,27 @@ class Mechanize::Cookie
|
|
106
107
|
log.warn("Couldn't parse domain: #{value}") if log
|
107
108
|
end
|
108
109
|
when 'path'
|
110
|
+
next unless value && !value.empty?
|
109
111
|
cookie.path = value
|
110
112
|
when 'expires'
|
111
|
-
|
112
|
-
cookie.session = true
|
113
|
-
next
|
114
|
-
end
|
115
|
-
|
113
|
+
next unless value && !value.empty?
|
116
114
|
begin
|
117
115
|
cookie.expires = Time::parse(value)
|
118
116
|
rescue
|
119
117
|
log.warn("Couldn't parse expires: #{value}") if log
|
120
118
|
end
|
121
119
|
when 'max-age'
|
120
|
+
next unless value && !value.empty?
|
122
121
|
begin
|
123
122
|
cookie.max_age = Integer(value)
|
124
123
|
rescue
|
125
124
|
log.warn("Couldn't parse max age '#{value}'") if log
|
126
125
|
end
|
127
126
|
when 'comment'
|
127
|
+
next unless value
|
128
128
|
cookie.comment = value
|
129
129
|
when 'version'
|
130
|
+
next unless value
|
130
131
|
begin
|
131
132
|
cookie.version = Integer(value)
|
132
133
|
rescue
|
@@ -141,6 +142,11 @@ class Mechanize::Cookie
|
|
141
142
|
cookie.path ||= (uri + './').path
|
142
143
|
cookie.secure ||= false
|
143
144
|
cookie.domain ||= uri.host
|
145
|
+
|
146
|
+
# RFC 6265 4.1.2.2
|
147
|
+
cookie.expires = Time.now + cookie.max_age if cookie.max_age
|
148
|
+
cookie.session = !cookie.expires
|
149
|
+
|
144
150
|
# Move this in to the cookie jar
|
145
151
|
yield cookie if block_given?
|
146
152
|
|
data/lib/mechanize/download.rb
CHANGED
@@ -40,6 +40,15 @@ class Mechanize::Download
|
|
40
40
|
yield self if block_given?
|
41
41
|
end
|
42
42
|
|
43
|
+
##
|
44
|
+
# The body of this response as a String.
|
45
|
+
#
|
46
|
+
# Take care, this may use lots of memory if the response body is large.
|
47
|
+
|
48
|
+
def body
|
49
|
+
@body_io.read.tap { @body_io.rewind }
|
50
|
+
end
|
51
|
+
|
43
52
|
##
|
44
53
|
# Saves a copy of the body_io to +filename+
|
45
54
|
|
data/lib/mechanize/http/agent.rb
CHANGED
@@ -98,7 +98,7 @@ class Mechanize::HTTP::Agent
|
|
98
98
|
attr_accessor :cookie_jar
|
99
99
|
|
100
100
|
# Responses larger than this will be written to a Tempfile instead of stored
|
101
|
-
# in memory.
|
101
|
+
# in memory. Setting this to nil disables creation of Tempfiles.
|
102
102
|
attr_accessor :max_file_buffer
|
103
103
|
|
104
104
|
# :section: Utility
|
@@ -126,7 +126,7 @@ class Mechanize::HTTP::Agent
|
|
126
126
|
@gzip_enabled = true
|
127
127
|
@history = Mechanize::History.new
|
128
128
|
@keep_alive = true
|
129
|
-
@max_file_buffer =
|
129
|
+
@max_file_buffer = 100_000 # 5MB for response bodies
|
130
130
|
@open_timeout = nil
|
131
131
|
@post_connect_hooks = []
|
132
132
|
@pre_connect_hooks = []
|
@@ -375,14 +375,7 @@ class Mechanize::HTTP::Agent
|
|
375
375
|
log.debug('gzip response') if log
|
376
376
|
|
377
377
|
zio = Zlib::GzipReader.new body_io
|
378
|
-
out_io =
|
379
|
-
out_io.unlink
|
380
|
-
out_io.binmode
|
381
|
-
|
382
|
-
until zio.eof? do
|
383
|
-
out_io.write zio.read 16384
|
384
|
-
end
|
385
|
-
|
378
|
+
out_io = auto_io 'mechanize-gunzip', 16384, zio
|
386
379
|
zio.finish
|
387
380
|
|
388
381
|
return out_io
|
@@ -400,6 +393,7 @@ class Mechanize::HTTP::Agent
|
|
400
393
|
end
|
401
394
|
ensure
|
402
395
|
zio.close if zio and not zio.closed?
|
396
|
+
body_io.close unless body_io.closed?
|
403
397
|
end
|
404
398
|
|
405
399
|
##
|
@@ -421,6 +415,8 @@ class Mechanize::HTTP::Agent
|
|
421
415
|
log.error("unable to inflate response: #{e}") if log
|
422
416
|
raise
|
423
417
|
end
|
418
|
+
ensure
|
419
|
+
body_io.close
|
424
420
|
end
|
425
421
|
|
426
422
|
def disable_keep_alive request
|
@@ -739,7 +735,10 @@ class Mechanize::HTTP::Agent
|
|
739
735
|
raise Mechanize::Error, message
|
740
736
|
ensure
|
741
737
|
begin
|
742
|
-
|
738
|
+
if Tempfile === body_io and
|
739
|
+
(StringIO === out_io or out_io.path != body_io.path) then
|
740
|
+
body_io.close!
|
741
|
+
end
|
743
742
|
rescue IOError
|
744
743
|
# HACK ruby 1.8 raises IOError when closing the stream
|
745
744
|
end
|
@@ -783,7 +782,7 @@ class Mechanize::HTTP::Agent
|
|
783
782
|
sleep delay
|
784
783
|
@history.push(page, page.uri)
|
785
784
|
fetch new_url, :get, {}, [],
|
786
|
-
Mechanize::Page.new
|
785
|
+
Mechanize::Page.new, redirects
|
787
786
|
end
|
788
787
|
|
789
788
|
def response_log response
|
@@ -804,7 +803,7 @@ class Mechanize::HTTP::Agent
|
|
804
803
|
def response_read response, request, uri
|
805
804
|
content_length = response.content_length
|
806
805
|
|
807
|
-
if
|
806
|
+
if use_tempfile? content_length then
|
808
807
|
body_io = Tempfile.new 'mechanize-raw'
|
809
808
|
body_io.unlink
|
810
809
|
body_io.binmode if defined? body_io.binmode
|
@@ -819,7 +818,7 @@ class Mechanize::HTTP::Agent
|
|
819
818
|
response.read_body { |part|
|
820
819
|
total += part.length
|
821
820
|
|
822
|
-
if StringIO === body_io and total
|
821
|
+
if StringIO === body_io and use_tempfile? total then
|
823
822
|
new_io = Tempfile.new 'mechanize-raw'
|
824
823
|
new_io.unlink
|
825
824
|
new_io.binmode
|
@@ -1034,17 +1033,52 @@ class Mechanize::HTTP::Agent
|
|
1034
1033
|
|
1035
1034
|
# :section: Utility
|
1036
1035
|
|
1036
|
+
##
|
1037
|
+
# Creates a new output IO by reading +input_io+ in +read_size+ chunks. If
|
1038
|
+
# the output is over the max_file_buffer size a Tempfile with +name+ is
|
1039
|
+
# created.
|
1040
|
+
#
|
1041
|
+
# If a block is provided, each chunk of +input_io+ is yielded for further
|
1042
|
+
# processing.
|
1043
|
+
|
1044
|
+
def auto_io name, read_size, input_io
|
1045
|
+
out_io = StringIO.new
|
1046
|
+
|
1047
|
+
out_io.set_encoding Encoding::BINARY if out_io.respond_to? :set_encoding
|
1048
|
+
|
1049
|
+
until input_io.eof? do
|
1050
|
+
if StringIO === out_io and use_tempfile? out_io.size then
|
1051
|
+
new_io = Tempfile.new name
|
1052
|
+
new_io.unlink
|
1053
|
+
new_io.binmode
|
1054
|
+
|
1055
|
+
new_io.write out_io.string
|
1056
|
+
out_io = new_io
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
chunk = input_io.read read_size
|
1060
|
+
chunk = yield chunk if block_given?
|
1061
|
+
|
1062
|
+
out_io.write chunk
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
out_io.rewind
|
1066
|
+
|
1067
|
+
out_io
|
1068
|
+
end
|
1069
|
+
|
1037
1070
|
def inflate compressed, window_bits = nil
|
1038
1071
|
inflate = Zlib::Inflate.new window_bits
|
1039
|
-
out_io = Tempfile.new 'mechanize-decode'
|
1040
1072
|
|
1041
|
-
|
1042
|
-
|
1073
|
+
out_io = auto_io 'mechanize-inflate', 1024, compressed do |chunk|
|
1074
|
+
inflate.inflate chunk
|
1043
1075
|
end
|
1044
1076
|
|
1045
1077
|
out_io.write inflate.finish
|
1046
1078
|
|
1047
1079
|
out_io
|
1080
|
+
ensure
|
1081
|
+
inflate.close
|
1048
1082
|
end
|
1049
1083
|
|
1050
1084
|
def log
|
@@ -1083,5 +1117,12 @@ class Mechanize::HTTP::Agent
|
|
1083
1117
|
@http.proxy = proxy_uri
|
1084
1118
|
end
|
1085
1119
|
|
1120
|
+
def use_tempfile? size
|
1121
|
+
return false unless @max_file_buffer
|
1122
|
+
return false unless size
|
1123
|
+
|
1124
|
+
size >= @max_file_buffer
|
1125
|
+
end
|
1126
|
+
|
1086
1127
|
end
|
1087
1128
|
|
data/lib/mechanize/page.rb
CHANGED
@@ -13,6 +13,10 @@ class Mechanize::Page < Mechanize::File
|
|
13
13
|
extend Forwardable
|
14
14
|
extend Mechanize::ElementMatcher
|
15
15
|
|
16
|
+
DEFAULT_RESPONSE = {
|
17
|
+
'content-type' => 'text/html',
|
18
|
+
}.freeze
|
19
|
+
|
16
20
|
attr_accessor :mech
|
17
21
|
|
18
22
|
##
|
@@ -21,8 +25,9 @@ class Mechanize::Page < Mechanize::File
|
|
21
25
|
attr_reader :encodings
|
22
26
|
|
23
27
|
def initialize(uri=nil, response=nil, body=nil, code=nil, mech=nil)
|
28
|
+
response ||= DEFAULT_RESPONSE
|
24
29
|
raise Mechanize::ContentTypeError, response['content-type'] unless
|
25
|
-
response['content-type'] =~
|
30
|
+
response['content-type'] =~ %r{\A(?:text/html|application/xhtml\+xml)(?:$|\s*[\s;,])}i
|
26
31
|
|
27
32
|
@meta_content_type = nil
|
28
33
|
@encoding = nil
|
@@ -16,6 +16,10 @@ require 'mechanize/page'
|
|
16
16
|
# Mechanize::File. For large files you should subclass Mechanize::Download as
|
17
17
|
# the content is only loaded into memory in small chunks.
|
18
18
|
#
|
19
|
+
# When writing your own pluggable parser, be sure to provide a method #body
|
20
|
+
# that returns a String containing the response body for compatibility with
|
21
|
+
# Mechanize#get_file.
|
22
|
+
#
|
19
23
|
# == Example
|
20
24
|
#
|
21
25
|
# To create your own parser, just create a class that takes four parameters in
|
data/lib/mechanize/test_case.rb
CHANGED
@@ -38,9 +38,7 @@ class Mechanize::TestCase < MiniTest::Unit::TestCase
|
|
38
38
|
</html>
|
39
39
|
END
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
Mechanize::Page.new uri, response, html, 200, agent
|
41
|
+
Mechanize::Page.new uri, nil, html, 200, agent
|
44
42
|
end
|
45
43
|
|
46
44
|
def have_encoding?
|
@@ -49,7 +47,7 @@ class Mechanize::TestCase < MiniTest::Unit::TestCase
|
|
49
47
|
|
50
48
|
def html_page body
|
51
49
|
uri = URI 'http://example/'
|
52
|
-
Mechanize::Page.new uri,
|
50
|
+
Mechanize::Page.new uri, nil, body, 200, @mech
|
53
51
|
end
|
54
52
|
|
55
53
|
def in_tmpdir
|
data/test/test_mechanize.rb
CHANGED
@@ -388,13 +388,6 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
388
388
|
assert block_called
|
389
389
|
end
|
390
390
|
|
391
|
-
def test_get_file
|
392
|
-
page = @mech.get("http://localhost/frame_test.html")
|
393
|
-
content_length = page.header['Content-Length']
|
394
|
-
page_as_string = @mech.get_file("http://localhost/frame_test.html")
|
395
|
-
assert_equal(content_length.to_i, page_as_string.length.to_i)
|
396
|
-
end
|
397
|
-
|
398
391
|
def test_get_follow_meta_refresh
|
399
392
|
@mech.follow_meta_refresh = true
|
400
393
|
|
@@ -696,6 +689,21 @@ but not <a href="/" rel="me nofollow">this</a>!
|
|
696
689
|
assert_equal('File Upload Form', pages.title)
|
697
690
|
end
|
698
691
|
|
692
|
+
def test_get_file
|
693
|
+
body = @mech.get_file 'http://localhost/frame_test.html'
|
694
|
+
|
695
|
+
assert_kind_of String, body
|
696
|
+
refute_empty body
|
697
|
+
end
|
698
|
+
|
699
|
+
def test_get_file_download
|
700
|
+
# non-Mechanize::File
|
701
|
+
body = @mech.get_file 'http://localhost/button.jpg'
|
702
|
+
|
703
|
+
assert_kind_of String, body
|
704
|
+
refute_empty body
|
705
|
+
end
|
706
|
+
|
699
707
|
def test_head
|
700
708
|
page = @mech.head('http://localhost/verb', { 'q' => 'foo' })
|
701
709
|
assert_equal 0, @mech.history.length
|
@@ -179,14 +179,46 @@ class TestMechanizeCookie < Mechanize::TestCase
|
|
179
179
|
assert !cookie.for_domain?
|
180
180
|
end
|
181
181
|
|
182
|
-
def
|
183
|
-
|
182
|
+
def test_parse_max_age
|
183
|
+
url = URI.parse('http://localhost/')
|
184
|
+
|
185
|
+
date = 'Mon, 19 Feb 2012 19:26:04 GMT'
|
186
|
+
|
187
|
+
cookie = Mechanize::Cookie.parse(url, "name=Akinori; expires=#{date}").first
|
188
|
+
assert_equal Time.at(1329679564), cookie.expires
|
189
|
+
|
190
|
+
cookie = Mechanize::Cookie.parse(url, 'name=Akinori; max-age=3600').first
|
191
|
+
assert_in_delta Time.now + 3600, cookie.expires, 1
|
192
|
+
|
193
|
+
# Max-Age has precedence over Expires
|
194
|
+
cookie = Mechanize::Cookie.parse(url, "name=Akinori; max-age=3600; expires=#{date}").first
|
195
|
+
assert_in_delta Time.now + 3600, cookie.expires, 1
|
196
|
+
|
197
|
+
cookie = Mechanize::Cookie.parse(url, "name=Akinori; expires=#{date}; max-age=3600").first
|
198
|
+
assert_in_delta Time.now + 3600, cookie.expires, 1
|
199
|
+
end
|
184
200
|
|
201
|
+
def test_parse_expires_session
|
185
202
|
url = URI.parse('http://localhost/')
|
186
203
|
|
187
|
-
|
204
|
+
[
|
205
|
+
'name=Akinori',
|
206
|
+
'name=Akinori; expires',
|
207
|
+
'name=Akinori; max-age',
|
208
|
+
'name=Akinori; expires=',
|
209
|
+
'name=Akinori; max-age=',
|
210
|
+
].each { |str|
|
211
|
+
cookie = Mechanize::Cookie.parse(url, str).first
|
212
|
+
assert cookie.session, str
|
213
|
+
}
|
188
214
|
|
189
|
-
|
215
|
+
[
|
216
|
+
'name=Akinori; expires=Mon, 19 Feb 2012 19:26:04 GMT',
|
217
|
+
'name=Akinori; max-age=3600',
|
218
|
+
].each { |str|
|
219
|
+
cookie = Mechanize::Cookie.parse(url, str).first
|
220
|
+
assert !cookie.session, str
|
221
|
+
}
|
190
222
|
end
|
191
223
|
|
192
224
|
def test_parse_many
|
@@ -198,10 +230,15 @@ class TestMechanizeCookie < Mechanize::TestCase
|
|
198
230
|
"name=Aaron; Domain=localhost; Expires=Sun, 06 Nov 2011 00:29:51 GMT; Path=/; HttpOnly, " \
|
199
231
|
"expired=doh; Expires=Fri, 04 Nov 2011 00:29:51 GMT; Path=/, " \
|
200
232
|
"a_path=some_path; Expires=Sun, 06 Nov 2011 00:29:51 GMT; Path=/some_path, " \
|
201
|
-
"
|
233
|
+
"no_path1=no_path; Expires=Sun, 06 Nov 2011 00:29:52 GMT, no_expires=nope; Path=/, " \
|
234
|
+
"no_path2=no_path; Expires=Sun, 06 Nov 2011 00:29:52 GMT; no_expires=nope; Path, " \
|
235
|
+
"no_path3=no_path; Expires=Sun, 06 Nov 2011 00:29:52 GMT; no_expires=nope; Path=, " \
|
236
|
+
"no_domain1=no_domain; Expires=Sun, 06 Nov 2011 00:29:53 GMT; no_expires=nope, " \
|
237
|
+
"no_domain2=no_domain; Expires=Sun, 06 Nov 2011 00:29:53 GMT; no_expires=nope; Domain, " \
|
238
|
+
"no_domain3=no_domain; Expires=Sun, 06 Nov 2011 00:29:53 GMT; no_expires=nope; Domain="
|
202
239
|
|
203
240
|
cookies = Mechanize::Cookie.parse url, cookie_str
|
204
|
-
assert_equal
|
241
|
+
assert_equal 13, cookies.length
|
205
242
|
|
206
243
|
name = cookies.find { |c| c.name == 'name' }
|
207
244
|
assert_equal "Aaron", name.value
|
@@ -218,10 +255,20 @@ class TestMechanizeCookie < Mechanize::TestCase
|
|
218
255
|
assert_equal "/", no_expires.path
|
219
256
|
assert_nil no_expires.expires
|
220
257
|
|
221
|
-
|
222
|
-
assert_equal
|
223
|
-
|
224
|
-
|
258
|
+
no_path_cookies = cookies.select { |c| c.value == 'no_path' }
|
259
|
+
assert_equal 3, no_path_cookies.size
|
260
|
+
no_path_cookies.each { |c|
|
261
|
+
assert_equal "/", c.path, c.name
|
262
|
+
assert_equal Time.at(1320539392), c.expires, c.name
|
263
|
+
}
|
264
|
+
|
265
|
+
no_domain_cookies = cookies.select { |c| c.value == 'no_domain' }
|
266
|
+
assert_equal 3, no_domain_cookies.size
|
267
|
+
no_domain_cookies.each { |c|
|
268
|
+
assert !c.for_domain?, c.name
|
269
|
+
assert_equal c.domain, url.host, c.name
|
270
|
+
assert_equal Time.at(1320539393), c.expires, c.name
|
271
|
+
}
|
225
272
|
|
226
273
|
assert cookies.find { |c| c.name == 'expired' }
|
227
274
|
end
|
@@ -8,6 +8,16 @@ class TestMechanizeDownload < Mechanize::TestCase
|
|
8
8
|
@parser = Mechanize::Download
|
9
9
|
end
|
10
10
|
|
11
|
+
def test_body
|
12
|
+
uri = URI.parse 'http://example/foo.html'
|
13
|
+
body_io = StringIO.new '0123456789'
|
14
|
+
|
15
|
+
download = @parser.new uri, nil, body_io
|
16
|
+
|
17
|
+
assert_equal '0123456789', download.body
|
18
|
+
assert_equal 0, download.body_io.pos
|
19
|
+
end
|
20
|
+
|
11
21
|
def test_save_string_io
|
12
22
|
uri = URI.parse 'http://example/foo.html'
|
13
23
|
body_io = StringIO.new '0123456789'
|
@@ -31,6 +31,69 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
31
31
|
realm
|
32
32
|
end
|
33
33
|
|
34
|
+
def test_auto_io
|
35
|
+
Tempfile.open 'input' do |input_io|
|
36
|
+
input_io.binmode
|
37
|
+
input_io.write '12345'
|
38
|
+
input_io.rewind
|
39
|
+
|
40
|
+
out_io = @agent.auto_io __name__, 1024, input_io
|
41
|
+
|
42
|
+
assert_equal '12345', out_io.string
|
43
|
+
|
44
|
+
assert_equal Encoding::BINARY, out_io.string.encoding if
|
45
|
+
Object.const_defined? :Encoding
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_auto_io_chunk
|
50
|
+
Tempfile.open 'input' do |input_io|
|
51
|
+
chunks = []
|
52
|
+
|
53
|
+
input_io.binmode
|
54
|
+
input_io.write '12345'
|
55
|
+
input_io.rewind
|
56
|
+
|
57
|
+
@agent.auto_io __name__, 1, input_io do |chunk|
|
58
|
+
chunks << chunk
|
59
|
+
end
|
60
|
+
|
61
|
+
assert_equal %w[1 2 3 4 5], chunks
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_auto_io_tempfile
|
66
|
+
@agent.max_file_buffer = 3
|
67
|
+
|
68
|
+
Tempfile.open 'input' do |input_io|
|
69
|
+
input_io.binmode
|
70
|
+
input_io.write '12345'
|
71
|
+
input_io.rewind
|
72
|
+
|
73
|
+
out_io = @agent.auto_io __name__, 1, input_io
|
74
|
+
|
75
|
+
result = out_io.read
|
76
|
+
assert_equal '12345', result
|
77
|
+
|
78
|
+
assert_equal Encoding::BINARY, result.encoding if
|
79
|
+
Object.const_defined? :Encoding
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_auto_io_yield
|
84
|
+
Tempfile.open 'input' do |input_io|
|
85
|
+
input_io.binmode
|
86
|
+
input_io.write '12345'
|
87
|
+
input_io.rewind
|
88
|
+
|
89
|
+
out_io = @agent.auto_io __name__, 1024, input_io do |chunk|
|
90
|
+
"x#{chunk}"
|
91
|
+
end
|
92
|
+
|
93
|
+
assert_equal 'x12345', out_io.string
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
34
97
|
def test_certificate_equals
|
35
98
|
cert_path = File.expand_path '../data/server.crt', __FILE__
|
36
99
|
cert = OpenSSL::X509::Certificate.new File.read cert_path
|
@@ -176,8 +239,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
176
239
|
@agent.follow_meta_refresh = true
|
177
240
|
@agent.follow_meta_refresh_self = true
|
178
241
|
|
179
|
-
page = Mechanize::Page.new(@uri,
|
180
|
-
200, @mech)
|
242
|
+
page = Mechanize::Page.new(@uri, nil, '', 200, @mech)
|
181
243
|
@res.instance_variable_set :@header, 'refresh' => ['0']
|
182
244
|
|
183
245
|
refresh = @agent.get_meta_refresh @res, @uri, page
|
@@ -186,8 +248,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
186
248
|
end
|
187
249
|
|
188
250
|
def test_get_meta_refresh_header_no_follow
|
189
|
-
page = Mechanize::Page.new(@uri,
|
190
|
-
200, @mech)
|
251
|
+
page = Mechanize::Page.new(@uri, nil, '', 200, @mech)
|
191
252
|
@res.instance_variable_set :@header, 'refresh' => ['0']
|
192
253
|
|
193
254
|
refresh = @agent.get_meta_refresh @res, @uri, page
|
@@ -198,8 +259,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
198
259
|
def test_get_meta_refresh_header_no_follow_self
|
199
260
|
@agent.follow_meta_refresh = true
|
200
261
|
|
201
|
-
page = Mechanize::Page.new(@uri,
|
202
|
-
200, @mech)
|
262
|
+
page = Mechanize::Page.new(@uri, nil, '', 200, @mech)
|
203
263
|
@res.instance_variable_set :@header, 'refresh' => ['0']
|
204
264
|
|
205
265
|
refresh = @agent.get_meta_refresh @res, @uri, page
|
@@ -216,8 +276,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
216
276
|
<meta http-equiv="refresh" content="0">
|
217
277
|
BODY
|
218
278
|
|
219
|
-
page = Mechanize::Page.new(@uri,
|
220
|
-
200, @mech)
|
279
|
+
page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
|
221
280
|
|
222
281
|
refresh = @agent.get_meta_refresh @res, @uri, page
|
223
282
|
|
@@ -230,8 +289,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
230
289
|
<meta http-equiv="refresh" content="0">
|
231
290
|
BODY
|
232
291
|
|
233
|
-
page = Mechanize::Page.new(@uri,
|
234
|
-
200, @mech)
|
292
|
+
page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
|
235
293
|
|
236
294
|
refresh = @agent.get_meta_refresh @res, @uri, page
|
237
295
|
|
@@ -246,8 +304,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
246
304
|
<meta http-equiv="refresh" content="0">
|
247
305
|
BODY
|
248
306
|
|
249
|
-
page = Mechanize::Page.new(@uri,
|
250
|
-
200, @mech)
|
307
|
+
page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
|
251
308
|
|
252
309
|
refresh = @agent.get_meta_refresh @res, @uri, page
|
253
310
|
|
@@ -301,6 +358,14 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
301
358
|
assert_equal 1, @agent.http.idle_timeout
|
302
359
|
end
|
303
360
|
|
361
|
+
def test_inflate
|
362
|
+
body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
|
363
|
+
|
364
|
+
result = @agent.inflate body_io
|
365
|
+
|
366
|
+
assert_equal 'part', result.read
|
367
|
+
end
|
368
|
+
|
304
369
|
def test_post_connect
|
305
370
|
@agent.post_connect_hooks << proc { |agent, uri, response, body|
|
306
371
|
assert_equal @agent, agent
|
@@ -716,6 +781,8 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
716
781
|
body = @agent.response_content_encoding @res, body_io
|
717
782
|
|
718
783
|
assert_equal 'part', body.read
|
784
|
+
|
785
|
+
assert body_io.closed?
|
719
786
|
end
|
720
787
|
|
721
788
|
def test_response_content_encoding_deflate_chunked
|
@@ -737,6 +804,8 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
737
804
|
|
738
805
|
assert_match %r%error handling content-encoding deflate:%, e.message
|
739
806
|
assert_match %r%Zlib%, e.message
|
807
|
+
|
808
|
+
assert body_io.closed?
|
740
809
|
end
|
741
810
|
|
742
811
|
def test_response_content_encoding_deflate_empty
|
@@ -764,6 +833,8 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
764
833
|
body = @agent.response_content_encoding @res, body_io
|
765
834
|
|
766
835
|
assert_equal 'part', body.read
|
836
|
+
|
837
|
+
assert body_io.closed?
|
767
838
|
end
|
768
839
|
|
769
840
|
def test_response_content_encoding_gzip_chunked
|
@@ -795,6 +866,8 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
795
866
|
|
796
867
|
assert_match %r%unable to gunzip response, trying raw inflate%, log.string
|
797
868
|
assert_match %r%unable to gunzip response:%, log.string
|
869
|
+
|
870
|
+
assert body_io.closed?
|
798
871
|
end
|
799
872
|
|
800
873
|
def test_response_content_encoding_gzip_corrupt_checksum
|
@@ -958,8 +1031,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
958
1031
|
<meta http-equiv="refresh" content="0">
|
959
1032
|
BODY
|
960
1033
|
|
961
|
-
page = Mechanize::Page.new(uri,
|
962
|
-
200, @mech)
|
1034
|
+
page = Mechanize::Page.new(uri, nil, body, 200, @mech)
|
963
1035
|
|
964
1036
|
@agent.follow_meta_refresh = true
|
965
1037
|
@agent.follow_meta_refresh_self = true
|
@@ -977,8 +1049,7 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
977
1049
|
<meta http-equiv="refresh" content="0">
|
978
1050
|
BODY
|
979
1051
|
|
980
|
-
page = Mechanize::Page.new(uri,
|
981
|
-
200, @mech)
|
1052
|
+
page = Mechanize::Page.new(uri, nil, body, 200, @mech)
|
982
1053
|
|
983
1054
|
@agent.follow_meta_refresh = true
|
984
1055
|
@agent.follow_meta_refresh_self = true
|
@@ -1159,6 +1230,8 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
1159
1230
|
end
|
1160
1231
|
|
1161
1232
|
def test_response_read_large
|
1233
|
+
@agent.max_file_buffer = 10240
|
1234
|
+
|
1162
1235
|
def @res.read_body() yield 'a' * 10241 end
|
1163
1236
|
def @res.content_length() 10241 end
|
1164
1237
|
|
@@ -1169,6 +1242,8 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
1169
1242
|
end
|
1170
1243
|
|
1171
1244
|
def test_response_read_large_chunked
|
1245
|
+
@agent.max_file_buffer = 10240
|
1246
|
+
|
1172
1247
|
def @res.read_body
|
1173
1248
|
11.times do yield 'a' * 1024 end
|
1174
1249
|
end
|
@@ -1363,6 +1438,19 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
|
|
1363
1438
|
end
|
1364
1439
|
end
|
1365
1440
|
|
1441
|
+
def test_use_tempfile_eh
|
1442
|
+
refute @agent.use_tempfile? nil
|
1443
|
+
|
1444
|
+
@agent.max_file_buffer = 1
|
1445
|
+
|
1446
|
+
refute @agent.use_tempfile? 0
|
1447
|
+
assert @agent.use_tempfile? 1
|
1448
|
+
|
1449
|
+
@agent.max_file_buffer = nil
|
1450
|
+
|
1451
|
+
refute @agent.use_tempfile? 1
|
1452
|
+
end
|
1453
|
+
|
1366
1454
|
def test_verify_none_equals
|
1367
1455
|
@agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
1368
1456
|
|
data/test/test_mechanize_page.rb
CHANGED
@@ -8,13 +8,43 @@ class TestMechanizePage < Mechanize::TestCase
|
|
8
8
|
@uri = URI 'http://example/'
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def test_initialize_good_content_type
|
12
|
+
page = Mechanize::Page.new
|
13
|
+
assert_equal('text/html', page.content_type)
|
14
|
+
|
15
|
+
[
|
16
|
+
'text/html',
|
17
|
+
'Text/HTML',
|
18
|
+
'text/html; charset=UTF-8',
|
19
|
+
'text/html ; charset=US-ASCII',
|
20
|
+
'application/xhtml+xml',
|
21
|
+
'Application/XHTML+XML',
|
22
|
+
'application/xhtml+xml; charset=UTF-8',
|
23
|
+
'application/xhtml+xml ; charset=US-ASCII',
|
24
|
+
].each { |content_type|
|
25
|
+
page = Mechanize::Page.new(URI('http://example/'),
|
26
|
+
{ 'content-type' => content_type }, 'hello', '200')
|
27
|
+
|
28
|
+
assert_equal(content_type, page.content_type, content_type)
|
29
|
+
}
|
30
|
+
end
|
16
31
|
|
17
|
-
|
32
|
+
def test_initialize_bad_content_type
|
33
|
+
[
|
34
|
+
'text/xml',
|
35
|
+
'text/xhtml',
|
36
|
+
'text/htmlfu',
|
37
|
+
'footext/html',
|
38
|
+
'application/xhtml+xmlfu',
|
39
|
+
'fooapplication/xhtml+xml',
|
40
|
+
].each { |content_type|
|
41
|
+
e = assert_raises(Mechanize::ContentTypeError, content_type) do
|
42
|
+
Mechanize::Page.new(URI('http://example/'),
|
43
|
+
{ 'content-type' => content_type }, 'hello', '200')
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_equal(content_type, e.content_type, content_type)
|
47
|
+
}
|
18
48
|
end
|
19
49
|
|
20
50
|
def test_frames
|
@@ -8,8 +8,7 @@ class TestMechanizePageImage < Mechanize::TestCase
|
|
8
8
|
@uri = URI 'http://example/'
|
9
9
|
@src = (@uri + 'a.jpg').to_s
|
10
10
|
|
11
|
-
@empty_page = Mechanize::Page.new(@uri,
|
12
|
-
'', 200, @mech)
|
11
|
+
@empty_page = Mechanize::Page.new(@uri, nil, '', 200, @mech)
|
13
12
|
end
|
14
13
|
|
15
14
|
def img attributes
|
@@ -15,8 +15,7 @@ class TestMechanizePageMetaRefresh < Mechanize::TestCase
|
|
15
15
|
<head><meta http-equiv="refresh" content="#{delay};url=#{uri}"></head>
|
16
16
|
BODY
|
17
17
|
|
18
|
-
Mechanize::Page.new(@uri,
|
19
|
-
@mech)
|
18
|
+
Mechanize::Page.new(@uri, nil, body, 200, @mech)
|
20
19
|
end
|
21
20
|
|
22
21
|
def util_meta_refresh page
|
@@ -126,8 +125,7 @@ class TestMechanizePageMetaRefresh < Mechanize::TestCase
|
|
126
125
|
<head><meta http-equiv="refresh"></head>
|
127
126
|
BODY
|
128
127
|
|
129
|
-
page = Mechanize::Page.new(@uri,
|
130
|
-
200, @mech)
|
128
|
+
page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
|
131
129
|
|
132
130
|
assert_nil util_meta_refresh page
|
133
131
|
end
|
@@ -137,8 +135,7 @@ class TestMechanizePageMetaRefresh < Mechanize::TestCase
|
|
137
135
|
<head><meta http-equiv="other-thing" content="0;"></head>
|
138
136
|
BODY
|
139
137
|
|
140
|
-
page = Mechanize::Page.new(@uri,
|
141
|
-
200, @mech)
|
138
|
+
page = Mechanize::Page.new(@uri, nil, body, 200, @mech)
|
142
139
|
|
143
140
|
assert_nil util_meta_refresh page
|
144
141
|
end
|
metadata
CHANGED
@@ -5,9 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 2.2.1
|
8
|
+
- 3
|
9
|
+
version: "2.3"
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Eric Hodel
|
@@ -39,7 +38,7 @@ cert_chain:
|
|
39
38
|
YJY7T/W2n+eWy8WuPhzVUkyzguj0bQe27NDeabgCh2mHd4Hynk2AkYh8MQ==
|
40
39
|
-----END CERTIFICATE-----
|
41
40
|
|
42
|
-
date: 2012-02-
|
41
|
+
date: 2012-02-21 00:00:00 Z
|
43
42
|
dependencies:
|
44
43
|
- !ruby/object:Gem::Dependency
|
45
44
|
name: net-http-digest_auth
|
metadata.gz.sig
CHANGED
Binary file
|