watobo 0.9.13 → 0.9.14

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.
@@ -19,7 +19,7 @@
19
19
  # along with WATOBO; if not, write to the Free Software
20
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
21
  # .
22
- # @private
22
+ # @private
23
23
  module Watobo#:nodoc: all
24
24
  module Interceptor
25
25
  #
@@ -31,17 +31,16 @@ module Watobo#:nodoc: all
31
31
 
32
32
  attr_accessor :proxy_mode
33
33
 
34
- attr_accessor :contentLength
35
- attr_accessor :contentTypes
34
+ # attr_accessor :contentLength
35
+ #attr_accessor :contentTypes
36
36
  attr_accessor :target
37
- attr :www_auth
37
+ #attr :www_auth
38
38
  attr_accessor :client_certificates
39
-
40
39
  def self.transparent?
41
40
  return true if ( Watobo::Conf::Interceptor.proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
42
41
  return false
43
42
  end
44
-
43
+
45
44
  def server
46
45
  @bind_addr
47
46
  end
@@ -91,7 +90,7 @@ module Watobo#:nodoc: all
91
90
  puts "[#{self.class}] stop"
92
91
  if @t_server.respond_to? :status
93
92
  puts @t_server.status
94
- Thread.kill @t_server
93
+ Thread.kill @t_server
95
94
  @intercept_srv.close
96
95
  end
97
96
  rescue IOError => bang
@@ -111,6 +110,7 @@ module Watobo#:nodoc: all
111
110
  end
112
111
 
113
112
  def start()
113
+ @wait_queue = Queue.new
114
114
 
115
115
  if transparent?
116
116
  Watobo::Interceptor::Transparent.start
@@ -136,25 +136,30 @@ module Watobo#:nodoc: all
136
136
 
137
137
  c_sock = Watobo::HTTPSocket::ClientSocket.connect(session)
138
138
  Thread.exit if c_sock.nil?
139
+ # loop for reusing client connections
140
+ max_loop = 0
139
141
  loop do
140
142
  flags = []
141
143
  begin
142
-
143
- request = c_sock.request
144
-
145
- if request.nil? or request.empty? then
144
+
145
+ # puts "#{c_sock} - read request"
146
+ request = c_sock.request
147
+ if request.nil? or request.empty? then
148
+ print "c/"
146
149
  c_sock.close
147
150
  Thread.exit
148
151
  end
149
- puts "*[I] #{request.url}"
152
+
153
+ url = ( request.url.to_s.length > 65 ) ? request.url.to_s.slice(0,65) + "..." : request.url.to_s
154
+ puts "\n[I] #{url}"
150
155
 
151
156
  rescue => bang
152
157
  puts "!!! Error reading client request "
153
158
  puts bang
154
159
  puts bang.backtrace
155
- puts request.class
160
+ # puts request.class
156
161
  # puts request
157
- closeSocket(c_sock)
162
+ c_sock.close
158
163
  Thread.exit
159
164
  #break
160
165
  end
@@ -164,18 +169,18 @@ module Watobo#:nodoc: all
164
169
  if request.first =~ /WATOBOPreview=([0-9a-zA-Z]*)/ then
165
170
 
166
171
  puts "* preview requested ..."
167
- puts request.url
172
+ # puts request.url
168
173
 
169
174
  hashid = $1
170
175
  response = @preview[hashid]
171
176
 
172
177
  if response then
173
178
  c_sock.write response.join
174
- closeSocket(c_sock)
179
+ c_sock.close
175
180
  end
176
181
  end
177
182
  #next
178
- Thread.current.exit
183
+ Thread.exit
179
184
  end
180
185
 
181
186
  request_intercepted = false
@@ -197,9 +202,9 @@ module Watobo#:nodoc: all
197
202
  #notify(:modify_request, request, Thread.current)
198
203
  Watobo.print_debug "send request to target"
199
204
  @target.addRequest(request, Thread.current)
200
- puts "* stopping thread: #{Thread.current} ..."
205
+ # puts "* stopping thread: #{Thread.current} ..."
201
206
  Thread.stop
202
- puts "* released thread: #{Thread.current}"
207
+ # puts "* released thread: #{Thread.current}"
203
208
  else
204
209
  p "! no target for editing request"
205
210
  end
@@ -213,13 +218,15 @@ module Watobo#:nodoc: all
213
218
  begin
214
219
 
215
220
  s_sock, req, resp = @sender.sendHTTPRequest(request, :update_sids => true, :update_session => false, :update_contentlength => true, :www_auth => @www_auth, :client_certificates => @client_certificates)
221
+
216
222
  if s_sock.nil? then
223
+ puts "s_sock is nil! bye, bye, ..."
217
224
  puts request if $DEBUG
218
225
  c_sock.write resp.join unless resp.nil?
219
226
  c_sock.close
220
227
  #Thread.kill Thread.current
221
228
  Thread.exit
222
- next
229
+ #next
223
230
  end
224
231
 
225
232
  rescue => bang
@@ -232,16 +239,22 @@ module Watobo#:nodoc: all
232
239
 
233
240
  # check if response should be passed throug
234
241
  #Thread.current.exit if isPassThrough?(req, resp, s_sock, c_sock)
242
+ if isPassThrough?(req, resp, s_sock, c_sock)
243
+ Watobo::HTTPSocket.close s_sock
244
+ c_sock.close
245
+ Thread.exit
246
+ end
235
247
  #p "no pass-through"
236
248
 
237
249
  begin
238
250
  # puts "* got response status: #{resp.status}"
239
251
  missing_credentials = false
240
252
  rs = resp.status
253
+ auth_type = AUTH_TYPE_NONE
241
254
  if rs =~ /^(401|407)/ then
242
255
  missing_credentials = true
243
256
 
244
- auth_type = AUTH_TYPE_NONE
257
+
245
258
  resp.each do |rl|
246
259
  if rl =~ /^(Proxy|WWW)-Authenticate: Basic/i
247
260
  auth_type = AUTH_TYPE_BASIC
@@ -272,11 +285,11 @@ module Watobo#:nodoc: all
272
285
  resp.fix_content_length
273
286
 
274
287
  end
275
- else
288
+ end
289
+ unless auth_type == AUTH_TYPE_UNKNOWN or req.method =~ /^head/i
276
290
  # don't try to read body if request method is HEAD
277
- unless req.method =~ /^head/i
278
291
  @sender.readHTTPBody(s_sock, resp, req, :update_sids => true)
279
- end
292
+ Watobo::HTTPSocket.close s_sock
280
293
  end
281
294
  rescue => bang
282
295
  puts "!!! could not send request !!!"
@@ -310,17 +323,29 @@ module Watobo#:nodoc: all
310
323
  end
311
324
 
312
325
  # puts ">> SEND TO CLIENT"
326
+ # puts ">>C<< - Close: #{request.connection_close?}"
327
+ #request.headers("Connection"){ |h| puts h }
328
+
313
329
  if missing_credentials
314
330
  resp.set_header("Connection", "close")
315
- c_sock.write resp.join
316
- c_sock.close
331
+ elsif request.connection_close? or resp.content_length < 0 or max_loop > 4
332
+ resp.set_header("Proxy-Connection","close")
333
+ resp.set_header("Connection","close")
317
334
  else
318
- c_sock.write resp.join
319
- end
320
- # puts resp.join
321
- # puts "-----"
322
- # closeSocket(c_sock)
323
-
335
+ resp.set_header("Connection","keep-alive")
336
+ resp.set_header("Keep-Alive", "max=4, timeout=120")
337
+ end
338
+
339
+ resp_data = resp.join
340
+ c_sock.write resp_data
341
+ c_sock.flush
342
+ # puts "= RESPONSE ="
343
+ # puts resp_data
344
+ # puts "---"
345
+ # puts resp_data.unpack("H*")[0]
346
+ # puts "==="
347
+ # puts
348
+
324
349
  rescue Errno::ECONNRESET
325
350
  print "x"
326
351
  # puts "!!! ERROR (Reset): reading body"
@@ -337,11 +362,19 @@ module Watobo#:nodoc: all
337
362
  #return
338
363
  end
339
364
 
340
- chat = Chat.new(request.copy, resp.copy, :source => CHAT_SOURCE_INTERCEPT)
341
- # notify(:new_interception, chat)
365
+ chat = Chat.new(request.copy, resp.copy, :source => CHAT_SOURCE_INTERCEPT)
366
+
342
367
  Watobo::Chats.add chat
343
- Thread.current.exit if missing_credentials
344
- end
368
+
369
+
370
+ if missing_credentials or request.connection_close? or resp.content_length < 0 or max_loop > 4
371
+ c_sock.close
372
+ Thread.exit
373
+ end
374
+ print "o"
375
+ max_loop += 1
376
+
377
+ end
345
378
  }
