mechanize 2.5.1 → 2.6.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.

Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +16 -0
  3. data/CHANGELOG.rdoc +54 -1
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +5 -5
  6. data/Rakefile +4 -2
  7. data/lib/mechanize.rb +53 -10
  8. data/lib/mechanize/cookie.rb +8 -2
  9. data/lib/mechanize/cookie_jar.rb +33 -7
  10. data/lib/mechanize/directory_saver.rb +14 -2
  11. data/lib/mechanize/download.rb +2 -0
  12. data/lib/mechanize/element_matcher.rb +17 -6
  13. data/lib/mechanize/file.rb +25 -1
  14. data/lib/mechanize/form.rb +73 -28
  15. data/lib/mechanize/form/field.rb +6 -2
  16. data/lib/mechanize/form/select_list.rb +4 -4
  17. data/lib/mechanize/http/agent.rb +36 -15
  18. data/lib/mechanize/http/auth_challenge.rb +7 -8
  19. data/lib/mechanize/http/content_disposition_parser.rb +1 -1
  20. data/lib/mechanize/http/www_authenticate_parser.rb +9 -4
  21. data/lib/mechanize/page.rb +38 -12
  22. data/lib/mechanize/page/image.rb +1 -1
  23. data/lib/mechanize/parser.rb +12 -3
  24. data/lib/mechanize/pluggable_parsers.rb +8 -3
  25. data/lib/mechanize/test_case.rb +13 -0
  26. data/lib/mechanize/test_case/digest_auth_servlet.rb +4 -4
  27. data/lib/mechanize/util.rb +2 -2
  28. data/lib/mechanize/xml_file.rb +47 -0
  29. data/test/htdocs/tc_follow_meta_loop_1.html +8 -0
  30. data/test/htdocs/tc_follow_meta_loop_2.html +8 -0
  31. data/test/test_mechanize.rb +66 -12
  32. data/test/test_mechanize_cookie.rb +34 -0
  33. data/test/test_mechanize_cookie_jar.rb +67 -1
  34. data/test/test_mechanize_directory_saver.rb +10 -0
  35. data/test/test_mechanize_file.rb +22 -4
  36. data/test/test_mechanize_form.rb +14 -0
  37. data/test/test_mechanize_form_field.rb +14 -0
  38. data/test/test_mechanize_form_multi_select_list.rb +9 -0
  39. data/test/test_mechanize_form_option.rb +4 -0
  40. data/test/test_mechanize_form_select_list.rb +4 -0
  41. data/test/test_mechanize_http_agent.rb +59 -11
  42. data/test/test_mechanize_http_auth_challenge.rb +1 -1
  43. data/test/test_mechanize_http_content_disposition_parser.rb +8 -0
  44. data/test/test_mechanize_http_www_authenticate_parser.rb +29 -12
  45. data/test/test_mechanize_page.rb +58 -0
  46. data/test/test_mechanize_page_encoding.rb +1 -1
  47. data/test/test_mechanize_page_image.rb +2 -1
  48. data/test/test_mechanize_pluggable_parser.rb +4 -4
  49. data/test/test_mechanize_xml_file.rb +29 -0
  50. metadata +173 -229
  51. data.tar.gz.sig +0 -0
  52. metadata.gz.sig +0 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 65bb3082549e10c6ed19080676ab618e0e663f24
4
+ data.tar.gz: 4e1bab1272afcb0003e819641091507cb1b0080c
5
+ SHA512:
6
+ metadata.gz: dcbc3f181d1b07d4a659e234c0cd769d48f8c7a1cf275905c7a4121ed6efc4661defe764c6a32b43b1ae3aa83ed5fcbf0bf100bdfe0ab3128cf9df156022f986
7
+ data.tar.gz: de01e70e18111ab5626dbf33d1e508b0fbb65acce86280edfa3f99f3d0f057f18a2aba96c6280261e582aeaf44dabd91324788bc2ae266ea30f89d7955272225
@@ -0,0 +1,16 @@
1
+ ---
2
+ after_script:
3
+ - rake travis:after -t
4
+ before_script:
5
+ - gem install hoe-travis --no-rdoc --no-ri
6
+ - rake travis:before -t
7
+ language: ruby
8
+ notifications:
9
+ email:
10
+ - drbrain@segment7.net
11
+ - ljjarvis@gmail.com
12
+ rvm:
13
+ - 1.8.7
14
+ - 1.9.2
15
+ - 1.9.3
16
+ script: rake travis
@@ -1,5 +1,58 @@
1
1
  = Mechanize CHANGELOG
