watobo 0.9.20 → 0.9.21
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +54 -2
- data/README.md +1 -1
- data/config/scanner.yml +1 -0
- data/custom-views/prettify-json.rb +19 -0
- data/lib/watobo/adapters/file/marshal_store.rb +297 -0
- data/lib/watobo/adapters.rb +2 -1
- data/lib/watobo/core/active_check.rb +4 -0
- data/lib/watobo/core/chat.rb +8 -0
- data/lib/watobo/core/chats.rb +2 -1
- data/lib/watobo/core/cookie.rb +3 -3
- data/lib/watobo/core/finding.rb +7 -0
- data/lib/watobo/core/request.rb +3 -3
- data/lib/watobo/core/session.rb +6 -2
- data/lib/watobo/framework/init_modules.rb +18 -16
- data/lib/watobo/gui/conversation_table.rb +13 -16
- data/lib/watobo/gui/conversation_table_ctrl2.rb +1 -0
- data/lib/watobo/gui/custom_viewer.rb +101 -76
- data/lib/watobo/gui/define_scope_frame.rb +44 -10
- data/lib/watobo/gui/edit_scope_dialog.rb +1 -1
- data/lib/watobo/gui/fuzzer_gui.rb +61 -23
- data/lib/watobo/gui/main_window.rb +1 -1
- data/lib/watobo/gui/scanner_settings_dialog.rb +15 -0
- data/lib/watobo/http/data/json.rb +6 -0
- data/lib/watobo/interceptor/html/favicon.ico +0 -0
- data/lib/watobo/interceptor/html/index.html +13 -0
- data/lib/watobo/interceptor/proxy.rb +70 -18
- data/lib/watobo/mixins/httpparser.rb +26 -16
- data/lib/watobo/mixins/shapers.rb +49 -5
- data/lib/watobo/mixins/transcoders.rb +8 -8
- data/lib/watobo/sockets/connection.rb +1 -1
- data/lib/watobo/utils/load_chat.rb +62 -0
- data/lib/watobo/utils/response_hash.rb +3 -3
- data/lib/watobo.rb +1 -1
- data/modules/active/cq5/cq5_default_selectors.rb +116 -0
- data/modules/active/cq5/cqp_user_enumeration.rb +134 -0
- data/modules/active/struts2/include_params_ognl.rb +1 -1
- data/modules/active/xml/xml_xxe.rb +6 -1
- data/modules/passive/disclosure_domino.rb +1 -1
- data/modules/passive/in_script_parameter.rb +9 -4
- data/plugins/aem/aem.rb +21 -0
- data/plugins/aem/gui/main.rb +128 -0
- data/plugins/aem/gui/tree_view.rb +180 -0
- data/plugins/aem/icons/aem.ico +0 -0
- data/plugins/aem/lib/agent.rb +140 -0
- data/plugins/aem/lib/dispatcher.rb +53 -0
- data/plugins/aem/lib/engine.rb +187 -0
- data/plugins/filefinder/dbs/cq5.db +23 -0
- data/plugins/filefinder/dbs/subs-big.lst +44 -44
- data/plugins/filefinder/filefinder.rb +4 -4
- data/plugins/sqlmap/lib/sqlmap_ctrl.rb +11 -10
- metadata +16 -2
@@ -26,7 +26,7 @@ module Watobo#:nodoc: all
|
|
26
26
|
|
27
27
|
def initialize(owner, prefs)
|
28
28
|
#super(owner, "Edit Target Scope", DECOR_TITLE|DECOR_BORDER, :width => 300, :height => 425)
|
29
|
-
super(owner, "Edit Target Scope", DECOR_ALL, :width =>
|
29
|
+
super(owner, "Edit Target Scope", DECOR_ALL, :width => 350, :height => 425)
|
30
30
|
|
31
31
|
@scope = Hash.new
|
32
32
|
|
@@ -62,6 +62,8 @@ module Watobo#:nodoc: all
|
|
62
62
|
fuzz_request.extend Watobo::Mixin::Parser::Url
|
63
63
|
|
64
64
|
test_request, test_response = doRequest(fuzz_request, @prefs)
|
65
|
+
|
66
|
+
notify(:stats, test_response)
|
65
67
|
|
66
68
|
notify(:fuzzer_match, test_fuzzle, test_request, test_response, test_response.join) if @filter_list.empty?
|
67
69
|
|
@@ -359,10 +361,36 @@ module Watobo#:nodoc: all
|
|
359
361
|
end
|
360
362
|
|
361
363
|
def addResponse(response)
|
364
|
+
|
365
|
+
@log_queue << response
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
def clearResponseCodeTable()
|
370
|
+
@response_code_tbl.clearItems()
|
371
|
+
@response_code_tbl.setTableSize(0, 2)
|
372
|
+
|
373
|
+
@response_code_tbl.setColumnText( 0, "STATUS" )
|
374
|
+
@response_code_tbl.setColumnText( 1, "COUNT" )
|
375
|
+
|
376
|
+
@response_code_tbl.rowHeader.width = 0
|
377
|
+
@response_code_tbl.setColumnWidth(0, 70)
|
378
|
+
|
379
|
+
@response_code_tbl.setColumnWidth(1, 70)
|
362
380
|
|
363
|
-
return nil unless response.respond_to? :status
|
364
381
|
|
365
|
-
|
382
|
+
end
|
383
|
+
|
384
|
+
def start_update_timer
|
385
|
+
@timer = FXApp.instance.addTimeout( 1000, :repeat => true) {
|
386
|
+
#print @log_queue.length
|
387
|
+
while @log_queue.length > 0
|
388
|
+
response = @log_queue.deq
|
389
|
+
|
390
|
+
if response.respond_to? :status
|
391
|
+
@count_total += 1
|
392
|
+
@count_text.text = "Total: #{@count_total}"
|
393
|
+
|
366
394
|
cstatus = response.status
|
367
395
|
count_item = nil
|
368
396
|
@response_code_tbl.getNumRows.times do |i|
|
@@ -381,24 +409,13 @@ module Watobo#:nodoc: all
|
|
381
409
|
c = count_item.text.to_i
|
382
410
|
count_item.text = ( c + 1 ).to_s
|
383
411
|
end
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
@response_code_tbl.clearItems()
|
390
|
-
@response_code_tbl.setTableSize(0, 2)
|
391
|
-
|
392
|
-
@response_code_tbl.setColumnText( 0, "STATUS" )
|
393
|
-
@response_code_tbl.setColumnText( 1, "COUNT" )
|
394
|
-
|
395
|
-
@response_code_tbl.rowHeader.width = 0
|
396
|
-
@response_code_tbl.setColumnWidth(0, 70)
|
397
|
-
|
398
|
-
@response_code_tbl.setColumnWidth(1, 70)
|
399
|
-
|
412
|
+
@count_text.handle(self, FXSEL(SEL_UPDATE, 0), nil)
|
413
|
+
end
|
414
|
+
|
415
|
+
end
|
416
|
+
}
|
400
417
|
|
401
|
-
|
418
|
+
end
|
402
419
|
|
403
420
|
def clearResponseLengthTable()
|
404
421
|
@response_length_tbl.clearItems()
|
@@ -419,13 +436,18 @@ module Watobo#:nodoc: all
|
|
419
436
|
@response_length_tbl.getItem(lastRowIndex, 1).justify = FXTableItem::LEFT
|
420
437
|
end
|
421
438
|
end
|
422
|
-
|
439
|
+
|
440
|
+
|
423
441
|
def initialize(parent, opts)
|
424
442
|
super(parent, opts)
|
425
443
|
|
426
|
-
@
|
444
|
+
@log_queue = Queue.new
|
427
445
|
|
428
446
|
@count_total = 0
|
447
|
+
|
448
|
+
@count_text = FXLabel.new(self, "Total: 0")
|
449
|
+
@count_text.setFont(FXFont.new(getApp(), "helvetica", 11, FONTWEIGHT_BOLD, FONTENCODING_DEFAULT))
|
450
|
+
|
429
451
|
counter_frame = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
430
452
|
response_code_gb = FXGroupBox.new(counter_frame, "Response Codes", LAYOUT_SIDE_BOTTOM|FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0)
|
431
453
|
frame = FXVerticalFrame.new(response_code_gb, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y )
|
@@ -439,7 +461,11 @@ module Watobo#:nodoc: all
|
|
439
461
|
sunken = FXVerticalFrame.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
|
440
462
|
@response_length_tbl = FXTable.new(sunken, :opts => FRAME_SUNKEN|TABLE_COL_SIZABLE|TABLE_ROW_SIZABLE|LAYOUT_FILL_X|LAYOUT_FILL_Y|TABLE_READONLY|LAYOUT_SIDE_TOP, :padding => 2)
|
441
463
|
@response_length_tbl.columnHeader.connect(SEL_COMMAND) { }
|
464
|
+
|
465
|
+
|
442
466
|
clearResponseLengthTable()
|
467
|
+
|
468
|
+
start_update_timer
|
443
469
|
end
|
444
470
|
end
|
445
471
|
|
@@ -909,12 +935,17 @@ module Watobo#:nodoc: all
|
|
909
935
|
return 0 if response != MBOX_CLICKED_YES
|
910
936
|
|
911
937
|
end
|
912
|
-
|
938
|
+
r = []
|
913
939
|
@matchTable.numRows.times do |i|
|
914
940
|
#puts items[1].to_s
|
941
|
+
tv = @matchTable.getItemData(i,0)
|
915
942
|
data = @matchTable.getItemData(i,1)
|
916
|
-
|
943
|
+
if data
|
944
|
+
r << { :tag => tv, :data => data.strip }
|
945
|
+
end
|
917
946
|
end
|
947
|
+
fh = File.new(filename, "w")
|
948
|
+
fh.puts YAML.dump(r)
|
918
949
|
fh.close
|
919
950
|
end
|
920
951
|
rescue => bang
|
@@ -954,6 +985,7 @@ module Watobo#:nodoc: all
|
|
954
985
|
lastRowIndex = @matchTable.getNumRows
|
955
986
|
@matchTable.appendRows(1)
|
956
987
|
@matchTable.setItemText(lastRowIndex, 0, s.join("\n"))
|
988
|
+
@matchTable.setItemData(lastRowIndex, 0, fuzzle )
|
957
989
|
@matchTable.getItem(lastRowIndex, 0).justify = FXTableItem::LEFT
|
958
990
|
@matchTable.fitRowsToContents(lastRowIndex)
|
959
991
|
cell_text = match.gsub(/(\n+|\r+)/, " ")
|
@@ -999,6 +1031,12 @@ module Watobo#:nodoc: all
|
|
999
1031
|
@pbar.increment(1)
|
1000
1032
|
}
|
1001
1033
|
|
1034
|
+
@stat_viewer.clearView
|
1035
|
+
|
1036
|
+
check_list.first.subscribe(:stats) { |response|
|
1037
|
+
@stat_viewer.addResponse(response)
|
1038
|
+
}
|
1039
|
+
|
1002
1040
|
check_list.first.subscribe(:fuzzer_match) { |fuzzle, request, response, match|
|
1003
1041
|
@stat_viewer.addResponse(response)
|
1004
1042
|
addMatch(fuzzle, match)
|
@@ -1418,7 +1418,7 @@ module Watobo#:nodoc: all
|
|
1418
1418
|
|
1419
1419
|
# C H A T T A B L E
|
1420
1420
|
@chatTable = ConversationTable.new(@conversation_table_ctrl )
|
1421
|
-
@conversation_table_ctrl.table= @chatTable
|
1421
|
+
@conversation_table_ctrl.table = @chatTable
|
1422
1422
|
|
1423
1423
|
@chatTable.autoscroll = true
|
1424
1424
|
=begin
|
@@ -18,6 +18,7 @@ module Watobo#:nodoc: all
|
|
18
18
|
settings[:max_parallel_checks] = @max_par_checks.value
|
19
19
|
settings[:smart_scan] = @enable_smart_scan.checked?
|
20
20
|
settings[:run_passive_checks] = @enable_passive_checks.checked?
|
21
|
+
settings[:ignore_server_errors] = @ignore_server_errors.checked?
|
21
22
|
|
22
23
|
settings[:scanlog_dir] = ''
|
23
24
|
if @log_scan_cb.checked? then
|
@@ -104,6 +105,20 @@ module Watobo#:nodoc: all
|
|
104
105
|
text = "If Smart Scan is enabled the scanner will reduce the number of checks."
|
105
106
|
fxtext.setText(text)
|
106
107
|
|
108
|
+
gbox = FXGroupBox.new(scroll_area, "Response Codes", LAYOUT_SIDE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 50)
|
109
|
+
gbframe = FXVerticalFrame.new(gbox, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
|
110
|
+
frame = FXHorizontalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
|
111
|
+
@ignore_server_errors = FXCheckButton.new(frame, "Ignore Server Errors ", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT)
|
112
|
+
@ignore_server_errors.checkState = @settings[:ignore_server_errors]
|
113
|
+
|
114
|
+
#@edit_uniq_parms_btn = FXButton.new(frame, "Non-Unique Parms", :opts => LAYOUT_RIGHT|FRAME_RAISED)
|
115
|
+
|
116
|
+
fxtext = FXText.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
|
117
|
+
fxtext.backColor = fxtext.parent.backColor
|
118
|
+
fxtext.disable
|
119
|
+
text = "Handle error codes (5xx) as file does not exist"
|
120
|
+
fxtext.setText(text)
|
121
|
+
|
107
122
|
|
108
123
|
gbox = FXGroupBox.new(scroll_area, "Passive Checks", LAYOUT_SIDE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 150)
|
109
124
|
gbframe = FXVerticalFrame.new(gbox, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
|
@@ -33,10 +33,16 @@ module Watobo#:nodoc: all
|
|
33
33
|
parms = []
|
34
34
|
json_str = @root.body.to_s
|
35
35
|
|
36
|
+
begin
|
36
37
|
JSON.parse(json_str).each do |k,v|
|
37
38
|
val = v.is_a?(String) ? v : v.to_s
|
38
39
|
parms << Watobo::JSONParameter.new( :name => k, :value => val )
|
39
40
|
end
|
41
|
+
rescue => bang
|
42
|
+
puts "! could not parse JSON parameters !"
|
43
|
+
puts @root.headers
|
44
|
+
puts json_str.gsub(/[^[:print:]]/, '.')
|
45
|
+
end
|
40
46
|
parms
|
41
47
|
end
|
42
48
|
|
Binary file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>WATOBO - Interceptor</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<h1>Thank you for using WATOBO - The Webapplication Toolbox</h1>
|
7
|
+
Info:<br>
|
8
|
+
Version: WATOBO_VERSION<br />
|
9
|
+
Home dir: WATOBO_HOME<br />
|
10
|
+
<br /><br />
|
11
|
+
<a href="watobo.pem">Download Certificate</a>
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -27,6 +27,50 @@ module Watobo#:nodoc: all
|
|
27
27
|
def self.transparent?
|
28
28
|
return true if ( Watobo::Conf::Interceptor.proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
|
29
29
|
return false
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
def watobo_srv_get(file)
|
35
|
+
srv_file = file.empty? ? File.join(@srv_path, 'index.html') : File.join(@srv_path, file)
|
36
|
+
if File.exist? srv_file
|
37
|
+
ct = case srv_file
|
38
|
+
when /\.ico/
|
39
|
+
"image/vnd.microsoft.icon"
|
40
|
+
when /\.htm/
|
41
|
+
'text/html; charset=iso-8859-1'
|
42
|
+
else
|
43
|
+
'text/plain'
|
44
|
+
end
|
45
|
+
headers = [ "HTTP/1.0 200 OK", "Server: Watobo-Interceptor", "Connection: close", "Content-Type: #{ct}"]
|
46
|
+
content = File.open(srv_file,"rb").read
|
47
|
+
content.gsub!('WATOBO_VERSION', Watobo::VERSION )
|
48
|
+
content.gsub!('WATOBO_HOME', Watobo.working_directory )
|
49
|
+
headers << "Content-Length: #{content.length}"
|
50
|
+
r = headers.join("\r\n")
|
51
|
+
r << "\r\n\r\n"
|
52
|
+
r << content
|
53
|
+
return r
|
54
|
+
end
|
55
|
+
|
56
|
+
headers = [ "HTTP/1.0 404 Not Found", "Server: Watobo-Interceptor", "Connection: close", "Content-Type: text/plain; charset=iso-8859-1"]
|
57
|
+
content = "The requested file (#{file}) does not exist in the interceptor web folder."
|
58
|
+
headers << "Content-Length: #{content.length}"
|
59
|
+
r = headers.join("\r\n")
|
60
|
+
r << "\r\n\r\n"
|
61
|
+
r << content
|
62
|
+
return r
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def cert_response
|
67
|
+
crt_file = File.join(Watobo.working_directory, "CA", "cacert.pem")
|
68
|
+
headers = [ "HTTP/1.0 200 OK", "Server: Watobo-Interceptor", "Connection: close", "Content-Type: application/x-pem-file"]
|
69
|
+
content = File.read(crt_file)
|
70
|
+
headers << "Content-Length: #{content.length}"
|
71
|
+
r = headers.join("\r\n")
|
72
|
+
r << "\r\n\r\n"
|
73
|
+
r << content
|
30
74
|
end
|
31
75
|
|
32
76
|
def server
|
@@ -183,6 +227,19 @@ module Watobo#:nodoc: all
|
|
183
227
|
end
|
184
228
|
#next
|
185
229
|
Thread.exit
|
230
|
+
end
|
231
|
+
|
232
|
+
# check for watobo info page
|
233
|
+
if request.host =~ /^watobo$/
|
234
|
+
if request.path =~ /watobo\.pem/
|
235
|
+
response = cert_response
|
236
|
+
else
|
237
|
+
response = watobo_srv_get(request.path)
|
238
|
+
end
|
239
|
+
|
240
|
+
c_sock.write response
|
241
|
+
c_sock.close
|
242
|
+
Thread.exit
|
186
243
|
end
|
187
244
|
|
188
245
|
request_intercepted = false
|
@@ -231,17 +288,16 @@ module Watobo#:nodoc: all
|
|
231
288
|
Thread.exit
|
232
289
|
end
|
233
290
|
|
234
|
-
# check if response should be passed
|
291
|
+
# check if response should be passed through
|
235
292
|
#Thread.current.exit if isPassThrough?(req, resp, s_sock, c_sock)
|
236
293
|
if isPassThrough?(req, resp, s_sock, c_sock)
|
294
|
+
#puts "[Interceptor] PassThrough >> #{req.url}"
|
237
295
|
Watobo::HTTPSocket.close s_sock
|
238
296
|
c_sock.close
|
239
297
|
Thread.exit
|
240
298
|
end
|
241
|
-
|
242
|
-
|
299
|
+
|
243
300
|
begin
|
244
|
-
# puts "* got response status: #{resp.status}"
|
245
301
|
missing_credentials = false
|
246
302
|
rs = resp.status
|
247
303
|
auth_type = AUTH_TYPE_NONE
|
@@ -271,18 +327,11 @@ module Watobo#:nodoc: all
|
|
271
327
|
resp.unshift "HTTP/1.1 200 OK\r\n"
|
272
328
|
end
|
273
329
|
end
|
274
|
-
#else
|
275
|
-
|
276
|
-
#resp.push "WATOBO: Unknown authorization type.<br><br>\r\n" + resp.join("<br>\r\n")
|
277
|
-
#resp.shift
|
278
|
-
#resp.unshift "HTTP/1.1 200 OK\r\n"
|
279
|
-
#resp.fix_content_length
|
280
|
-
|
281
330
|
end
|
282
331
|
end
|
283
|
-
|
284
|
-
|
285
|
-
|
332
|
+
|
333
|
+
# don't try to read body if request method is HEAD
|
334
|
+
unless auth_type == AUTH_TYPE_UNKNOWN or req.method =~ /^head/i
|
286
335
|
sender.readHTTPBody(s_sock, resp, req, :update_sids => true)
|
287
336
|
Watobo::HTTPSocket.close s_sock
|
288
337
|
end
|
@@ -319,8 +368,8 @@ module Watobo#:nodoc: all
|
|
319
368
|
end
|
320
369
|
|
321
370
|
# puts ">> SEND TO CLIENT"
|
322
|
-
|
323
|
-
#request.headers("Connection"){ |h| puts h }
|
371
|
+
# puts ">>C<< - Close: #{request.connection_close?}"
|
372
|
+
# request.headers("Connection"){ |h| puts h }
|
324
373
|
|
325
374
|
if missing_credentials
|
326
375
|
resp.set_header("Connection", "close")
|
@@ -388,7 +437,9 @@ module Watobo#:nodoc: all
|
|
388
437
|
|
389
438
|
#Watobo::Interceptor.proxy_mode = INTERCEPT_NONE
|
390
439
|
|
391
|
-
init_instance_vars
|
440
|
+
init_instance_vars
|
441
|
+
|
442
|
+
@srv_path = File.join(File.dirname(__FILE__),'html')
|
392
443
|
|
393
444
|
@awaiting_requests = 0
|
394
445
|
@awaiting_responses = 0
|
@@ -658,7 +709,8 @@ module Watobo#:nodoc: all
|
|
658
709
|
begin
|
659
710
|
# return false if true
|
660
711
|
reason = nil
|
661
|
-
clen = response.content_length
|
712
|
+
clen = response.content_length
|
713
|
+
|
662
714
|
# no pass-through necessary if request method is HEAD
|
663
715
|
return false if request.method =~ /^head/i
|
664
716
|
|
@@ -215,6 +215,7 @@ module Watobo#:nodoc: all
|
|
215
215
|
end
|
216
216
|
url
|
217
217
|
end
|
218
|
+
# alias :url :url_string
|
218
219
|
|
219
220
|
def site
|
220
221
|
#@site ||= nil
|
@@ -422,10 +423,10 @@ module Watobo#:nodoc: all
|
|
422
423
|
self.headers.each do |header|
|
423
424
|
begin
|
424
425
|
if header =~ /^#{header_name}/i then
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
426
|
+
vstart = header.index ':'
|
427
|
+
unless vstart.nil?
|
428
|
+
header_values.push header[vstart+1..-1].strip
|
429
|
+
end
|
429
430
|
end
|
430
431
|
rescue => bang
|
431
432
|
puts bang
|
@@ -438,11 +439,21 @@ module Watobo#:nodoc: all
|
|
438
439
|
def content_type(default_ct='undefined')
|
439
440
|
ct = default_ct
|
440
441
|
self.each do |line|
|
442
|
+
begin
|
441
443
|
break if line.strip.empty?
|
442
|
-
|
444
|
+
#cl = line.encode('ASCII', :invalid => :replace, :undef => :replace)
|
445
|
+
cl = line.force_encoding('ASCII-8BIT')
|
446
|
+
if cl =~ /^Content-Type:([^;]*);?/i then
|
443
447
|
ct = $1
|
444
448
|
break
|
445
449
|
end
|
450
|
+
rescue => bang
|
451
|
+
puts "! could not parse content_type !"
|
452
|
+
puts bang
|
453
|
+
puts cl
|
454
|
+
# puts cl.gsub(/[^[:print:]]/, '.')
|
455
|
+
|
456
|
+
end
|
446
457
|
end
|
447
458
|
return ct.strip
|
448
459
|
end
|
@@ -451,7 +462,9 @@ module Watobo#:nodoc: all
|
|
451
462
|
ct = default_ct
|
452
463
|
self.each do |line|
|
453
464
|
break if line.strip.empty?
|
454
|
-
|
465
|
+
# cl = line.encode('ASCII', :invalid => :replace, :undef => :replace)
|
466
|
+
cl = line.force_encoding('ASCII-8BIT')
|
467
|
+
if cl =~ /^Content-Type:(.*)/i then
|
455
468
|
ct = $1.strip
|
456
469
|
break
|
457
470
|
end
|
@@ -654,13 +667,15 @@ def content_encoding
|
|
654
667
|
return b.unpack("C*").pack("C*")
|
655
668
|
end
|
656
669
|
|
657
|
-
def
|
670
|
+
def status_code
|
658
671
|
if self.first =~ /^HTTP\/... (\d+) /
|
659
672
|
return $1
|
660
673
|
else
|
661
674
|
return nil
|
662
675
|
end
|
663
676
|
end
|
677
|
+
|
678
|
+
alias :responseCode :status_code
|
664
679
|
|
665
680
|
# returns array of new cookies
|
666
681
|
# Set-Cookie: mycookie=b41dc9e55d6163f78321996b10c940edcec1b4e55a76464c4e9d25e160ac0ec5b769806b; Path=/
|
@@ -708,23 +723,18 @@ end
|
|
708
723
|
|
709
724
|
def headers(filter=nil, &b)
|
710
725
|
begin
|
726
|
+
filter = '.*' if filter.nil?
|
711
727
|
header_list=[]
|
712
728
|
self.each do |line|
|
713
|
-
cl = line.
|
729
|
+
cl = line.force_encoding('ASCII-8BIT')
|
714
730
|
return header_list if cl.strip.empty?
|
715
|
-
|
716
|
-
if cl =~ /#{filter}/
|
717
|
-
yield line if block_given?
|
718
|
-
header_list.push line
|
719
|
-
end
|
720
|
-
else
|
731
|
+
if cl =~ /#{filter}/
|
721
732
|
yield line if block_given?
|
722
733
|
header_list.push line
|
723
|
-
end
|
734
|
+
end
|
724
735
|
end
|
725
736
|
return header_list
|
726
737
|
rescue => bang
|
727
|
-
puts "! no headers available !".upcase
|
728
738
|
puts bang
|
729
739
|
puts bang.backtrace
|
730
740
|
if $DEBUG
|