346
379
 
347
380
  end
@@ -400,24 +433,7 @@ end
400
433
  @preview = Hash.new
401
434
  @preview['ProxyTest'] = ["HTTP/1.0 200 OK\r\nServer: Watobo-Interceptor\r\nConnection: close\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<html><body>PROXY_OK</body></html>"]
402
435
 
403
- # p @settings[:certificate_path]
404
- # p @settings[:cert_file]
405
- # p @settings[:key_file]
406
- # crt_path = Watobo::Conf::Interceptor.certificate_path
407
- # crt_file = Watobo::Conf::Interceptor.cert_file
408
- # key_file = Watobo::Conf::Interceptor.key_file
409
- # dh_key_file = Watobo::Conf::Interceptor.dh_key_file
410
-
411
- # crt_filename = File.join(Watobo.base_directory, crt_path, crt_file)
412
- # key_filename = File.join(Watobo.base_directory, crt_path, key_file)
413
-
414
- # @ctx = OpenSSL::SSL::SSLContext.new('SSLv23_server')
415
- # @cert = OpenSSL::X509::Certificate.new(File.read(crt_filename))
416
- # @key = OpenSSL::PKey::RSA.new(File.read(key_filename))
417
-
418
- #@dh_key = OpenSSL::PKey::DH.new(File.read(dh_filename))
419
436
  @dh_key = Watobo::CA.dh_key