2
2
 
3
+ === 2.6.0
4
+
5
+ * New Features
6
+ * Mechanize#start and Mechanize#shutdown (Thanks, Damian Janowski!)
7
+ * Added Mechanize::Agent#allowed_error_codes for setting an Array
8
+ of status codes which should not raise an error. #248 Laurence Rowe.
9
+ * Added `File.save!` for overwriting existing files #219.
10
+ * DirectorySaver::save_to now accepts an option to decode filename. #262
11
+ * element(s)_with methods now accept a :search option for doing xpath/css
12
+ selector searching. #287 Philippe Bourgau
13
+ * Added httponly option for Mechanize::Cookie #242 by Paolo Perego.
14
+ * Added Mechanize::XmlFile as a default pluggable parser for handling
15
+ XML responses. #289
16
+
17
+ * Minor enhancements
18
+ * Added Mechanize::Download#save_as as an alias to #save. #246
19
+ * Fix documentation for `Mechanize::Page` element matchers. #269
20
+ * Added Mechanize::Form::Field#raw_value for fetching a fields value
21
+ before it's sent through Mechanize::Util.html_unescape. #283
22
+ * Added iPad and Android user agents. #277 by sambit, #278 by seansay.
23
+
24
+ * Bug fix
25
+ * Mechanize#cert and Mechanize#key now return the values set by
26
+ #cert= and #key=. #244, #245 (Thanks, Robert Gogolok!)
27
+ * Mechanize no longer submits disabled form fields. #276 by Bogdan Gusiev,
28
+ #279 by Ricardo Valeriano.
29
+ * Mechanize::File#save now behaves like Mechanize::Download#save in
30
+ that it will create the parent directory before saving.
31
+ #272, #280 by Ryan Kowalick
32
+ * Ensure `application/xml` is registered as an XML parser in
33
+ `PluggableParser`, not just `text/xml`. #266 James Gregory
34
+ * Mechanize now writes cookiestxt with a prefixed dot for wildcard domain
35
+ handling. #295 by Mike Morearty.
36
+
37
+ === 2.5.2
38
+
39
+ * New Features
40
+ * Mechanize::CookieJar#save_as takes a keyword option "session" to say
41
+ that session cookies should be saved. Based on #230 by Jim Jones.
42
+
43
+ * Minor enhancements
44
+ * Added Mechanize#follow_redirect= as an alias to redirect_ok=.
45
+
46
+ * Bug fix
47
+ * Fixed casing of the Mac Firefox user-agent alias to match Linux Firefox.
48
+ In mechanize 3 the old "Mac FireFox" user-agent alias will be removed.
49
+ Pull request #231 by Gavin Miller.
50
+ * Mechanize now authenticates using the raw challenge, not a reconstructed
51
+ one, to avoid dealing with quoting rules of RFC 2617. Fixes failures in
52
+ #231 due to net-http-digest_auth 1.2.1
53
+ * Fixed Content-Disposition parameter parser to be case insensitive. #233
54
+ * Fixed redirection counting in following meta refresh. #240
55
+
3
56
  === 2.5.1
4
57
 
5
58
  * Bug fix
@@ -860,4 +913,4 @@ Mechanize is now under the MIT license
860
913
  * Added a response code exception
861
914
  * Thanks to Brian Ellin (brianellin@gmail.com) for:
862
915
  Added support for CA files, and support for 301 response codes
863
-
916
+
@@ -1,4 +1,5 @@
1
1
  .autotest
2
+ .travis.yml
2
3
  CHANGELOG.rdoc
3
4
  EXAMPLES.rdoc
4
5
  GUIDE.rdoc
@@ -98,6 +99,7 @@ lib/mechanize/test_case/verb_servlet.rb
98
99
  lib/mechanize/unauthorized_error.rb
99
100
  lib/mechanize/unsupported_scheme_error.rb
100
101
  lib/mechanize/util.rb
102
+ lib/mechanize/xml_file.rb
101
103
  test/data/htpasswd
102
104
  test/data/server.crt
103
105
  test/data/server.csr
