wwmd 0.2.20.3
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 +38 -0
- data/README.rdoc +87 -0
- data/Rakefile +33 -0
- data/examples/config_example.yaml +24 -0
- data/examples/wwmd_example.rb +73 -0
- data/lib/wwmd.rb +84 -0
- data/lib/wwmd/class_extensions.rb +4 -0
- data/lib/wwmd/class_extensions/extensions_base.rb +251 -0
- data/lib/wwmd/class_extensions/extensions_encoding.rb +79 -0
- data/lib/wwmd/class_extensions/extensions_external.rb +18 -0
- data/lib/wwmd/class_extensions/extensions_nilclass.rb +11 -0
- data/lib/wwmd/class_extensions/extensions_rbkb.rb +193 -0
- data/lib/wwmd/class_extensions/mixins_string_encoding.rb +40 -0
- data/lib/wwmd/guid.rb +155 -0
- data/lib/wwmd/page.rb +3 -0
- data/lib/wwmd/page/_fa.old +302 -0
- data/lib/wwmd/page/auth.rb +17 -0
- data/lib/wwmd/page/constants.rb +63 -0
- data/lib/wwmd/page/form.rb +99 -0
- data/lib/wwmd/page/form_array.rb +304 -0
- data/lib/wwmd/page/headers.rb +118 -0
- data/lib/wwmd/page/helpers.rb +41 -0
- data/lib/wwmd/page/html2text_hpricot.rb +76 -0
- data/lib/wwmd/page/html2text_nokogiri.rb +42 -0
- data/lib/wwmd/page/inputs.rb +47 -0
- data/lib/wwmd/page/irb_helpers.rb +114 -0
- data/lib/wwmd/page/page.rb +257 -0
- data/lib/wwmd/page/parsing_convenience.rb +98 -0
- data/lib/wwmd/page/reporting_helpers.rb +89 -0
- data/lib/wwmd/page/scrape.rb +196 -0
- data/lib/wwmd/page/spider.rb +127 -0
- data/lib/wwmd/urlparse.rb +125 -0
- data/lib/wwmd/viewstate.rb +17 -0
- data/lib/wwmd/viewstate/viewstate.rb +101 -0
- data/lib/wwmd/viewstate/viewstate_deserializer_methods.rb +217 -0
- data/lib/wwmd/viewstate/viewstate_from_xml.rb +129 -0
- data/lib/wwmd/viewstate/viewstate_types.rb +51 -0
- data/lib/wwmd/viewstate/viewstate_utils.rb +164 -0
- data/lib/wwmd/viewstate/viewstate_yaml.rb +25 -0
- data/lib/wwmd/viewstate/vs_stubs.rb +22 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_array.rb +38 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_binary_serialized.rb +30 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_hashtable.rb +42 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_hybrid_dict.rb +42 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_indexed_string.rb +6 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_indexed_string_ref.rb +24 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_int_enum.rb +27 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_list.rb +34 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_pair.rb +29 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_read_types.rb +11 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_read_value.rb +35 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_sparse_array.rb +58 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_string.rb +33 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_string_array.rb +39 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_string_formatted.rb +32 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_stub_helpers.rb +37 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_triplet.rb +31 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_type.rb +23 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_unit.rb +30 -0
- data/lib/wwmd/viewstate/vs_stubs/vs_value.rb +35 -0
- data/lib/wwmd/wwmd_config.rb +52 -0
- data/lib/wwmd/wwmd_puts.rb +9 -0
- data/lib/wwmd/wwmd_utils.rb +28 -0
- data/spec/README +3 -0
- data/spec/form_array.spec +49 -0
- data/spec/spider_csrf_test.spec +28 -0
- data/spec/urlparse_test.spec +101 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- metadata +222 -0
@@ -0,0 +1,304 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
This is a weird kind of data structure for no other reason than
|
3
|
+
I wanted to keep the form inputs in order when they come in.
|
4
|
+
|
5
|
+
Accessing this either as a hash or an array (but => won't work)
|
6
|
+
|
7
|
+
Some of the methods in here are kept for backward compat before the refactor
|
8
|
+
and now everything in this array should be accessed with []= and []
|
9
|
+
|
10
|
+
Set :action and take a block. Page#submit_form should take this and do the
|
11
|
+
right thing.
|
12
|
+
=end
|
13
|
+
|
14
|
+
module WWMD
|
15
|
+
class FormArray < Array
|
16
|
+
attr_accessor :action
|
17
|
+
attr_accessor :type
|
18
|
+
attr_accessor :delimiter
|
19
|
+
attr_accessor :equals
|
20
|
+
|
21
|
+
def initialize(fields=nil,action=nil,&block)
|
22
|
+
set_fields(fields)
|
23
|
+
@delimiter = "&"
|
24
|
+
@equals = "="
|
25
|
+
@action = action
|
26
|
+
instance_eval(&block) if block_given?
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_fields(fields=nil)
|
30
|
+
return nil if fields.nil?
|
31
|
+
# this first one is an array of field objects
|
32
|
+
if fields.class == Array
|
33
|
+
fields.each do |f|
|
34
|
+
name = f['name']
|
35
|
+
if self.name_exists(name)
|
36
|
+
if f['type'] == "hidden"
|
37
|
+
self.set name,f.get_value
|
38
|
+
elsif f['type'] == "checkbox" and f.to_html.grep(/checked/) != ''
|
39
|
+
self[name] = f.get_value
|
40
|
+
end
|
41
|
+
else
|
42
|
+
self << [ f['name'],f.get_value ]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
elsif fields.class == Hash
|
46
|
+
fields.each_pair { |k,v| self[k] = v }
|
47
|
+
elsif fields.class == String
|
48
|
+
fields.split(@delimiter).each do |f|
|
49
|
+
k,v = f.split(@equals,2)
|
50
|
+
self[k] = v
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# "deep enough" copy of this object to make it a real copy
|
56
|
+
# instead of references to the arrays that already exist
|
57
|
+
def clone
|
58
|
+
ret = self.class.new
|
59
|
+
self.each { |r| ret << r.clone }
|
60
|
+
ret.action = self.action
|
61
|
+
return ret
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear
|
65
|
+
self.delete_if { |x| true }
|
66
|
+
end
|
67
|
+
|
68
|
+
# check if the passed name exists in the form
|
69
|
+
def include?(key)
|
70
|
+
self.map { |x| x.first }.flatten.include?(key)
|
71
|
+
end
|
72
|
+
|
73
|
+
alias_method :name_exists, :include?#:nodoc:
|
74
|
+
alias_method :name_exists?, :include?#:nodoc:
|
75
|
+
alias_method :has_key?, :include?#:nodoc:
|
76
|
+
|
77
|
+
# add key/value pairs to form
|
78
|
+
def add(key,value)
|
79
|
+
self << [key,value]
|
80
|
+
end
|
81
|
+
|
82
|
+
# key = Fixnum set value at index key
|
83
|
+
# key = String find key named string and set value
|
84
|
+
def set_value!(key,value)
|
85
|
+
if key.class == Fixnum
|
86
|
+
self[key][1] = value
|
87
|
+
return [self[key][0], value]
|
88
|
+
end
|
89
|
+
self.each_index do |i|
|
90
|
+
if self[i][0] == key
|
91
|
+
self[i] = [key,value]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
return [key,value]
|
95
|
+
end
|
96
|
+
|
97
|
+
# get a value using its index
|
98
|
+
# override Array#[]
|
99
|
+
alias_method :old_get, :[]#:nodoc:
|
100
|
+
def [](*args)
|
101
|
+
if args.first.class == Fixnum
|
102
|
+
self.old_get(args.first)
|
103
|
+
else
|
104
|
+
self.get_value(args.first)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
alias_method :old_set, :[]=#:nodoc:
|
109
|
+
# set a key using its index, array key or add using a new key i.e.:
|
110
|
+
# if setting:
|
111
|
+
# form = [['key','value'],['foo','bar']]
|
112
|
+
# form[0] = ["replacekey","newalue"]
|
113
|
+
# form["replacekey"] = "newervalue"
|
114
|
+
# if adding:
|
115
|
+
# form["newkey"] = "value"
|
116
|
+
#
|
117
|
+
def []=(*args)
|
118
|
+
key,value = args
|
119
|
+
if args.first.kind_of?(Fixnum)
|
120
|
+
return self.old_set(*args)
|
121
|
+
elsif self.has_key?(key)
|
122
|
+
return self.set_value(key,value)
|
123
|
+
else
|
124
|
+
return self.add(key,value)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
alias_method :set_value, :set_value!
|
129
|
+
alias_method :set, :set_value!
|
130
|
+
|
131
|
+
def get_value(key)
|
132
|
+
if key.class == Fixnum
|
133
|
+
return self[key][1]
|
134
|
+
end
|
135
|
+
self.each_index do |i|
|
136
|
+
if self[i][0] == key
|
137
|
+
return self[i][1]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
return nil
|
141
|
+
end
|
142
|
+
|
143
|
+
alias_method :get, :get_value
|
144
|
+
|
145
|
+
def keys
|
146
|
+
self.map { |k,v| k }
|
147
|
+
end
|
148
|
+
|
149
|
+
def setall!(value)
|
150
|
+
self.each_index { |i| self.set_value!(i,value) }
|
151
|
+
end
|
152
|
+
|
153
|
+
alias_method :setall, :setall!#:nodoc:
|
154
|
+
alias_method :set_all!, :setall!#:nodoc:
|
155
|
+
alias_method :set_all, :setall!#:nodoc:
|
156
|
+
|
157
|
+
# delete all key = value pairs from self where key = key
|
158
|
+
def delete_key(key)
|
159
|
+
self.reject! { |x,y| x == key }
|
160
|
+
end
|
161
|
+
|
162
|
+
alias_method :delete_keys!, :delete_key #:nodoc:
|
163
|
+
alias_method :delete_key!, :delete_key #:nodoc:
|
164
|
+
|
165
|
+
# escape form keys in place
|
166
|
+
def escape_keys!(reg=WWMD::ESCAPE[:url])
|
167
|
+
return nil if reg == :none
|
168
|
+
self.map! { |x,y| [x.escape(reg),y] }
|
169
|
+
end
|
170
|
+
|
171
|
+
# unescape form keys in place
|
172
|
+
def unescape_keys!(reg=WWMD::ESCAPE[:url])
|
173
|
+
return nil if reg == :none
|
174
|
+
self.map! { |x,y| [x.unescape,y] }
|
175
|
+
end
|
176
|
+
|
177
|
+
# escape form values in place
|
178
|
+
def escape_all!(reg=WWMD::ESCAPE[:url])
|
179
|
+
return nil if reg == :none
|
180
|
+
self.map! { |x,y| [x,y.escape(reg)] }
|
181
|
+
end
|
182
|
+
|
183
|
+
alias_method :escape_all, :escape_all!#:nodoc:
|
184
|
+
|
185
|
+
# unescape all form values in place
|
186
|
+
def unescape_all!
|
187
|
+
self.map! { |x,y| [x,y.unescape] }
|
188
|
+
end
|
189
|
+
|
190
|
+
alias_method :unescape_all, :unescape_all!#:nodoc:
|
191
|
+
|
192
|
+
# remove form elements with null values
|
193
|
+
def remove_nulls!
|
194
|
+
self.delete_if { |x| x[1].to_s.empty? || x[1].nil? }
|
195
|
+
end
|
196
|
+
|
197
|
+
alias_method :squeeze!, :remove_nulls!
|
198
|
+
|
199
|
+
# remove form elements with null keys (for housekeeping returns)
|
200
|
+
def remove_null_keys!
|
201
|
+
self.delete_if { |x,y| x.to_s.empty? || x.nil? }
|
202
|
+
end
|
203
|
+
|
204
|
+
alias_method :squeeze_keys!, :remove_null_keys!
|
205
|
+
|
206
|
+
## viewstate
|
207
|
+
|
208
|
+
# clear viewstate variables
|
209
|
+
def clear_viewstate
|
210
|
+
self.each { |k,v|
|
211
|
+
self[k] = "" if k =~ /^__/
|
212
|
+
}
|
213
|
+
end
|
214
|
+
|
215
|
+
# remove viewstate variables
|
216
|
+
def rm_viewstate
|
217
|
+
# my least favorite ruby idiom
|
218
|
+
self.replace(self.map { |k,v| [k,v] if not k =~ /^__/ }.reject { |x| x.nil? })
|
219
|
+
end
|
220
|
+
|
221
|
+
alias_method :extend!, :add #:nodoc (this is here for backward compat)
|
222
|
+
|
223
|
+
# add viewstate stuff
|
224
|
+
def add_viewstate#:nodoc:
|
225
|
+
self.insert(0,[ "__VIEWSTATE","" ])
|
226
|
+
self.insert(0,[ "__EVENTARGUMENT","" ])
|
227
|
+
self.insert(0,[ "__EVENTTARGET","" ])
|
228
|
+
self.insert(0,[ "__EVENTVALIDATION","" ])
|
229
|
+
return nil
|
230
|
+
end
|
231
|
+
|
232
|
+
## conversions
|
233
|
+
|
234
|
+
# convert form into a post parameters string
|
235
|
+
def to_post
|
236
|
+
ret = []
|
237
|
+
self.each do |i|
|
238
|
+
ret << i.join(@equals)
|
239
|
+
end
|
240
|
+
ret.join(@delimiter)
|
241
|
+
end
|
242
|
+
|
243
|
+
# convert form into a get parameters string
|
244
|
+
#
|
245
|
+
# pass me a base to get a full url to pass to Page.get
|
246
|
+
def to_get(base="")
|
247
|
+
return base if self.empty?
|
248
|
+
ret = []
|
249
|
+
self.each do |i|
|
250
|
+
ret << i.join(@equals)
|
251
|
+
end
|
252
|
+
ret = ret.join(@delimiter)
|
253
|
+
return base.to_s.clip + "?" + ret.to_s
|
254
|
+
end
|
255
|
+
|
256
|
+
## parsing convenience
|
257
|
+
|
258
|
+
# dump a web page containing a csrf example of the current FormArray
|
259
|
+
def to_csrf(quot=nil,action=nil,unescval=false)
|
260
|
+
quot = "'" unless quot
|
261
|
+
action = self.action unless action
|
262
|
+
ret = ""
|
263
|
+
ret << "<html><body>\n"
|
264
|
+
ret << "<form method=#{quot}post#{quot} id=#{quot}wwmdtest#{quot} name=#{quot}wwmdtest#{quot} action=#{quot}#{action}#{quot}>\n"
|
265
|
+
self.each do |key,val|
|
266
|
+
val.gsub!(/\+/," ")
|
267
|
+
val = val.unescape.gsub(/'/) { %q[\'] } if unescval
|
268
|
+
ret << "<input name=#{quot}#{key.to_s.unescape}#{quot} type=#{quot}hidden#{quot} value=#{quot}#{val.to_s.unescape}#{quot} />\n"
|
269
|
+
end
|
270
|
+
ret << "</form>\n"
|
271
|
+
ret << "<script>document.wwmdtest.submit()</script>\n"
|
272
|
+
ret << "</body></html>\n"
|
273
|
+
return ret
|
274
|
+
end
|
275
|
+
|
276
|
+
# add markers for burp intruder to form
|
277
|
+
def burpify(all=true) #:nodoc:
|
278
|
+
ret = self.clone
|
279
|
+
ret.each_index do |i|
|
280
|
+
next if ret[i][0] =~ /^__/
|
281
|
+
# ret.set_value!(i,"#{ret.get_value(i)}" + "\302\247" + "\302\247")
|
282
|
+
if all
|
283
|
+
ret.set_value!(i,"\244" + "#{ret.get_value(i)}" + "\244")
|
284
|
+
else
|
285
|
+
ret.set_value!(i,"#{ret.get_value(i)}" + "\244" + "\244")
|
286
|
+
end
|
287
|
+
end
|
288
|
+
ret.to_post.pbcopy
|
289
|
+
return ret
|
290
|
+
end
|
291
|
+
|
292
|
+
# return md5 hash of sorted list of keys
|
293
|
+
def fingerprint
|
294
|
+
return (self.action.to_s + self.map { |k,v| k }.sort.to_s).md5
|
295
|
+
end
|
296
|
+
alias_method :fp, :fingerprint #:nodoc:
|
297
|
+
|
298
|
+
def from_array(arr)
|
299
|
+
self.clear
|
300
|
+
arr.each { |k,v| self[k] = v }
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module WWMD
|
2
|
+
class Page
|
3
|
+
|
4
|
+
#:section: Header helper methods
|
5
|
+
|
6
|
+
def user_agent=(ua)
|
7
|
+
self.headers["User-Agent"] = ua
|
8
|
+
end
|
9
|
+
|
10
|
+
# clear header at <key>
|
11
|
+
def clear_header(key)
|
12
|
+
self.headers.delete_if { |k,v| k.upcase == key.upcase }
|
13
|
+
return nil
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :delete_header, :clear_header#:nodoc:
|
17
|
+
|
18
|
+
# clear all headers
|
19
|
+
def clear_headers
|
20
|
+
self.headers.delete_if { |k,v| true }
|
21
|
+
"headers cleared"
|
22
|
+
end
|
23
|
+
|
24
|
+
# set headers from passed argument
|
25
|
+
# Nil: set headers from WWMD::DEFAULT_HEADERS
|
26
|
+
# Symbol: entry in WWMD::HEADERS to set from
|
27
|
+
# Hash: hash to set headers from
|
28
|
+
# String: filename (NOT IMPLEMENTED)
|
29
|
+
#
|
30
|
+
# if clear == true then headers will be cleared before setting
|
31
|
+
def set_headers(arg=nil,clear=false)
|
32
|
+
clear_headers if clear
|
33
|
+
if arg.nil?
|
34
|
+
begin
|
35
|
+
clear_headers
|
36
|
+
WWMD::DEFAULT_HEADERS.each { |k,v| self.headers[k] = v }
|
37
|
+
return "headers set from default"
|
38
|
+
rescue => e
|
39
|
+
putw "WARN: " + e
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
elsif arg.class == Symbol
|
43
|
+
set_headers(WWMD::HEADERS[arg])
|
44
|
+
putw "headers set from #{arg}"
|
45
|
+
return true
|
46
|
+
elsif arg.class == Hash
|
47
|
+
arg.each { |k,v| self.headers[k] = v }
|
48
|
+
putw "headers set from hash"
|
49
|
+
return true
|
50
|
+
end
|
51
|
+
putw "error setting headers"
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
|
55
|
+
# set headers back to default headers
|
56
|
+
def default_headers(arg=nil)
|
57
|
+
set_headers
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :set_default, :default_headers
|
61
|
+
|
62
|
+
# set headers from text
|
63
|
+
def headers_from_array(arr)
|
64
|
+
clear_headers
|
65
|
+
arr = arr.split("\r\n\r\n").first if arr.class == String
|
66
|
+
arr.each do |line|
|
67
|
+
next if (line.empty? || line =~ /^(GET|POST)/)
|
68
|
+
k,v = line.split(":",2)
|
69
|
+
self.headers[k.strip] = v.strip
|
70
|
+
end
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
#;
|
74
|
+
|
75
|
+
# set headers from paste
|
76
|
+
def headers_from_paste
|
77
|
+
headers_from_array(%x[pbpaste])
|
78
|
+
end
|
79
|
+
|
80
|
+
# set headers from file
|
81
|
+
def headers_from_file(fn)
|
82
|
+
clear_headers
|
83
|
+
headers_from_array(File.read(fn).split("\n"))
|
84
|
+
return "headers set from #{fn}"
|
85
|
+
end
|
86
|
+
|
87
|
+
# set headers to utf7 encoding post
|
88
|
+
def set_utf7_headers
|
89
|
+
self.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-7"
|
90
|
+
return "headers set to utf7"
|
91
|
+
end
|
92
|
+
|
93
|
+
# set headers to ajax
|
94
|
+
def set_ajax_headers
|
95
|
+
self.headers["X-Requested-With"] = "XMLHttpRequest"
|
96
|
+
self.headers["X-Prototype-Version"] = "1.5.0"
|
97
|
+
return "headers set to ajax"
|
98
|
+
end
|
99
|
+
|
100
|
+
# set headers to SOAP request headers
|
101
|
+
def set_soap_headers
|
102
|
+
self.headers['Content-Type'] = "text/xml;charset=utf-8"
|
103
|
+
self.headers['SOAPAction'] = "\"\""
|
104
|
+
return "headers set to soap"
|
105
|
+
end
|
106
|
+
|
107
|
+
# get the current Cookie header
|
108
|
+
def get_cookie
|
109
|
+
self.headers["Cookie"]
|
110
|
+
end
|
111
|
+
|
112
|
+
# set the Cookie header
|
113
|
+
def set_cookie(cookie=nil)
|
114
|
+
self.headers["Cookie"] = cookie
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,41 @@
|
|
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
|
+
|
8
|
+
def from_input(req)
|
9
|
+
self.enable_cookies = false
|
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 from_file(fn)
|
26
|
+
h = headers.clone
|
27
|
+
ret = from_input(File.read(fn))
|
28
|
+
headers.replace(h)
|
29
|
+
ret
|
30
|
+
end
|
31
|
+
|
32
|
+
def from_paste
|
33
|
+
from_input(%x[pbpaste])
|
34
|
+
end
|
35
|
+
|
36
|
+
def resp_paste
|
37
|
+
self.body_data = %x[pbpaste].split("\r\n\r\n",2)[1]
|
38
|
+
self.set_data
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|