420
- # @ctx.ciphers = nil # ['TLSv1/SSLv3', 56, 56 ]
421
437
 
422
438
  rescue => bang
423
439
  puts "!!!could not read certificate files:"
@@ -548,7 +564,7 @@ end
548
564
  end
549
565
  end
550
566
  return false if match_ctype == false
551
- puts "* pass ctype filter"
567
+ #puts "* pass ctype filter"
552
568
  match_rcode = true
553
569
  rcode_filter = @response_filter_settings[:response_code_filter]
554
570
  negate = @response_filter_settings[:negate_response_code_filter]
@@ -564,7 +580,7 @@ end
564
580
  end
565
581
  end
566
582
  return false if match_rcode == false
567
- puts "* pass rcode filter"
583
+ #puts "* pass rcode filter"
568
584
  true
569
585
  end
570
586
 
@@ -574,10 +590,9 @@ end
574
590
  #
575
591
  #
576
592
  def pass_through(server, client, maxbytes = 0)
577
- buf = ''
578
- print "[~"
593
+
579
594
  bytes_read = 0
580
- while buf
595
+ while 1
581
596
  begin
582
597
  #timeout(2) do
583
598
  buf = nil
@@ -586,18 +601,25 @@ end
586
601
  rescue EOFError
587
602
  #client.write buf if buf
588
603
  #print "~]"
604
+ # msg = "\n[pass_through] EOF - "
605
+ # msg += buf.nil? ? "nil" : buf.size
606
+ # puts msg
589
607
  return if buf.nil?