@@ -140,6 +142,8 @@ test/htdocs/tc_checkboxes.html
140
142
  test/htdocs/tc_encoded_links.html
141
143
  test/htdocs/tc_field_precedence.html
142
144
  test/htdocs/tc_follow_meta.html
145
+ test/htdocs/tc_follow_meta_loop_1.html
146
+ test/htdocs/tc_follow_meta_loop_2.html
143
147
  test/htdocs/tc_form_action.html
144
148
  test/htdocs/tc_links.html
145
149
  test/htdocs/tc_meta_in_body.html
@@ -194,4 +198,5 @@ test/test_mechanize_redirect_not_get_or_head_error.rb
194
198
  test/test_mechanize_response_read_error.rb
195
199
  test/test_mechanize_subclass.rb
196
200
  test/test_mechanize_util.rb
201
+ test/test_mechanize_xml_file.rb
197
202
  test/test_multi_select.rb
@@ -1,9 +1,9 @@
1
1
  = Mechanize
2
2
 
3
3
  * http://mechanize.rubyforge.org
4
- * https://github.com/tenderlove/mechanize
4
+ * https://github.com/sparklemotion/mechanize
5
5
 
6
- == DESCRIPTION
6
+ == Description
7
7
 
8
8
  The Mechanize library is used for automating interaction with websites.
9
9
  Mechanize automatically stores and sends cookies, follows redirects,
@@ -16,15 +16,15 @@ a history.
16
16
  * ruby 1.8.7, 1.9.2, or 1.9.3
17
17
  * nokogiri[http://nokogiri.rubyforge.org]
18
18
 
19
- == SUPPORT:
19
+ == Support:
20
20
 
21
21
  The mechanize mailing list is available here:
22
22
 
23
- * http://rubyforge.org/mailman/listinfo/mechanize-users
23
+ * http://rubyforge.org/mailman/listinfo/mechanize-users
24
24
 
25
25
  The bug tracker is available here:
26
26
 
27
- * https://github.com/tenderlove/mechanize/issues
27
+ * https://github.com/sparklemotion/mechanize/issues
28
28
 
29
29
  == Examples
30
30
 
data/Rakefile CHANGED
@@ -3,25 +3,27 @@ require 'hoe'
3
3
 
4
4
  Hoe.plugin :git
5
5
  Hoe.plugin :minitest
6
+ Hoe.plugin :travis
6
7
 
7
8
  hoe = Hoe.spec 'mechanize' do
8
9
  developer 'Eric Hodel', 'drbrain@segment7.net'
9
10
  developer 'Aaron Patterson', 'aaronp@rubyforge.org'
10
11
  developer 'Mike Dalessio', 'mike.dalessio@gmail.com'
11
12
  developer 'Akinori MUSHA', 'knu@idaemons.org'
13
+ developer 'Lee Jarvis', 'ljjarvis@gmail.com'
12
14
 
13
15
  self.readme_file = 'README.rdoc'
14
16
  self.history_file = 'CHANGELOG.rdoc'
15
17
  self.extra_rdoc_files += Dir['*.rdoc']
16
18
 
17
- rdoc_locations << 'drbrain@rubyforge.org:/var/www/gforge-projects/mechanize/'
19
+ rdoc_locations << 'rubyforge.org:/var/www/gforge-projects/mechanize/'
18
20
 
19
21
  self.extra_deps << ['net-http-digest_auth', '~> 1.1', '>= 1.1.1']
20
22
  self.extra_deps << ['net-http-persistent', '~> 2.5', '>= 2.5.2']
21
23
  self.extra_deps << ['mime-types', '~> 1.17', '>= 1.17.2']
22
24
  self.extra_deps << ['nokogiri', '~> 1.4']
23
25
  self.extra_deps << ['ntlm-http', '~> 0.1', '>= 0.1.1']
24
- self.extra_deps << ['webrobots', '~> 0.0', '>= 0.0.9']
26
+ self.extra_deps << ['webrobots', '< 0.2', '>= 0.0.9']
25
27
  self.extra_deps << ['domain_name', '~> 0.5', '>= 0.5.1']
26
28
 
27
29
  self.spec_extras[:required_ruby_version] = '>= 1.8.7'
@@ -37,7 +37,7 @@ require 'zlib'
37
37
  # == Issues with mechanize
38
38
  #
39
39
  # If you think you have a bug with mechanize, but aren't sure, please file a
40
- # ticket at https://github.com/tenderlove/mechanize/issues
40
+ # ticket at https://github.com/sparklemotion/mechanize/issues
41
41
  #
42
42
  # Here are some common problems you may experience with mechanize
43
43
  #
@@ -73,7 +73,7 @@ class Mechanize
73
73
  ##
74
74
  # The version of Mechanize you are using.
75
75
 
76
- VERSION = '2.5.1'
76
+ VERSION = '2.6.0'
77
77
 
78
78
  ##
79
79
  # Base mechanize error class
@@ -106,6 +106,8 @@ class Mechanize
106
106
  # * Windows IE 9
107
107
  # * Windows Mozilla
108
108
  # * iPhone (3.0)
109
+ # * iPad
110
+ # * Android (Motorola Xoom)
109
111
  #
110
112
  # Example:
111
113
  #
@@ -113,11 +115,11 @@ class Mechanize
113
115
  # agent.user_agent_alias = 'Mac Safari'
114
116
 
115
117
  AGENT_ALIASES = {
116
- 'Mechanize' => "Mechanize/#{VERSION} Ruby/#{ruby_version} (http://github.com/tenderlove/mechanize/)",
118
+ 'Mechanize' => "Mechanize/#{VERSION} Ruby/#{ruby_version} (http://github.com/sparklemotion/mechanize/)",
117
119
  'Linux Firefox' => 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.1) Gecko/20100122 firefox/3.6.1',
118
120
  'Linux Konqueror' => 'Mozilla/5.0 (compatible; Konqueror/3; Linux)',
119
121
  'Linux Mozilla' => 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624',
120
- 'Mac FireFox' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6',
122
+ 'Mac Firefox' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6',
121
123
  'Mac Mozilla' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4a) Gecko/20030401',
