miketracy-wwmd 0.2.16 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +21 -0
- data/{README → README.rdoc} +27 -2
- data/lib/wwmd.rb +4 -4
- data/lib/wwmd/class_extensions.rb +2 -0
- data/lib/wwmd/{mixins.rb → class_extensions/extensions_base.rb} +25 -121
- data/lib/wwmd/class_extensions/extensions_encoding.rb +79 -0
- data/lib/wwmd/{mixins_external.rb → class_extensions/extensions_external.rb} +0 -0
- data/lib/wwmd/class_extensions/extensions_nilclass.rb +11 -0
- data/lib/wwmd/{mixins_extends.rb → class_extensions/extensions_rbkb.rb} +0 -0
- data/lib/wwmd/{encoding.rb → class_extensions/mixins_string_encoding.rb} +6 -6
- data/lib/wwmd/page.rb +3 -245
- data/lib/wwmd/page/auth.rb +0 -166
- data/lib/wwmd/page/constants.rb +7 -4
- data/lib/wwmd/page/form.rb +0 -15
- data/lib/wwmd/page/form_array.rb +96 -74
- data/lib/wwmd/page/headers.rb +25 -21
- data/lib/wwmd/page/helpers.rb +30 -0
- data/lib/wwmd/{hpricot_html2text.rb → page/html2text_hpricot.rb} +1 -1
- data/lib/wwmd/{nokogiri_html2text.rb → page/html2text_nokogiri.rb} +0 -0
- data/lib/wwmd/page/inputs.rb +1 -1
- data/lib/wwmd/page/irb_helpers.rb +37 -13
- data/lib/wwmd/page/page.rb +238 -0
- data/lib/wwmd/page/parsing_convenience.rb +8 -3
- data/lib/wwmd/page/scrape.rb +15 -19
- data/lib/wwmd/page/spider.rb +11 -11
- data/lib/wwmd/urlparse.rb +20 -5
- data/lib/wwmd/viewstate.rb +9 -112
- data/lib/wwmd/viewstate/viewstate.rb +101 -0
- data/lib/wwmd/viewstate/viewstate_deserializer_methods.rb +36 -36
- data/lib/wwmd/viewstate/viewstate_types.rb +0 -4
- data/lib/wwmd/viewstate/viewstate_utils.rb +6 -1
- data/lib/wwmd/viewstate/vs_stubs.rb +22 -0
- data/lib/wwmd/viewstate/{vs_array.rb → vs_stubs/vs_array.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_binary_serialized.rb → vs_stubs/vs_binary_serialized.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_hashtable.rb → vs_stubs/vs_hashtable.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_hybrid_dict.rb → vs_stubs/vs_hybrid_dict.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_indexed_string.rb → vs_stubs/vs_indexed_string.rb} +1 -1
- data/lib/wwmd/viewstate/{vs_indexed_string_ref.rb → vs_stubs/vs_indexed_string_ref.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_int_enum.rb → vs_stubs/vs_int_enum.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_list.rb → vs_stubs/vs_list.rb} +2 -1
- data/lib/wwmd/viewstate/{vs_pair.rb → vs_stubs/vs_pair.rb} +3 -1
- data/lib/wwmd/viewstate/vs_stubs/vs_read_types.rb +11 -0
- data/lib/wwmd/viewstate/{vs_read_value.rb → vs_stubs/vs_read_value.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_sparse_array.rb → vs_stubs/vs_sparse_array.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_string.rb → vs_stubs/vs_string.rb} +2 -1
- data/lib/wwmd/viewstate/{vs_string_array.rb → vs_stubs/vs_string_array.rb} +4 -2
- data/lib/wwmd/viewstate/{vs_string_formatted.rb → vs_stubs/vs_string_formatted.rb} +4 -2
- data/lib/wwmd/viewstate/{viewstate_class_helpers.rb → vs_stubs/vs_stub_helpers.rb} +2 -1
- data/lib/wwmd/viewstate/{vs_triplet.rb → vs_stubs/vs_triplet.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_type.rb → vs_stubs/vs_type.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_unit.rb → vs_stubs/vs_unit.rb} +3 -1
- data/lib/wwmd/viewstate/{vs_value.rb → vs_stubs/vs_value.rb} +4 -2
- data/lib/wwmd/wwmd_config.rb +44 -36
- data/lib/wwmd/wwmd_puts.rb +9 -0
- data/lib/wwmd/wwmd_utils.rb +22 -24
- data/tasks/setup.rb +1 -1
- metadata +41 -35
- data/README.txt +0 -62
- data/lib/wwmd/viewstate/vs_read_types.rb +0 -11
- data/wwmd.gemspec +0 -0
data/lib/wwmd/page/headers.rb
CHANGED
@@ -25,58 +25,62 @@ module WWMD
|
|
25
25
|
#
|
26
26
|
# if clear == true then headers will be cleared before setting
|
27
27
|
def set_headers(arg=nil,clear=false)
|
28
|
-
|
28
|
+
clear_headers if clear
|
29
29
|
if arg.nil?
|
30
30
|
begin
|
31
|
-
|
31
|
+
clear_headers
|
32
32
|
WWMD::DEFAULT_HEADERS.each { |k,v| self.headers[k] = v }
|
33
33
|
return "headers set from default"
|
34
34
|
rescue => e
|
35
|
-
|
36
|
-
return
|
35
|
+
putw "WARN: " + e
|
36
|
+
return false
|
37
37
|
end
|
38
38
|
elsif arg.class == Symbol
|
39
|
-
|
40
|
-
|
39
|
+
set_headers(WWMD::HEADERS[arg])
|
40
|
+
putw "headers set from #{arg}"
|
41
|
+
return true
|
41
42
|
elsif arg.class == Hash
|
42
43
|
arg.each { |k,v| self.headers[k] = v }
|
43
|
-
|
44
|
+
putw "headers set from hash"
|
45
|
+
return true
|
44
46
|
end
|
45
|
-
"error setting headers"
|
47
|
+
putw "error setting headers"
|
48
|
+
return false
|
46
49
|
end
|
47
50
|
|
48
51
|
# set headers back to default headers
|
49
52
|
def default_headers(arg=nil)
|
50
|
-
|
53
|
+
set_headers
|
51
54
|
end
|
52
55
|
|
53
56
|
alias_method :set_default, :default_headers
|
54
57
|
|
55
58
|
# set headers from text
|
56
59
|
def headers_from_array(arr)
|
57
|
-
|
60
|
+
clear_headers
|
58
61
|
arr.each do |line|
|
59
|
-
|
60
|
-
|
61
|
-
self.headers[
|
62
|
+
next if (line.empty? || line =~ /^(GET|POST)/)
|
63
|
+
k,v = line.split(":",2)
|
64
|
+
self.headers[k.strip] = v.strip
|
62
65
|
end
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
# set headers from paste
|
70
|
+
def headers_from_paste
|
71
|
+
headers_from_array(%x[pbpaste])
|
63
72
|
end
|
64
73
|
|
65
74
|
# set headers from file
|
66
75
|
def headers_from_file(fn)
|
67
|
-
|
68
|
-
|
69
|
-
h = line.split(":",2)
|
70
|
-
next if h[1].class != String
|
71
|
-
self.headers[h[0]] = h[1].strip
|
72
|
-
end
|
73
|
-
return nil
|
76
|
+
headers_from_array(File.read(fn).split("\n"))
|
77
|
+
return "headers set from #{fn}"
|
74
78
|
end
|
75
79
|
|
76
80
|
# set headers to utf7 encoding post
|
77
81
|
def set_utf7_headers
|
78
82
|
self.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-7"
|
79
|
-
"headers set to utf7"
|
83
|
+
return "headers set to utf7"
|
80
84
|
end
|
81
85
|
|
82
86
|
# set headers to ajax
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module WWMD
|
2
|
+
class Page
|
3
|
+
# copy and paste from burp request windows
|
4
|
+
# page object gets set with headers and url (not correct)
|
5
|
+
# returns [headers,form]
|
6
|
+
# form = page.from_paste
|
7
|
+
def from_paste
|
8
|
+
self.enable_cookies = false
|
9
|
+
req = %x[pbpaste]
|
10
|
+
return false if not req
|
11
|
+
h,b = req.chomp.split("\r\n\r\n",2)
|
12
|
+
oh = h
|
13
|
+
h = h.split("\r\n")
|
14
|
+
m,u,p = h.shift.split(" ")
|
15
|
+
return nil unless m =~ (/^(POST|GET)/)
|
16
|
+
self.url = self.base_url + u
|
17
|
+
self.headers_from_array(h)
|
18
|
+
self.body_data = b
|
19
|
+
self.set_data
|
20
|
+
form = b.to_form
|
21
|
+
form.action = @urlparse.parse(self.base_url, u).to_s
|
22
|
+
[oh,form]
|
23
|
+
end
|
24
|
+
|
25
|
+
def resp_paste
|
26
|
+
self.body_data = %x[pbpaste].split("\r\n\r\n",2)[1]
|
27
|
+
self.set_data
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
File without changes
|
data/lib/wwmd/page/inputs.rb
CHANGED
@@ -16,14 +16,14 @@ module WWMD
|
|
16
16
|
|
17
17
|
# IRB: text report what has been parsed from this page
|
18
18
|
def report(short=nil)
|
19
|
-
|
19
|
+
puts "-------------------------------------------------"
|
20
20
|
self.summary
|
21
|
-
|
22
|
-
self.links.each_index { |i|
|
23
|
-
|
24
|
-
self.jlinks.each { |url|
|
25
|
-
|
26
|
-
|
21
|
+
puts "---- links found [#{self.has_links?.to_s} | #{self.links.size}]"
|
22
|
+
self.links.each_index { |i| puts "#{i.to_s} :: #{@links[i]}" } if short.nil?
|
23
|
+
puts "---- javascript found [#{self.has_jlinks?.to_s} | #{self.jlinks.size}]"
|
24
|
+
self.jlinks.each { |url| puts url } if short.nil?
|
25
|
+
puts "---- forms found [#{self.has_form?.to_s} | #{self.forms.size}]"
|
26
|
+
puts "---- comments found [#{self.has_comments?.to_s}]"
|
27
27
|
return nil
|
28
28
|
end
|
29
29
|
|
@@ -32,13 +32,13 @@ module WWMD
|
|
32
32
|
# IRB: display summary of what has been parsed from this page
|
33
33
|
def summary
|
34
34
|
status = self.page_status
|
35
|
-
|
35
|
+
puts "XXXX[#{self.report_flags}] | #{self.response_code.to_s} | #{status} | #{self.url} | #{self.size}"
|
36
36
|
return nil
|
37
37
|
end
|
38
38
|
|
39
39
|
# IRB: display current headers
|
40
40
|
def request_headers
|
41
|
-
self.headers.each_pair { |k,v|
|
41
|
+
self.headers.each_pair { |k,v| puts "#{k}: #{v}" }
|
42
42
|
return nil
|
43
43
|
end
|
44
44
|
|
@@ -47,7 +47,7 @@ module WWMD
|
|
47
47
|
|
48
48
|
# IRB: display response headers
|
49
49
|
def response_headers
|
50
|
-
self.header_data.each { |x|
|
50
|
+
self.header_data.each { |x| puts "#{x[0]} :: #{x[1]}" }
|
51
51
|
return nil
|
52
52
|
end
|
53
53
|
|
@@ -55,18 +55,18 @@ module WWMD
|
|
55
55
|
|
56
56
|
# display self.body_data
|
57
57
|
def dump_body
|
58
|
-
|
58
|
+
puts self.body_data
|
59
59
|
end
|
60
60
|
|
61
61
|
alias_method :dump, :dump_body#:nodoc:
|
62
62
|
|
63
63
|
# IRB: puts the page filtered through html2text
|
64
|
-
def to_text;
|
64
|
+
def to_text; puts self.html2text; end
|
65
65
|
def text; self.html2text; end
|
66
66
|
|
67
67
|
# IRB: display a human readable report of all forms contained in page.body_data
|
68
68
|
def all_forms
|
69
|
-
self.forms.each_index { |x|
|
69
|
+
self.forms.each_index { |x| puts "[#{x.to_s}]-------"; self.forms[x].report }
|
70
70
|
nil
|
71
71
|
end
|
72
72
|
|
@@ -87,4 +87,28 @@ module WWMD
|
|
87
87
|
%x[open #{fn}]
|
88
88
|
end
|
89
89
|
end
|
90
|
+
|
91
|
+
class Form
|
92
|
+
def report
|
93
|
+
return nil if not WWMD::console
|
94
|
+
puts "action = #{self.action}"
|
95
|
+
self.fields.each { |field| puts field.to_text }
|
96
|
+
return nil
|
97
|
+
end
|
98
|
+
alias_method :show, :report
|
99
|
+
end
|
100
|
+
|
101
|
+
class FormArray
|
102
|
+
# IRB: puts the form in human readable format
|
103
|
+
# if you <tt>form.show(true)</tt> it will show unescaped values
|
104
|
+
def show(unescape=false)
|
105
|
+
if unescape
|
106
|
+
self.each_index { |i| puts i.to_s + " :: " + self[i][0].to_s + " = " + self[i][1].to_s.unescape }
|
107
|
+
else
|
108
|
+
self.each_index { |i| puts i.to_s + " :: " + self[i][0].to_s + " = " + self[i][1].to_s }
|
109
|
+
end
|
110
|
+
return nil
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
90
114
|
end
|
@@ -0,0 +1,238 @@
|
|
1
|
+
module WWMD
|
2
|
+
attr_accessor :curl_object
|
3
|
+
attr_accessor :body_data
|
4
|
+
attr_accessor :post_data
|
5
|
+
attr_accessor :header_data
|
6
|
+
attr_accessor :use_referer
|
7
|
+
attr_reader :forms
|
8
|
+
attr_reader :last_error
|
9
|
+
attr_reader :links # array of links (urls)
|
10
|
+
attr_reader :jlinks # array of included javascript files
|
11
|
+
attr_reader :spider # spider object
|
12
|
+
attr_reader :scrape # scrape object
|
13
|
+
attr_reader :urlparse # urlparse object
|
14
|
+
attr_reader :comments
|
15
|
+
|
16
|
+
attr_accessor :base_url # needed to properly munge relative urls into fq urls
|
17
|
+
attr_accessor :logged_in # are we logged in?
|
18
|
+
|
19
|
+
attr_accessor :opts
|
20
|
+
attr_accessor :inputs
|
21
|
+
|
22
|
+
# WWMD::Page is an extension of a Curl::Easy object which provides methods to
|
23
|
+
# enhance and ease the performance of web application penetration testing.
|
24
|
+
class Page
|
25
|
+
|
26
|
+
include WWMDUtils
|
27
|
+
|
28
|
+
def initialize(opts={}, &block)
|
29
|
+
@opts = opts.clone
|
30
|
+
DEFAULTS.each { |k,v| @opts[k] = v unless opts[k] }
|
31
|
+
@spider = Spider.new(opts)
|
32
|
+
@scrape = Scrape.new
|
33
|
+
@base_url ||= opts[:base_url]
|
34
|
+
@scrape.warn = opts[:scrape_warn] if !opts[:scrape_warn].nil? # yeah yeah... bool false
|
35
|
+
@urlparse = URLParse.new()
|
36
|
+
@inputs = Inputs.new(self)
|
37
|
+
@logged_in = false
|
38
|
+
@body_data = ""
|
39
|
+
@post_data = ""
|
40
|
+
@comments = []
|
41
|
+
@header_data = FormArray.new
|
42
|
+
|
43
|
+
@curl_object = Curl::Easy.new
|
44
|
+
@opts.each do |k,v|
|
45
|
+
next if k == :proxy_url
|
46
|
+
self.instance_variable_set("@#{k.to_s}".intern,v)
|
47
|
+
if (@curl_object.methods.include?("#{k}="))
|
48
|
+
@curl_object.send("#{k}=",v)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
@curl_object.on_body { |data| self._body_cb(data) }
|
52
|
+
@curl_object.on_header { |data| self._header_cb(data) }
|
53
|
+
|
54
|
+
# cookies?
|
55
|
+
@curl_object.enable_cookies = @opts[:enable_cookies]
|
56
|
+
if @curl_object.enable_cookies?
|
57
|
+
@curl_object.cookiejar = @opts[:cookiejar] || "./__cookiejar"
|
58
|
+
end
|
59
|
+
|
60
|
+
#proxy?
|
61
|
+
@curl_object.proxy_url = @opts[:proxy_url] if @opts[:use_proxy]
|
62
|
+
instance_eval(&block) if block_given?
|
63
|
+
if opts.empty? && @scrape.warn
|
64
|
+
putw "Page initialized without opts"
|
65
|
+
@scrape.warn = false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#:section: Heavy Lifting
|
70
|
+
|
71
|
+
# set reporting data for the page
|
72
|
+
#
|
73
|
+
# Scan for comments, anchors, links and javascript includes and
|
74
|
+
# set page flags. The heavy lifting for parsing is done in the
|
75
|
+
# scrape class.
|
76
|
+
#
|
77
|
+
# returns: <tt>array [ code, page_status, body_data.size ]</tt>
|
78
|
+
def set_data
|
79
|
+
# reset scrape and inputs object
|
80
|
+
# transparently gunzip
|
81
|
+
begin
|
82
|
+
io = StringIO.new(self.body_data)
|
83
|
+
gz = Zlib::GzipReader.new(io)
|
84
|
+
self.body_data.replace(gz.read)
|
85
|
+
rescue => e
|
86
|
+
end
|
87
|
+
@scrape.reset(self.body_data)
|
88
|
+
@inputs.set
|
89
|
+
|
90
|
+
# remove comments that are css selectors for IE silliness
|
91
|
+
@comments = @scrape.for_comments.reject do |c|
|
92
|
+
c =~ /\[if IE\]/ ||
|
93
|
+
c =~ /\[if IE \d/ ||
|
94
|
+
c =~ /\[if lt IE \d/
|
95
|
+
end
|
96
|
+
@links = @scrape.for_links.map do |url|
|
97
|
+
@urlparse.parse(self.last_effective_url,url).to_s
|
98
|
+
end
|
99
|
+
@jlinks = @scrape.for_javascript_links
|
100
|
+
@forms = @scrape.for_forms
|
101
|
+
@spider.add(self.last_effective_url,@links)
|
102
|
+
return [self.code,self.body_data.size]
|
103
|
+
end
|
104
|
+
|
105
|
+
# clear self.body_data and self.header_data
|
106
|
+
def clear_data
|
107
|
+
return false if self.opts[:parse] = false
|
108
|
+
@body_data = ""
|
109
|
+
@header_data.clear
|
110
|
+
@last_error = nil
|
111
|
+
end
|
112
|
+
|
113
|
+
# override Curl::Easy.perform to perform page actions,
|
114
|
+
# call <tt>self.set_data</tt>
|
115
|
+
#
|
116
|
+
# returns: <tt>array [ code, page_status, body_data.size ]</tt>
|
117
|
+
#
|
118
|
+
# don't call this directly if we are in console mode
|
119
|
+
# use get and submit respectively for GET and POST
|
120
|
+
def perform
|
121
|
+
self.clear_data
|
122
|
+
self.headers["Referer"] = self.cur if self.use_referer
|
123
|
+
begin
|
124
|
+
@curl_object.perform
|
125
|
+
rescue => e
|
126
|
+
@last_error = e
|
127
|
+
putw "WARN: #{e.class}" if e.class =~ /Curl::Err/
|
128
|
+
end
|
129
|
+
self.set_data
|
130
|
+
end
|
131
|
+
|
132
|
+
# replacement for Curl::Easy.http_post
|
133
|
+
#
|
134
|
+
# post the form attempting to remove curl supplied headers (Expect, X-Forwarded-For
|
135
|
+
# call <tt>self.set_data</tt>
|
136
|
+
#
|
137
|
+
# if passed a regexp, escape values in the form using regexp before submitting
|
138
|
+
# if passed nil for the regexp arg, the form will not be escaped
|
139
|
+
# default: WWMD::ESCAPE[:url]
|
140
|
+
#
|
141
|
+
# returns: <tt>array [ code, body_data.size ]</tt>
|
142
|
+
def submit(iform=nil,reg=WWMD::ESCAPE[:default])
|
143
|
+
## this is just getting worse and worse
|
144
|
+
if iform.class == "Symbol"
|
145
|
+
reg = iform
|
146
|
+
iform = nil
|
147
|
+
end
|
148
|
+
self.clear_data
|
149
|
+
["Expect","X-Forwarded-For","Content-length"].each { |s| self.clear_header(s) }
|
150
|
+
self.headers["Referer"] = self.cur if self.use_referer
|
151
|
+
unless iform
|
152
|
+
unless self.form.empty?
|
153
|
+
sform = self.form.clone
|
154
|
+
else
|
155
|
+
return "no form provided"
|
156
|
+
end
|
157
|
+
else
|
158
|
+
sform = iform.clone # clone the form so that we don't change the original
|
159
|
+
end
|
160
|
+
sform.escape_all!(reg)
|
161
|
+
self.url = sform.action if sform.action
|
162
|
+
if sform.empty?
|
163
|
+
self.http_post('')
|
164
|
+
else
|
165
|
+
self.http_post(self.post_data = sform.to_post)
|
166
|
+
end
|
167
|
+
self.set_data
|
168
|
+
end
|
169
|
+
|
170
|
+
# submit a form using POST string
|
171
|
+
def submit_string(post_string)
|
172
|
+
self.clear_data
|
173
|
+
self.http_post(post_string)
|
174
|
+
putw "WARN: authentication headers in response" if self.auth?
|
175
|
+
self.set_data
|
176
|
+
end
|
177
|
+
|
178
|
+
# override for Curl::Easy.perform
|
179
|
+
#
|
180
|
+
# if the passed url string doesn't contain an fully qualified
|
181
|
+
# path, we'll guess and prepend opts[:base_url]
|
182
|
+
#
|
183
|
+
# returns: <tt>array [ code, body_data.size ]</tt>
|
184
|
+
def get(url=nil,parse=true)
|
185
|
+
if !(url =~ /[a-z]+:\/\//) && parse
|
186
|
+
self.url = @urlparse.parse(self.opts[:base_url],url).to_s if url
|
187
|
+
elsif url
|
188
|
+
self.url = url
|
189
|
+
end
|
190
|
+
self.perform
|
191
|
+
putw "WARN: authentication headers in response" if self.auth?
|
192
|
+
self.set_data
|
193
|
+
end
|
194
|
+
|
195
|
+
# GET with params and POST it as a form
|
196
|
+
def post(url=nil)
|
197
|
+
ep = url.clip
|
198
|
+
self.url = @urlparse.parse(self.opts[:base_url],ep).to_s if ep
|
199
|
+
form = url.clop.to_form
|
200
|
+
self.submit(form)
|
201
|
+
end
|
202
|
+
|
203
|
+
# send arbitrary verb (only works with patch to taf2-curb
|
204
|
+
def verb(verb,url=nil)
|
205
|
+
return false if !@curl_object.respond_to?(:http_verb)
|
206
|
+
self.url = url if url
|
207
|
+
self.clear_data
|
208
|
+
self.headers["Referer"] = self.cur if self.use_referer
|
209
|
+
self.http_verb(verb)
|
210
|
+
self.set_data
|
211
|
+
end
|
212
|
+
|
213
|
+
#:section: Data callbacks and method_missing
|
214
|
+
|
215
|
+
# callback for <tt>self.on_body</tt>
|
216
|
+
def _body_cb(data)
|
217
|
+
@body_data << data if data
|
218
|
+
return data.length.to_i
|
219
|
+
end
|
220
|
+
|
221
|
+
# callback for <tt>self.on_header</tt>
|
222
|
+
def _header_cb(data)
|
223
|
+
myArr = Array.new(data.split(":",2))
|
224
|
+
@header_data.extend! myArr[0].to_s.strip,myArr[1].to_s.strip
|
225
|
+
return data.length.to_i
|
226
|
+
end
|
227
|
+
|
228
|
+
# send methods not defined here to <tt>@curl_object</tt>
|
229
|
+
def method_missing(methodname, *args)
|
230
|
+
if WWMD.respond_to?(methodname)
|
231
|
+
WWMD.send(methodname, *args)
|
232
|
+
else
|
233
|
+
@curl_object.send(methodname, *args)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
end
|