mechanize 0.6.7 → 0.6.8
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.txt +11 -0
- data/Manifest.txt +3 -0
- data/Rakefile +1 -1
- data/lib/mechanize.rb +66 -25
- data/lib/mechanize/form.rb +19 -23
- data/lib/mechanize/form_elements.rb +2 -3
- data/lib/mechanize/monkey_patch.rb +15 -0
- data/lib/mechanize/page.rb +5 -6
- data/lib/mechanize/page_elements.rb +5 -12
- data/lib/mechanize/pluggable_parsers.rb +31 -3
- data/test/tc_keep_alive.rb +38 -0
- data/test/tc_save_file.rb +31 -0
- data/test/tc_watches.rb +1 -1
- data/test/test_all.rb +1 -0
- data/test/test_includes.rb +1 -0
- data/test/test_mechanize_file.rb +52 -0
- data/test/test_servlets.rb +11 -0
- metadata +152 -148
data/CHANGELOG.txt
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
= Mechanize CHANGELOG
|
2
2
|
|
3
|
+
== 0.6.8
|
4
|
+
|
5
|
+
* Keep alive can be shut off now with WWW::Mechanize#keep_alive
|
6
|
+
* Conditional requests can be shut off with WWW::Mechanize#conditional_requests
|
7
|
+
* Monkey patched Net::HTTP#keep_alive?
|
8
|
+
* [#9877] Moved last request time. Thanks Max Stepanov
|
9
|
+
* Added WWW::Mechanize::File#save
|
10
|
+
* Defaulting file name to URI or Content-Disposition
|
11
|
+
* Updating compatability with hpricot
|
12
|
+
* Added more unit tests
|
13
|
+
|
3
14
|
== 0.6.7
|
4
15
|
|
5
16
|
* Fixed a bug with keep-alive requests
|
data/Manifest.txt
CHANGED
@@ -19,6 +19,7 @@ lib/mechanize/form_elements.rb
|
|
19
19
|
lib/mechanize/history.rb
|
20
20
|
lib/mechanize/inspect.rb
|
21
21
|
lib/mechanize/list.rb
|
22
|
+
lib/mechanize/monkey_patch.rb
|
22
23
|
lib/mechanize/net-overrides/net/http.rb
|
23
24
|
lib/mechanize/net-overrides/net/https.rb
|
24
25
|
lib/mechanize/net-overrides/net/protocol.rb
|
@@ -86,6 +87,7 @@ test/tc_gzipping.rb
|
|
86
87
|
test/tc_history.rb
|
87
88
|
test/tc_html_unscape_forms.rb
|
88
89
|
test/tc_if_modified_since.rb
|
90
|
+
test/tc_keep_alive.rb
|
89
91
|
test/tc_links.rb
|
90
92
|
test/tc_mech.rb
|
91
93
|
test/tc_multi_select.rb
|
@@ -112,4 +114,5 @@ test/tc_upload.rb
|
|
112
114
|
test/tc_watches.rb
|
113
115
|
test/test_all.rb
|
114
116
|
test/test_includes.rb
|
117
|
+
test/test_mechanize_file.rb
|
115
118
|
test/test_servlets.rb
|
data/Rakefile
CHANGED
@@ -54,7 +54,7 @@ MechHoe.new('mechanize', WWW::Mechanize::VERSION) do |p|
|
|
54
54
|
p.description = p.paragraphs_of('README.txt', 3).join("\n\n")
|
55
55
|
p.url = p.paragraphs_of('README.txt', 1).first.strip
|
56
56
|
p.changes = p.paragraphs_of('CHANGELOG.txt', 0..2).join("\n\n")
|
57
|
-
p.extra_deps = ['hpricot']
|
57
|
+
p.extra_deps = [['hpricot', '>= 0.5.0']]
|
58
58
|
end
|
59
59
|
|
60
60
|
|
data/lib/mechanize.rb
CHANGED
@@ -28,6 +28,7 @@ require 'uri'
|
|
28
28
|
require 'webrick/httputils'
|
29
29
|
require 'zlib'
|
30
30
|
require 'stringio'
|
31
|
+
require 'mechanize/monkey_patch'
|
31
32
|
require 'mechanize/cookie'
|
32
33
|
require 'mechanize/errors'
|
33
34
|
require 'mechanize/pluggable_parsers'
|
@@ -62,7 +63,7 @@ class Mechanize
|
|
62
63
|
##
|
63
64
|
# The version of Mechanize you are using.
|
64
65
|
|
65
|
-
VERSION = '0.6.
|
66
|
+
VERSION = '0.6.8'
|
66
67
|
|
67
68
|
##
|
68
69
|
# User Agent aliases
|
@@ -89,6 +90,8 @@ class Mechanize
|
|
89
90
|
attr_accessor :pass
|
90
91
|
attr_accessor :redirect_ok
|
91
92
|
attr_accessor :keep_alive_time
|
93
|
+
attr_accessor :keep_alive
|
94
|
+
attr_accessor :conditional_requests
|
92
95
|
|
93
96
|
attr_reader :history
|
94
97
|
attr_reader :pluggable_parser
|
@@ -123,9 +126,12 @@ class Mechanize
|
|
123
126
|
@proxy_port = nil
|
124
127
|
@proxy_user = nil
|
125
128
|
|
129
|
+
@conditional_requests = true
|
130
|
+
|
126
131
|
# Connection Cache & Keep alive
|
127
132
|
@connection_cache = {}
|
128
133
|
@keep_alive_time = 300
|
134
|
+
@keep_alive = true
|
129
135
|
|
130
136
|
yield self if block_given?
|
131
137
|
end
|
@@ -204,9 +210,8 @@ class Mechanize
|
|
204
210
|
# agent.post('http://example.com/', [ ["foo", "bar"] ])
|
205
211
|
def post(url, query={})
|
206
212
|
node = Hpricot::Elem.new(Hpricot::STag.new('form'))
|
207
|
-
node
|
208
|
-
node
|
209
|
-
node.attributes['enctype'] = 'application/x-www-form-urlencoded'
|
213
|
+
node['method'] = 'POST'
|
214
|
+
node['enctype'] = 'application/x-www-form-urlencoded'
|
210
215
|
|
211
216
|
form = Form.new(node)
|
212
217
|
query.each { |k,v|
|
@@ -268,8 +273,12 @@ class Mechanize
|
|
268
273
|
|
269
274
|
protected
|
270
275
|
def set_headers(uri, request, cur_page)
|
271
|
-
|
272
|
-
|
276
|
+
if @keep_alive
|
277
|
+
request.add_field('Connection', 'keep-alive')
|
278
|
+
request.add_field('Keep-Alive', keep_alive_time.to_s)
|
279
|
+
else
|
280
|
+
request.add_field('Connection', 'close')
|
281
|
+
end
|
273
282
|
request.add_field('Accept-Encoding', 'gzip,identity')
|
274
283
|
request.add_field('Accept-Language', 'en-us,en;q0.5')
|
275
284
|
request.add_field('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
|
@@ -294,8 +303,10 @@ class Mechanize
|
|
294
303
|
request.add_field('User-Agent', @user_agent) if @user_agent
|
295
304
|
|
296
305
|
# Add If-Modified-Since if page is in history
|
297
|
-
if
|
298
|
-
|
306
|
+
if @conditional_requests
|
307
|
+
if( (page = visited_page(uri)) && page.response['Last-Modified'] )
|
308
|
+
request.add_field('If-Modified-Since', page.response['Last-Modified'])
|
309
|
+
end
|
299
310
|
end
|
300
311
|
|
301
312
|
request.basic_auth(@user, @password) if @user || @password
|
@@ -366,9 +377,13 @@ class Mechanize
|
|
366
377
|
|
367
378
|
page = nil
|
368
379
|
|
369
|
-
|
380
|
+
cache_obj = (@connection_cache["#{uri.host}:#{uri.port}"] ||= {
|
381
|
+
:connection => nil,
|
382
|
+
:keep_alive_options => {},
|
383
|
+
})
|
384
|
+
http_obj = cache_obj[:connection]
|
370
385
|
if http_obj.nil? || ! http_obj.started?
|
371
|
-
http_obj =
|
386
|
+
http_obj = cache_obj[:connection] =
|
372
387
|
Net::HTTP.new( uri.host,
|
373
388
|
uri.port,
|
374
389
|
@proxy_addr,
|
@@ -376,6 +391,11 @@ class Mechanize
|
|
376
391
|
@proxy_user,
|
377
392
|
@proxy_pass
|
378
393
|
)
|
394
|
+
cache_obj[:keep_alive_options] = {}
|
395
|
+
|
396
|
+
# Specify timeouts if given
|
397
|
+
http_obj.open_timeout = @open_timeout if @open_timeout
|
398
|
+
http_obj.read_timeout = @read_timeout if @read_timeout
|
379
399
|
end
|
380
400
|
|
381
401
|
if uri.scheme == 'https' && ! http_obj.started?
|
@@ -391,6 +411,21 @@ class Mechanize
|
|
391
411
|
end
|
392
412
|
end
|
393
413
|
|
414
|
+
# If we're keeping connections alive and the last request time is too
|
415
|
+
# long ago, stop the connection. Or, if the max requests left is 1,
|
416
|
+
# reset the connection.
|
417
|
+
if @keep_alive && http_obj.started?
|
418
|
+
opts = cache_obj[:keep_alive_options]
|
419
|
+
if((opts[:timeout] &&
|
420
|
+
Time.now.to_i - cache_obj[:last_request_time] > opts[:timeout].to_i) ||
|
421
|
+
opts[:max] && opts[:max].to_i == 1)
|
422
|
+
|
423
|
+
log.debug('Finishing stale connection') if log
|
424
|
+
http_obj.finish
|
425
|
+
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
394
429
|
http_obj.start unless http_obj.started?
|
395
430
|
|
396
431
|
request = set_headers(uri, request, cur_page)
|
@@ -402,24 +437,10 @@ class Mechanize
|
|
402
437
|
end
|
403
438
|
end
|
404
439
|
|
405
|
-
|
406
|
-
http_obj.open_timeout = @open_timeout if @open_timeout
|
407
|
-
http_obj.read_timeout = @read_timeout if @read_timeout
|
440
|
+
cache_obj[:last_request_time] = Time.now.to_i
|
408
441
|
|
409
442
|
# Send the request
|
410
443
|
response = http_obj.request(request, *request_data) {|response|
|
411
|
-
if log
|
412
|
-
response.each_header {|k,v|
|
413
|
-
log.debug("response-header: #{ k } => #{ v }")
|
414
|
-
}
|
415
|
-
end
|
416
|
-
|
417
|
-
(response.get_fields('Set-Cookie')||[]).each do |cookie|
|
418
|
-
Cookie::parse(uri, cookie, log) { |c|
|
419
|
-
log.debug("saved cookie: #{c}") if log
|
420
|
-
@cookie_jar.add(uri, c)
|
421
|
-
}
|
422
|
-
end
|
423
444
|
|
424
445
|
body = StringIO.new
|
425
446
|
total = 0
|
@@ -430,6 +451,10 @@ class Mechanize
|
|
430
451
|
}
|
431
452
|
body.rewind
|
432
453
|
|
454
|
+
response.each_header { |k,v|
|
455
|
+
log.debug("response-header: #{ k } => #{ v }")
|
456
|
+
} if log
|
457
|
+
|
433
458
|
content_type = nil
|
434
459
|
unless response['Content-Type'].nil?
|
435
460
|
data = response['Content-Type'].match(/^([^;]*)/)
|
@@ -464,6 +489,22 @@ class Mechanize
|
|
464
489
|
|
465
490
|
}
|
466
491
|
|
492
|
+
# If the server sends back keep alive options, save them
|
493
|
+
if keep_alive_info = response['keep-alive']
|
494
|
+
keep_alive_info.split(/,\s*/).each do |option|
|
495
|
+
k, v = option.split(/=/)
|
496
|
+
cache_obj[:keep_alive_options] ||= {}
|
497
|
+
cache_obj[:keep_alive_options][k.intern] = v
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
(response.get_fields('Set-Cookie')||[]).each do |cookie|
|
502
|
+
Cookie::parse(uri, cookie, log) { |c|
|
503
|
+
log.debug("saved cookie: #{c}") if log
|
504
|
+
@cookie_jar.add(uri, c)
|
505
|
+
}
|
506
|
+
end
|
507
|
+
|
467
508
|
log.info("status: #{ page.code }") if log
|
468
509
|
|
469
510
|
res_klass = Net::HTTPResponse::CODE_TO_OBJ[page.code.to_s]
|
data/lib/mechanize/form.rb
CHANGED
@@ -32,11 +32,10 @@ module WWW
|
|
32
32
|
def initialize(form_node, elements_node)
|
33
33
|
@form_node, @elements_node = form_node, elements_node
|
34
34
|
|
35
|
-
@form_node
|
36
|
-
@
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@enctype = @form_node.attributes['enctype'] || 'application/x-www-form-urlencoded'
|
35
|
+
@method = (@form_node['method'] || 'GET').upcase
|
36
|
+
@action = Util::html_unescape(@form_node['action'])
|
37
|
+
@name = @form_node['name']
|
38
|
+
@enctype = @form_node['enctype'] || 'application/x-www-form-urlencoded'
|
40
39
|
@clicked_buttons = []
|
41
40
|
|
42
41
|
parse
|
@@ -122,43 +121,40 @@ module WWW
|
|
122
121
|
|
123
122
|
# Find all input tags
|
124
123
|
(@elements_node/'input').each do |node|
|
125
|
-
node
|
126
|
-
|
127
|
-
name = node.attributes['name']
|
124
|
+
type = (node['type'] || 'text').downcase
|
125
|
+
name = node['name']
|
128
126
|
next if name.nil? && !(type == 'submit' || type =='button')
|
129
127
|
case type
|
130
128
|
when 'text', 'password', 'hidden', 'int'
|
131
|
-
@fields << Field.new(node
|
129
|
+
@fields << Field.new(node['name'], node['value'] || '')
|
132
130
|
when 'radio'
|
133
|
-
@radiobuttons << RadioButton.new(node
|
131
|
+
@radiobuttons << RadioButton.new(node['name'], node['value'], node.has_attribute?('checked'), self)
|
134
132
|
when 'checkbox'
|
135
|
-
@checkboxes << CheckBox.new(node
|
133
|
+
@checkboxes << CheckBox.new(node['name'], node['value'], node.has_attribute?('checked'), self)
|
136
134
|
when 'file'
|
137
|
-
@file_uploads << FileUpload.new(node
|
135
|
+
@file_uploads << FileUpload.new(node['name'], nil)
|
138
136
|
when 'submit'
|
139
|
-
@buttons << Button.new(node
|
137
|
+
@buttons << Button.new(node['name'], node['value'])
|
140
138
|
when 'button'
|
141
|
-
@buttons << Button.new(node
|
139
|
+
@buttons << Button.new(node['name'], node['value'])
|
142
140
|
when 'image'
|
143
|
-
@buttons << ImageButton.new(node
|
141
|
+
@buttons << ImageButton.new(node['name'], node['value'])
|
144
142
|
end
|
145
143
|
end
|
146
144
|
|
147
145
|
# Find all textarea tags
|
148
146
|
(@elements_node/'textarea').each do |node|
|
149
|
-
next if node.
|
150
|
-
|
151
|
-
@fields << Field.new(node.attributes['name'], node.inner_text)
|
147
|
+
next if node['name'].nil?
|
148
|
+
@fields << Field.new(node['name'], node.inner_text)
|
152
149
|
end
|
153
150
|
|
154
151
|
# Find all select tags
|
155
152
|
(@elements_node/'select').each do |node|
|
156
|
-
next if node.
|
157
|
-
|
158
|
-
|
159
|
-
@fields << MultiSelectList.new(node.attributes['name'], node)
|
153
|
+
next if node['name'].nil?
|
154
|
+
if node.has_attribute? 'multiple'
|
155
|
+
@fields << MultiSelectList.new(node['name'], node)
|
160
156
|
else
|
161
|
-
@fields << SelectList.new(node
|
157
|
+
@fields << SelectList.new(node['name'], node)
|
162
158
|
end
|
163
159
|
end
|
164
160
|
end
|
@@ -217,10 +217,9 @@ module WWW
|
|
217
217
|
alias :selected? :selected
|
218
218
|
|
219
219
|
def initialize(node, select_list)
|
220
|
-
node.attributes ||= {}
|
221
220
|
@text = node.inner_text
|
222
|
-
@value = Util.html_unescape(node
|
223
|
-
@selected = node.
|
221
|
+
@value = Util.html_unescape(node['value'])
|
222
|
+
@selected = node.has_attribute? 'selected'
|
224
223
|
@select_list = select_list # The select list this option belongs to
|
225
224
|
end
|
226
225
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Net
|
2
|
+
class HTTP
|
3
|
+
alias :old_keep_alive? :keep_alive?
|
4
|
+
def keep_alive?(req, res)
|
5
|
+
return false if /close/i =~ req['connection'].to_s
|
6
|
+
return false if @seems_1_0_server
|
7
|
+
return false if /close/i =~ res['connection'].to_s
|
8
|
+
return true if /keep-alive/i =~ res['connection'].to_s
|
9
|
+
return false if /close/i =~ res['proxy-connection'].to_s
|
10
|
+
return true if /keep-alive/i =~ res['proxy-connection'].to_s
|
11
|
+
(@curr_http_version == '1.1')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
data/lib/mechanize/page.rb
CHANGED
@@ -89,14 +89,13 @@ module WWW
|
|
89
89
|
|
90
90
|
# Find all 'meta' tags
|
91
91
|
(@parser/'meta').each do |node|
|
92
|
-
next
|
93
|
-
next unless node
|
94
|
-
|
95
|
-
|
96
|
-
content = node.attributes['content']
|
92
|
+
next unless node['http-equiv']
|
93
|
+
next unless node['content']
|
94
|
+
equiv = node['http-equiv']
|
95
|
+
content = node['content']
|
97
96
|
if equiv != nil && equiv.downcase == 'refresh'
|
98
97
|
if content != nil && content =~ /^\d+\s*;\s*url\s*=\s*(\S+)/i
|
99
|
-
node
|
98
|
+
node['href'] = $1
|
100
99
|
@meta << Meta.new(node, @mech, self)
|
101
100
|
end
|
102
101
|
end
|
@@ -18,24 +18,18 @@ module WWW
|
|
18
18
|
alias :referer :page
|
19
19
|
|
20
20
|
def initialize(node, mech, page)
|
21
|
-
node.attributes ||= {}
|
22
21
|
@node = node
|
23
|
-
@href = node
|
22
|
+
@href = node['href']
|
24
23
|
@text = node.inner_text
|
25
24
|
@page = page
|
26
25
|
@mech = mech
|
27
|
-
@attributes = node
|
26
|
+
@attributes = node
|
28
27
|
|
29
28
|
# If there is no text, try to find an image and use it's alt text
|
30
29
|
if (@text.nil? || @text.length == 0) && (node/'img').length > 0
|
31
30
|
@text = ''
|
32
31
|
(node/'img').each do |e|
|
33
|
-
e
|
34
|
-
@text << (
|
35
|
-
(e.attributes.has_key?('alt') && e.attributes['alt']) ?
|
36
|
-
e.attributes['alt'] :
|
37
|
-
''
|
38
|
-
)
|
32
|
+
@text << ( e['alt'] || '')
|
39
33
|
end
|
40
34
|
end
|
41
35
|
|
@@ -68,10 +62,9 @@ module WWW
|
|
68
62
|
|
69
63
|
def initialize(node, mech, referer)
|
70
64
|
super(node, mech, referer)
|
71
|
-
node.attributes ||= {}
|
72
65
|
@node = node
|
73
|
-
@text = node
|
74
|
-
@href = node
|
66
|
+
@text = node['name']
|
67
|
+
@href = node['src']
|
75
68
|
end
|
76
69
|
end
|
77
70
|
end
|
@@ -17,29 +17,57 @@ module WWW
|
|
17
17
|
# agent.get('http://example.com/foo.jpg').class #=> WWW::Mechanize::File
|
18
18
|
#
|
19
19
|
class File
|
20
|
-
attr_accessor :uri, :response, :body, :code
|
20
|
+
attr_accessor :uri, :response, :body, :code, :filename
|
21
21
|
alias :header :response
|
22
22
|
|
23
23
|
alias :content :body
|
24
24
|
|
25
25
|
def initialize(uri=nil, response=nil, body=nil, code=nil)
|
26
26
|
@uri, @body, @code = uri, body, code
|
27
|
+
@response = Headers.new
|
28
|
+
|
27
29
|
# Copy the headers in to a hash to prevent memory leaks
|
28
30
|
if response
|
29
|
-
@response = Headers.new
|
30
31
|
response.each { |k,v|
|
31
32
|
@response[k] = v
|
32
33
|
}
|
33
34
|
end
|
35
|
+
|
36
|
+
@filename = 'index.html'
|
37
|
+
|
38
|
+
# Set the filename
|
39
|
+
if disposition = @response['content-disposition']
|
40
|
+
disposition.split(/;\s*/).each do |pair|
|
41
|
+
k,v = pair.split(/=/, 2)
|
42
|
+
@filename = v if k.downcase == 'filename'
|
43
|
+
end
|
44
|
+
else
|
45
|
+
if @uri
|
46
|
+
@filename = @uri.path.split(/\//).last || 'index.html'
|
47
|
+
@filename << ".html" unless @filename =~ /\./
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
34
51
|
yield self if block_given?
|
35
52
|
end
|
36
53
|
|
37
54
|
# Use this method to save the content of this object to filename
|
38
|
-
def save_as(filename)
|
55
|
+
def save_as(filename = nil)
|
56
|
+
if filename.nil?
|
57
|
+
filename = @filename
|
58
|
+
number = 1
|
59
|
+
while(::File.exists?(filename))
|
60
|
+
filename = "#{@filename}.#{number}"
|
61
|
+
number += 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
39
65
|
::File::open(filename, "wb") { |f|
|
40
66
|
f.write body
|
41
67
|
}
|
42
68
|
end
|
69
|
+
|
70
|
+
alias :save :save_as
|
43
71
|
end
|
44
72
|
|
45
73
|
# = Synopsis
|
@@ -0,0 +1,38 @@
|
|
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 TestKeepAlive < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_keep_alive
|
16
|
+
page = @agent.get('http://localhost/http_headers')
|
17
|
+
headers = {}
|
18
|
+
page.body.split(/[\r\n]+/).each do |header|
|
19
|
+
headers.[]=(*header.chomp.split(/\|/))
|
20
|
+
end
|
21
|
+
assert(headers.has_key?('connection'))
|
22
|
+
assert_equal('keep-alive', headers['connection'])
|
23
|
+
assert(headers.has_key?('keep-alive'))
|
24
|
+
assert_equal('300', headers['keep-alive'])
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_close_connection
|
28
|
+
@agent.keep_alive = false
|
29
|
+
page = @agent.get('http://localhost/http_headers')
|
30
|
+
headers = {}
|
31
|
+
page.body.split(/[\r\n]+/).each do |header|
|
32
|
+
headers.[]=(*header.chomp.split(/\|/))
|
33
|
+
end
|
34
|
+
assert(headers.has_key?('connection'))
|
35
|
+
assert_equal('close', headers['connection'])
|
36
|
+
assert(!headers.has_key?('keep-alive'))
|
37
|
+
end
|
38
|
+
end
|
data/test/tc_save_file.rb
CHANGED
@@ -22,4 +22,35 @@ class TestSaveFile < Test::Unit::TestCase
|
|
22
22
|
FileUtils.rm("test.html")
|
23
23
|
assert_equal(length.to_i, file_length)
|
24
24
|
end
|
25
|
+
|
26
|
+
def test_save_file_default
|
27
|
+
page = WWW::Mechanize::File.new(
|
28
|
+
URI.parse('http://localhost/test.html'),
|
29
|
+
{},
|
30
|
+
"hello"
|
31
|
+
)
|
32
|
+
page.save
|
33
|
+
assert(File.exists?('test.html'))
|
34
|
+
page.save
|
35
|
+
assert(File.exists?('test.html.1'))
|
36
|
+
page.save
|
37
|
+
assert(File.exists?('test.html.2'))
|
38
|
+
FileUtils.rm("test.html")
|
39
|
+
FileUtils.rm("test.html.1")
|
40
|
+
FileUtils.rm("test.html.2")
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_save_file_default_with_dots
|
44
|
+
page = WWW::Mechanize::File.new(
|
45
|
+
URI.parse('http://localhost/../test.html'),
|
46
|
+
{},
|
47
|
+
"hello"
|
48
|
+
)
|
49
|
+
page.save
|
50
|
+
assert(File.exists?('test.html'))
|
51
|
+
page.save
|
52
|
+
assert(File.exists?('test.html.1'))
|
53
|
+
FileUtils.rm("test.html")
|
54
|
+
FileUtils.rm("test.html.1")
|
55
|
+
end
|
25
56
|
end
|
data/test/tc_watches.rb
CHANGED
data/test/test_all.rb
CHANGED
data/test/test_includes.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
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 MechanizeFileTest < Test::Unit::TestCase
|
9
|
+
def test_content_disposition
|
10
|
+
file = WWW::Mechanize::File.new(
|
11
|
+
URI.parse('http://localhost/foo'),
|
12
|
+
{ 'content-disposition' => 'attachment; filename=genome.jpeg; modification-date="Wed, 12 Feb 1997 16:29:51 -0500"', }
|
13
|
+
)
|
14
|
+
assert_equal('genome.jpeg', file.filename)
|
15
|
+
|
16
|
+
file = WWW::Mechanize::File.new(
|
17
|
+
URI.parse('http://localhost/foo'),
|
18
|
+
{ 'content-disposition' => 'filename=genome.jpeg; modification-date="Wed, 12 Feb 1997 16:29:51 -0500"', }
|
19
|
+
)
|
20
|
+
assert_equal('genome.jpeg', file.filename)
|
21
|
+
|
22
|
+
file = WWW::Mechanize::File.new(
|
23
|
+
URI.parse('http://localhost/foo'),
|
24
|
+
{ 'content-disposition' => 'filename=genome.jpeg', }
|
25
|
+
)
|
26
|
+
assert_equal('genome.jpeg', file.filename)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_from_uri
|
30
|
+
file = WWW::Mechanize::File.new(
|
31
|
+
URI.parse('http://localhost/foo'),
|
32
|
+
{}
|
33
|
+
)
|
34
|
+
assert_equal('foo.html', file.filename)
|
35
|
+
|
36
|
+
file = WWW::Mechanize::File.new(
|
37
|
+
URI.parse('http://localhost/foo.jpg'),
|
38
|
+
{}
|
39
|
+
)
|
40
|
+
assert_equal('foo.jpg', file.filename)
|
41
|
+
|
42
|
+
file = WWW::Mechanize::File.new(
|
43
|
+
URI.parse('http://localhost/foo.jpg')
|
44
|
+
)
|
45
|
+
assert_equal('foo.jpg', file.filename)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_no_uri
|
49
|
+
file = WWW::Mechanize::File.new()
|
50
|
+
assert_equal('index.html', file.filename)
|
51
|
+
end
|
52
|
+
end
|
data/test/test_servlets.rb
CHANGED
@@ -4,6 +4,17 @@ require 'date'
|
|
4
4
|
require 'zlib'
|
5
5
|
require 'stringio'
|
6
6
|
|
7
|
+
class HeaderServlet < WEBrick::HTTPServlet::AbstractServlet
|
8
|
+
def do_GET(req, res)
|
9
|
+
res['Content-Type'] = "text/html"
|
10
|
+
body = ''
|
11
|
+
req.each_header do |k,v|
|
12
|
+
body << "#{k}|#{v}\n"
|
13
|
+
end
|
14
|
+
res.body = body
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
7
18
|
class RefererServlet < WEBrick::HTTPServlet::AbstractServlet
|
8
19
|
def do_GET(req, res)
|
9
20
|
res['Content-Type'] = "text/html"
|
metadata
CHANGED
@@ -1,177 +1,181 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.0
|
3
3
|
specification_version: 1
|
4
4
|
name: mechanize
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.6.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.6.8
|
7
|
+
date: 2007-04-15 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: http://mechanize.rubyforge.org/
|
13
13
|
rubyforge_project: mechanize
|
14
|
-
description: The Mechanize library is used for automating interaction with websites.
|
14
|
+
description: "The Mechanize library is used for automating interaction with websites.
|
15
|
+
Mechanize automatically stores and sends cookies, follows redirects, can follow
|
16
|
+
links, and submit forms. Form fields can be populated and submitted. Mechanize
|
17
|
+
also keeps track of the sites that you have visited as a history."
|
15
18
|
autorequire:
|
16
19
|
default_executable:
|
17
20
|
bindir: bin
|
18
21
|
has_rdoc: true
|
19
22
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
23
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
-
|
25
|
+
- ">"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.0.0
|
24
28
|
version:
|
25
29
|
platform: ruby
|
26
30
|
signing_key:
|
27
31
|
cert_chain:
|
28
32
|
post_install_message:
|
29
33
|
authors:
|
30
|
-
- Aaron Patterson
|
34
|
+
- Aaron Patterson
|
31
35
|
files:
|
32
|
-
- CHANGELOG.txt
|
33
|
-
- EXAMPLES.txt
|
34
|
-
- GUIDE.txt
|
35
|
-
- LICENSE.txt
|
36
|
-
- Manifest.txt
|
37
|
-
- NOTES.txt
|
38
|
-
- README.txt
|
39
|
-
- Rakefile
|
40
|
-
- eg/flickr_upload.rb
|
41
|
-
- eg/mech-dump.rb
|
42
|
-
- eg/proxy_req.rb
|
43
|
-
- eg/rubyforge.rb
|
44
|
-
- eg/spider.rb
|
45
|
-
- lib/mechanize.rb
|
46
|
-
- lib/mechanize/cookie.rb
|
47
|
-
- lib/mechanize/errors.rb
|
48
|
-
- lib/mechanize/form.rb
|
49
|
-
- lib/mechanize/form_elements.rb
|
50
|
-
- lib/mechanize/history.rb
|
51
|
-
- lib/mechanize/inspect.rb
|
52
|
-
- lib/mechanize/list.rb
|
53
|
-
- lib/mechanize/
|
54
|
-
- lib/mechanize/net-overrides/net/
|
55
|
-
- lib/mechanize/net-overrides/net/
|
56
|
-
- lib/mechanize/
|
57
|
-
- lib/mechanize/
|
58
|
-
- lib/mechanize/
|
59
|
-
- lib/mechanize/
|
60
|
-
- lib/mechanize/
|
61
|
-
-
|
62
|
-
-
|
63
|
-
- test/data/
|
64
|
-
- test/data/server.
|
65
|
-
- test/data/server.
|
66
|
-
- test/data/server.
|
67
|
-
- test/
|
68
|
-
- test/htdocs/
|
69
|
-
- test/htdocs/
|
70
|
-
- test/htdocs/
|
71
|
-
- test/htdocs/
|
72
|
-
- test/htdocs/
|
73
|
-
- test/htdocs/
|
74
|
-
- test/htdocs/
|
75
|
-
- test/htdocs/
|
76
|
-
- test/htdocs/
|
77
|
-
- test/htdocs/
|
78
|
-
- test/htdocs/
|
79
|
-
- test/htdocs/
|
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/
|
102
|
-
- test/
|
103
|
-
- test/
|
104
|
-
- test/
|
105
|
-
- test/
|
106
|
-
- test/
|
107
|
-
- test/
|
108
|
-
- test/
|
109
|
-
- test/
|
110
|
-
- test/
|
111
|
-
- test/
|
112
|
-
- test/
|
113
|
-
- test/
|
114
|
-
- test/
|
115
|
-
- test/
|
116
|
-
- test/
|
117
|
-
- test/
|
118
|
-
- test/
|
119
|
-
- test/
|
120
|
-
- test/
|
121
|
-
- test/
|
122
|
-
- test/
|
123
|
-
- test/
|
124
|
-
- test/
|
125
|
-
- test/
|
126
|
-
- test/
|
127
|
-
- test/
|
128
|
-
- test/
|
129
|
-
- test/
|
130
|
-
- test/
|
131
|
-
- test/
|
132
|
-
- test/
|
133
|
-
- test/
|
134
|
-
- test/
|
135
|
-
- test/
|
136
|
-
- test/
|
137
|
-
- test/
|
138
|
-
- test/
|
139
|
-
- test/
|
140
|
-
- test/
|
141
|
-
- test/
|
142
|
-
- test/
|
143
|
-
- test/
|
144
|
-
- test/
|
145
|
-
- test/
|
146
|
-
- test/
|
36
|
+
- CHANGELOG.txt
|
37
|
+
- EXAMPLES.txt
|
38
|
+
- GUIDE.txt
|
39
|
+
- LICENSE.txt
|
40
|
+
- Manifest.txt
|
41
|
+
- NOTES.txt
|
42
|
+
- README.txt
|
43
|
+
- Rakefile
|
44
|
+
- eg/flickr_upload.rb
|
45
|
+
- eg/mech-dump.rb
|
46
|
+
- eg/proxy_req.rb
|
47
|
+
- eg/rubyforge.rb
|
48
|
+
- eg/spider.rb
|
49
|
+
- lib/mechanize.rb
|
50
|
+
- lib/mechanize/cookie.rb
|
51
|
+
- lib/mechanize/errors.rb
|
52
|
+
- lib/mechanize/form.rb
|
53
|
+
- lib/mechanize/form_elements.rb
|
54
|
+
- lib/mechanize/history.rb
|
55
|
+
- lib/mechanize/inspect.rb
|
56
|
+
- lib/mechanize/list.rb
|
57
|
+
- lib/mechanize/monkey_patch.rb
|
58
|
+
- lib/mechanize/net-overrides/net/http.rb
|
59
|
+
- lib/mechanize/net-overrides/net/https.rb
|
60
|
+
- lib/mechanize/net-overrides/net/protocol.rb
|
61
|
+
- lib/mechanize/page.rb
|
62
|
+
- lib/mechanize/page_elements.rb
|
63
|
+
- lib/mechanize/parsers/rexml_page.rb
|
64
|
+
- lib/mechanize/pluggable_parsers.rb
|
65
|
+
- lib/mechanize/rexml.rb
|
66
|
+
- setup.rb
|
67
|
+
- test/data/htpasswd
|
68
|
+
- test/data/server.crt
|
69
|
+
- test/data/server.csr
|
70
|
+
- test/data/server.key
|
71
|
+
- test/data/server.pem
|
72
|
+
- test/htdocs/alt_text.html
|
73
|
+
- test/htdocs/bad_form_test.html
|
74
|
+
- test/htdocs/button.jpg
|
75
|
+
- test/htdocs/empty_form.html
|
76
|
+
- test/htdocs/file_upload.html
|
77
|
+
- test/htdocs/find_link.html
|
78
|
+
- test/htdocs/form_multi_select.html
|
79
|
+
- test/htdocs/form_multival.html
|
80
|
+
- test/htdocs/form_no_action.html
|
81
|
+
- test/htdocs/form_no_input_name.html
|
82
|
+
- test/htdocs/form_select.html
|
83
|
+
- test/htdocs/form_select_all.html
|
84
|
+
- test/htdocs/form_select_none.html
|
85
|
+
- test/htdocs/form_select_noopts.html
|
86
|
+
- test/htdocs/form_set_fields.html
|
87
|
+
- test/htdocs/form_test.html
|
88
|
+
- test/htdocs/frame_test.html
|
89
|
+
- test/htdocs/google.html
|
90
|
+
- test/htdocs/iframe_test.html
|
91
|
+
- test/htdocs/index.html
|
92
|
+
- test/htdocs/link with space.html
|
93
|
+
- test/htdocs/no_title_test.html
|
94
|
+
- test/htdocs/relative/tc_relative_links.html
|
95
|
+
- test/htdocs/tc_bad_links.html
|
96
|
+
- test/htdocs/tc_checkboxes.html
|
97
|
+
- test/htdocs/tc_encoded_links.html
|
98
|
+
- test/htdocs/tc_form_action.html
|
99
|
+
- test/htdocs/tc_links.html
|
100
|
+
- test/htdocs/tc_no_attributes.html
|
101
|
+
- test/htdocs/tc_pretty_print.html
|
102
|
+
- test/htdocs/tc_radiobuttons.html
|
103
|
+
- test/htdocs/tc_referer.html
|
104
|
+
- test/htdocs/tc_relative_links.html
|
105
|
+
- test/htdocs/tc_textarea.html
|
106
|
+
- test/ssl_server.rb
|
107
|
+
- test/tc_authenticate.rb
|
108
|
+
- test/tc_bad_links.rb
|
109
|
+
- test/tc_checkboxes.rb
|
110
|
+
- test/tc_cookie_class.rb
|
111
|
+
- test/tc_cookie_jar.rb
|
112
|
+
- test/tc_cookies.rb
|
113
|
+
- test/tc_encoded_links.rb
|
114
|
+
- test/tc_errors.rb
|
115
|
+
- test/tc_form_action.rb
|
116
|
+
- test/tc_form_as_hash.rb
|
117
|
+
- test/tc_form_button.rb
|
118
|
+
- test/tc_form_no_inputname.rb
|
119
|
+
- test/tc_forms.rb
|
120
|
+
- test/tc_frames.rb
|
121
|
+
- test/tc_gzipping.rb
|
122
|
+
- test/tc_history.rb
|
123
|
+
- test/tc_html_unscape_forms.rb
|
124
|
+
- test/tc_if_modified_since.rb
|
125
|
+
- test/tc_keep_alive.rb
|
126
|
+
- test/tc_links.rb
|
127
|
+
- test/tc_mech.rb
|
128
|
+
- test/tc_multi_select.rb
|
129
|
+
- test/tc_no_attributes.rb
|
130
|
+
- test/tc_page.rb
|
131
|
+
- test/tc_pluggable_parser.rb
|
132
|
+
- test/tc_post_form.rb
|
133
|
+
- test/tc_pretty_print.rb
|
134
|
+
- test/tc_proxy.rb
|
135
|
+
- test/tc_radiobutton.rb
|
136
|
+
- test/tc_referer.rb
|
137
|
+
- test/tc_relative_links.rb
|
138
|
+
- test/tc_response_code.rb
|
139
|
+
- test/tc_save_file.rb
|
140
|
+
- test/tc_select.rb
|
141
|
+
- test/tc_select_all.rb
|
142
|
+
- test/tc_select_none.rb
|
143
|
+
- test/tc_select_noopts.rb
|
144
|
+
- test/tc_set_fields.rb
|
145
|
+
- test/tc_ssl_server.rb
|
146
|
+
- test/tc_subclass.rb
|
147
|
+
- test/tc_textarea.rb
|
148
|
+
- test/tc_upload.rb
|
149
|
+
- test/tc_watches.rb
|
150
|
+
- test/test_all.rb
|
151
|
+
- test/test_includes.rb
|
152
|
+
- test/test_mechanize_file.rb
|
153
|
+
- test/test_servlets.rb
|
147
154
|
test_files:
|
148
|
-
- test/test_all.rb
|
155
|
+
- test/test_all.rb
|
149
156
|
rdoc_options: []
|
150
|
-
|
151
157
|
extra_rdoc_files: []
|
152
|
-
|
153
158
|
executables: []
|
154
|
-
|
155
159
|
extensions: []
|
156
|
-
|
157
160
|
requirements: []
|
158
|
-
|
159
161
|
dependencies:
|
160
|
-
- !ruby/object:Gem::Dependency
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
162
|
+
- !ruby/object:Gem::Dependency
|
163
|
+
name: hpricot
|
164
|
+
version_requirement:
|
165
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
166
|
+
requirements:
|
167
|
+
-
|
168
|
+
- ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: 0.5.0
|
171
|
+
version:
|
172
|
+
- !ruby/object:Gem::Dependency
|
173
|
+
name: hoe
|
174
|
+
version_requirement:
|
175
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
176
|
+
requirements:
|
177
|
+
-
|
178
|
+
- ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 1.2.0
|
181
|
+
version:
|