122
124
  'Mac Safari 4' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; de-at) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10',
123
125
  'Mac Safari' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/534.51.22 (KHTML, like Gecko) Version/5.1.1 Safari/534.51.22',
@@ -127,14 +129,36 @@ class Mechanize
127
129
  'Windows IE 9' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
128
130
  'Windows Mozilla' => 'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030516 Mozilla Firebird/0.6',
129
131
  'iPhone' => 'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C28 Safari/419.3',
132
+ 'iPad' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10',
133
+ 'Android' => 'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13'
130
134
  }
131
135
 
136
+ AGENT_ALIASES['Mac FireFox'] = AGENT_ALIASES['Mac Firefox']
137
+ AGENT_ALIASES['Linux FireFox'] = AGENT_ALIASES['Linux Firefox']
138
+
132
139
  def self.inherited(child) # :nodoc:
133
- child.html_parser ||= html_parser
134
- child.log ||= log
140
+ child.html_parser = html_parser
141
+ child.log = log
135
142
  super
136
143
  end
137
144
 
145
+ ##
146
+ # Creates a new Mechanize instance and yields it to the given block.
147
+ #
148
+ # After the block executes, the instance is cleaned up. This includes
149
+ # closing all open connections.
150
+ #
151
+ # Mechanize.start do |m|
152
+ # m.get("http://example.com")
153
+ # end
154
+
155
+ def self.start
156
+ instance = new
157
+ yield(instance)
158
+ ensure
159
+ instance.shutdown
160
+ end
161
+
138
162
  ##
139
163
  # Creates a new mechanize instance. If a block is given, the created
140
164
  # instance is yielded to the block for setting up pre-connection state such
@@ -443,7 +467,7 @@ class Mechanize
443
467
  # agent.post('http://example.com/', "<message>hello</message>",
444
468
  # 'Content-Type' => 'application/xml')
445
469
 
446
- def post(uri, query={}, headers={})
470
+ def post(uri, query = {}, headers = {})
447
471
  return request_with_entity(:post, uri, query, headers) if String === query
448
472
 
449
473
  node = {}
@@ -507,7 +531,7 @@ class Mechanize
507
531
  #
508
532
  # agent.submit(page.forms.first, page.forms.first.buttons.first)
509
533
 
510
- def submit(form, button=nil, headers={})
534
+ def submit(form, button = nil, headers = {})
511
535
  form.add_button_to_query(button) if button
512
536
 
513
537
  case form.method.upcase