590
608
  rescue Errno::ECONNRESET
591
609
  # puts "!!! ERROR (Reset): reading body"
592
610
  # puts "* last data seen on socket: #{buf}"
593
- print "R"
611
+ # msg = "!R - "
612
+ # msg += buf.nil? ? "nil" : buf.size
613
+ # msg << " !\n"
614
+ # puts msg
615
+
594
616
  return if buf.nil?
595
617
  rescue Timeout::Error
596
618
  #puts "!!! ERROR (Timeout): reading body"
597
619
  #puts "* last data seen on socket:"
598
620
  #client.write buf if buf
599
621
  print "T"
600
- return if buf.nil?
622
+ return
601
623
  rescue => bang
602
624
  puts "!!! could not read body !!!"
603
625
  puts bang
@@ -611,25 +633,24 @@ end
611
633
 
612
634
  begin
613
635
  return if buf.nil?
614
- print "~"
636
+ # print "~"
615
637
  client.write buf
616
638
  bytes_read += buf.length
617
- # puts "##{bytes_read} of #{maxbytes}"
639
+ # puts "#{server} #{bytes_read} of #{maxbytes}"
618
640
  if maxbytes > 0 and bytes_read >= maxbytes
619
- print "~]"
620
- return
641
+ #print "~]"
642
+ return
621
643
  end
622
-
623
644
  rescue Errno::ECONNRESET
624
- print "~x]"
645
+ #print "~x]"
625
646
  # puts "!!! ERROR (Reset): reading body"
626
647
  # puts "* last data seen on socket: #{buf}"
627
648
  return
628
649
  rescue Errno::ECONNABORTED
629
- print "~x]"
650
+ # print "~x]"
630
651
  return
631
652
  rescue Errno::EPIPE
632
- print "~x]"
653
+ # print "~x]"
633
654
  return
634
655
  rescue => bang
635
656
  puts "!!! client communication broken !!!"
@@ -642,8 +663,7 @@ end
642
663
  end
643
664
 
644
665
  def transparent?
