mechanize 0.5.3 → 0.5.4
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/CHANGELOG +15 -0
- data/EXAMPLES +60 -22
- data/NOTES +20 -0
- data/lib/mechanize.rb +92 -79
- data/lib/mechanize/form.rb +37 -8
- data/lib/mechanize/mech_version.rb +1 -1
- data/lib/mechanize/page.rb +4 -0
- data/lib/mechanize/pluggable_parsers.rb +17 -6
- data/test/data/server.crt +14 -12
- data/test/data/server.csr +10 -9
- data/test/data/server.key +13 -16
- data/test/data/server.pem +13 -13
- data/test/htdocs/file_upload.html +5 -0
- data/test/server.rb +1 -0
- data/test/servlets.rb +21 -0
- data/test/ssl_server.rb +0 -1
- data/test/tc_forms.rb +12 -0
- data/test/tc_gzipping.rb +23 -0
- data/test/tc_mech.rb +12 -0
- data/test/tc_pluggable_parser.rb +35 -0
- data/test/tc_upload.rb +42 -0
- data/test/ts_mech.rb +1 -0
- metadata +134 -125
data/CHANGELOG
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
= Mechanize CHANGELOG
|
2
2
|
|
3
|
+
== 0.5.4
|
4
|
+
|
5
|
+
* Added WWW::Mechanize#trasact for saving history state between in a
|
6
|
+
transaction. See the EXAMPLES file. Thanks Johan Kiviniemi.
|
7
|
+
* Added support for gzip compressed pages
|
8
|
+
* Forms can now be accessed like a hash. For example, to set the value
|
9
|
+
of an input field named 'name' to "Aaron", you can do this:
|
10
|
+
form['name'] = "Aaron"
|
11
|
+
Or to get the value of a field named 'name', do this:
|
12
|
+
puts form['name']
|
13
|
+
* File uploads will now read the file specified in FileUpload#file_name
|
14
|
+
* FileUpload can use an IO object in FileUpload#file_data
|
15
|
+
* Fixed a bug with saving files on windows
|
16
|
+
* Fixed a bug with the filename being set in forms
|
17
|
+
|
3
18
|
== 0.5.3
|
4
19
|
|
5
20
|
* Mechanize#click will now act on the first element of an array. So if an
|
data/EXAMPLES
CHANGED
@@ -29,28 +29,27 @@
|
|
29
29
|
== File Upload
|
30
30
|
This example uploads one image as two different images to flickr.
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
agent.submit(form)
|
32
|
+
require 'rubygems'
|
33
|
+
require 'mechanize'
|
34
|
+
|
35
|
+
agent = WWW::Mechanize.new
|
36
|
+
|
37
|
+
# Get the flickr sign in page
|
38
|
+
page = agent.get('http://flickr.com/signin/flickr/')
|
39
|
+
|
40
|
+
# Fill out the login form
|
41
|
+
form = page.forms.name('flickrloginform').first
|
42
|
+
form.email = ARGV[0]
|
43
|
+
form.password = ARGV[1]
|
44
|
+
page = agent.submit(form)
|
45
|
+
|
46
|
+
# Go to the upload page
|
47
|
+
page = agent.click page.links.text('Upload')
|
48
|
+
|
49
|
+
# Fill out the form
|
50
|
+
form = page.forms.action('/photos_upload_process.gne').first
|
51
|
+
form.file_uploads.name('file1').first.file_name = ARGV[2]
|
52
|
+
agent.submit(form)
|
54
53
|
|
55
54
|
== Pluggable Parsers
|
56
55
|
Lets say you want html pages to automatically be parsed with Rubyful Soup.
|
@@ -84,3 +83,42 @@ Beautiful Soup for that page.
|
|
84
83
|
agent.set_proxy('localhost', '8000')
|
85
84
|
page = agent.get(ARGV[0])
|
86
85
|
puts page.body
|
86
|
+
|
87
|
+
== The transact method
|
88
|
+
|
89
|
+
transact runs the given block and then resets the page history. I.e. after the
|
90
|
+
block has been executed, you're back at the original page; no need count how
|
91
|
+
many times to call the back method at the end of a loop (while accounting for
|
92
|
+
possible exceptions).
|
93
|
+
|
94
|
+
This example also demonstrates subclassing Mechanize.
|
95
|
+
|
96
|
+
require 'mechanize'
|
97
|
+
|
98
|
+
class TestMech < WWW::Mechanize
|
99
|
+
def process
|
100
|
+
get 'http://rubyforge.org/'
|
101
|
+
search_form = page.forms.first
|
102
|
+
search_form.words = 'WWW'
|
103
|
+
submit search_form
|
104
|
+
|
105
|
+
page.links.with.href( %r{/projects/} ).each do |link|
|
106
|
+
next if link.href =~ %r{/projects/support/}
|
107
|
+
|
108
|
+
puts 'Loading %-30s %s' % [link.href, link.text]
|
109
|
+
begin
|
110
|
+
transact do
|
111
|
+
click link
|
112
|
+
# Do stuff, maybe click more links.
|
113
|
+
end
|
114
|
+
# Now we're back at the original page.
|
115
|
+
|
116
|
+
rescue => e
|
117
|
+
$stderr.puts "#{e.class}: #{e.message}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
TestMech.new.process
|
124
|
+
|
data/NOTES
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
= Mechanize Release Notes
|
2
2
|
|
3
|
+
== 0.5.4 (Sylvester)
|
4
|
+
|
5
|
+
WWW::Mechanize 0.5.4 aka Sylvester is fresh out the the frying pan and in to
|
6
|
+
the fire! It is also ready for you to download and use.
|
7
|
+
|
8
|
+
New features include WWW::Mechanize#transact (thanks to Johan Kiviniemi) which
|
9
|
+
lets you maintain your history state between transactions. Forms can now be
|
10
|
+
accessed as a hash. For example, to set the value of an input field, you can
|
11
|
+
do the following:
|
12
|
+
form['name'] = "Aaron"
|
13
|
+
Doing this assumes that you are setting the first field. If there are multiple
|
14
|
+
fields with the same name, you must use a different method to set the value.
|
15
|
+
|
16
|
+
Form file uploads will now read the file specified by FileUpload#file_name.
|
17
|
+
The mime type will also be automatically determined for you! Take a look
|
18
|
+
at the EXAMPLES file for a new flickr upload script.
|
19
|
+
|
20
|
+
Lastly, gzip encoding is now supported! WWW::Mechanize now supports pages
|
21
|
+
being sent gzip encoded. This means less network bandwidth. Yay!
|
22
|
+
|
3
23
|
== 0.5.3 (Twan)
|
4
24
|
|
5
25
|
Here it is. Mechanize 0.5.3 also named the "Twan" release. There are a few
|
data/lib/mechanize.rb
CHANGED
@@ -15,8 +15,9 @@ require 'net/http'
|
|
15
15
|
require 'net/https'
|
16
16
|
|
17
17
|
require 'uri'
|
18
|
-
require 'logger'
|
19
18
|
require 'webrick'
|
19
|
+
require 'zlib'
|
20
|
+
require 'stringio'
|
20
21
|
require 'web/htmltools/xmltree' # narf
|
21
22
|
require 'mechanize/module'
|
22
23
|
require 'mechanize/mech_version'
|
@@ -134,7 +135,9 @@ class Mechanize
|
|
134
135
|
cur_page = current_page() || Page.new
|
135
136
|
|
136
137
|
# fetch the page
|
137
|
-
|
138
|
+
abs_uri = to_absolute_uri(url, cur_page)
|
139
|
+
request = fetch_request(abs_uri)
|
140
|
+
page = fetch_page(abs_uri, request, cur_page)
|
138
141
|
add_to_history(page)
|
139
142
|
page
|
140
143
|
end
|
@@ -148,7 +151,7 @@ class Mechanize
|
|
148
151
|
# Clicks the WWW::Mechanize::Link object passed in and returns the
|
149
152
|
# page fetched.
|
150
153
|
def click(link)
|
151
|
-
uri = to_absolute_uri(link.href)
|
154
|
+
uri = to_absolute_uri(link.href.strip)
|
152
155
|
get(uri)
|
153
156
|
end
|
154
157
|
|
@@ -210,11 +213,20 @@ class Mechanize
|
|
210
213
|
|
211
214
|
# Returns whether or not a url has been visited
|
212
215
|
def visited?(url)
|
213
|
-
if url.
|
214
|
-
|
216
|
+
url = url.uri if url.respond_to? :uri
|
217
|
+
uri = to_absolute_uri(url).to_s
|
218
|
+
! @history.find { |h| h.uri.to_s == uri }.nil?
|
219
|
+
end
|
220
|
+
|
221
|
+
# Runs given block, then resets the page history as it was before. self is
|
222
|
+
# given as a parameter to the block. Returns the value of the block.
|
223
|
+
def transact
|
224
|
+
history_backup = @history.dup
|
225
|
+
begin
|
226
|
+
yield self
|
227
|
+
ensure
|
228
|
+
@history = history_backup
|
215
229
|
end
|
216
|
-
uri = to_absolute_uri(url)
|
217
|
-
! @history.find { |h| h.uri.to_s == uri.to_s }.nil?
|
218
230
|
end
|
219
231
|
|
220
232
|
alias :page :current_page
|
@@ -222,51 +234,54 @@ class Mechanize
|
|
222
234
|
private
|
223
235
|
|
224
236
|
def to_absolute_uri(url, cur_page=current_page())
|
225
|
-
|
226
|
-
uri = url
|
227
|
-
else
|
228
|
-
uri = URI.parse(url.strip.gsub(/\s/, '%20'))
|
229
|
-
end
|
237
|
+
url = URI.parse(URI.escape(url.to_s.strip)) unless url.is_a? URI
|
230
238
|
|
231
239
|
# construct an absolute uri
|
232
|
-
if
|
233
|
-
|
234
|
-
|
235
|
-
else
|
236
|
-
raise 'no history. please specify an absolute URL'
|
237
|
-
end
|
240
|
+
if url.relative?
|
241
|
+
raise 'no history. please specify an absolute URL' unless cur_page.uri
|
242
|
+
url = cur_page.uri + url
|
238
243
|
end
|
239
244
|
|
240
|
-
return
|
245
|
+
return url
|
241
246
|
end
|
242
247
|
|
243
248
|
def post_form(url, form)
|
244
249
|
cur_page = current_page() || Page.new
|
245
250
|
|
246
|
-
request_data =
|
251
|
+
request_data = form.request_data
|
247
252
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
}
|
253
|
+
abs_url = to_absolute_uri(url, cur_page)
|
254
|
+
request = fetch_request(abs_url, :post)
|
255
|
+
request.add_field('Content-Type', form.enctype)
|
256
|
+
request.add_field('Content-Length', request_data.size.to_s)
|
257
|
+
|
258
|
+
log.debug("query: #{ request_data.inspect }") if log
|
254
259
|
|
255
260
|
# fetch the page
|
256
|
-
page = fetch_page(
|
261
|
+
page = fetch_page(abs_url, request, cur_page, [request_data])
|
257
262
|
add_to_history(page)
|
258
263
|
page
|
259
264
|
end
|
260
265
|
|
266
|
+
# Creates a new request object based on the scheme and type
|
267
|
+
def fetch_request(uri, type = :get)
|
268
|
+
raise "unsupported scheme" unless ['http', 'https'].include?(uri.scheme)
|
269
|
+
if type == :get
|
270
|
+
Net::HTTP::Get.new(uri.request_uri)
|
271
|
+
else
|
272
|
+
Net::HTTP::Post.new(uri.request_uri)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
261
276
|
# uri is an absolute URI
|
262
|
-
def fetch_page(uri,
|
277
|
+
def fetch_page(uri, request, cur_page=current_page(), request_data=[])
|
263
278
|
raise "unsupported scheme" unless ['http', 'https'].include?(uri.scheme)
|
264
279
|
|
265
|
-
log.info("#{
|
280
|
+
log.info("#{ request.class }: #{ uri.to_s }") if log
|
266
281
|
|
267
282
|
page = Page.new(uri)
|
268
283
|
|
269
|
-
|
284
|
+
http_obj = Net::HTTP.new( uri.host,
|
270
285
|
uri.port,
|
271
286
|
@proxy_addr,
|
272
287
|
@proxy_port,
|
@@ -275,73 +290,55 @@ class Mechanize
|
|
275
290
|
)
|
276
291
|
|
277
292
|
if uri.scheme == 'https'
|
278
|
-
|
279
|
-
|
293
|
+
http_obj.use_ssl = true
|
294
|
+
http_obj.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
280
295
|
if @ca_file
|
281
|
-
|
282
|
-
|
296
|
+
http_obj.ca_file = @ca_file
|
297
|
+
http_obj.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
283
298
|
end
|
284
299
|
if @cert && @key
|
285
|
-
|
286
|
-
|
300
|
+
http_obj.cert = OpenSSL::X509::Certificate.new(::File.read(@cert))
|
301
|
+
http_obj.key = OpenSSL::PKey::RSA.new(::File.read(@key), @pass)
|
287
302
|
end
|
288
303
|
end
|
289
304
|
|
305
|
+
request.add_field('Accept-Encoding', 'gzip,identity')
|
290
306
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
298
|
-
else
|
299
|
-
raise ArgumentError
|
300
|
-
end
|
301
|
-
|
302
|
-
unless @cookie_jar.empty?(uri)
|
303
|
-
cookies = @cookie_jar.cookies(uri)
|
304
|
-
cookie = cookies.length > 0 ? cookies.join("; ") : nil
|
305
|
-
if log
|
306
|
-
cookies.each do |c|
|
307
|
-
log.debug("using cookie: #{c}")
|
308
|
-
end
|
307
|
+
unless @cookie_jar.empty?(uri)
|
308
|
+
cookies = @cookie_jar.cookies(uri)
|
309
|
+
cookie = cookies.length > 0 ? cookies.join("; ") : nil
|
310
|
+
if log
|
311
|
+
cookies.each do |c|
|
312
|
+
log.debug("using cookie: #{c}")
|
309
313
|
end
|
310
|
-
request.add_field('Cookie', cookie)
|
311
|
-
end
|
312
|
-
|
313
|
-
# Add Referer header to request
|
314
|
-
|
315
|
-
unless cur_page.uri.nil?
|
316
|
-
request.add_field('Referer', cur_page.uri.to_s)
|
317
314
|
end
|
315
|
+
request.add_field('Cookie', cookie)
|
316
|
+
end
|
318
317
|
|
319
|
-
|
320
|
-
|
321
|
-
request.add_field('
|
322
|
-
|
323
|
-
request.basic_auth(@user, @password) if @user
|
318
|
+
# Add Referer header to request
|
319
|
+
unless cur_page.uri.nil?
|
320
|
+
request.add_field('Referer', cur_page.uri.to_s)
|
321
|
+
end
|
324
322
|
|
325
|
-
|
323
|
+
# Add User-Agent header to request
|
324
|
+
request.add_field('User-Agent', @user_agent) if @user_agent
|
326
325
|
|
327
|
-
|
326
|
+
request.basic_auth(@user, @password) if @user
|
328
327
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
end
|
328
|
+
# Log specified headers for the request
|
329
|
+
if log
|
330
|
+
request.each_header do |k, v|
|
331
|
+
log.debug("request-header: #{ k } => #{ v }")
|
334
332
|
end
|
333
|
+
end
|
335
334
|
|
335
|
+
http_obj.start { |http|
|
336
336
|
# Specify timeouts if given
|
337
|
-
|
338
337
|
http.open_timeout = @open_timeout if @open_timeout
|
339
338
|
http.read_timeout = @read_timeout if @read_timeout
|
340
339
|
|
341
340
|
# Send the request
|
342
|
-
|
343
341
|
http.request(request, *request_data) {|response|
|
344
|
-
|
345
342
|
if log
|
346
343
|
response.each_header {|k,v|
|
347
344
|
log.debug("response-header: #{ k } => #{ v }")
|
@@ -363,12 +360,24 @@ class Mechanize
|
|
363
360
|
content_type = data[1].downcase unless data.nil?
|
364
361
|
end
|
365
362
|
|
363
|
+
response_body =
|
364
|
+
if encoding = response['Content-Encoding']
|
365
|
+
case encoding.downcase
|
366
|
+
when 'gzip'
|
367
|
+
log.debug('gunzip body') if log
|
368
|
+
Zlib::GzipReader.new(StringIO.new(response.body)).read
|
369
|
+
else
|
370
|
+
raise 'Unsupported content encoding'
|
371
|
+
end
|
372
|
+
else
|
373
|
+
response.body
|
374
|
+
end
|
366
375
|
|
367
376
|
# Find our pluggable parser
|
368
377
|
page = @pluggable_parser.parser(content_type).new(
|
369
378
|
uri,
|
370
379
|
response,
|
371
|
-
|
380
|
+
response_body,
|
372
381
|
response.code
|
373
382
|
)
|
374
383
|
|
@@ -383,11 +392,15 @@ class Mechanize
|
|
383
392
|
return page
|
384
393
|
when "301", "302"
|
385
394
|
log.info("follow redirect to: #{ response['Location'] }") if log
|
386
|
-
|
395
|
+
abs_uri = to_absolute_uri(
|
396
|
+
URI.parse(
|
397
|
+
URI.escape(URI.unescape(response['Location'].to_s))), page)
|
398
|
+
request = fetch_request(abs_uri)
|
399
|
+
return fetch_page(abs_uri, request, page)
|
387
400
|
else
|
388
401
|
raise ResponseCodeError.new(page.code), "Unhandled response", caller
|
389
402
|
end
|
390
|
-
}
|
403
|
+
}
|
391
404
|
}
|
392
405
|
end
|
393
406
|
|
data/lib/mechanize/form.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mime/types'
|
2
|
+
|
1
3
|
module WWW
|
2
4
|
class Mechanize
|
3
5
|
# =Synopsis
|
@@ -106,7 +108,6 @@ module WWW
|
|
106
108
|
# multi-part post,
|
107
109
|
def request_data
|
108
110
|
query_params = build_query()
|
109
|
-
query = nil
|
110
111
|
case @enctype.downcase
|
111
112
|
when 'multipart/form-data'
|
112
113
|
boundary = rand_string(20)
|
@@ -114,13 +115,11 @@ module WWW
|
|
114
115
|
params = []
|
115
116
|
query_params.each { |k,v| params << param_to_multipart(k, v) }
|
116
117
|
@file_uploads.each { |f| params << file_to_multipart(f) }
|
117
|
-
|
118
|
+
params.collect { |p| "--#{boundary}\r\n#{p}" }.join('') +
|
118
119
|
"--#{boundary}--\r\n"
|
119
120
|
else
|
120
|
-
|
121
|
+
WWW::Mechanize.build_query_string(query_params)
|
121
122
|
end
|
122
|
-
|
123
|
-
query
|
124
123
|
end
|
125
124
|
|
126
125
|
private
|
@@ -147,7 +146,7 @@ module WWW
|
|
147
146
|
when 'checkbox'
|
148
147
|
@checkboxes << CheckBox.new(node.attributes['name'], node.attributes['value'], node.attributes.has_key?('checked'), self)
|
149
148
|
when 'file'
|
150
|
-
@file_uploads << FileUpload.new(node.attributes['name'],
|
149
|
+
@file_uploads << FileUpload.new(node.attributes['name'], nil)
|
151
150
|
when 'submit'
|
152
151
|
@buttons << Button.new(node.attributes['name'], node.attributes['value'])
|
153
152
|
when 'image'
|
@@ -187,12 +186,23 @@ module WWW
|
|
187
186
|
"#{mime_value_quote(file.name)}\"; " +
|
188
187
|
"filename=\"#{mime_value_quote(file.file_name || '')}\"\r\n" +
|
189
188
|
"Content-Transfer-Encoding: binary\r\n"
|
189
|
+
|
190
|
+
if file.file_data.nil? and ! file.file_name.nil?
|
191
|
+
file.file_data = ::File.open(file.file_name, "rb") { |f| f.read }
|
192
|
+
file.mime_type = MIME::Types.type_for(file.file_name).first
|
193
|
+
end
|
194
|
+
|
190
195
|
if file.mime_type != nil
|
191
196
|
body << "Content-Type: #{file.mime_type}\r\n"
|
192
197
|
end
|
193
198
|
|
194
|
-
body <<
|
195
|
-
|
199
|
+
body <<
|
200
|
+
if file.file_data.respond_to? :read
|
201
|
+
"\r\n#{file.file_data.read}\r\n"
|
202
|
+
else
|
203
|
+
"\r\n#{file.file_data}\r\n"
|
204
|
+
end
|
205
|
+
|
196
206
|
body
|
197
207
|
end
|
198
208
|
end
|
@@ -206,6 +216,9 @@ module WWW
|
|
206
216
|
# Find a form and print out its fields
|
207
217
|
# form = page.forms.first # => WWW::Mechanize::Form
|
208
218
|
# form.fields.each { |f| puts f.name }
|
219
|
+
# Set the input field 'name' to "Aaron"
|
220
|
+
# form['name'] = 'Aaron'
|
221
|
+
# puts form['name']
|
209
222
|
class Form < GlobalForm
|
210
223
|
attr_reader :node
|
211
224
|
|
@@ -239,6 +252,22 @@ module WWW
|
|
239
252
|
end
|
240
253
|
end
|
241
254
|
|
255
|
+
# Fetch the value of the first input field with the name passed in
|
256
|
+
# ==Example
|
257
|
+
# Fetch the value set in the input field 'name'
|
258
|
+
# puts form['name']
|
259
|
+
def [](field_name)
|
260
|
+
field(field_name).value
|
261
|
+
end
|
262
|
+
|
263
|
+
# Set the value of the first input field with the name passed in
|
264
|
+
# ==Example
|
265
|
+
# Set the value in the input field 'name' to "Aaron"
|
266
|
+
# form['name'] = 'Aaron'
|
267
|
+
def []=(field_name, value)
|
268
|
+
field(field_name).value = value
|
269
|
+
end
|
270
|
+
|
242
271
|
# Treat form fields like accessors.
|
243
272
|
def method_missing(id,*args)
|
244
273
|
method = id.to_s.gsub(/=$/, '')
|
data/lib/mechanize/page.rb
CHANGED
@@ -27,7 +27,7 @@ module WWW
|
|
27
27
|
|
28
28
|
# Use this method to save the content of this object to filename
|
29
29
|
def save_as(filename)
|
30
|
-
::File::open(filename, "
|
30
|
+
::File::open(filename, "wb") { |f|
|
31
31
|
f.write body
|
32
32
|
}
|
33
33
|
end
|
@@ -47,14 +47,25 @@ module WWW
|
|
47
47
|
# agent.get('http://example.com/foo.pdf')
|
48
48
|
#
|
49
49
|
class FileSaver < File
|
50
|
+
attr_reader :filename
|
51
|
+
|
50
52
|
def initialize(uri=nil, response=nil, body=nil, code=nil)
|
51
53
|
@uri, @response, @body, @code = uri, response, body, code
|
52
|
-
path = uri.path
|
53
|
-
path =~
|
54
|
-
|
55
|
-
|
54
|
+
path = uri.path.empty? ? 'index.html' : uri.path.gsub(/^[\/]*/, '')
|
55
|
+
path += 'index.html' if path =~ /\/$/
|
56
|
+
|
57
|
+
split_path = path.split(/\//)
|
58
|
+
filename = split_path.length > 0 ? split_path.pop : 'index.html'
|
59
|
+
joined_path = split_path.join(::File::SEPARATOR)
|
60
|
+
path = if joined_path.empty?
|
61
|
+
uri.host
|
62
|
+
else
|
63
|
+
"#{uri.host}#{::File::SEPARATOR}#{joined_path}"
|
64
|
+
end
|
65
|
+
|
66
|
+
@filename = "#{path}#{::File::SEPARATOR}#{filename}"
|
56
67
|
FileUtils.mkdir_p(path)
|
57
|
-
save_as(
|
68
|
+
save_as(@filename)
|
58
69
|
end
|
59
70
|
end
|
60
71
|
|
data/test/data/server.crt
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
2
|
+
MIICmzCCAgQCCQDq2kM3TCIM0DANBgkqhkiG9w0BAQQFADCBkTELMAkGA1UEBhMC
|
3
|
+
VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEjAQBgNV
|
4
|
+
BAoTCU1lY2hhbml6ZTESMBAGA1UECxMJTWVjaGFuaXplMQ4wDAYDVQQDEwVBYXJv
|
5
|
+
bjEjMCEGCSqGSIb3DQEJARYUYWFyb25wQHJ1Ynlmb3JnZS5vcmcwHhcNMDYwODIz
|
6
|
+
MDU0NTMwWhcNMDcwODIzMDU0NTMwWjCBkTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
7
|
+
Cldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEjAQBgNVBAoTCU1lY2hhbml6
|
8
|
+
ZTESMBAGA1UECxMJTWVjaGFuaXplMQ4wDAYDVQQDEwVBYXJvbjEjMCEGCSqGSIb3
|
9
|
+
DQEJARYUYWFyb25wQHJ1Ynlmb3JnZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
|
10
|
+
MIGJAoGBAKpnmI4Y4tBz3SJsHR28QoUr7IYxkqbD8qjqgIN0LXOslyFyiGzNKca5
|
11
|
+
Ln2Au8CZLyCugt/vutjfV+Eq0bl0HwbKdo6HjP6RxmGX6EKWX7NOrsof+s96DhLm
|
12
|
+
JaWWbtvqP8eyy9PNInKjX6n/7wsVetQutjhNy/cAkrh6UOsjyCGvAgMBAAEwDQYJ
|
13
|
+
KoZIhvcNAQEEBQADgYEAGtqgxn1fh0X5MxDG1yMp5aGcZ6HhtEtlm5S0ZsRnMsqU
|
14
|
+
Hh6Bd57+zUQ66XnLCbQN2cwNeeSoqtI16Ccc1I5cAhQnIZESMsPG21i1BnpEhKph
|
15
|
+
HfNFNpWI/upT2EXNUM6Vx2Kk2aCw2ysrD2pHpsTo5bCOly00uK1ZkoJVQMTL4gU=
|
14
16
|
-----END CERTIFICATE-----
|
data/test/data/server.csr
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
-----BEGIN CERTIFICATE REQUEST-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
MIIB0jCCATsCAQAwgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
3
|
+
MRAwDgYDVQQHEwdTZWF0dGxlMRIwEAYDVQQKEwlNZWNoYW5pemUxEjAQBgNVBAsT
|
4
|
+
CU1lY2hhbml6ZTEOMAwGA1UEAxMFQWFyb24xIzAhBgkqhkiG9w0BCQEWFGFhcm9u
|
5
|
+
cEBydWJ5Zm9yZ2Uub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqZ5iO
|
6
|
+
GOLQc90ibB0dvEKFK+yGMZKmw/Ko6oCDdC1zrJchcohszSnGuS59gLvAmS8groLf
|
7
|
+
77rY31fhKtG5dB8GynaOh4z+kcZhl+hCll+zTq7KH/rPeg4S5iWllm7b6j/HssvT
|
8
|
+
zSJyo1+p/+8LFXrULrY4Tcv3AJK4elDrI8ghrwIDAQABoAAwDQYJKoZIhvcNAQEE
|
9
|
+
BQADgYEAT7SPe71NQvT2BYGEmbWb7FlSQrPh+rDQMHt/Akb8+r91NLkxZtbD1e/F
|
10
|
+
iyI9JloPCEwJXxHBl0VVRpFCRuJNN0z0E/G4NUWu6n+ZkihtnmV6uazzAQmD4pTl
|
11
|
+
SjoiyVLWU+r4Q4yXWXtJ9GR8Attv32fL3PcP+GGLeurXJAn0MNU=
|
11
12
|
-----END CERTIFICATE REQUEST-----
|
data/test/data/server.key
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
/0PAxOR6x+HzRBDc/5cMA6WUNWrGK/QQPKmGFGyZW8oSYTCEmeiKxFSHNCv38bVq
|
16
|
-
11TlZ5Lj1/+jYbz88pN4qkVYNIN7tqUUOxIowc3atZLBQzn21toJcRygv9abkRSh
|
17
|
-
XmgzQYK6N3laTSr1R7KsmIA90+yDXTo44064gOu6VaTMeOJoMegetA==
|
2
|
+
MIICXAIBAAKBgQCqZ5iOGOLQc90ibB0dvEKFK+yGMZKmw/Ko6oCDdC1zrJchcohs
|
3
|
+
zSnGuS59gLvAmS8groLf77rY31fhKtG5dB8GynaOh4z+kcZhl+hCll+zTq7KH/rP
|
4
|
+
eg4S5iWllm7b6j/HssvTzSJyo1+p/+8LFXrULrY4Tcv3AJK4elDrI8ghrwIDAQAB
|
5
|
+
AoGAC+iZfLS4hSDTv2gW0NErROtA6E/mk8j12GArAwTHeGIDXc8HQbNEzCJ84UBx
|
6
|
+
3o/V/06yzruOL0HMfmvjpDY9RLsH02xZb2F/lruw4MJLu50i/Zu8Sjmb1YPSfCh/
|
7
|
+
3+8lREA3Uznlq+wHC3yPxQzMBy5jaEdH4IKxT0Bq8TeF0AECQQDSpL47YpRVRsLn
|
8
|
+
sS00ndEgQQmT5AJWJJtPpbHk6AA0a+zdNeuDRbdF42zG483YEqU7meZbPKR8QbkK
|
9
|
+
ZQPEBuevAkEAzxjGcz6NZesmN/NQOtOpylewEs1bdIJyBIBmcnmkimLBtdxd0t34
|
10
|
+
wUKVHLDSj2aemuAHHwsyn/BNXs6F+obmAQJBALpbkAXAAFW1xefvo3vih8sOXyfd
|
11
|
+
WIfX2SRNBqbq7otyVFudQaChBDUrsOgBUPLyBAdH8DoV27wm9UuR9RPvu/cCQFRr
|
12
|
+
WgICXqtMFtE56tuACreD1S9k7MHqpsW0/Y3ujicnKKWUhd5+Q3esR5JhdgOkpkSl
|
13
|
+
y+FYtDNERpW+BBliwgECQA+Vc7pnxwDIOP8kFumdAUmRmhEZjuwArFcywPzrCUn9
|
14
|
+
4/KBOp5wDN7kanBwNGZCZ/eQtkb6thAS8C9pufHD1lw=
|
18
15
|
-----END RSA PRIVATE KEY-----
|
data/test/data/server.pem
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
2
|
+
MIICXAIBAAKBgQCqZ5iOGOLQc90ibB0dvEKFK+yGMZKmw/Ko6oCDdC1zrJchcohs
|
3
|
+
zSnGuS59gLvAmS8groLf77rY31fhKtG5dB8GynaOh4z+kcZhl+hCll+zTq7KH/rP
|
4
|
+
eg4S5iWllm7b6j/HssvTzSJyo1+p/+8LFXrULrY4Tcv3AJK4elDrI8ghrwIDAQAB
|
5
|
+
AoGAC+iZfLS4hSDTv2gW0NErROtA6E/mk8j12GArAwTHeGIDXc8HQbNEzCJ84UBx
|
6
|
+
3o/V/06yzruOL0HMfmvjpDY9RLsH02xZb2F/lruw4MJLu50i/Zu8Sjmb1YPSfCh/
|
7
|
+
3+8lREA3Uznlq+wHC3yPxQzMBy5jaEdH4IKxT0Bq8TeF0AECQQDSpL47YpRVRsLn
|
8
|
+
sS00ndEgQQmT5AJWJJtPpbHk6AA0a+zdNeuDRbdF42zG483YEqU7meZbPKR8QbkK
|
9
|
+
ZQPEBuevAkEAzxjGcz6NZesmN/NQOtOpylewEs1bdIJyBIBmcnmkimLBtdxd0t34
|
10
|
+
wUKVHLDSj2aemuAHHwsyn/BNXs6F+obmAQJBALpbkAXAAFW1xefvo3vih8sOXyfd
|
11
|
+
WIfX2SRNBqbq7otyVFudQaChBDUrsOgBUPLyBAdH8DoV27wm9UuR9RPvu/cCQFRr
|
12
|
+
WgICXqtMFtE56tuACreD1S9k7MHqpsW0/Y3ujicnKKWUhd5+Q3esR5JhdgOkpkSl
|
13
|
+
y+FYtDNERpW+BBliwgECQA+Vc7pnxwDIOP8kFumdAUmRmhEZjuwArFcywPzrCUn9
|
14
|
+
4/KBOp5wDN7kanBwNGZCZ/eQtkb6thAS8C9pufHD1lw=
|
15
15
|
-----END RSA PRIVATE KEY-----
|
@@ -17,5 +17,10 @@
|
|
17
17
|
File to process: <input name="green[eggs]" type="file" /><br />
|
18
18
|
<input type="submit" value="Send File" />
|
19
19
|
</form>
|
20
|
+
<form enctype="multipart/form-data" action="/file_upload" name="value_test" method="post">
|
21
|
+
Your name: <input type="text" name="name" /><br />
|
22
|
+
File to process: <input name="green[eggs]" value="/etc/hosts" type="file" /><br />
|
23
|
+
<input type="submit" value="Send File" />
|
24
|
+
</form>
|
20
25
|
</body>
|
21
26
|
</html>
|
data/test/server.rb
CHANGED
@@ -22,6 +22,7 @@ s.mount("/response_code", ResponseCodeTest)
|
|
22
22
|
s.mount("/file_upload", FileUploadTest)
|
23
23
|
s.mount("/bad_content_type", BadContentTypeTest)
|
24
24
|
s.mount("/content_type_test", ContentTypeTest)
|
25
|
+
s.mount("/gzip", GzipServlet)
|
25
26
|
|
26
27
|
htpasswd = WEBrick::HTTPAuth::Htpasswd.new(base_dir + '/data/htpasswd')
|
27
28
|
auth = WEBrick::HTTPAuth::BasicAuth.new(
|
data/test/servlets.rb
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
require 'webrick'
|
2
2
|
require 'logger'
|
3
3
|
require 'date'
|
4
|
+
require 'zlib'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
class GzipServlet < WEBrick::HTTPServlet::AbstractServlet
|
8
|
+
def do_GET(req, res)
|
9
|
+
if req['Accept-Encoding'] =~ /gzip/
|
10
|
+
File.open("htdocs/#{req.query['file']}", 'r') do |file|
|
11
|
+
string = ""
|
12
|
+
zipped = StringIO.new string, 'w'
|
13
|
+
gz = Zlib::GzipWriter.new(zipped)
|
14
|
+
gz.write file.read
|
15
|
+
gz.close
|
16
|
+
res['Content-Encoding'] = 'gzip'
|
17
|
+
res['Content-Type'] = "text/html"
|
18
|
+
res.body = string
|
19
|
+
end
|
20
|
+
else
|
21
|
+
raise 'no gzip'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
4
25
|
|
5
26
|
class BadContentTypeTest < WEBrick::HTTPServlet::AbstractServlet
|
6
27
|
def do_GET(req, res)
|
data/test/ssl_server.rb
CHANGED
data/test/tc_forms.rb
CHANGED
@@ -476,4 +476,16 @@ class FormsMechTest < Test::Unit::TestCase
|
|
476
476
|
form.first = 'Aaron'
|
477
477
|
assert_equal('Aaron', form.first)
|
478
478
|
end
|
479
|
+
|
480
|
+
def test_fields_as_hash
|
481
|
+
page = @agent.get("http://localhost:#{PORT}/form_multival.html")
|
482
|
+
form = page.forms.name('post_form').first
|
483
|
+
|
484
|
+
assert_not_nil(form)
|
485
|
+
assert_equal(2, form.fields.name('first').length)
|
486
|
+
|
487
|
+
form['first'] = 'Aaron'
|
488
|
+
assert_equal('Aaron', form['first'])
|
489
|
+
assert_equal('Aaron', form.fields.name('first').first.value)
|
490
|
+
end
|
479
491
|
end
|
data/test/tc_gzipping.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class TestGzip < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_request_gzip
|
16
|
+
page = nil
|
17
|
+
assert_nothing_raised do
|
18
|
+
page = @agent.get("http://localhost:#{PORT}/gzip?file=index.html")
|
19
|
+
end
|
20
|
+
assert_kind_of(WWW::Mechanize::Page, page)
|
21
|
+
assert_match('Hello World', page.body)
|
22
|
+
end
|
23
|
+
end
|
data/test/tc_mech.rb
CHANGED
@@ -103,4 +103,16 @@ class MechMethodsTest < Test::Unit::TestCase
|
|
103
103
|
page_as_string = @agent.get_file("http://localhost:#{PORT}/frame_test.html")
|
104
104
|
assert_equal(content_length.to_i, page_as_string.length.to_i)
|
105
105
|
end
|
106
|
+
|
107
|
+
def test_transact
|
108
|
+
page = @agent.get("http://localhost:#{PORT}/frame_test.html")
|
109
|
+
assert_equal(1, @agent.history.length)
|
110
|
+
@agent.transact { |a|
|
111
|
+
5.times {
|
112
|
+
@agent.get("http://localhost:#{PORT}/frame_test.html")
|
113
|
+
}
|
114
|
+
assert_equal(6, @agent.history.length)
|
115
|
+
}
|
116
|
+
assert_equal(1, @agent.history.length)
|
117
|
+
end
|
106
118
|
end
|
data/test/tc_pluggable_parser.rb
CHANGED
@@ -100,4 +100,39 @@ class PluggableParserTest < Test::Unit::TestCase
|
|
100
100
|
assert_equal(Filter, @agent.pluggable_parser['text/xml'])
|
101
101
|
assert_kind_of(Filter, page)
|
102
102
|
end
|
103
|
+
|
104
|
+
def test_file_saver_no_path
|
105
|
+
url = URI::HTTP.new('http', nil, 'example.com', nil, nil, '', nil, nil, nil)
|
106
|
+
fs = WWW::Mechanize::FileSaver.new(url, nil, 'hello world', 200)
|
107
|
+
assert_equal('example.com/index.html', fs.filename)
|
108
|
+
FileUtils.rm_rf('example.com')
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_file_saver_slash
|
112
|
+
url = URI::HTTP.new('http', nil, 'example.com', nil, nil, '/', nil, nil, nil)
|
113
|
+
fs = WWW::Mechanize::FileSaver.new(url, nil, 'hello world', 200)
|
114
|
+
assert_equal('example.com/index.html', fs.filename)
|
115
|
+
FileUtils.rm_rf('example.com')
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_file_saver_slash_file
|
119
|
+
url = URI::HTTP.new('http', nil, 'example.com', nil, nil, '/foo.html', nil, nil, nil)
|
120
|
+
fs = WWW::Mechanize::FileSaver.new(url, nil, 'hello world', 200)
|
121
|
+
assert_equal('example.com/foo.html', fs.filename)
|
122
|
+
FileUtils.rm_rf('example.com')
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_file_saver_long_path_no_file
|
126
|
+
url = URI::HTTP.new('http', nil, 'example.com', nil, nil, '/one/two/', nil, nil, nil)
|
127
|
+
fs = WWW::Mechanize::FileSaver.new(url, nil, 'hello world', 200)
|
128
|
+
assert_equal('example.com/one/two/index.html', fs.filename)
|
129
|
+
FileUtils.rm_rf('example.com')
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_file_saver_long_path
|
133
|
+
url = URI::HTTP.new('http', nil, 'example.com', nil, nil, '/one/two/foo.html', nil, nil, nil)
|
134
|
+
fs = WWW::Mechanize::FileSaver.new(url, nil, 'hello world', 200)
|
135
|
+
assert_equal('example.com/one/two/foo.html', fs.filename)
|
136
|
+
FileUtils.rm_rf('example.com')
|
137
|
+
end
|
103
138
|
end
|
data/test/tc_upload.rb
CHANGED
@@ -53,6 +53,41 @@ class UploadMechTest < Test::Unit::TestCase
|
|
53
53
|
)
|
54
54
|
end
|
55
55
|
|
56
|
+
def test_form_read_file
|
57
|
+
page = @agent.get("http://localhost:#{PORT}/file_upload.html")
|
58
|
+
assert_equal('multipart/form-data', page.forms[1].enctype)
|
59
|
+
|
60
|
+
form = page.forms[1]
|
61
|
+
form.file_uploads.first.file_name = "README"
|
62
|
+
|
63
|
+
page = @agent.submit(form)
|
64
|
+
|
65
|
+
contents = File.open("README", 'rb') { |f| f.read }
|
66
|
+
assert_match(
|
67
|
+
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"README\"",
|
68
|
+
page.body
|
69
|
+
)
|
70
|
+
assert_match(contents, page.body)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_form_io_obj
|
74
|
+
page = @agent.get("http://localhost:#{PORT}/file_upload.html")
|
75
|
+
assert_equal('multipart/form-data', page.forms[1].enctype)
|
76
|
+
|
77
|
+
form = page.forms[1]
|
78
|
+
form.file_uploads.first.file_name = "README"
|
79
|
+
form.file_uploads.first.file_data = File.open("README", 'rb')
|
80
|
+
|
81
|
+
page = @agent.submit(form)
|
82
|
+
|
83
|
+
contents = File.open("README", 'rb') { |f| f.read }
|
84
|
+
assert_match(
|
85
|
+
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"README\"",
|
86
|
+
page.body
|
87
|
+
)
|
88
|
+
assert_match(contents, page.body)
|
89
|
+
end
|
90
|
+
|
56
91
|
def test_submit_no_file
|
57
92
|
page = @agent.get("http://localhost:#{PORT}/file_upload.html")
|
58
93
|
form = page.forms.first
|
@@ -64,4 +99,11 @@ class UploadMechTest < Test::Unit::TestCase
|
|
64
99
|
page.body
|
65
100
|
)
|
66
101
|
end
|
102
|
+
|
103
|
+
def test_no_value
|
104
|
+
page = @agent.get("http://localhost:#{PORT}/file_upload.html")
|
105
|
+
form = page.form('value_test')
|
106
|
+
assert_nil(form.file_uploads.first.value)
|
107
|
+
assert_nil(form.file_uploads.first.file_name)
|
108
|
+
end
|
67
109
|
end
|
data/test/ts_mech.rb
CHANGED
metadata
CHANGED
@@ -3,11 +3,11 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: mechanize
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.5.
|
7
|
-
date: 2006-08-
|
6
|
+
version: 0.5.4
|
7
|
+
date: 2006-08-29 00:00:00 -07:00
|
8
8
|
summary: Mechanize provides automated web-browsing
|
9
9
|
require_paths:
|
10
|
-
- lib
|
10
|
+
- lib
|
11
11
|
email: aaronp@rubyforge.org
|
12
12
|
homepage: mechanize.rubyforge.org
|
13
13
|
rubyforge_project: mechanize
|
@@ -18,139 +18,148 @@ bindir: bin
|
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
24
25
|
version:
|
25
26
|
platform: ruby
|
26
27
|
signing_key:
|
27
28
|
cert_chain:
|
28
29
|
post_install_message:
|
29
30
|
authors:
|
30
|
-
- Aaron Patterson
|
31
|
+
- Aaron Patterson
|
31
32
|
files:
|
32
|
-
- test/
|
33
|
-
- test/
|
34
|
-
- test/
|
35
|
-
- test/
|
36
|
-
- test/
|
37
|
-
- test/
|
38
|
-
- test/
|
39
|
-
- test/
|
40
|
-
- test/
|
41
|
-
- test/
|
42
|
-
- test/
|
43
|
-
- test/
|
44
|
-
- test/
|
45
|
-
- test/
|
46
|
-
- test/
|
47
|
-
- test/
|
48
|
-
- test/
|
49
|
-
- test/
|
50
|
-
- test/
|
51
|
-
- test/
|
52
|
-
- test/
|
53
|
-
- test/
|
54
|
-
- test/
|
55
|
-
- test/
|
56
|
-
- test/
|
57
|
-
- test/
|
58
|
-
- test/
|
59
|
-
- test/
|
60
|
-
- test/
|
61
|
-
- test/
|
62
|
-
- test/
|
63
|
-
- test/tc_select.rb
|
64
|
-
- test/
|
65
|
-
- test/
|
66
|
-
- test/
|
67
|
-
- test/
|
68
|
-
- test/
|
69
|
-
- test/
|
70
|
-
- test/
|
71
|
-
- test/
|
72
|
-
- test/
|
73
|
-
- test/
|
74
|
-
- test/
|
75
|
-
- test/data/
|
76
|
-
- test/data/server.
|
77
|
-
- test/data/server.
|
78
|
-
- test/data/
|
79
|
-
- test/
|
80
|
-
- test/htdocs/
|
81
|
-
- test/htdocs/
|
82
|
-
- test/htdocs/
|
83
|
-
- test/htdocs/
|
84
|
-
- test/htdocs/
|
85
|
-
- test/htdocs/
|
86
|
-
- test/htdocs/
|
87
|
-
- test/htdocs/
|
88
|
-
- test/htdocs/
|
89
|
-
- test/htdocs/
|
90
|
-
- test/htdocs/
|
91
|
-
- test/htdocs/
|
92
|
-
- test/htdocs/
|
93
|
-
- test/htdocs/
|
94
|
-
- test/htdocs/
|
95
|
-
- test/htdocs/
|
96
|
-
- test/htdocs/
|
97
|
-
- test/htdocs/
|
98
|
-
- test/htdocs/
|
99
|
-
- test/htdocs/
|
100
|
-
- test/htdocs/
|
101
|
-
- test/htdocs/
|
102
|
-
- test/htdocs/
|
103
|
-
- test/htdocs/
|
104
|
-
-
|
105
|
-
- lib/mechanize
|
106
|
-
- lib/mechanize
|
107
|
-
- lib/mechanize/
|
108
|
-
- lib/mechanize/
|
109
|
-
- lib/mechanize/
|
110
|
-
- lib/mechanize/
|
111
|
-
- lib/mechanize/
|
112
|
-
- lib/mechanize/
|
113
|
-
- lib/mechanize/mech_version.rb
|
114
|
-
- lib/mechanize/
|
115
|
-
- lib/mechanize/
|
116
|
-
- lib/mechanize/
|
117
|
-
- lib/mechanize/page_elements.rb
|
118
|
-
- lib/mechanize/
|
119
|
-
- lib/mechanize/
|
120
|
-
- lib/mechanize/net-overrides/net
|
121
|
-
- lib/mechanize/net-overrides/net/
|
122
|
-
- lib/mechanize/net-overrides/net/
|
123
|
-
-
|
124
|
-
-
|
125
|
-
-
|
126
|
-
-
|
127
|
-
-
|
33
|
+
- test/data
|
34
|
+
- test/htdocs
|
35
|
+
- test/parse.rb
|
36
|
+
- test/proxy.rb
|
37
|
+
- test/README
|
38
|
+
- test/server.rb
|
39
|
+
- test/servlets.rb
|
40
|
+
- test/ssl_server.rb
|
41
|
+
- test/tc_authenticate.rb
|
42
|
+
- test/tc_bad_links.rb
|
43
|
+
- test/tc_checkboxes.rb
|
44
|
+
- test/tc_cookie_class.rb
|
45
|
+
- test/tc_cookie_jar.rb
|
46
|
+
- test/tc_cookies.rb
|
47
|
+
- test/tc_errors.rb
|
48
|
+
- test/tc_form_no_inputname.rb
|
49
|
+
- test/tc_forms.rb
|
50
|
+
- test/tc_frames.rb
|
51
|
+
- test/tc_gzipping.rb
|
52
|
+
- test/tc_links.rb
|
53
|
+
- test/tc_mech.rb
|
54
|
+
- test/tc_multi_select.rb
|
55
|
+
- test/tc_page.rb
|
56
|
+
- test/tc_parsing.rb
|
57
|
+
- test/tc_pluggable_parser.rb
|
58
|
+
- test/tc_post_form.rb
|
59
|
+
- test/tc_pretty_print.rb
|
60
|
+
- test/tc_proxy.rb
|
61
|
+
- test/tc_radiobutton.rb
|
62
|
+
- test/tc_response_code.rb
|
63
|
+
- test/tc_save_file.rb
|
64
|
+
- test/tc_select.rb
|
65
|
+
- test/tc_select_all.rb
|
66
|
+
- test/tc_select_none.rb
|
67
|
+
- test/tc_select_noopts.rb
|
68
|
+
- test/tc_set_fields.rb
|
69
|
+
- test/tc_ssl_server.rb
|
70
|
+
- test/tc_textarea.rb
|
71
|
+
- test/tc_upload.rb
|
72
|
+
- test/tc_watches.rb
|
73
|
+
- test/test_includes.rb
|
74
|
+
- test/test_mech.rb
|
75
|
+
- test/ts_mech.rb
|
76
|
+
- test/data/htpasswd
|
77
|
+
- test/data/server.crt
|
78
|
+
- test/data/server.csr
|
79
|
+
- test/data/server.key
|
80
|
+
- test/data/server.pem
|
81
|
+
- test/htdocs/alt_text.html
|
82
|
+
- test/htdocs/bad_form_test.html
|
83
|
+
- test/htdocs/button.jpg
|
84
|
+
- test/htdocs/file_upload.html
|
85
|
+
- test/htdocs/find_link.html
|
86
|
+
- test/htdocs/form_multi_select.html
|
87
|
+
- test/htdocs/form_multival.html
|
88
|
+
- test/htdocs/form_no_action.html
|
89
|
+
- test/htdocs/form_no_input_name.html
|
90
|
+
- test/htdocs/form_select.html
|
91
|
+
- test/htdocs/form_select_all.html
|
92
|
+
- test/htdocs/form_select_none.html
|
93
|
+
- test/htdocs/form_select_noopts.html
|
94
|
+
- test/htdocs/form_set_fields.html
|
95
|
+
- test/htdocs/form_test.html
|
96
|
+
- test/htdocs/frame_test.html
|
97
|
+
- test/htdocs/google.html
|
98
|
+
- test/htdocs/iframe_test.html
|
99
|
+
- test/htdocs/index.html
|
100
|
+
- test/htdocs/no_title_test.html
|
101
|
+
- test/htdocs/tc_bad_links.html
|
102
|
+
- test/htdocs/tc_checkboxes.html
|
103
|
+
- test/htdocs/tc_pretty_print.html
|
104
|
+
- test/htdocs/tc_radiobuttons.html
|
105
|
+
- test/htdocs/tc_textarea.html
|
106
|
+
- lib/mechanize
|
107
|
+
- lib/mechanize.rb
|
108
|
+
- lib/mechanize/cookie.rb
|
109
|
+
- lib/mechanize/errors.rb
|
110
|
+
- lib/mechanize/form.rb
|
111
|
+
- lib/mechanize/form_elements.rb
|
112
|
+
- lib/mechanize/inspect.rb
|
113
|
+
- lib/mechanize/list.rb
|
114
|
+
- lib/mechanize/mech_version.rb
|
115
|
+
- lib/mechanize/module.rb
|
116
|
+
- lib/mechanize/net-overrides
|
117
|
+
- lib/mechanize/page.rb
|
118
|
+
- lib/mechanize/page_elements.rb
|
119
|
+
- lib/mechanize/parsing.rb
|
120
|
+
- lib/mechanize/pluggable_parsers.rb
|
121
|
+
- lib/mechanize/net-overrides/net
|
122
|
+
- lib/mechanize/net-overrides/net/http.rb
|
123
|
+
- lib/mechanize/net-overrides/net/https.rb
|
124
|
+
- lib/mechanize/net-overrides/net/protocol.rb
|
125
|
+
- README
|
126
|
+
- EXAMPLES
|
127
|
+
- CHANGELOG
|
128
|
+
- LICENSE
|
129
|
+
- NOTES
|
128
130
|
test_files: []
|
129
|
-
|
130
131
|
rdoc_options:
|
131
|
-
- --main
|
132
|
-
- README
|
133
|
-
- --title
|
134
|
-
- "'WWW::Mechanize RDoc'"
|
132
|
+
- "--main"
|
133
|
+
- README
|
134
|
+
- "--title"
|
135
|
+
- "'WWW::Mechanize RDoc'"
|
135
136
|
extra_rdoc_files:
|
136
|
-
- README
|
137
|
-
- EXAMPLES
|
138
|
-
- CHANGELOG
|
139
|
-
- LICENSE
|
140
|
-
- NOTES
|
137
|
+
- README
|
138
|
+
- EXAMPLES
|
139
|
+
- CHANGELOG
|
140
|
+
- LICENSE
|
141
|
+
- NOTES
|
141
142
|
executables: []
|
142
|
-
|
143
143
|
extensions: []
|
144
|
-
|
145
144
|
requirements: []
|
146
|
-
|
147
145
|
dependencies:
|
148
|
-
- !ruby/object:Gem::Dependency
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: ruby-web
|
148
|
+
version_requirement:
|
149
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
150
|
+
requirements:
|
151
|
+
-
|
152
|
+
- ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: 1.1.0
|
155
|
+
version:
|
156
|
+
- !ruby/object:Gem::Dependency
|
157
|
+
name: mime-types
|
158
|
+
version_requirement:
|
159
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
160
|
+
requirements:
|
161
|
+
-
|
162
|
+
- ">"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: 0.0.0
|
165
|
+
version:
|