@@ -542,6 +566,7 @@ class Mechanize
542
566
  # keep-alives, compression, redirects and headers.
543
567
 
544
568
  @html_parser = Nokogiri::HTML
569
+ @log = nil
545
570
 
546
571
  class << self
547
572
 
@@ -884,6 +909,8 @@ Use of #auth and #basic_auth are deprecated due to a security vulnerability.
884
909
  @agent.redirect_ok = follow
885
910
  end
886
911
 
912
+ alias follow_redirect= redirect_ok=
913
+
887
914
  ##
888
915
  # Maximum number of redirections to follow
889
916
 
@@ -1017,7 +1044,7 @@ Use of #auth and #basic_auth are deprecated due to a security vulnerability.
1017
1044
  # An OpenSSL client certificate or the path to a certificate file.
1018
1045
 
1019
1046
  def cert
1020
- @agent.cert
1047
+ @agent.certificate
1021
1048
  end
1022
1049
 
1023
1050
  ##
@@ -1076,7 +1103,7 @@ Use of #auth and #basic_auth are deprecated due to a security vulnerability.
1076
1103
  # An OpenSSL private key or the path to a private key
1077
1104
 
1078
1105
  def key
1079
- @agent.key
1106
+ @agent.private_key
1080
1107
  end
1081
1108
 
1082
1109
  ##
@@ -1207,6 +1234,22 @@ Use of #auth and #basic_auth are deprecated due to a security vulnerability.
1207
1234
  @agent.set_proxy address, port, user, password
1208
1235
  end
1209
1236
 
1237
+ ##
1238
+ # Clears history and cookies.
1239
+
1240
+ def reset
1241
+ @agent.reset
1242
+ end
1243
+
1244
+ ##
1245
+ # Shuts down this session by clearing browsing state and closing all
1246
+ # persistent connections.
1247
+
1248
+ def shutdown
1249
+ reset
1250
+ @agent.shutdown
1251
+ end
1252
+
1210
1253
  private
1211
1254
 
1212
1255
  ##
@@ -10,6 +10,7 @@ class Mechanize::Cookie
10
10
  attr_accessor :comment, :max_age
11
11
 
12
12
  attr_accessor :session
13
+ attr_accessor :httponly
13
14
 
14
15
  attr_accessor :created_at
15
16
  attr_accessor :accessed_at
@@ -33,7 +34,7 @@ class Mechanize::Cookie
33
34
  @version = 0 # Netscape Cookie
34
35
 
35
36
  @domain = @path = @secure = @comment = @max_age =
36
- @expires = @comment_url = @discard = @port = nil
37
+ @expires = @comment_url = @discard = @port = @httponly = nil
37
38
 
38
39
  @created_at = @accessed_at = Time.now
39
40
  case args.size
@@ -78,7 +79,7 @@ class Mechanize::Cookie
78
79
  # array of Cookie objects. Note that this array may contain
79
80
  # nil's when some of the cookie-pairs are malformed.
80
81
  def parse(uri, str, log = Mechanize.log)