645
- return true if ( @proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
646
- return false
666
+ ( @proxy_mode & Watobo::Interceptor::MODE_TRANSPARENT ) > 0
647
667
  end
648
668
 
649
669
  def read_request(socket)
@@ -809,6 +829,7 @@ end
809
829
 
810
830
  def isPassThrough?(request, response, s_sock, c_sock)
811
831
  begin
832
+ # return false if true
812
833
  reason = nil
813
834
  clen = response.content_length
814
835
  # no pass-through necessary if request method is HEAD
@@ -816,19 +837,25 @@ end
816
837
 
817
838
  if matchContentType?(response.content_type) then
818
839
  # first forward headers
819
- c_sock.write response.join
840
+ #c_sock.write response.join
820
841
  reason = []
821
842
  reason.push "---> WATOBO: PASS_THROUGH <---"
822
843
  reason.push "Reason: Content-Type = #{response.content_type}"
823
844
  elsif clen > @contentLength
824
845
  # puts "PASS-THROUGH: #{response.content_length}"
825
- c_sock.write response.join
846
+ #c_sock.write response.join
826
847
  reason = []
827
848
  reason.push "---> WATOBO: PASS_THROUGH <---"
828
849
  reason.push "Reason: Content-Length > #{@contentLength} (#{response.content_length})"
829
850
  end
830
851
 
831
852
  return false if reason.nil?
853
+
854
+ response.remove_header("Keep-Alive")
855
+ response.set_header("Connection", "close")
856
+
857
+ c_sock.write response.join
858
+
832
859
  reason.push "* DO MANUAL REQUEST TO GET FULL RESPONSE *"
833
860
  response.push reason.join("\n")
834
861
  chat = Watobo::Chat.new(request, response, :source => CHAT_SOURCE_INTERCEPT)
@@ -837,45 +864,16 @@ end
837
864
 
838
865
  pass_through(s_sock, c_sock, clen)
839
866
  # puts "* Close Server Socket..."
840
- closeSocket(c_sock)
867
+ #closeSocket(c_sock)
841
868
  # puts "* Close Client Socket..."
842
- closeSocket(s_sock)
869
+ #closeSocket(s_sock)
843
870
  # puts "... done."
844
- true
845
- rescue => bang
846
- puts bang
847
- puts bang.backtrace if $DEBUG
848
- return false
849
- end
850
- end
851
-
852
- def notify(event, *args)
853
- if @event_dispatcher_listeners[event]
854
- @event_dispatcher_listeners[event].each do |m|
855
- m.call(*args) if m.respond_to? :call
856
- end
857
- end
858
- end
859
-
860
- def closeSocket(socket)
861
- #puts socket.class
862
- return false if socket.nil?
863
- begin
864
- #if socket.class.to_s =~ /SSLSocket/
865
- if socket.respond_to? :sysclose
866
- #socket.io.shutdown(2)
867
- socket.sysclose
868
- elsif socket.respond_to? :shutdown
869
- socket.shutdown(2)
870
- elsif socket.respond_to? :close
871
- socket.close
872
- end
873
871
  return true
874
872
  rescue => bang
875
873
  puts bang
876
874
  puts bang.backtrace if $DEBUG
877
875
  end
878
- false
876
+ return false
879
877
  end
880
878
 
881
879
  end
@@ -426,23 +426,7 @@ module Watobo#:nodoc: all
426
426
 
427
427
  end
428
428
 
429
- # def get_parm_names
430
-
431
- # parm_names=[]
432
- # parmlist=[]
433
- # parmlist.concat(get_parms)
434
-
435
- # parmlist.each do |p|
436
- # if p then
437
- # p.gsub!(/=.*/,'')
438
- # parm_names.push p
439
- # end
440
- # end
441
-
442
- # return parm_names
443
-
444
- # end
445
-
429
+
446
430
  def header_value(header_name)
447
431
  header_values =[]
448
432
  self.headers.each do |header|
@@ -593,6 +577,20 @@ def content_encoding
593
577
  def has_body?
594
578
  self.body.nil? ? false : true
595
579
  end
580
+
581
+ def __connection_close?
582
+ headers("Connection") do |h|
583
+ return true if h =~ /close/i
584
+ end
585
+ return false
586
+ end
587
+
588
+ def connection_close?
589
+ headers("Connection") do |h|
590
+ return false if h =~ /keep\-alive/i
591
+ end
592
+ return true
593
+ end
596
594
 
597
595
  def has_header?(name)
598
596
  self.each do |l|
@@ -708,6 +706,7 @@ end
708
706
  rescue => bang
709
707
  puts "! no headers available !".upcase
710
708
  puts bang
709
+ puts bang.backtrace
711
710
  if $DEBUG
712
711
  puts bang.backtrace
713
712
  puts self.to_yaml
@@ -186,10 +186,12 @@ module Watobo#:nodoc: all
186
186
 
187
187
  def removeHeader(header)
188
188
  begin
189
- eoh_index = self.length
190
- eoh_index -= 1 unless self.body.nil?
191
-
192
- self.delete_if {|x| self.index(x) <= eoh_index and x =~ /#{header}/i }
189
+ matches = []
190
+ headers.each_with_index do |h,i|
191
+ matches << i if h =~ /#{header}/i
192
+ end
193
+ matches.map{ |m| self.delete_at(m) }
194
+
193
195
  rescue => bang
194
196
  puts bang
195
197
  puts bang.backtrace if $DEBUG
data/lib/watobo.rb CHANGED
@@ -39,6 +39,7 @@ require 'net/ntlm'
39
39
  require 'drb'
40
40
  require 'nokogiri'
41
41
  require 'stringio'
42
+ require 'mechanize'
42
43
 
43
44
  require 'watobo/constants'
44
45
  require 'watobo/utils'
@@ -56,10 +57,13 @@ require 'watobo/parser'
56
57
  require 'watobo/interceptor'
57
58
  require 'watobo/http_socket'
58
59
 
60
+ # WORKAROUND FOR LINUX :(
61
+ dont_know_why_REQUIRE_hangs = Mechanize.new
62
+
59
63
  # @private
60
64
  module Watobo#:nodoc: all #:nodoc: all
61
65
 
62
- VERSION = "0.9.13"
66
+ VERSION = "0.9.14"
63
67
 
64
68
  def self.base_directory
65
69
  @base_directory ||= ""
@@ -91,11 +91,8 @@ module Watobo#:nodoc: all
91
91
  old_cookies = chat.request.cookies.select do |rc|
92
92
  cookie_old = true
93
93
  chat.response.new_cookies do |nc|
94
- if rc =~ /^#{nc.name}/
95
- rc_name, rc_value = rc.split("=")
96
- cookie_old = false unless rc_value == nc.value
97
- end
98
- puts ":#{rc} - #{nc.name} - #{cookie_old}"
94
+ cookie_old = false unless rc.value == nc.value
95
+ #puts ":#{rc} - #{nc.name} - #{cookie_old}"
99
96
  end
100
97
  puts ":#{rc} >> #{cookie_old}"
101
98
  cookie_old
@@ -19,62 +19,7 @@
19
19
  # along with WATOBO; if not, write to the Free Software
20
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
21
  # .
22
- begin
23
- require 'mechanize'
24
- rescue LoadError
25
- puts "To use the crawler plugin you must install the 'mechanize' gem."
26
- puts "Simply enter the command 'gem install mechanize'"
27
- end
28
-
29
-
30
-
31
-
32
- path = File.expand_path(File.dirname(__FILE__))
33
-
34
22
  %w( constants bags grabber engine uri_mp).each do |l|
35
- require File.join(path, "lib", l)
23
+ require_relative File.join("lib", l)
36
24
  end
37
25
 
38
- if $0 == __FILE__
39
- # @private
40
- module Watobo#:nodoc: all
41
- module Conf
42
- class Interceptor
43
- def self.port
44
- # 8081
45
- nil
46
- end
47
- end
48
- end
49
- end
50
-
51
- require 'yaml'
52
- if ARGV.length > 0
53
- url = ARGV[0]
54
- end
55
-
56
- hook = lambda{ |agent, request|
57
- begin
58
- puts request.class
59
- puts request.method
60
- puts request.methods.sort
61
-
62
- exit
63
- clean_jar = Mechanize::CookieJar.new
64
- agent.cookie_jar.each{|cookie|
65
- puts "Cookie: #{cookie.name}"
66
- clean_jar.add! cookie unless cookie.name =~ /^box/i
67
- }
68
- exit unless agent.cookie_jar.empty?(request.url.to_s)
69
- agent.cookie_jar = clean_jar
70
- rescue => bang
71
- puts bang
72
- puts bang.backtrace
73
- end
74
-
75
- }
76
- hook = nil
77
-
78
- crawler = Watobo::Crawler::Engine.new
79
- crawler.run(url, :pre_connect_hook => hook, :num_grabbers => 1 )
80
- end
@@ -266,15 +266,14 @@ module Watobo#:nodoc: all
266
266
  prefs.update general_settings
267
267
  prefs.update hook_settings
268
268
 
269
- # puts prefs.to_yaml
269
+ add_update_timer(250)
270
270
 
271
- Thread.new{
272
- url = @url_txt.text
273
- @crawler.run(url, prefs)
271
+ Thread.new(@url_txt.text,prefs){|turl,tprefs|
272
+ @crawler.run(turl, tprefs)
274
273
  }
275
274
 
276
275
  @start_button.text = 'Cancel'
277
- add_update_timer()
276
+
278
277
 
279
278
  rescue PasswordMatchError
280
279
  #puts "Passwords Don't Match!"