81
- return str.split(/,(?=[^;,]*=)|,$/).map { |c|
82
+ return str.to_s.split(/,(?=[^;,]*=)|,$/).map { |c|
82
83
  cookie_elem = c.split(/;+/)
83
84
  first_elem = cookie_elem.shift
84
85
  first_elem.strip!
@@ -97,6 +98,7 @@ class Mechanize::Cookie
97
98
  next unless key
98
99
  value = WEBrick::HTTPUtils.dequote(value.strip) if value
99
100
 
101
+
100
102
  case key.downcase
101
103
  when 'domain'
102
104
  next unless value && !value.empty?
@@ -134,6 +136,8 @@ class Mechanize::Cookie
134
136
  log.warn("Couldn't parse version '#{value}'") if log
135
137
  cookie.version = nil
136
138
  end
139
+ when 'httponly'
140
+ cookie.httponly = true
137
141
  when 'secure'
138
142
  cookie.secure = true
139
143
  end
@@ -142,6 +146,7 @@ class Mechanize::Cookie
142
146
  cookie.path ||= (uri + './').path
143
147
  cookie.secure ||= false
144
148
  cookie.domain ||= uri.host
149
+ cookie.httponly ||= false
145
150
 
146
151
  # RFC 6265 4.1.2.2
147
152
  cookie.expires = Time.now + cookie.max_age if cookie.max_age
@@ -193,6 +198,7 @@ class Mechanize::Cookie
193
198
  end
194
199
 
195
200
  alias secure? secure
201
+ alias httponly? httponly
196
202
 
197
203
  def acceptable_from_uri?(uri)
198
204
  host = DomainName.new(uri.host)
@@ -70,14 +70,37 @@ class Mechanize::CookieJar
70
70
  }
71
71
  end
72
72
 
73
- # Save the cookie jar to a file in the format specified.
73
+ # call-seq:
74
+ # jar.save_as(file, format = :yaml)
75
+ # jar.save_as(file, options)
74
76
  #
75
- # Available formats:
76
- # :yaml <- YAML structure
77
- # :cookiestxt <- Mozilla's cookies.txt format
78
- def save_as(file, format = :yaml)
77
+ # Save the cookie jar to a file in the format specified and return
78
+ # self.
79
+ #
80
+ # Available option keywords are below:
81
+ #
82
+ # * +format+
83
+ # [<tt>:yaml</tt>]
84
+ # YAML structure (default)
85
+ # [<tt>:cookiestxt</tt>]
86
+ # Mozilla's cookies.txt format
87
+ # * +session+
88
+ # [+true+]
89
+ # Save session cookies as well.
90
+ # [+false+]
91
+ # Do not save session cookies. (default)
92
+ def save_as(file, options = nil)
93
+ if Symbol === options
94
+ format = options
95
+ session = false
96
+ else
97
+ options ||= {}
98
+ format = options[:format] || :yaml
99
+ session = !!options[:session]
100
+ end
101
+
79
102
  jar = dup
80
- jar.cleanup true
103
+ jar.cleanup !session
81
104
 
82
105
  open(file, 'w') { |f|
83
106
  case format
@@ -164,9 +187,12 @@ class Mechanize::CookieJar
164
187
 
165
188
  # Write cookies to Mozilla cookies.txt-style IO stream
166
189
  def dump_cookiestxt(io)
190
+ io.puts "# HTTP Cookie File"
191
+ io.puts "# This file was generated by Ruby Mechanize " \
192
+ "#{Mechanize::VERSION} https://github.com/sparklemotion/mechanize.\n\n"
167
193
  to_a.each do |cookie|
168
194
  io.puts([
169
- cookie.domain,
195
+ (cookie.for_domain? ? "." : "") + cookie.domain,
170
196
  cookie.for_domain? ? "TRUE" : "FALSE",
171
197
  cookie.path,
172
198
  cookie.secure ? "TRUE" : "FALSE",
@@ -10,16 +10,20 @@
10
10
  class Mechanize::DirectorySaver < Mechanize::Download
11
11
 
12
12
  @directory = nil
13
+ @options = {}
13
14
 
14
15
  ##
15
16
  # Creates a DirectorySaver subclass that will save responses to the given
16
- # +directory+.
17
+ # +directory+. If +options+ includes a +decode_filename+ value set to +true+
18
+ # then the downloaded filename will be ran through +CGI.unescape+ before
19
+ # being saved.
17
20
 
18
- def self.save_to directory
21
+ def self.save_to directory, options = {}
19
22
  directory = File.expand_path directory
20
23
 
21
24
  Class.new self do |klass|
22
25
  klass.instance_variable_set :@directory, directory
26
+ klass.instance_variable_set :@options, options
23
27
  end
24
28
  end
25
29
 
@@ -30,6 +34,13 @@ class Mechanize::DirectorySaver < Mechanize::Download
30
34
  @directory
31
35
  end
32
36
 
37
+ ##
38
+ # True if downloaded files should have their names decoded before saving.
39
+
40
+ def self.decode_filename?
41
+ @options[:decode_filename]
42
+ end
43
+
33
44
  ##
34
45
  # Saves the +body_io+ into the directory specified for this DirectorySaver
35
46
  # by save_to. The filename is chosen by Mechanize::Parser#extract_filename.
@@ -44,6 +55,7 @@ class Mechanize::DirectorySaver < Mechanize::Download
44
55
 
45
56
  super
46
57
 
58
+ @filename = CGI.unescape(@filename) if self.class.decode_filename?
47
59
  path = File.join directory, @filename
48
60
 
49
61
  save path