watobo 0.9.19 → 0.9.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (266) hide show
  1. data/CHANGELOG.md +104 -0
  2. data/bin/nfq_server.rb +8 -20
  3. data/bin/watobo_gui.rb +8 -20
  4. data/config/forwarding_proxy.yml +2 -2
  5. data/lib/watobo.rb +12 -22
  6. data/lib/watobo/adapters.rb +12 -24
  7. data/lib/watobo/adapters/data_store.rb +76 -66
  8. data/lib/watobo/adapters/file/file_store.rb +295 -307
  9. data/lib/watobo/adapters/session_store.rb +13 -25
  10. data/lib/watobo/ca.rb +9 -21
  11. data/lib/watobo/config.rb +205 -217
  12. data/lib/watobo/constants.rb +8 -20
  13. data/lib/watobo/core.rb +11 -23
  14. data/lib/watobo/core/active_check.rb +11 -21
  15. data/lib/watobo/core/active_checks.rb +57 -69
  16. data/lib/watobo/core/ca.rb +388 -398
  17. data/lib/watobo/core/cert_store.rb +42 -54
  18. data/lib/watobo/core/chat.rb +100 -112
  19. data/lib/watobo/core/chats.rb +271 -275
  20. data/lib/watobo/core/client_cert_store.rb +33 -45
  21. data/lib/watobo/core/conversation.rb +56 -68
  22. data/lib/watobo/core/cookie.rb +31 -43
  23. data/lib/watobo/core/finding.rb +74 -86
  24. data/lib/watobo/core/findings.rb +113 -125
  25. data/lib/watobo/core/forwarding_proxy.rb +44 -35
  26. data/lib/watobo/core/fuzz_gen.rb +8 -20
  27. data/lib/watobo/core/intercept_carver.rb +176 -188
  28. data/lib/watobo/core/intercept_filter.rb +243 -255
  29. data/lib/watobo/core/interceptor.rb +106 -118
  30. data/lib/watobo/core/min_class.rb +12 -24
  31. data/lib/watobo/core/netfilter_queue.rb +178 -190
  32. data/lib/watobo/core/ott_cache.rb +152 -148
  33. data/lib/watobo/core/parameter.rb +53 -58
  34. data/lib/watobo/core/passive_check.rb +8 -20
  35. data/lib/watobo/core/passive_checks.rb +56 -68
  36. data/lib/watobo/core/passive_scanner.rb +54 -66
  37. data/lib/watobo/core/plugin.rb +19 -31
  38. data/lib/watobo/core/project.rb +8 -20
  39. data/lib/watobo/core/proxy.rb +51 -63
  40. data/lib/watobo/core/request.rb +128 -120
  41. data/lib/watobo/core/response.rb +59 -61
  42. data/lib/watobo/core/scanner.rb +8 -20
  43. data/lib/watobo/core/scanner3.rb +413 -425
  44. data/lib/watobo/core/scope.rb +91 -103
  45. data/lib/watobo/core/session.rb +109 -87
  46. data/lib/watobo/core/sid_cache.rb +106 -118
  47. data/lib/watobo/core/subscriber.rb +33 -45
  48. data/lib/watobo/defaults.rb +29 -41
  49. data/lib/watobo/external/diff/lcs.rb +8 -20
  50. data/lib/watobo/external/diff/lcs/array.rb +8 -20
  51. data/lib/watobo/external/diff/lcs/block.rb +8 -20
  52. data/lib/watobo/external/diff/lcs/callbacks.rb +8 -20
  53. data/lib/watobo/external/diff/lcs/change.rb +8 -20
  54. data/lib/watobo/external/diff/lcs/hunk.rb +8 -20
  55. data/lib/watobo/external/diff/lcs/ldiff.rb +8 -20
  56. data/lib/watobo/external/diff/lcs/string.rb +8 -20
  57. data/lib/watobo/externals.rb +14 -26
  58. data/lib/watobo/framework.rb +12 -24
  59. data/lib/watobo/framework/create_project.rb +68 -80
  60. data/lib/watobo/framework/init.rb +8 -20
  61. data/lib/watobo/framework/init_modules.rb +8 -20
  62. data/lib/watobo/framework/license_text.rb +36 -48
  63. data/lib/watobo/framework/load_chat.rb +21 -33
  64. data/lib/watobo/gui.rb +121 -133
  65. data/lib/watobo/gui/about_watobo.rb +8 -20
  66. data/lib/watobo/gui/browser_preview.rb +8 -20
  67. data/lib/watobo/gui/certificate_dialog.rb +8 -20
  68. data/lib/watobo/gui/chat_diff.rb +11 -21
  69. data/lib/watobo/gui/chatviewer_frame.rb +10 -22
  70. data/lib/watobo/gui/checkboxtree.rb +8 -20
  71. data/lib/watobo/gui/checks_policy_frame.rb +8 -20
  72. data/lib/watobo/gui/client_cert_dialog.rb +10 -21
  73. data/lib/watobo/gui/confirm_scan_dialog.rb +8 -20
  74. data/lib/watobo/gui/conversation_table.rb +54 -44
  75. data/lib/watobo/gui/conversation_table_ctrl.rb +215 -227
  76. data/lib/watobo/gui/conversation_table_ctrl2.rb +385 -393
  77. data/lib/watobo/gui/csrf_token_dialog.rb +11 -25
  78. data/lib/watobo/gui/custom_viewer.rb +357 -369
  79. data/lib/watobo/gui/dashboard.rb +8 -20
  80. data/lib/watobo/gui/define_scope_frame.rb +8 -20
  81. data/lib/watobo/gui/differ_frame.rb +223 -235
  82. data/lib/watobo/gui/edit_comment.rb +8 -20
  83. data/lib/watobo/gui/edit_scope_dialog.rb +8 -20
  84. data/lib/watobo/gui/export_dialog.rb +114 -0
  85. data/lib/watobo/gui/finding_info.rb +9 -21
  86. data/lib/watobo/gui/findings_tree.rb +8 -20
  87. data/lib/watobo/gui/full_scan_dialog.rb +8 -20
  88. data/lib/watobo/gui/fuzzer_gui.rb +8 -20
  89. data/lib/watobo/gui/goto_url_dialog.rb +78 -90
  90. data/lib/watobo/gui/hex_viewer.rb +25 -27
  91. data/lib/watobo/gui/html_viewer.rb +295 -307
  92. data/lib/watobo/gui/intercept_filter_dialog.rb +196 -208
  93. data/lib/watobo/gui/interceptor_gui.rb +1046 -1041
  94. data/lib/watobo/gui/interceptor_settings_dialog.rb +8 -20
  95. data/lib/watobo/gui/list_box.rb +109 -121
  96. data/lib/watobo/gui/log_file_viewer.rb +40 -52
  97. data/lib/watobo/gui/log_viewer.rb +87 -99
  98. data/lib/watobo/gui/login_wizzard.rb +8 -20
  99. data/lib/watobo/gui/main_window.rb +34 -33
  100. data/lib/watobo/gui/manual_request_editor.rb +25 -35
  101. data/lib/watobo/gui/master_pw_dialog.rb +8 -20
  102. data/lib/watobo/gui/mixins/gui_settings.rb +37 -49
  103. data/lib/watobo/gui/page_tree.rb +225 -237
  104. data/lib/watobo/gui/password_policy_dialog.rb +8 -20
  105. data/lib/watobo/gui/plugin_board.rb +8 -20
  106. data/lib/watobo/gui/preferences_dialog.rb +8 -20
  107. data/lib/watobo/gui/progress_window.rb +8 -20
  108. data/lib/watobo/gui/project_wizzard.rb +8 -20
  109. data/lib/watobo/gui/proxy_dialog.rb +117 -85
  110. data/lib/watobo/gui/quick_scan_dialog.rb +8 -20
  111. data/lib/watobo/gui/request_builder_frame.rb +125 -122
  112. data/lib/watobo/gui/request_editor.rb +53 -28
  113. data/lib/watobo/gui/rewrite_filters_dialog.rb +402 -414
  114. data/lib/watobo/gui/rewrite_rules_dialog.rb +380 -392
  115. data/lib/watobo/gui/save_chat_dialog.rb +148 -160
  116. data/lib/watobo/gui/scanner_settings_dialog.rb +8 -20
  117. data/lib/watobo/gui/select_chat_dialog.rb +8 -20
  118. data/lib/watobo/gui/session_management_dialog.rb +8 -20
  119. data/lib/watobo/gui/sites_tree.rb +118 -22
  120. data/lib/watobo/gui/status_bar.rb +8 -20
  121. data/lib/watobo/gui/table_editor.rb +76 -53
  122. data/lib/watobo/gui/tagless_viewer.rb +10 -21
  123. data/lib/watobo/gui/templates/plugin.rb +8 -20
  124. data/lib/watobo/gui/templates/plugin2.rb +99 -111
  125. data/lib/watobo/gui/templates/plugin_base.rb +152 -164
  126. data/lib/watobo/gui/text_viewer.rb +8 -20
  127. data/lib/watobo/gui/transcoder_window.rb +15 -22
  128. data/lib/watobo/gui/utils/gui_utils.rb +8 -20
  129. data/lib/watobo/gui/utils/init_icons.rb +94 -106
  130. data/lib/watobo/gui/utils/load_icons.rb +41 -53
  131. data/lib/watobo/gui/utils/load_plugins.rb +118 -130
  132. data/lib/watobo/gui/utils/master_password.rb +76 -88
  133. data/lib/watobo/gui/utils/save_default_settings.rb +121 -133
  134. data/lib/watobo/gui/utils/save_project_settings.rb +8 -20
  135. data/lib/watobo/gui/utils/save_proxy_settings.rb +53 -21
  136. data/lib/watobo/gui/utils/save_scanner_settings.rb +26 -38
  137. data/lib/watobo/gui/utils/session_history.rb +120 -132
  138. data/lib/watobo/gui/workspace_dialog.rb +8 -20
  139. data/lib/watobo/gui/www_auth_dialog.rb +8 -20
  140. data/lib/watobo/gui/xml_viewer_frame.rb +8 -20
  141. data/lib/watobo/http.rb +12 -23
  142. data/lib/watobo/http/cookies/cookies.rb +63 -70
  143. data/lib/watobo/http/data/data.rb +56 -64
  144. data/lib/watobo/http/data/json.rb +51 -0
  145. data/lib/watobo/http/url/url.rb +46 -58
  146. data/lib/watobo/http/xml/xml.rb +129 -141
  147. data/lib/watobo/interceptor.rb +11 -23
  148. data/lib/watobo/interceptor/proxy.rb +624 -625
  149. data/lib/watobo/interceptor/transparent.rb +22 -34
  150. data/lib/watobo/mixins.rb +18 -30
  151. data/lib/watobo/mixins/check_info.rb +35 -47
  152. data/lib/watobo/mixins/httpparser.rb +42 -35
  153. data/lib/watobo/mixins/request_parser.rb +8 -20
  154. data/lib/watobo/mixins/shapers.rb +484 -477
  155. data/lib/watobo/mixins/transcoders.rb +8 -20
  156. data/lib/watobo/parser.rb +9 -21
  157. data/lib/watobo/parser/html.rb +91 -103
  158. data/lib/watobo/sockets.rb +11 -23
  159. data/lib/watobo/sockets/agent.rb +836 -848
  160. data/lib/watobo/sockets/client_socket.rb +283 -277
  161. data/lib/watobo/sockets/connection.rb +409 -421
  162. data/lib/watobo/sockets/http_socket.rb +16 -23
  163. data/lib/watobo/sockets/ntlm_auth.rb +137 -149
  164. data/lib/watobo/utils.rb +18 -30
  165. data/lib/watobo/utils/check_regex.rb +8 -20
  166. data/lib/watobo/utils/copy_object.rb +8 -20
  167. data/lib/watobo/utils/crypto.rb +8 -20
  168. data/lib/watobo/utils/expand_range.rb +31 -43
  169. data/lib/watobo/utils/export_xml.rb +108 -0
  170. data/lib/watobo/utils/file_management.rb +8 -20
  171. data/lib/watobo/utils/hexprint.rb +17 -29
  172. data/lib/watobo/utils/load_chat.rb +8 -20
  173. data/lib/watobo/utils/load_icon.rb +8 -20
  174. data/lib/watobo/{external/ntlm → utils}/ntlm.rb +874 -796
  175. data/lib/watobo/utils/print_debug.rb +20 -32
  176. data/lib/watobo/utils/response_builder.rb +98 -110
  177. data/lib/watobo/utils/response_hash.rb +9 -20
  178. data/lib/watobo/utils/secure_eval.rb +10 -22
  179. data/lib/watobo/utils/strings.rb +18 -30
  180. data/lib/watobo/utils/text2request.rb +12 -20
  181. data/lib/watobo/utils/url.rb +31 -43
  182. data/lib/watobo/utils/utf16.rb +22 -0
  183. data/modules/active/Apache/mod_status.rb +9 -0
  184. data/modules/active/Apache/multiview.rb +161 -0
  185. data/modules/active/Flash/crossdomain.rb +9 -0
  186. data/modules/active/directories/dirwalker.rb +8 -20
  187. data/modules/active/discovery/fileextensions.rb +10 -22
  188. data/modules/active/discovery/http_methods.rb +8 -20
  189. data/modules/active/domino/domino_db.rb +8 -20
  190. data/modules/active/dotNET/custom_errors.rb +110 -122
  191. data/modules/active/dotNET/dotnet_files.rb +98 -110
  192. data/modules/active/fileinclusion/lfi_simple.rb +8 -20
  193. data/modules/active/jboss/jboss_basic.rb +8 -20
  194. data/modules/active/sap/business_objects.rb +63 -0
  195. data/modules/active/sap/its_commands.rb +8 -20
  196. data/modules/active/sap/its_service_parameter.rb +8 -20
  197. data/modules/active/sap/its_services.rb +8 -20
  198. data/modules/active/sap/its_xss.rb +8 -20
  199. data/modules/active/shell_shock/shell_shock.rb +149 -0
  200. data/modules/active/siebel/siebel_apps.rb +168 -180
  201. data/modules/active/sqlinjection/sql_boolean.rb +9 -21
  202. data/modules/active/sqlinjection/sqli_error.rb +10 -22
  203. data/modules/active/sqlinjection/sqli_timing.rb +228 -240
  204. data/modules/active/struts2/default_handler_ognl.rb +114 -126
  205. data/modules/active/struts2/include_params_ognl.rb +113 -125
  206. data/modules/active/xml/xml_xxe.rb +122 -127
  207. data/modules/active/xss/xss_ng.rb +223 -234
  208. data/modules/active/xss/xss_simple.rb +8 -20
  209. data/modules/passive/ajax.rb +76 -84
  210. data/modules/passive/autocomplete.rb +64 -76
  211. data/modules/passive/cookie_options.rb +8 -20
  212. data/modules/passive/cookie_xss.rb +9 -21
  213. data/modules/passive/detect_code.rb +9 -21
  214. data/modules/passive/detect_fileupload.rb +11 -22
  215. data/modules/passive/detect_infrastructure.rb +23 -35
  216. data/modules/passive/detect_one_time_tokens.rb +8 -20
  217. data/modules/passive/dirindexing.rb +9 -21
  218. data/modules/passive/disclosure_domino.rb +66 -79
  219. data/modules/passive/disclosure_emails.rb +9 -21
  220. data/modules/passive/disclosure_ipaddr.rb +15 -23
  221. data/modules/passive/filename_as_parameter.rb +8 -20
  222. data/modules/passive/form_spotter.rb +15 -21
  223. data/modules/passive/hidden_fields.rb +64 -70
  224. data/modules/passive/hotspots.rb +13 -22
  225. data/modules/passive/in_script_parameter.rb +15 -24
  226. data/modules/passive/multiple_server_headers.rb +8 -20
  227. data/modules/passive/possible_login.rb +12 -23
  228. data/modules/passive/redirect_url.rb +10 -22
  229. data/modules/passive/redirectionz.rb +9 -21
  230. data/modules/passive/sap-headers.rb +64 -76
  231. data/modules/passive/xss_dom.rb +10 -21
  232. data/plugins/catalog/catalog.rb +17 -23
  233. data/plugins/crawler/crawler.rb +12 -24
  234. data/plugins/crawler/gui.rb +13 -25
  235. data/plugins/crawler/gui/auth_frame.rb +278 -290
  236. data/plugins/crawler/gui/crawler_gui.rb +302 -320
  237. data/plugins/crawler/gui/general_settings_frame.rb +104 -116
  238. data/plugins/crawler/gui/hooks_frame.rb +88 -100
  239. data/plugins/crawler/gui/scope_frame.rb +58 -70
  240. data/plugins/crawler/gui/settings_tabbook.rb +46 -58
  241. data/plugins/crawler/gui/status_frame.rb +67 -78
  242. data/plugins/crawler/lib/bags.rb +26 -38
  243. data/plugins/crawler/lib/constants.rb +19 -31
  244. data/plugins/crawler/lib/engine.rb +505 -508
  245. data/plugins/crawler/lib/grabber.rb +77 -87
  246. data/plugins/crawler/lib/status.rb +82 -0
  247. data/plugins/crawler/lib/uri_mp.rb +20 -32
  248. data/plugins/filefinder/dbs/siebel_paths.txt +1118 -0
  249. data/plugins/filefinder/dbs/subs-big.lst +31986 -0
  250. data/plugins/filefinder/filefinder.rb +13 -23
  251. data/plugins/sqlmap/bin/test.rb +86 -98
  252. data/plugins/sqlmap/gui.rb +12 -24
  253. data/plugins/sqlmap/gui/main.rb +226 -238
  254. data/plugins/sqlmap/gui/options_frame.rb +105 -117
  255. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +103 -115
  256. data/plugins/sqlmap/sqlmap.rb +10 -22
  257. data/plugins/sslchecker/cli/sslchecker_cli.rb +8 -20
  258. data/plugins/sslchecker/gui/cipher_table.rb +252 -264
  259. data/plugins/sslchecker/gui/gui.rb +267 -276
  260. data/plugins/sslchecker/gui/sslchecker.rb +12 -24
  261. data/plugins/sslchecker/lib/check.rb +172 -80
  262. data/plugins/wshell/gui/main.rb +115 -127
  263. data/plugins/wshell/lib/core.rb +85 -97
  264. data/plugins/wshell/wshell.rb +19 -31
  265. metadata +14 -6
  266. data/.yardopts +0 -24
@@ -1,211 +1,199 @@
1
- # .
1
+ #.
2
2
  # intercept_filter_dialog.rb
3
- #
4
- # Copyright 2013 by siberas, http://www.siberas.de
5
- #
6
- # This file is part of WATOBO (Web Application Tool Box)
7
- # http://watobo.sourceforge.com
8
- #
9
- # WATOBO is free software; you can redistribute it and/or modify
10
- # it under the terms of the GNU General Public License as published by
11
- # the Free Software Foundation version 2 of the License.
12
- #
13
- # WATOBO is distributed in the hope that it will be useful,
14
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- # GNU General Public License for more details.
17
- #
18
- # You should have received a copy of the GNU General Public License
19
- # along with WATOBO; if not, write to the Free Software
20
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- # .
22
- # @private
23
- module Watobo#:nodoc: all
24
- module Gui
25
- class InterceptFilterDialog < FXDialogBox
26
-
27
- include Responder
28
- def getRequestFilter()
29
- @request_filter
30
- end
31
-
32
- def getResponseFilter()
33
- @response_filter
34
- end
35
-
36
- def initialize(owner, settings = {} )
37
- super(owner, "Rewrite Settings", DECOR_ALL, :width => 300, :height => 425)
38
-
39
- @request_filter = { }
40
-
41
- @response_filter = { }
42
-
43
- @request_filter.update settings[:request_filter_settings]
44
- @response_filter.update settings[:response_filter_settings]
45
-
46
- FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
47
-
48
- base_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
49
- @tabbook = FXTabBook.new(base_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
50
- buttons_frame = FXHorizontalFrame.new(base_frame, :opts => LAYOUT_FILL_X)
51
- @req_opt_tab = FXTabItem.new(@tabbook, "Request Options", nil)
52
- frame = FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
53
- scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
54
- @req_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
55
-
56
- @resp_opt_tab = FXTabItem.new(@tabbook, "Response Options", nil)
57
- frame= FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
58
- scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
59
- @resp_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
60
-
61
- initRequestFilterFrame()
62
- updateRequestFilterFrame()
63
-
64
- initResponseFilterFrame()
65
- updateResponseFilterFrame()
66
-
67
- @finishButton = FXButton.new(buttons_frame, "Accept" , nil, nil, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
68
- @finishButton.enable
69
- @finishButton.connect(SEL_COMMAND) do |sender, sel, item|
70
- #self.handle(self, FXSEL(SEL_COMMAND, ID_CANCEL), nil)
71
- self.handle(self, FXSEL(SEL_COMMAND, ID_ACCEPT), nil)
72
- end
73
-
74
- @cancelButton = FXButton.new(buttons_frame, "Cancel" ,
75
- :target => self, :selector => FXDialogBox::ID_CANCEL,
76
- :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
77
- end
78
-
79
- private
80
-
81
- def onAccept(sender, sel, event)
82
- #TODO: Check if regex is valid
83
- @request_filter[:method_filter] = @method_filter_dt.value
84
- @request_filter[:negate_method_filter] = @neg_method_filter_cb.checked?
85
- @request_filter[:negate_url_filter] = @neg_url_filter_cb.checked?
86
- @request_filter[:url_filter] = @url_filter_dt.value
87
- @request_filter[:file_type_filter] = @ftype_filter_dt.value
88
- @request_filter[:negate_file_type_filter] = @neg_ftype_filter_cb.checked?
3
+ #.
4
+ # Copyright 2014 by siberas, http://www.siberas.de
5
+ # This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
6
+ # WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
7
+ # WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
+ # You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
89
9
 
90
- @request_filter[:parms_filter] = @parms_filter_dt.value
91
- @request_filter[:negate_parms_filter] = @neg_parms_filter_cb.checked?
92
-
93
- @response_filter[:content_type_filter] = @content_type_filter_dt.value
94
- @response_filter[:negate_content_type_filter] = @neg_ctype_filter_cb.checked?
95
-
96
- @response_filter[:response_code_filter] = @rcode_filter_dt.value
97
- @response_filter[:negate_response_code_filter] = @neg_rcode_filter_cb.checked?
98
-
99
- getApp().stopModal(self, 1)
100
- self.hide()
101
- return 1
102
- end
103
-
104
- def updateRequestFilterFrame()
105
- @parms_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
106
- @url_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
107
- @ftype_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
108
- @method_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
109
- end
110
-
111
- def updateResponseFilterFrame()
112
- @content_type_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
113
- @rcode_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
114
- # @neg_rcode_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
115
- # @neg_ctype_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
116
- end
117
-
118
- def initResponseFilterFrame()
119
-
120
- gbframe = FXGroupBox.new(@resp_opt_frame, "Content Type", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
121
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
122
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
123
- fxtext.backColor = fxtext.parent.backColor
124
- fxtext.disable
125
- text = "Regular expression for HTTP Content-Type. E.g., '(text|script)'"
126
- fxtext.setText(text)
127
- @content_type_filter_dt = FXDataTarget.new('')
128
- @content_type_filter_dt.value = @response_filter[:content_type_filter]
129
- @content_type_filter = FXTextField.new(frame, 20, :target => @content_type_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
130
- @neg_ctype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
131
- #@neg_method_filter_cb.checkState = false
132
- @neg_ctype_filter_cb.checkState = @response_filter[:negate_content_type_filter]
133
-
134
- gbframe = FXGroupBox.new(@resp_opt_frame, "Response Code", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
135
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
136
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
137
- fxtext.backColor = fxtext.parent.backColor
138
- fxtext.disable
139
- text = "Regular expression for HTTP Content-Type. E.g., '200'"
140
- fxtext.setText(text)
141
- @rcode_filter_dt = FXDataTarget.new('')
142
- @rcode_filter_dt.value = @response_filter[:response_code_filter]
143
-
144
- @rcode_filter = FXTextField.new(frame, 20, :target => @rcode_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
145
- @neg_rcode_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
146
- #@neg_method_filter_cb.checkState = false
147
- @neg_rcode_filter_cb.checkState = @response_filter[:negate_response_code_filter]
148
-
149
- end
150
-
151
- def initRequestFilterFrame()
152
- gbframe = FXGroupBox.new(@req_opt_frame, "URL Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
153
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
154
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
155
- fxtext.backColor = fxtext.parent.backColor
156
- fxtext.disable
157
- text = "Regular Expression Filter For URL. E.g., '.*www.mysite.com.*login.php'"
158
- fxtext.setText(text)
159
-
160
- @url_filter_dt = FXDataTarget.new('')
161
- @url_filter_dt.value = @request_filter[:url_filter]
162
- @url_filter = FXTextField.new(frame, 20, :target => @url_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
163
- @neg_url_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
164
- #@neg_url_filter_cb.checkState = false
165
- @neg_url_filter_cb.checkState = @request_filter[:negate_url_filter]
166
-
167
- gbframe = FXGroupBox.new(@req_opt_frame, "Method Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
168
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
169
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
170
- fxtext.backColor = fxtext.parent.backColor
171
- fxtext.disable
172
- text = "Regular expression for HTTP method. E.g., '(get|PoSt)'"
173
- fxtext.setText(text)
174
- @method_filter_dt = FXDataTarget.new('')
175
- @method_filter_dt.value = @request_filter[:method_filter]
176
- @method_filter = FXTextField.new(frame, 20, :target => @method_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
177
- @neg_method_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
178
- #@neg_method_filter_cb.checkState = false
179
- @neg_method_filter_cb.checkState = @request_filter[:negate_method_filter]
180
-
181
- gbframe = FXGroupBox.new(@req_opt_frame, "Parm Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
182
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
183
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
184
- fxtext.backColor = fxtext.parent.backColor
185
- fxtext.disable
186
- text = "Regular Expression Filter For Parameter Names. E.g., for intercepting requests containing parameters beginning with 'act' use the regex pattern '^act.*' (without single quotes)"
187
- fxtext.setText(text)
188
- @parms_filter_dt = FXDataTarget.new('')
189
- @parms_filter_dt.value = @request_filter[:parms_filter]
190
- @parms_filter = FXTextField.new(frame, 20, :target => @parms_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
191
- @neg_parms_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
192
- #@neg_parm_filter_cb.checkState = false
193
- @neg_parms_filter_cb.checkState = @request_filter[:negate_parms_filter]
194
-
195
- gbframe = FXGroupBox.new(@req_opt_frame, "File Type Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
196
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
197
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
198
- fxtext.backColor = fxtext.parent.backColor
199
- fxtext.disable
200
- text = "Regular expression for file types by its extension. E.g., for intercepting requests where file type is PHP use '^php$' (without single quotes)"
201
- fxtext.setText(text)
202
- @ftype_filter_dt = FXDataTarget.new('')
203
- @ftype_filter_dt.value = @request_filter[:file_type_filter]
204
- @ftype_filter = FXTextField.new(frame, 20, :target => @ftype_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
205
- @neg_ftype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
206
- #@neg_parm_filter_cb.checkState = false
207
- @neg_ftype_filter_cb.checkState = @request_filter[:negate_file_type_filter]
208
- end
209
- end
210
- end
10
+ # @private
11
+ module Watobo#:nodoc: all
12
+ module Gui
13
+ class InterceptFilterDialog < FXDialogBox
14
+
15
+ include Responder
16
+ def getRequestFilter()
17
+ @request_filter
18
+ end
19
+
20
+ def getResponseFilter()
21
+ @response_filter
22
+ end
23
+
24
+ def initialize(owner, settings = {} )
25
+ super(owner, "Rewrite Settings", DECOR_ALL, :width => 300, :height => 425)
26
+
27
+ @request_filter = { }
28
+
29
+ @response_filter = { }
30
+
31
+ @request_filter.update settings[:request_filter_settings]
32
+ @response_filter.update settings[:response_filter_settings]
33
+
34
+ FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
35
+
36
+ base_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
37
+ @tabbook = FXTabBook.new(base_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
38
+ buttons_frame = FXHorizontalFrame.new(base_frame, :opts => LAYOUT_FILL_X)
39
+ @req_opt_tab = FXTabItem.new(@tabbook, "Request Options", nil)
40
+ frame = FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
41
+ scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
42
+ @req_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
43
+
44
+ @resp_opt_tab = FXTabItem.new(@tabbook, "Response Options", nil)
45
+ frame= FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
46
+ scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
47
+ @resp_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
48
+
49
+ initRequestFilterFrame()
50
+ updateRequestFilterFrame()
51
+
52
+ initResponseFilterFrame()
53
+ updateResponseFilterFrame()
54
+
55
+ @finishButton = FXButton.new(buttons_frame, "Accept" , nil, nil, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
56
+ @finishButton.enable
57
+ @finishButton.connect(SEL_COMMAND) do |sender, sel, item|
58
+ #self.handle(self, FXSEL(SEL_COMMAND, ID_CANCEL), nil)
59
+ self.handle(self, FXSEL(SEL_COMMAND, ID_ACCEPT), nil)
60
+ end
61
+
62
+ @cancelButton = FXButton.new(buttons_frame, "Cancel" ,
63
+ :target => self, :selector => FXDialogBox::ID_CANCEL,
64
+ :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
65
+ end
66
+
67
+ private
68
+
69
+ def onAccept(sender, sel, event)
70
+ #TODO: Check if regex is valid
71
+ @request_filter[:method_filter] = @method_filter_dt.value
72
+ @request_filter[:negate_method_filter] = @neg_method_filter_cb.checked?
73
+ @request_filter[:negate_url_filter] = @neg_url_filter_cb.checked?
74
+ @request_filter[:url_filter] = @url_filter_dt.value
75
+ @request_filter[:file_type_filter] = @ftype_filter_dt.value
76
+ @request_filter[:negate_file_type_filter] = @neg_ftype_filter_cb.checked?
77
+
78
+ @request_filter[:parms_filter] = @parms_filter_dt.value
79
+ @request_filter[:negate_parms_filter] = @neg_parms_filter_cb.checked?
80
+
81
+ @response_filter[:content_type_filter] = @content_type_filter_dt.value
82
+ @response_filter[:negate_content_type_filter] = @neg_ctype_filter_cb.checked?
83
+
84
+ @response_filter[:response_code_filter] = @rcode_filter_dt.value
85
+ @response_filter[:negate_response_code_filter] = @neg_rcode_filter_cb.checked?
86
+
87
+ getApp().stopModal(self, 1)
88
+ self.hide()
89
+ return 1
90
+ end
91
+
92
+ def updateRequestFilterFrame()
93
+ @parms_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
94
+ @url_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
95
+ @ftype_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
96
+ @method_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
97
+ end
98
+
99
+ def updateResponseFilterFrame()
100
+ @content_type_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
101
+ @rcode_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
102
+ # @neg_rcode_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
103
+ # @neg_ctype_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
104
+ end
105
+
106
+ def initResponseFilterFrame()
107
+
108
+ gbframe = FXGroupBox.new(@resp_opt_frame, "Content Type", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
109
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
110
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
111
+ fxtext.backColor = fxtext.parent.backColor
112
+ fxtext.disable
113
+ text = "Regular expression for HTTP Content-Type. E.g., '(text|script)'"
114
+ fxtext.setText(text)
115
+ @content_type_filter_dt = FXDataTarget.new('')
116
+ @content_type_filter_dt.value = @response_filter[:content_type_filter]
117
+ @content_type_filter = FXTextField.new(frame, 20, :target => @content_type_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
118
+ @neg_ctype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
119
+ #@neg_method_filter_cb.checkState = false
120
+ @neg_ctype_filter_cb.checkState = @response_filter[:negate_content_type_filter]
121
+
122
+ gbframe = FXGroupBox.new(@resp_opt_frame, "Response Code", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
123
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
124
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
125
+ fxtext.backColor = fxtext.parent.backColor
126
+ fxtext.disable
127
+ text = "Regular expression for HTTP Content-Type. E.g., '200'"
128
+ fxtext.setText(text)
129
+ @rcode_filter_dt = FXDataTarget.new('')
130
+ @rcode_filter_dt.value = @response_filter[:response_code_filter]
131
+
132
+ @rcode_filter = FXTextField.new(frame, 20, :target => @rcode_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
133
+ @neg_rcode_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
134
+ #@neg_method_filter_cb.checkState = false
135
+ @neg_rcode_filter_cb.checkState = @response_filter[:negate_response_code_filter]
136
+
137
+ end
138
+
139
+ def initRequestFilterFrame()
140
+ gbframe = FXGroupBox.new(@req_opt_frame, "URL Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
141
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
142
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
143
+ fxtext.backColor = fxtext.parent.backColor
144
+ fxtext.disable
145
+ text = "Regular Expression Filter For URL. E.g., '.*www.mysite.com.*login.php'"
146
+ fxtext.setText(text)
147
+
148
+ @url_filter_dt = FXDataTarget.new('')
149
+ @url_filter_dt.value = @request_filter[:url_filter]
150
+ @url_filter = FXTextField.new(frame, 20, :target => @url_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
151
+ @neg_url_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
152
+ #@neg_url_filter_cb.checkState = false
153
+ @neg_url_filter_cb.checkState = @request_filter[:negate_url_filter]
154
+
155
+ gbframe = FXGroupBox.new(@req_opt_frame, "Method Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
156
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
157
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
158
+ fxtext.backColor = fxtext.parent.backColor
159
+ fxtext.disable
160
+ text = "Regular expression for HTTP method. E.g., '(get|PoSt)'"
161
+ fxtext.setText(text)
162
+ @method_filter_dt = FXDataTarget.new('')
163
+ @method_filter_dt.value = @request_filter[:method_filter]
164
+ @method_filter = FXTextField.new(frame, 20, :target => @method_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
165
+ @neg_method_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
166
+ #@neg_method_filter_cb.checkState = false
167
+ @neg_method_filter_cb.checkState = @request_filter[:negate_method_filter]
168
+
169
+ gbframe = FXGroupBox.new(@req_opt_frame, "Parm Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
170
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
171
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
172
+ fxtext.backColor = fxtext.parent.backColor
173
+ fxtext.disable
174
+ text = "Regular Expression Filter For Parameter Names. E.g., for intercepting requests containing parameters beginning with 'act' use the regex pattern '^act.*' (without single quotes)"
175
+ fxtext.setText(text)
176
+ @parms_filter_dt = FXDataTarget.new('')
177
+ @parms_filter_dt.value = @request_filter[:parms_filter]
178
+ @parms_filter = FXTextField.new(frame, 20, :target => @parms_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
179
+ @neg_parms_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
180
+ #@neg_parm_filter_cb.checkState = false
181
+ @neg_parms_filter_cb.checkState = @request_filter[:negate_parms_filter]
182
+
183
+ gbframe = FXGroupBox.new(@req_opt_frame, "File Type Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
184
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
185
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
186
+ fxtext.backColor = fxtext.parent.backColor
187
+ fxtext.disable
188
+ text = "Regular expression for file types by its extension. E.g., for intercepting requests where file type is PHP use '^php$' (without single quotes)"
189
+ fxtext.setText(text)
190
+ @ftype_filter_dt = FXDataTarget.new('')
191
+ @ftype_filter_dt.value = @request_filter[:file_type_filter]
192
+ @ftype_filter = FXTextField.new(frame, 20, :target => @ftype_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
193
+ @neg_ftype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
194
+ #@neg_parm_filter_cb.checkState = false
195
+ @neg_ftype_filter_cb.checkState = @request_filter[:negate_file_type_filter]
196
+ end
197
+ end
198
+ end
211
199
  end
@@ -1,1053 +1,1058 @@
1
- # .
1
+ #.
2
2
  # interceptor_gui.rb
3
- #
4
- # Copyright 2013 by siberas, http://www.siberas.de
5
- #
6
- # This file is part of WATOBO (Web Application Tool Box)
7
- # http://watobo.sourceforge.com
8
- #
9
- # WATOBO is free software; you can redistribute it and/or modify
10
- # it under the terms of the GNU General Public License as published by
11
- # the Free Software Foundation version 2 of the License.
12
- #
13
- # WATOBO is distributed in the hope that it will be useful,
14
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- # GNU General Public License for more details.
17
- #
18
- # You should have received a copy of the GNU General Public License
19
- # along with WATOBO; if not, write to the Free Software
20
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- # .
22
- # @private
23
- module Watobo#:nodoc: all
24
- module Gui
25
- class InterceptEditor < FXVerticalFrame
26
-
27
- include Watobo::Constants
28
- include Watobo::Interceptor
29
- include Watobo::Gui::Utils
30
-
31
- def initialize(owner, opts)
32
-
33
- super(owner, opts)
34
-
35
- @lock = Mutex.new
36
- @text = nil
37
-
38
- @event_dispatcher_listeners = Hash.new
39
-
40
- text_view_header = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_HEIGHT, :height => 24, :padding => 0)
41
-
42
- #@auto_apply_cbtn.connect(SEL_COMMAND, method(:onInterceptChanged))
43
-
44
- @pmatch_btn = FXButton.new(text_view_header, "<", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
45
- @pmatch_btn.disable
46
-
47
- @pmatch_btn.connect(SEL_COMMAND) {
48
- if @textbox.numMatches > 0
49
- @match_pos_label.textColor = 'black'
50
- pos = @textbox.showPrevMatch() + 1
51
- @match_pos_label.text = "#{pos}/#{@textbox.numMatches}"
52
- else
53
- @match_pos_label.textColor = 'grey'
54
- end
55
- }
56
-
57
- @match_pos_label = FXLabel.new(text_view_header, "0/0", :opts => LAYOUT_FILL_Y)
58
- @match_pos_label.textColor = 'grey'
59
-
60
- @nmatch_btn = FXButton.new(text_view_header, ">", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
61
- @nmatch_btn.disable
62
-
63
- @nmatch_btn.connect(SEL_COMMAND) {
64
-
65
- @textbox.showNextMatch()
66
- if @textbox.numMatches > 0
67
- @match_pos_label.textColor = 'black'
68
- pos = @textbox.showNextMatch() + 1
69
- @match_pos_label.text = "#{pos}/#{@textbox.numMatches}"
70
- else
71
- @match_pos_label.textColor = 'grey'
72
- end
73
- }
74
-
75
- @filter_dt = FXDataTarget.new('')
76
- # @filter_text = FXTextField.new(text_view_header, 10,
77
- # :target => @filter_dt, :selector => FXDataTarget::ID_VALUE,
78
- # :opts => FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
79
-
80
- @filter_text = FXComboBox.new(text_view_header, 20, @filter_dt, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
81
- @filter_text.connect(SEL_COMMAND){
82
- applyFilter()
83
- addFilterHistory()
84
- }
85
-
86
- @filter_text.connect(SEL_CHANGED) {
87
- applyFilter()
88
- }
89
- inputFieldHotkeyHandler(@filter_text)
90
-
91
- @auto_select_cbtn = FXCheckButton.new(text_view_header, "auto-select", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_RIGHT|LAYOUT_FILL_Y)
92
- #@mode_btn = FXButton.new(text_view_header, "Highlight", :opts=> MENUBUTTON_DOWN|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_RIGHT|LAYOUT_FILL_Y)
93
-
94
- reset_button = FXButton.new(text_view_header, "&Reset", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y)
95
- reset_button.connect(SEL_COMMAND){ resetTextbox() }
96
-
97
- #-----------------------
98
- text_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
99
-
100
- @textbox_dt = FXDataTarget.new('')
101
-
102
- @textbox = Watobo::Gui::TextView2.new(text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
103
- # @textbox = Watobo::Gui::TextView2.new(text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
104
- # @textbox = FXText.new(text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
105
- # @textbox = FXText.new(text_frame, :target => @textbox_dt, :selector => FXDataTarget::ID_VALUE, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
106
- @textbox.textStyle -= TEXT_WORDWRAP
107
- @textbox.extend Watobo::Mixins::RequestParser
108
-
109
- @textbox.editable = true
110
-
111
- @markers = []
112
-
113
- @record_input = false # EXPERIMENTAL !!!
114
-
115
- @last_cursor_pos = 0
116
- @start_selection_pos = 0
117
-
118
- @input_start = 0
119
- @input_len = 0
120
-
121
- @textbox.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, event|
122
- unless event.moved?
123
- FXMenuPane.new(self) do |menu_pane|
124
- addStringInfo(menu_pane, sender)
125
- addDecoder(menu_pane, sender)
126
- addEncoder(menu_pane, sender)
127
- FXMenuSeparator.new(menu_pane)
128
- target = FXMenuCheck.new(menu_pane, "word wrap" )
129
- target.check = ( @textbox.textStyle & TEXT_WORDWRAP > 0 ) ? true : false
130
- target.connect(SEL_COMMAND) { |tsender, tsel, titem|
131
- if tsender.checked?
132
- @textbox.textStyle |= TEXT_WORDWRAP
133
- else
134
- @textbox.textStyle ^= TEXT_WORDWRAP
135
- end
136
- }
137
-
138
- menu_pane.create
139
- menu_pane.popup(nil, event.root_x, event.root_y)
140
- app.runModalWhileShown(menu_pane)
141
- end
142
-
143
- end
144
- end
145
-
146
- # KEY_Return
147
- # KEY_Control_L
148
- # KEY_Control_R
149
- # KEY_s
150
- @ctrl_pressed = false
151
-
152
- @textbox.connect(SEL_KEYPRESS, method(:initEditKeys))
153
-
154
- @textbox.connect(SEL_KEYRELEASE) do |sender, sel, event|
155
- @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
156
- false
157
- end
158
-
159
- end
160
-
161
- def subscribe(event, &callback)
162
- (@event_dispatcher_listeners[event] ||= []) << callback
163
- end
164
-
165
- def clearEvents(event)
166
- @event_dispatcher_listener[event].clear
167
- end
168
-
169
- def empty?
170
- @textbox.to_s.empty?
171
- end
172
-
173
- def clear
174
- @textbox.setText('')
175
- end
176
-
177
- def setText(text=nil)
178
- return false if text.nil?
179
- if text.is_a? Array
180
- new_text = text.join
181
- else
182
- new_text = "#{text}"
183
- end
184
-
185
- @lock.synchronize do
186
- @text = new_text.strip.gsub(/\r/,'')
187
-
188
- unless @text.empty?
189
- @textbox.setText @text
190
- end
191
- end
192
- # @textbox.handle(self, FXSEL(SEL_UPDATE, 0), nil)
193
- #@textbox.update
194
-
195
- end
196
-
197
- def parseRequest(prefs={})
198
- begin
199
- return @textbox.to_request(prefs)
200
- rescue SyntaxError, LocalJumpError, NameError
201
- notify(:error, "#{$!}")
202
- rescue => bang
203
- puts bang
204
- puts bang.backtrace if $DEBUG
205
- notify(:error, "Could not parse request: #{$!}")
206
- end
207
-
208
- return nil
209
- end
210
-
211
- def to_response(prefs={})
212
- begin
213
- return @textbox.to_response(prefs)
214
- rescue SyntaxError, LocalJumpError, NameError
215
- # puts bang
216
- # puts bang.backtrace if $DEBUG
217
- notify(:error, "#{$!}")
218
- rescue => bang
219
- puts bang
220
- notify(:error, "Could not parse request: #{$!}")
221
- end
222
-
223
- return nil
224
- end
225
-
226
- private
227
-
228
- def recordedText
229
- @textbox.extractText(@input_start, @input_len)
230
- end
231
-
232
- def applyFilter
233
- pattern = @filter_text.text
234
- @textbox.reset_text
235
- @match_pos_label.textColor = 'grey'
236
- @match_pos_label.text = "0/0"
237
- return true if pattern == ''
238
-
239
- @textbox.applyFilter(pattern)
240
- if @textbox.numMatches > 0
241
-
242
- @match_pos_label.text = "1/#{@textbox.numMatches}"
243
- #@match_pos_label.enable
244
- @match_pos_label.textColor = 'black'
245
- @textbox.showMatch(0, :select_match => @auto_select_cbtn.checked? )
246
- @nmatch_btn.enable
247
- @pmatch_btn.enable
248
- else
249
- @nmatch_btn.disable
250
- @pmatch_btn.disable
251
- end
252
- # puts "got #{matches.length} matches for pattern #{Regexp.quote(pattern)}"
253
- end
254
-
255
- def inputFieldHotkeyHandler(widget)
256
- @ctrl_pressed = false
257
-
258
- widget.connect(SEL_KEYPRESS) { |sender, sel, event|
259
- # puts event.code
260
- @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
261
- # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
262
- if event.code == KEY_Return
263
- applyFilter()
264
- @textbox.setFocus()
265
- @textbox.setDefault()
266
- @textbox.showMatch(0, :select_match => @auto_select_cbtn.checked? )
267
- true # special handling of KEY_Return, because we don't want a linebreak in textbox.
268
- end
269
-
270
- if @ctrl_pressed
271
- case event.code
272
- when KEY_w
273
- @textbox.textStyle ^= TEXT_WORDWRAP
274
- when KEY_n
275
- @textbox.showNextMatch()
276
- addFilterHistory()
277
- when KEY_N
278
- @textbox.showPrevMatch()
279
- addFilterHistory()
280
- when KEY_r
281
- @textbox.reset_filter()
282
- end
283
- end
284
-
285
- if event.code == KEY_F1
286
-
287
- unless event.moved?
288
- FXMenuPane.new(self) do |menu_pane|
289
- FXMenuCaption.new(menu_pane, "Hotkeys:")
290
- FXMenuSeparator.new(menu_pane)
291
- [ "<ctrl-r> - Reset Filter",
292
- "<ctrl-n> - Goto Next",
293
- "<ctrl-shift-n> - Goto Prev",
294
- "<ctrl-w> - Switch Wordwrap"
295
- ].each do |hk|
296
- FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
297
- end
298
-
299
- menu_pane.create
300
-
301
- menu_pane.popup(nil, event.root_x, event.root_y)
302
- app.runModalWhileShown(menu_pane)
303
- end
304
-
305
- end
306
- true
307
- else
308
- false
309
- end
310
- }
311
-
312
- widget.connect(SEL_KEYRELEASE) { |sender, sel, event|
313
- @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
314
- false
315
- }
316
- end
317
-
318
- def initEditKeys(sender, sel, event)
319
- # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
320
- if event.code == KEY_F1
321
-
322
- unless event.moved?
323
- FXMenuPane.new(self) do |menu_pane|
324
- FXMenuCaption.new(menu_pane, "Hotkeys:")
325
- FXMenuSeparator.new(menu_pane)
326
- [ "<ctrl-r> - Reset Filter",
327
- "<ctrl-n> - Goto Next",
328
- "<ctrl-shift-n> - Goto Prev",
329
- "<ctrl-w> - Switch Wordwrap",
330
- "<ctrl-b> - Encode Base64",
331
- "<ctrl-shift-b> - Decode Base64",
332
- "<ctrl-u> - Encode URL",
333
- "<ctrl-shift-u> - Decode URL",
334
- ].each do |hk|
335
- FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
336
- end
337
-
338
- menu_pane.create
339
-
340
- menu_pane.popup(nil, event.root_x, event.root_y)
341
- app.runModalWhileShown(menu_pane)
342
- end
343
-
344
- end
345
- end
346
-
347
- if @ctrl_pressed
348
- return true if event.code == KEY_Control_L or event.code == KEY_Control_R
349
- if event.code == KEY_Return
350
- notify(:hotkey_ctrl_enter)
351
- true # special handling of KEY_Return, because we don't want a linebreak in textbox.
352
- else
353
-
354
- case event.code
355
- when KEY_w
356
- @textbox.textStyle ^= TEXT_WORDWRAP
357
- when KEY_n
358
- @textbox.showNextMatch()
359
- addFilterHistory()
360
- when KEY_N
361
- @textbox.showPrevMatch()
362
- addFilterHistory()
363
- when KEY_r
364
- resetTextbox()
365
- end
366
-
367
- pos = @textbox.selStartPos
368
- len = @textbox.selEndPos - pos
369
-
370
- if len == 0 then
371
- pos = @input_start
372
- len = @input_len
373
- end
374
-
375
- unless len==0
376
- text = @textbox.extractText(pos,len)
377
- rptxt = case event.code
378
- when KEY_u
379
- CGI::escape(text).strip
380
- when KEY_b
381
- Base64.encode64(text).strip
382
- when KEY_U
383
- CGI::unescape(text).strip
384
- when KEY_B
385
- Base64.decode64(text).strip
386
- else
387
- text
388
- end
389
- @textbox.replaceText(pos, len, rptxt,false)
390
- @textbox.setSelection(pos,rptxt.length)
391
- end
392
- false
393
- end
394
- else
395
- @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
396
- false
397
- end
398
- end
399
-
400
- def addFilterHistory()
401
- text = @filter_text.text
402
- return true if text == ''
403
- has_item = false
404
- @filter_text.each do |item, data|
405
- has_item = true if data == text
406
- end
407
- @filter_text.appendItem(text, text) unless has_item == true
408
- @filter_text.numVisible = @filter_text.numItems
409
- end
410
-
411
- def resetTextbox()
412
- @textbox.setPrintable(@text)
413
- @textbox.reset_text
414
- @match_pos_label.text = "0/0"
415
- @match_pos_label.textColor = 'grey'
416
- end
417
-
418
- def notify(event, *args)
419
- if @event_dispatcher_listeners[event]
420
- @event_dispatcher_listeners[event].each do |m|
421
- m.call(*args) if m.respond_to? :call
422
- end
423
- end
424
- end
425
-
426
- end
427
-
428
- class InterceptorUI < FXTopWindow
429
-
430
- include Responder
431
- include Watobo
432
- include Watobo::Interceptor
433
- include Watobo::Gui::Icons
434
- def execute
435
- create
436
- show(PLACEMENT_SCREEN)
437
- # getApp().runModalFor(self)
438
- end
439
-
440
- # this method is obsolet! Use addRequest() instead
441
- def modifyRequest(request, thread)
442
- addRequest(request, thread)
443
- end
444
-
445
- # this method is obsolet! Use addResponse() instead
446
- def modifyResponse(request, thread)
447
- addResponse(request, thread)
448
- end
449
-
450
- def addRequest(request, thread)
451
- puts "* [Interceptor] addRequest"
452
-
453
- new_request = {
454
- :request => request,
455
- :thread => thread
456
- }
457
-
458
- @request_lock.synchronize do
459
- # enable_buttons()
460
- @request_queue << new_request
461
-
462
- end
463
-
464
- # enable_buttons()
465
-
466
- end
467
-
468
- def addResponse(response, thread)
469
- response.extend Watobo::Mixin::Parser::Web10
470
- response.extend Watobo::Mixin::Shaper::Web10
471
-
472
- response.fixupContentLength()
473
-
474
- # puts response
475
-
476
- new_response = {
477
- :response => response,
478
- :thread => thread
479
- }
480
-
481
- @response_lock.synchronize do
482
- @response_queue.push new_response
483
-
484
- end
485
- end
486
-
487
- def initialize(owner, opts)
488
- # Invoke base class initialize function first
489
-
490
- super( owner, 'Interceptor', nil, nil, DECOR_ALL|DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE, 0, 0, 600, 400, 0, 0, 0, 0, 0, 0)
491
- self.connect(SEL_CLOSE, method(:onClose))
492
- self.icon = ICON_INTERCEPTOR
493
- #@interceptor = interceptor
494
-
495
- @request_list = []
496
- @response_list = []
3
+ #.
4
+ # Copyright 2014 by siberas, http://www.siberas.de
5
+ # This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
6
+ # WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
7
+ # WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
+ # You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
497
9
 
498
- @request_queue = []
499
- @response_queue = []
500
-
501
- @request_lock = Mutex.new
10
+ # @private
11
+ module Watobo#:nodoc: all
12
+ module Gui
13
+ class InterceptEditor < FXVerticalFrame
14
+
15
+ include Watobo::Constants
16
+ include Watobo::Interceptor
17
+ include Watobo::Gui::Utils
18
+
19
+ def initialize(owner, opts)
20
+
21
+ super(owner, opts)
22
+
23
+ @lock = Mutex.new
24
+ @text = nil
25
+
26
+ @event_dispatcher_listeners = Hash.new
27
+
28
+ text_view_header = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_HEIGHT, :height => 24, :padding => 0)
29
+
30
+ #@auto_apply_cbtn.connect(SEL_COMMAND, method(:onInterceptChanged))
31
+
32
+ @pmatch_btn = FXButton.new(text_view_header, "<", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
33
+ @pmatch_btn.disable
34
+
35
+ @pmatch_btn.connect(SEL_COMMAND) {
36
+ if @textbox.numMatches > 0
37
+ @match_pos_label.textColor = 'black'
38
+ pos = @textbox.showPrevMatch() + 1
39
+ @match_pos_label.text = "#{pos}/#{@textbox.numMatches}"
40
+ else
41
+ @match_pos_label.textColor = 'grey'
42
+ end
43
+ }
44
+
45
+ @match_pos_label = FXLabel.new(text_view_header, "0/0", :opts => LAYOUT_FILL_Y)
46
+ @match_pos_label.textColor = 'grey'
47
+
48
+ @nmatch_btn = FXButton.new(text_view_header, ">", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
49
+ @nmatch_btn.disable
50
+
51
+ @nmatch_btn.connect(SEL_COMMAND) {
52
+
53
+ @textbox.showNextMatch()
54
+ if @textbox.numMatches > 0
55
+ @match_pos_label.textColor = 'black'
56
+ pos = @textbox.showNextMatch() + 1
57
+ @match_pos_label.text = "#{pos}/#{@textbox.numMatches}"
58
+ else
59
+ @match_pos_label.textColor = 'grey'
60
+ end
61
+ }
62
+
63
+ @filter_dt = FXDataTarget.new('')
64
+ # @filter_text = FXTextField.new(text_view_header, 10,
65
+ # :target => @filter_dt, :selector => FXDataTarget::ID_VALUE,
66
+ # :opts => FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
67
+
68
+ @filter_text = FXComboBox.new(text_view_header, 20, @filter_dt, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
69
+ @filter_text.connect(SEL_COMMAND){
70
+ applyFilter()
71
+ addFilterHistory()
72
+ }
73
+
74
+ @filter_text.connect(SEL_CHANGED) {
75
+ applyFilter()
76
+ }
77
+ inputFieldHotkeyHandler(@filter_text)
78
+
79
+ @auto_select_cbtn = FXCheckButton.new(text_view_header, "auto-select", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_RIGHT|LAYOUT_FILL_Y)
80
+ #@mode_btn = FXButton.new(text_view_header, "Highlight", :opts=> MENUBUTTON_DOWN|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_RIGHT|LAYOUT_FILL_Y)
81
+
82
+ reset_button = FXButton.new(text_view_header, "&Reset", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y)
83
+ reset_button.connect(SEL_COMMAND){ resetTextbox() }
84
+
85
+ #-----------------------
86
+ text_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
87
+
88
+ @textbox_dt = FXDataTarget.new('')
89
+
90
+ @textbox = Watobo::Gui::TextView2.new(text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
91
+ # @textbox = Watobo::Gui::TextView2.new(text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
92
+ # @textbox = FXText.new(text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
93
+ # @textbox = FXText.new(text_frame, :target => @textbox_dt, :selector => FXDataTarget::ID_VALUE, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
94
+ @textbox.textStyle -= TEXT_WORDWRAP
95
+ @textbox.extend Watobo::Mixins::RequestParser
96
+
97
+ @textbox.editable = true
98
+
99
+ @markers = []
100
+
101
+ @record_input = false # EXPERIMENTAL !!!
102
+
103
+ @last_cursor_pos = 0
104
+ @start_selection_pos = 0
105
+
106
+ @input_start = 0
107
+ @input_len = 0
108
+
109
+ @textbox.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, event|
110
+ unless event.moved?
111
+ FXMenuPane.new(self) do |menu_pane|
112
+ addStringInfo(menu_pane, sender)
113
+ addDecoder(menu_pane, sender)
114
+ addEncoder(menu_pane, sender)
115
+ FXMenuSeparator.new(menu_pane)
116
+ target = FXMenuCheck.new(menu_pane, "word wrap" )
117
+ target.check = ( @textbox.textStyle & TEXT_WORDWRAP > 0 ) ? true : false
118
+ target.connect(SEL_COMMAND) { |tsender, tsel, titem|
119
+ if tsender.checked?
120
+ @textbox.textStyle |= TEXT_WORDWRAP
121
+ else
122
+ @textbox.textStyle ^= TEXT_WORDWRAP
123
+ end
124
+ }
125
+
126
+ menu_pane.create
127
+ menu_pane.popup(nil, event.root_x, event.root_y)
128
+ app.runModalWhileShown(menu_pane)
129
+ end
130
+
131
+ end
132
+ end
133
+
134
+ # KEY_Return
135
+ # KEY_Control_L
136
+ # KEY_Control_R
137
+ # KEY_s
138
+ @ctrl_pressed = false
139
+
140
+ @textbox.connect(SEL_KEYPRESS, method(:initEditKeys))
141
+
142
+ @textbox.connect(SEL_KEYRELEASE) do |sender, sel, event|
143
+ @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
144
+ false
145
+ end
146
+
147
+ end
148
+
149
+ def subscribe(event, &callback)
150
+ (@event_dispatcher_listeners[event] ||= []) << callback
151
+ end
152
+
153
+ def clearEvents(event)
154
+ @event_dispatcher_listener[event].clear
155
+ end
156
+
157
+ def empty?
158
+ @textbox.to_s.empty?
159
+ end
160
+
161
+ def clear
162
+ @textbox.setText('')
163
+ end
164
+
165
+ def setText(text=nil)
166
+ return false if text.nil?
167
+ if text.is_a? Array
168
+ new_text = text.join
169
+ else
170
+ new_text = "#{text}"
171
+ end
172
+
173
+ @lock.synchronize do
174
+ @text = new_text.strip.gsub(/\r/,'')
175
+
176
+ unless @text.empty?
177
+ @textbox.setText @text
178
+ end
179
+ end
180
+ # @textbox.handle(self, FXSEL(SEL_UPDATE, 0), nil)
181
+ #@textbox.update
182
+
183
+ end
184
+
185
+ def parseRequest(prefs={})
186
+ begin
187
+ return @textbox.to_request(prefs)
188
+ rescue SyntaxError, LocalJumpError, NameError
189
+ notify(:error, "#{$!}")
190
+ rescue => bang
191
+ puts bang
192
+ puts bang.backtrace if $DEBUG
193
+ notify(:error, "Could not parse request: #{$!}")
194
+ end
195
+
196
+ return nil
197
+ end
198
+
199
+ def to_response(prefs={})
200
+ begin
201
+ return @textbox.to_response(prefs)
202
+ rescue SyntaxError, LocalJumpError, NameError
203
+ # puts bang
204
+ # puts bang.backtrace if $DEBUG
205
+ notify(:error, "#{$!}")
206
+ rescue => bang
207
+ puts bang
208
+ notify(:error, "Could not parse request: #{$!}")
209
+ end
210
+
211
+ return nil
212
+ end
213
+
214
+ private
215
+
216
+ def recordedText
217
+ @textbox.extractText(@input_start, @input_len)
218
+ end
219
+
220
+ def applyFilter
221
+ pattern = @filter_text.text
222
+ @textbox.reset_text
223
+ @match_pos_label.textColor = 'grey'
224
+ @match_pos_label.text = "0/0"
225
+ return true if pattern == ''
226
+
227
+ @textbox.applyFilter(pattern)
228
+ if @textbox.numMatches > 0
229
+
230
+ @match_pos_label.text = "1/#{@textbox.numMatches}"
231
+ #@match_pos_label.enable
232
+ @match_pos_label.textColor = 'black'
233
+ @textbox.showMatch(0, :select_match => @auto_select_cbtn.checked? )
234
+ @nmatch_btn.enable
235
+ @pmatch_btn.enable
236
+ else
237
+ @nmatch_btn.disable
238
+ @pmatch_btn.disable
239
+ end
240
+ # puts "got #{matches.length} matches for pattern #{Regexp.quote(pattern)}"
241
+ end
242
+
243
+ def inputFieldHotkeyHandler(widget)
244
+ @ctrl_pressed = false
245
+
246
+ widget.connect(SEL_KEYPRESS) { |sender, sel, event|
247
+ # puts event.code
248
+ @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
249
+ # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
250
+ if event.code == KEY_Return
251
+ applyFilter()
252
+ @textbox.setFocus()
253
+ @textbox.setDefault()
254
+ @textbox.showMatch(0, :select_match => @auto_select_cbtn.checked? )
255
+ true # special handling of KEY_Return, because we don't want a linebreak in textbox.
256
+ end
257
+
258
+ if @ctrl_pressed
259
+ case event.code
260
+ when KEY_w
261
+ @textbox.textStyle ^= TEXT_WORDWRAP
262
+ when KEY_n
263
+ @textbox.showNextMatch()
264
+ addFilterHistory()
265
+ when KEY_N
266
+ @textbox.showPrevMatch()
267
+ addFilterHistory()
268
+ when KEY_r
269
+ @textbox.reset_filter()
270
+ end
271
+ end
272
+
273
+ if event.code == KEY_F1
274
+
275
+ unless event.moved?
276
+ FXMenuPane.new(self) do |menu_pane|
277
+ FXMenuCaption.new(menu_pane, "Hotkeys:")
278
+ FXMenuSeparator.new(menu_pane)
279
+ [ "<ctrl-r> - Reset Filter",
280
+ "<ctrl-n> - Goto Next",
281
+ "<ctrl-shift-n> - Goto Prev",
282
+ "<ctrl-w> - Switch Wordwrap"
283
+ ].each do |hk|
284
+ FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
285
+ end
286
+
287
+ menu_pane.create
288
+
289
+ menu_pane.popup(nil, event.root_x, event.root_y)
290
+ app.runModalWhileShown(menu_pane)
291
+ end
292
+
293
+ end
294
+ true
295
+ else
296
+ false
297
+ end
298
+ }
299
+
300
+ widget.connect(SEL_KEYRELEASE) { |sender, sel, event|
301
+ @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
302
+ false
303
+ }
304
+ end
305
+
306
+ def initEditKeys(sender, sel, event)
307
+ # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
308
+ if event.code == KEY_F1
309
+
310
+ unless event.moved?
311
+ FXMenuPane.new(self) do |menu_pane|
312
+ FXMenuCaption.new(menu_pane, "Hotkeys:")
313
+ FXMenuSeparator.new(menu_pane)
314
+ [ "<ctrl-r> - Reset Filter",
315
+ "<ctrl-n> - Goto Next",
316
+ "<ctrl-shift-n> - Goto Prev",
317
+ "<ctrl-w> - Switch Wordwrap",
318
+ "<ctrl-b> - Encode Base64",
319
+ "<ctrl-shift-b> - Decode Base64",
320
+ "<ctrl-u> - Encode URL",
321
+ "<ctrl-shift-u> - Decode URL",
322
+ ].each do |hk|
323
+ FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
324
+ end
325
+
326
+ menu_pane.create
327
+
328
+ menu_pane.popup(nil, event.root_x, event.root_y)
329
+ app.runModalWhileShown(menu_pane)
330
+ end
331
+
332
+ end
333
+ end
334
+
335
+ if @ctrl_pressed
336
+ return true if event.code == KEY_Control_L or event.code == KEY_Control_R
337
+ if event.code == KEY_Return
338
+ notify(:hotkey_ctrl_enter)
339
+ true # special handling of KEY_Return, because we don't want a linebreak in textbox.
340
+ else
341
+
342
+ case event.code
343
+ when KEY_w
344
+ @textbox.textStyle ^= TEXT_WORDWRAP
345
+ when KEY_n
346
+ @textbox.showNextMatch()
347
+ addFilterHistory()
348
+ when KEY_N
349
+ @textbox.showPrevMatch()
350
+ addFilterHistory()
351
+ when KEY_r
352
+ resetTextbox()
353
+ end
354
+
355
+ pos = @textbox.selStartPos
356
+ len = @textbox.selEndPos - pos
357
+
358
+ if len == 0 then
359
+ pos = @input_start
360
+ len = @input_len
361
+ end
362
+
363
+ unless len==0
364
+ text = @textbox.extractText(pos,len)
365
+ rptxt = case event.code
366
+ when KEY_u
367
+ CGI::escape(text).strip
368
+ when KEY_b
369
+ Base64.encode64(text).strip
370
+ when KEY_U
371
+ CGI::unescape(text).strip
372
+ when KEY_B
373
+ Base64.decode64(text).strip
374
+ else
375
+ text
376
+ end
377
+ @textbox.replaceText(pos, len, rptxt,false)
378
+ @textbox.setSelection(pos,rptxt.length)
379
+ end
380
+ false
381
+ end
382
+ else
383
+ @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
384
+ false
385
+ end
386
+ end
387
+
388
+ def addFilterHistory()
389
+ text = @filter_text.text
390
+ return true if text == ''
391
+ has_item = false
392
+ @filter_text.each do |item, data|
393
+ has_item = true if data == text
394
+ end
395
+ @filter_text.appendItem(text, text) unless has_item == true
396
+ @filter_text.numVisible = @filter_text.numItems
397
+ end
398
+
399
+ def resetTextbox()
400
+ @textbox.setPrintable(@text)
401
+ @textbox.reset_text
402
+ @match_pos_label.text = "0/0"
403
+ @match_pos_label.textColor = 'grey'
404
+ end
405
+
406
+ def notify(event, *args)
407
+ if @event_dispatcher_listeners[event]
408
+ @event_dispatcher_listeners[event].each do |m|
409
+ m.call(*args) if m.respond_to? :call
410
+ end
411
+ end
412
+ end
413
+
414
+ end
415
+
416
+ class InterceptorUI < FXTopWindow
417
+
418
+ include Responder
419
+ include Watobo
420
+ include Watobo::Interceptor
421
+ include Watobo::Gui::Icons
422
+ def execute
423
+ create
424
+ show(PLACEMENT_SCREEN)
425
+ # getApp().runModalFor(self)
426
+ end
427
+
428
+ # this method is obsolet! Use addRequest() instead
429
+ def modifyRequest(request, thread)
430
+ addRequest(request, thread)
431
+ end
432
+
433
+ # this method is obsolet! Use addResponse() instead
434
+ def modifyResponse(request, thread)
435
+ addResponse(request, thread)
436
+ end
437
+
438
+ def addRequest(request, thread)
439
+ puts "* [Interceptor] addRequest"
440
+
441
+ new_request = {
442
+ :request => request,
443
+ :thread => thread
444
+ }
445
+
446
+ @request_lock.synchronize do
447
+ # enable_buttons()
448
+ @request_queue << new_request
449
+
450
+ end
451
+
452
+ # enable_buttons()
453
+
454
+ end
455
+
456
+ def addResponse(response, thread)
457
+ response.extend Watobo::Mixin::Parser::Web10
458
+ response.extend Watobo::Mixin::Shaper::Web10
459
+
460
+ response.fixupContentLength()
461
+
462
+ # puts response
463
+
464
+ new_response = {
465
+ :response => response,
466
+ :thread => thread
467
+ }
468
+
469
+ @response_lock.synchronize do
470
+ @response_queue.push new_response
471
+
472
+ end
473
+ end
474
+
475
+ def initialize(owner, opts)
476
+ # Invoke base class initialize function first
477
+
478
+ super( owner, 'Interceptor', nil, nil, DECOR_ALL|DECOR_TITLE|DECOR_BORDER|DECOR_RESIZE, 0, 0, 600, 400, 0, 0, 0, 0, 0, 0)
479
+ self.connect(SEL_CLOSE, method(:onClose))
480
+ self.icon = ICON_INTERCEPTOR
481
+ #@interceptor = interceptor
482
+
483
+ @request_list = []
484
+ @response_list = []
485
+
486
+ @request_queue = []
487
+ @response_queue = []
488
+
489
+ @request_lock = Mutex.new
502
490
  @response_lock = Mutex.new
503
-
504
- # initial frame setup
505
- mr_splitter = FXSplitter.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_VERTICAL|SPLITTER_REVERSED|SPLITTER_TRACKING)
506
-
507
- top_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM,:height => 500)
508
- top_splitter = FXSplitter.new(top_frame, LAYOUT_FILL_X|SPLITTER_HORIZONTAL|LAYOUT_FILL_Y|SPLITTER_TRACKING)
509
-
510
- #log_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM,:height => 100)
511
-
512
- filter_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM)
513
- gbframe = FXGroupBox.new(filter_frame, "Intercept", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
514
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
515
- # FXLabel.new(filter_frame, "Intercept:" )
516
- @intercept_request = FXCheckButton.new(frame, "Requests", nil, 0,
517
- ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
518
- @intercept_request.connect(SEL_COMMAND, method(:onInterceptChanged))
519
-
520
- @intercept_response = FXCheckButton.new(frame, "Response", nil, 0,
521
- ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
522
- @intercept_response.connect(SEL_COMMAND, method(:onInterceptChanged))
523
- @filter_options_btn = FXButton.new(frame, "Options", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
524
- @filter_options_btn.connect(SEL_COMMAND, method(:onBtnFilterOptions))
525
491
 
526
- gbframe = FXGroupBox.new(filter_frame, "Rewrite", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
527
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
528
- #FXLabel.new(filter_frame, "Rewrite:" )
529
- @rewrite_request = FXCheckButton.new(frame, "Requests", nil, 0,
530
- ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
531
- @rewrite_request.connect(SEL_COMMAND, method(:onInterceptChanged))
532
-
533
- @rewrite_response = FXCheckButton.new(frame, "Response", nil, 0,
534
- ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
535
- @rewrite_response.connect(SEL_COMMAND, method(:onInterceptChanged))
536
-
537
- @rewrite_options_btn = FXButton.new(frame, "Options", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
538
- @rewrite_options_btn.connect(SEL_COMMAND){ open_rewrite_options_dialog }
492
+ @request_box_available = true
493
+ @response_box_available = true
494
+
495
+ # initial frame setup
496
+ mr_splitter = FXSplitter.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_VERTICAL|SPLITTER_REVERSED|SPLITTER_TRACKING)
497
+
498
+ top_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM,:height => 500)
499
+ top_splitter = FXSplitter.new(top_frame, LAYOUT_FILL_X|SPLITTER_HORIZONTAL|LAYOUT_FILL_Y|SPLITTER_TRACKING)
500
+
501
+ #log_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM,:height => 100)
502
+
503
+ filter_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM)
504
+ gbframe = FXGroupBox.new(filter_frame, "Intercept", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
505
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
506
+ # FXLabel.new(filter_frame, "Intercept:" )
507
+ @intercept_request = FXCheckButton.new(frame, "Requests", nil, 0,
508
+ ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
509
+ @intercept_request.connect(SEL_COMMAND, method(:onInterceptChanged))
510
+
511
+ @intercept_response = FXCheckButton.new(frame, "Response", nil, 0,
512
+ ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
513
+ @intercept_response.connect(SEL_COMMAND, method(:onInterceptChanged))
514
+ @filter_options_btn = FXButton.new(frame, "Options", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
515
+ @filter_options_btn.connect(SEL_COMMAND, method(:onBtnFilterOptions))
516
+
517
+ gbframe = FXGroupBox.new(filter_frame, "Rewrite", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
518
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
519
+ #FXLabel.new(filter_frame, "Rewrite:" )
520
+ @rewrite_request = FXCheckButton.new(frame, "Requests", nil, 0,
521
+ ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
522
+ @rewrite_request.connect(SEL_COMMAND, method(:onInterceptChanged))
523
+
524
+ @rewrite_response = FXCheckButton.new(frame, "Response", nil, 0,
525
+ ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
526
+ @rewrite_response.connect(SEL_COMMAND, method(:onInterceptChanged))
527
+
528
+ @rewrite_options_btn = FXButton.new(frame, "Options", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
529
+ @rewrite_options_btn.connect(SEL_COMMAND){ open_rewrite_options_dialog }
530
+
531
+ #@intercept_request.checkState = false
532
+ #@intercept_response.checkState = false
533
+ if Watobo::Interceptor.active?
534
+
535
+ @intercept_request.checkState = Watobo::Interceptor.intercept_requests?
536
+ @intercept_response.checkState = Watobo::Interceptor.intercept_requests?
537
+ end
538
+
539
+ view_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM)
540
+
541
+ @tabBook = FXTabBook.new(view_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
542
+
543
+ button_frame = FXHorizontalFrame.new(view_frame, LAYOUT_FILL_X)
544
+ @tabBook.connect(SEL_COMMAND) { |sender, sel, item|
545
+ case item
546
+ when 0
547
+ enable_buttons if @request_list.length > 0
548
+ when 1
549
+ enable_buttons if @response_list.length > 0
550
+ end
551
+
552
+ }
553
+ @request_tab = FXTabItem.new(@tabBook, "Request (0)", nil)
554
+ request_frame_outer = FXVerticalFrame.new(@tabBook, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED)
555
+ # request_frame = FXVerticalFrame.new(request_frame_outer, LAYOUT_FILL_X|LAYOUT_FILL_Y)
556
+
557
+ # @requestbox = Watobo::Gui::InterceptEditor.new(request_frame_outer, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
558
+ @requestbox = Watobo::Gui::RequestBuilder.new(request_frame_outer, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
559
+
560
+ @response_tab = FXTabItem.new(@tabBook, "Response (0)", nil)
561
+ response_frame_outer = FXVerticalFrame.new(@tabBook, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED)
562
+ #response_frame = FXVerticalFrame.new(response_frame_outer, LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding=>0)
563
+ # @responsebox = Watobo::Gui::RequestEditor.new(response_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y )
539
564
 
540
- #@intercept_request.checkState = false
541
- #@intercept_response.checkState = false
542
- if Watobo::Interceptor.active?
543
-
544
- @intercept_request.checkState = Watobo::Interceptor.intercept_requests?
545
- @intercept_response.checkState = Watobo::Interceptor.intercept_requests?
546
- end
547
-
548
- view_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM)
549
-
550
- @tabBook = FXTabBook.new(view_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
551
-
552
- button_frame = FXHorizontalFrame.new(view_frame, LAYOUT_FILL_X)
553
- @tabBook.connect(SEL_COMMAND) { |sender, sel, item|
554
- case item
555
- when 0
556
- enable_buttons if @request_list.length > 0
557
- when 1
558
- enable_buttons if @response_list.length > 0
559
- end
560
-
561
- }
562
- @request_tab = FXTabItem.new(@tabBook, "Request (0)", nil)
563
- request_frame_outer = FXVerticalFrame.new(@tabBook, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED)
564
- # request_frame = FXVerticalFrame.new(request_frame_outer, LAYOUT_FILL_X|LAYOUT_FILL_Y)
565
-
566
- @requestbox = Watobo::Gui::InterceptEditor.new(request_frame_outer, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
567
-
568
-
569
- @response_tab = FXTabItem.new(@tabBook, "Response (0)", nil)
570
- response_frame_outer = FXVerticalFrame.new(@tabBook, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED)
571
- #response_frame = FXVerticalFrame.new(response_frame_outer, LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding=>0)
572
- # @responsebox = Watobo::Gui::RequestEditor.new(response_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y )
573
- @responsebox = Watobo::Gui::InterceptEditor.new(response_frame_outer, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
574
- # @responsebox.editable = true
575
-
576
- @accept_button = FXButton.new(button_frame, "Accept", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
577
- @accept_button.connect(SEL_COMMAND, method(:onAcceptChanges))
578
-
579
- @discard_button = FXButton.new(button_frame, "Discard", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
580
- @discard_button.connect(SEL_COMMAND, method(:onDiscard))
581
-
582
- @drop_button = FXButton.new(button_frame, "Drop", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
583
- @drop_button.connect(SEL_COMMAND, method(:onDrop))
584
-
585
- # log_text_frame = FXVerticalFrame.new(log_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
586
- # @log_viewer = FXText.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
587
-
588
- disable_buttons()
589
-
590
- # start an update timer
591
- @update_timer = FXApp.instance.addTimeout( 50, :repeat => true) {
592
- @request_lock.synchronize do
593
- unless @request_queue.empty?
594
- @request_list.concat @request_queue
595
- @request_queue.clear
596
- @request_tab.text = "Request (#{@request_list.length})"
597
- end
598
-
599
- if @request_list.length > 0 and @requestbox.empty?
600
- @requestbox.setText @request_list.first[:request]
601
- end
602
-
603
- end
604
- @response_lock.synchronize do
605
- unless @response_queue.empty?
606
- @response_list.concat @response_queue
607
- @response_queue.clear
608
- @response_tab.text = "Response (#{@response_list.length})"
609
- end
610
-
611
- if @response_list.length > 0 and @responsebox.empty?
612
- @responsebox.setText @response_list.first[:response]
613
- end
614
-
565
+ #@responsebox = Watobo::Gui::InterceptEditor.new(response_frame_outer, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
566
+ @responsebox = Watobo::Gui::RequestBuilder.new(response_frame_outer, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
567
+ # @responsebox.editable = true
568
+
569
+ @accept_button = FXButton.new(button_frame, "Accept", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
570
+ @accept_button.connect(SEL_COMMAND, method(:onAcceptChanges))
571
+
572
+ @discard_button = FXButton.new(button_frame, "Discard", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
573
+ @discard_button.connect(SEL_COMMAND, method(:onDiscard))
574
+
575
+ @drop_button = FXButton.new(button_frame, "Drop", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_LEFT)
576
+ @drop_button.connect(SEL_COMMAND, method(:onDrop))
577
+
578
+ # log_text_frame = FXVerticalFrame.new(log_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
579
+ # @log_viewer = FXText.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
580
+
581
+ disable_buttons()
582
+
583
+ # start an update timer
584
+ @update_timer = FXApp.instance.addTimeout( 50, :repeat => true) {
585
+
586
+ @request_lock.synchronize do
587
+ unless @request_queue.empty?
588
+ @request_list.concat @request_queue
589
+ @request_queue.clear
590
+ @request_tab.text = "Request (#{@request_list.length})"
591
+ end
592
+
593
+ if @request_list.length > 0 and @request_box_available
594
+ @requestbox.setRequest @request_list.first[:request]
595
+ @request_box_available = false
596
+ end
597
+
615
598
  end
616
- update_buttons
617
- }
618
-
619
- end
620
-
621
- def releaseAll()
622
- # puts "* closing interceptor"
623
- # puts "* disable all interceptions"
624
- #@project.intercept_request = false
625
- #@project.intercept_response = false
626
- # puts "* release all interceptions ..."
627
- @request_list.each do |ir|
628
- ir[:thread].run
629
- end
630
- @response_list.each do |ir|
631
- ir[:thread].run
632
- end
633
-
634
- end
635
-
636
- private
637
-
638
- def onAcceptChanges(sender, sel, ptr)
639
- if @tabBook.current == 0 then
640
-
641
- begin
642
- @request_lock.synchronize do
643
- request = @request_list.first
644
- if not request.nil?
645
- request[:request].clear
646
- request[:request].concat @requestbox.parseRequest
599
+
600
+ @response_lock.synchronize do
601
+ unless @response_queue.empty?
602
+ @response_list.concat @response_queue
603
+ @response_queue.clear
604
+ @response_tab.text = "Response (#{@response_list.length})"
605
+ end
606
+
607
+ if @response_list.length > 0 and @response_box_available
608
+ # @responsebox.setText @response_list.first[:response]
609
+ @responsebox.setRequest @response_list.first[:response]
610
+ @response_box_available = false
611
+ end
612
+
613
+ end
614
+ update_buttons
615
+ }
616
+
617
+ end
618
+
619
+ def releaseAll()
620
+ # puts "* closing interceptor"
621
+ # puts "* disable all interceptions"
622
+ #@project.intercept_request = false
623
+ #@project.intercept_response = false
624
+ # puts "* release all interceptions ..."
625
+ @request_list.each do |ir|
626
+ ir[:thread].run
627
+ end
628
+ @response_list.each do |ir|
629
+ ir[:thread].run
630
+ end
631
+
632
+ end
633
+
634
+ private
635
+
636
+ def onAcceptChanges(sender, sel, ptr)
637
+ if @tabBook.current == 0 then
638
+
639
+ begin
640
+ @request_lock.synchronize do
641
+ request = @request_list.first
642
+ if not request.nil?
643
+ request[:request].clear
644
+ request[:request].concat @requestbox.parseRequest
647
645
  @requestbox.clear
648
- Watobo.print_debug( self.class.to_s, "release thread #{request[:thread]}")
649
- request[:thread].run
650
- @request_list.shift
651
- @request_tab.text = "Request (#{@request_list.length})"
652
- #getNextRequest()
653
- else
654
- puts "* [INTERCEPTOR] NOTHING TO RELEASE"
655
- end
656
- end
657
- rescue => bang
658
- puts "!!! Error"
659
- puts bang
660
- end
661
- else
662
- begin
663
- @response_lock.synchronize do
664
- response = @response_list.first
665
- if not response.nil?
666
- response[:response].clear
667
- new_response = @responsebox.to_response(:update_content_length => true)
668
- #puts new_response.class
669
- response[:response].concat new_response
670
- #puts new_response
671
- response[:thread].run
646
+ @request_box_available = true
647
+ Watobo.print_debug( self.class.to_s, "release thread #{request[:thread]}")
648
+ request[:thread].run
649
+ @request_list.shift
650
+ @request_tab.text = "Request (#{@request_list.length})"
651
+ #getNextRequest()
652
+ else
653
+ puts "* [INTERCEPTOR] NOTHING TO RELEASE"
654
+ end
655
+ end
656
+ rescue => bang
657
+ puts "!!! Error"
658
+ puts bang
659
+ end
660
+ else
661
+ begin
662
+ @response_lock.synchronize do
663
+ response = @response_list.first
664
+ if not response.nil?
665
+ response[:response].clear
666
+ #new_response = @responsebox.to_response(:update_content_length => true)
667
+ new_response = @responsebox.parseRequest
668
+ #puts new_response.class
669
+ response[:response].concat new_response
670
+ #puts new_response
671
+ response[:thread].run
672
672
  @responsebox.clear
673
- @response_list.shift
674
- @response_tab.text = "Response (#{@response_list.length})"
675
- # getNextResponse()
676
- end
677
- end
678
- rescue => bang
679
- puts "!!! Error"
680
- puts bang
681
- puts bang.backtrace
682
- end
683
- end
684
-
685
- end
686
-
687
- def onDrop(sender, sel, ptr)
688
- if @tabBook.current == 0 then
689
- @request_lock.synchronize do
690
- request = @request_list.first
691
- if request
692
- request[:request].clear
693
- request[:thread].kill
694
- @request_list.shift
673
+ @response_box_available = true
674
+ @response_list.shift
675
+ @response_tab.text = "Response (#{@response_list.length})"
676
+ # getNextResponse()
677
+ end
678
+ end
679
+ rescue => bang
680
+ puts "!!! Error"
681
+ puts bang
682
+ puts bang.backtrace
683
+ end
684
+ end
685
+
686
+ end
687
+
688
+ def onDrop(sender, sel, ptr)
689
+ if @tabBook.current == 0 then
690
+ @request_lock.synchronize do
691
+ request = @request_list.first
692
+ if request
693
+ request[:request].clear
694
+ request[:thread].kill
695
+ @request_list.shift
695
696
  @requestbox.clear
696
- end
697
- @request_tab.text = "Request (#{@request_list.length})"
698
- end
699
- #getNextRequest()
700
- else
701
- @response_lock.synchronize do
702
- response = @response_list.first
703
- if response
704
- response[:response].clear
705
- response[:thread].kill
706
- @response_list.shift
697
+ @request_box_available = true
698
+ end
699
+ @request_tab.text = "Request (#{@request_list.length})"
700
+ end
701
+ #getNextRequest()
702
+ else
703
+ @response_lock.synchronize do
704
+ response = @response_list.first
705
+ if response
706
+ response[:response].clear
707
+ response[:thread].kill
708
+ @response_list.shift
707
709
  @responsebox.clear
708
- end
709
- @response_tab.text = "Response (#{@response_list.length})"
710
- # getNextResponse()
711
- end
712
- end
713
- end
714
-
715
- def onDiscard(sender, sel, ptr)
716
- if @tabBook.current == 0 then
717
- @request_lock.synchronize do
718
- request = @request_list.first
719
- request[:thread].run if request
720
- @request_list.shift
710
+ @response_box_available = true
711
+ end
712
+ @response_tab.text = "Response (#{@response_list.length})"
713
+ # getNextResponse()
714
+ end
715
+ end
716
+ end
717
+
718
+ def onDiscard(sender, sel, ptr)
719
+ if @tabBook.current == 0 then
720
+ @request_lock.synchronize do
721
+ request = @request_list.first
722
+ request[:thread].run if request
723
+ @request_list.shift
721
724
  @requestbox.clear
722
- @request_tab.text = "Request (#{@request_list.length})"
723
-
724
- end
725
- #getNextRequest()
726
- else
727
- @response_lock.synchronize do
728
- response = @response_list.first
729
- response[:thread].run if response
730
- @response_list.shift
725
+ @request_box_available = true
726
+ @request_tab.text = "Request (#{@request_list.length})"
727
+
728
+ end
729
+ #getNextRequest()
730
+ else
731
+ @response_lock.synchronize do
732
+ response = @response_list.first
733
+ response[:thread].run if response
734
+ @response_list.shift
731
735
  @responsebox.clear
732
- @response_tab.text = "Response (#{@response_list.length})"
733
- #getNextResponse()
734
- end
735
- end
736
- end
737
-
738
- def onDiscardAll(sender, sel, ptr)
739
-
740
- end
741
-
742
- # def onHide
743
- # # puts "* hiding interceptor"
744
- # Watobo::Interceptor.intercept_mode = INTERCEPT_NONE
745
- # @mutex.synchronize {
746
- # @cv.signal
747
- # }
748
- # end
749
-
750
- def onClose(sender, sel, ptr)
751
- puts "* closing Interceptor UI"
752
- puts "+ stop intercepting"
753
- Watobo::Interceptor.intercept_mode = INTERCEPT_NONE
754
- Watobo::Interceptor.rewrite_mode = REWRITE_NONE
755
- puts "+ release all interceptions"
756
- releaseAll()
757
- #getApp().stopModal(self, 1)
758
- puts "_"
759
-
760
- self.hide()
761
- end
762
-
763
- def enable_buttons
764
- @accept_button.enabled = true
765
- @discard_button.enabled = true
766
- @drop_button.enabled = true
767
- end
768
-
769
- def disable_buttons
770
- @accept_button.enabled = false
771
- @discard_button.enabled = false
772
- @drop_button.enabled = false
773
- end
774
-
775
- def update_buttons
776
- if @tabBook.current == 0 then
777
- @request_lock.synchronize do
778
- if @request_list.length > 0
779
- enable_buttons
780
- else
781
- disable_buttons
782
- end
783
- end
784
-
785
- else
786
- @response_lock.synchronize do
787
- if @response_list.length > 0
788
- enable_buttons
789
- else
790
- disable_buttons
791
- end
792
- end
793
- end
794
- end
795
-
796
- def onBtnFilterOptions(sender, sel, ptr)
797
-
798
- dlg = Watobo::Gui::InterceptorFilterSettingsDialog.new( self,
799
- :request_filter_settings => Interceptor.proxy.getRequestFilter(),
800
- :response_filter_settings => Interceptor.proxy.getResponseFilter()
801
- )
802
- if dlg.execute != 0 then
803
- # TODO: Apply interceptor settings
804
- Interceptor.proxy.setRequestFilter(dlg.getRequestFilter)
805
- Interceptor.proxy.setResponseFilter(dlg.getResponseFilter)
806
- end
807
-
808
- end
809
-
810
- def open_rewrite_options_dialog
811
- dlg = Watobo::Gui::RewriteRulesDialog.new( self )
812
- if dlg.execute != 0 then
813
- # TODO: Apply interceptor settings
814
- Interceptor::RequestCarver.set_carving_rules dlg.request_rules
815
- Interceptor::ResponseCarver.set_carving_rules dlg.response_rules
816
- end
817
- end
818
-
819
- def onInterceptChanged(sender, sel, ptr)
820
- begin
821
- # unless @interceptor.nil? then
822
- mode = @intercept_response.checked? ? INTERCEPT_RESPONSE : 0
823
- mode |= @intercept_request.checked? ? INTERCEPT_REQUEST : 0
824
- #Watobo::Interceptor.intercept_mode = @intercept_response.checked? ? INTERCEPT_RESPONSE : 0
825
- # Watobo::Interceptor.intercept_mode |= @intercept_request.checked? ? INTERCEPT_REQUEST : 0
826
- #puts Watobo::Interceptor.intercept_mode
827
- # puts "New Proxy Mode: #{mode}"
828
- Watobo::Interceptor.intercept_mode = mode
829
-
830
- mode = @rewrite_request.checked? ? REWRITE_REQUEST : 0
831
- mode |= @rewrite_response.checked? ? REWRITE_RESPONSE : 0
832
- Watobo::Interceptor.rewrite_mode = mode
833
- # end
834
- rescue => bang
835
- puts bang
836
- puts bang.backtrace if $DEBUG
837
- end
838
- end
839
-
840
- end
841
-
842
- class InterceptorFilterSettingsDialog < FXDialogBox
843
-
844
- include Responder
845
- include Watobo::Interceptor
846
-
847
- def getRequestFilter()
848
- @request_filter
849
- end
850
-
851
- def getResponseFilter()
852
- @response_filter
853
- end
854
-
855
- def initialize(owner, settings = {} )
856
- super(owner, "Interceptor Settings", DECOR_ALL, :width => 300, :height => 425)
857
-
858
- @request_filter = { }
859
-
860
- @response_filter = { }
861
-
862
- @request_filter.update settings[:request_filter_settings]
863
- @response_filter.update settings[:response_filter_settings]
864
-
865
- FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
866
-
867
- base_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
868
- @tabbook = FXTabBook.new(base_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
869
- buttons_frame = FXHorizontalFrame.new(base_frame, :opts => LAYOUT_FILL_X)
870
- @req_opt_tab = FXTabItem.new(@tabbook, "Request Options", nil)
871
- frame = FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
872
- scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
873
- @req_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
874
-
875
- @resp_opt_tab = FXTabItem.new(@tabbook, "Response Options", nil)
876
- frame= FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
877
- scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
878
- @resp_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
879
-
880
- initRequestFilterFrame()
881
- updateRequestFilterFrame()
882
-
883
- initResponseFilterFrame()
884
- updateResponseFilterFrame()
885
-
886
- @finishButton = FXButton.new(buttons_frame, "Accept" , nil, nil, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
887
- @finishButton.enable
888
- @finishButton.connect(SEL_COMMAND) do |sender, sel, item|
889
- #self.handle(self, FXSEL(SEL_COMMAND, ID_CANCEL), nil)
890
- self.handle(self, FXSEL(SEL_COMMAND, ID_ACCEPT), nil)
891
- end
892
-
893
- @cancelButton = FXButton.new(buttons_frame, "Cancel" ,
894
- :target => self, :selector => FXDialogBox::ID_CANCEL,
895
- :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
896
- end
897
-
898
- private
899
-
900
- def onAccept(sender, sel, event)
901
- #TODO: Check if regex is valid
902
- @request_filter[:method_filter] = @method_filter_dt.value
903
- @request_filter[:negate_method_filter] = @neg_method_filter_cb.checked?
904
- @request_filter[:negate_url_filter] = @neg_url_filter_cb.checked?
905
- @request_filter[:url_filter] = @url_filter_dt.value
906
- @request_filter[:file_type_filter] = @ftype_filter_dt.value
907
- @request_filter[:negate_file_type_filter] = @neg_ftype_filter_cb.checked?
908
-
909
- @request_filter[:parms_filter] = @parms_filter_dt.value
910
- @request_filter[:negate_parms_filter] = @neg_parms_filter_cb.checked?
911
-
912
- @response_filter[:content_type_filter] = @content_type_filter_dt.value
913
- @response_filter[:negate_content_type_filter] = @neg_ctype_filter_cb.checked?
914
-
915
- @response_filter[:response_code_filter] = @rcode_filter_dt.value
916
- @response_filter[:negate_response_code_filter] = @neg_rcode_filter_cb.checked?
917
-
918
- getApp().stopModal(self, 1)
919
- self.hide()
920
- return 1
921
- end
922
-
923
- def updateRequestFilterFrame()
924
- @parms_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
925
- @url_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
926
- @ftype_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
927
- @method_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
928
- end
929
-
930
- def updateResponseFilterFrame()
931
- @content_type_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
932
- @rcode_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
933
- # @neg_rcode_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
934
- # @neg_ctype_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
935
- end
936
-
937
- def initResponseFilterFrame()
938
-
939
- gbframe = FXGroupBox.new(@resp_opt_frame, "Content Type", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
940
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
941
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
942
- fxtext.backColor = fxtext.parent.backColor
943
- fxtext.disable
944
- text = "Regular expression for HTTP Content-Type. E.g., '(text|script)'"
945
- fxtext.setText(text)
946
- @content_type_filter_dt = FXDataTarget.new('')
947
- @content_type_filter_dt.value = @response_filter[:content_type_filter]
948
- @content_type_filter = FXTextField.new(frame, 20, :target => @content_type_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
949
- @neg_ctype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
950
- #@neg_method_filter_cb.checkState = false
951
- @neg_ctype_filter_cb.checkState = @response_filter[:negate_content_type_filter]
952
-
953
- gbframe = FXGroupBox.new(@resp_opt_frame, "Response Code", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
954
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
955
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
956
- fxtext.backColor = fxtext.parent.backColor
957
- fxtext.disable
958
- text = "Regular expression for HTTP Content-Type. E.g., '200'"
959
- fxtext.setText(text)
960
- @rcode_filter_dt = FXDataTarget.new('')
961
- @rcode_filter_dt.value = @response_filter[:response_code_filter]
962
-
963
- @rcode_filter = FXTextField.new(frame, 20, :target => @rcode_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
964
- @neg_rcode_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
965
- #@neg_method_filter_cb.checkState = false
966
- @neg_rcode_filter_cb.checkState = @response_filter[:negate_response_code_filter]
967
-
968
- end
969
-
970
- def initRequestFilterFrame()
971
- gbframe = FXGroupBox.new(@req_opt_frame, "URL Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
972
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
973
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
974
- fxtext.backColor = fxtext.parent.backColor
975
- fxtext.disable
976
- text = "Regular Expression Filter For URL. E.g., '.*www.mysite.com.*login.php'"
977
- fxtext.setText(text)
978
-
979
- @url_filter_dt = FXDataTarget.new('')
980
- @url_filter_dt.value = @request_filter[:url_filter]
981
- @url_filter = FXTextField.new(frame, 20, :target => @url_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
982
- @neg_url_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
983
- #@neg_url_filter_cb.checkState = false
984
- @neg_url_filter_cb.checkState = @request_filter[:negate_url_filter]
985
-
986
- gbframe = FXGroupBox.new(@req_opt_frame, "Method Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
987
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
988
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
989
- fxtext.backColor = fxtext.parent.backColor
990
- fxtext.disable
991
- text = "Regular expression for HTTP method. E.g., '(get|PoSt)'"
992
- fxtext.setText(text)
993
- @method_filter_dt = FXDataTarget.new('')
994
- @method_filter_dt.value = @request_filter[:method_filter]
995
- @method_filter = FXTextField.new(frame, 20, :target => @method_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
996
- @neg_method_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
997
- #@neg_method_filter_cb.checkState = false
998
- @neg_method_filter_cb.checkState = @request_filter[:negate_method_filter]
999
-
1000
- gbframe = FXGroupBox.new(@req_opt_frame, "Parm Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
1001
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
1002
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
1003
- fxtext.backColor = fxtext.parent.backColor
1004
- fxtext.disable
1005
- text = "Regular Expression Filter For Parameter Names. E.g., for intercepting requests containing parameters beginning with 'act' use the regex pattern '^act.*' (without single quotes)"
1006
- fxtext.setText(text)
1007
- @parms_filter_dt = FXDataTarget.new('')
1008
- @parms_filter_dt.value = @request_filter[:parms_filter]
1009
- @parms_filter = FXTextField.new(frame, 20, :target => @parms_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
1010
- @neg_parms_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
1011
- #@neg_parm_filter_cb.checkState = false
1012
- @neg_parms_filter_cb.checkState = @request_filter[:negate_parms_filter]
1013
-
1014
- gbframe = FXGroupBox.new(@req_opt_frame, "File Type Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
1015
- frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
1016
- fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
1017
- fxtext.backColor = fxtext.parent.backColor
1018
- fxtext.disable
1019
- text = "Regular expression for file types by its extension. E.g., for intercepting requests where file type is PHP use '^php$' (without single quotes)"
1020
- fxtext.setText(text)
1021
- @ftype_filter_dt = FXDataTarget.new('')
1022
- @ftype_filter_dt.value = @request_filter[:file_type_filter]
1023
- @ftype_filter = FXTextField.new(frame, 20, :target => @ftype_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
1024
- @neg_ftype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
1025
- #@neg_parm_filter_cb.checkState = false
1026
- @neg_ftype_filter_cb.checkState = @request_filter[:negate_file_type_filter]
1027
- end
1028
- end
1029
- #
1030
- end
1031
- end
1032
-
1033
- if __FILE__ == $0
1034
- class TestGui < FXMainWindow
1035
- def initialize(app)
1036
- # Call base class initializer first
1037
- super(app, "Test Application", :width => 800, :height => 600)
1038
- frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE)
1039
- Watobo::Gui::InterceptorUI.new(frame, nil, nil)
1040
- end
1041
-
1042
- # Create and show the main window
1043
- def create
1044
- super # Create the windows
1045
- show(PLACEMENT_SCREEN) # Make the main window appear
1046
-
1047
- end
1048
- end
1049
- # application = FXApp.new('LayoutTester', 'FoxTest')
1050
- TestGui.new($application)
1051
- $application.create
1052
- $application.run
1053
- end
736
+ @response_box_available = true
737
+ @response_tab.text = "Response (#{@response_list.length})"
738
+ #getNextResponse()
739
+ end
740
+ end
741
+ end
742
+
743
+ def onDiscardAll(sender, sel, ptr)
744
+
745
+ end
746
+
747
+ # def onHide
748
+ # # puts "* hiding interceptor"
749
+ # Watobo::Interceptor.intercept_mode = INTERCEPT_NONE
750
+ # @mutex.synchronize {
751
+ # @cv.signal
752
+ # }
753
+ # end
754
+
755
+ def onClose(sender, sel, ptr)
756
+ puts "* closing Interceptor UI"
757
+ puts "+ stop intercepting"
758
+ Watobo::Interceptor.intercept_mode = INTERCEPT_NONE
759
+ Watobo::Interceptor.rewrite_mode = REWRITE_NONE
760
+ puts "+ release all interceptions"
761
+ releaseAll()
762
+ #getApp().stopModal(self, 1)
763
+ puts "_"
764
+
765
+ self.hide()
766
+ end
767
+
768
+ def enable_buttons
769
+ @accept_button.enabled = true
770
+ @discard_button.enabled = true
771
+ @drop_button.enabled = true
772
+ end
773
+
774
+ def disable_buttons
775
+ @accept_button.enabled = false
776
+ @discard_button.enabled = false
777
+ @drop_button.enabled = false
778
+ end
779
+
780
+ def update_buttons
781
+ if @tabBook.current == 0 then
782
+ @request_lock.synchronize do
783
+ if @request_list.length > 0
784
+ enable_buttons
785
+ else
786
+ disable_buttons
787
+ end
788
+ end
789
+
790
+ else
791
+ @response_lock.synchronize do
792
+ if @response_list.length > 0
793
+ enable_buttons
794
+ else
795
+ disable_buttons
796
+ end
797
+ end
798
+ end
799
+ end
800
+
801
+ def onBtnFilterOptions(sender, sel, ptr)
802
+
803
+ dlg = Watobo::Gui::InterceptorFilterSettingsDialog.new( self,
804
+ :request_filter_settings => Interceptor.proxy.getRequestFilter(),
805
+ :response_filter_settings => Interceptor.proxy.getResponseFilter()
806
+ )
807
+ if dlg.execute != 0 then
808
+ # TODO: Apply interceptor settings
809
+ Interceptor.proxy.setRequestFilter(dlg.getRequestFilter)
810
+ Interceptor.proxy.setResponseFilter(dlg.getResponseFilter)
811
+ end
812
+
813
+ end
814
+
815
+ def open_rewrite_options_dialog
816
+ dlg = Watobo::Gui::RewriteRulesDialog.new( self )
817
+ if dlg.execute != 0 then
818
+ # TODO: Apply interceptor settings
819
+ Interceptor::RequestCarver.set_carving_rules dlg.request_rules
820
+ Interceptor::ResponseCarver.set_carving_rules dlg.response_rules
821
+ end
822
+ end
823
+
824
+ def onInterceptChanged(sender, sel, ptr)
825
+ begin
826
+ # unless @interceptor.nil? then
827
+ mode = @intercept_response.checked? ? INTERCEPT_RESPONSE : 0
828
+ mode |= @intercept_request.checked? ? INTERCEPT_REQUEST : 0
829
+ #Watobo::Interceptor.intercept_mode = @intercept_response.checked? ? INTERCEPT_RESPONSE : 0
830
+ # Watobo::Interceptor.intercept_mode |= @intercept_request.checked? ? INTERCEPT_REQUEST : 0
831
+ #puts Watobo::Interceptor.intercept_mode
832
+ # puts "New Proxy Mode: #{mode}"
833
+ Watobo::Interceptor.intercept_mode = mode
834
+
835
+ mode = @rewrite_request.checked? ? REWRITE_REQUEST : 0
836
+ mode |= @rewrite_response.checked? ? REWRITE_RESPONSE : 0
837
+ Watobo::Interceptor.rewrite_mode = mode
838
+ # end
839
+ rescue => bang
840
+ puts bang
841
+ puts bang.backtrace if $DEBUG
842
+ end
843
+ end
844
+
845
+ end
846
+
847
+ class InterceptorFilterSettingsDialog < FXDialogBox
848
+
849
+ include Responder
850
+ include Watobo::Interceptor
851
+
852
+ def getRequestFilter()
853
+ @request_filter
854
+ end
855
+
856
+ def getResponseFilter()
857
+ @response_filter
858
+ end
859
+
860
+ def initialize(owner, settings = {} )
861
+ super(owner, "Interceptor Settings", DECOR_ALL, :width => 300, :height => 425)
862
+
863
+ @request_filter = { }
864
+
865
+ @response_filter = { }
866
+
867
+ @request_filter.update settings[:request_filter_settings]
868
+ @response_filter.update settings[:response_filter_settings]
869
+
870
+ FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
871
+
872
+ base_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
873
+ @tabbook = FXTabBook.new(base_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
874
+ buttons_frame = FXHorizontalFrame.new(base_frame, :opts => LAYOUT_FILL_X)
875
+ @req_opt_tab = FXTabItem.new(@tabbook, "Request Options", nil)
876
+ frame = FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
877
+ scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
878
+ @req_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
879
+
880
+ @resp_opt_tab = FXTabItem.new(@tabbook, "Response Options", nil)
881
+ frame= FXVerticalFrame.new(@tabbook, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
882
+ scroll_window = FXScrollWindow.new(frame, SCROLLERS_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y)
883
+ @resp_opt_frame = FXVerticalFrame.new(scroll_window, :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
884
+
885
+ initRequestFilterFrame()
886
+ updateRequestFilterFrame()
887
+
888
+ initResponseFilterFrame()
889
+ updateResponseFilterFrame()
890
+
891
+ @finishButton = FXButton.new(buttons_frame, "Accept" , nil, nil, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
892
+ @finishButton.enable
893
+ @finishButton.connect(SEL_COMMAND) do |sender, sel, item|
894
+ #self.handle(self, FXSEL(SEL_COMMAND, ID_CANCEL), nil)
895
+ self.handle(self, FXSEL(SEL_COMMAND, ID_ACCEPT), nil)
896
+ end
897
+
898
+ @cancelButton = FXButton.new(buttons_frame, "Cancel" ,
899
+ :target => self, :selector => FXDialogBox::ID_CANCEL,
900
+ :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
901
+ end
902
+
903
+ private
904
+
905
+ def onAccept(sender, sel, event)
906
+ #TODO: Check if regex is valid
907
+ @request_filter[:method_filter] = @method_filter_dt.value
908
+ @request_filter[:negate_method_filter] = @neg_method_filter_cb.checked?
909
+ @request_filter[:negate_url_filter] = @neg_url_filter_cb.checked?
910
+ @request_filter[:url_filter] = @url_filter_dt.value
911
+ @request_filter[:file_type_filter] = @ftype_filter_dt.value
912
+ @request_filter[:negate_file_type_filter] = @neg_ftype_filter_cb.checked?
913
+
914
+ @request_filter[:parms_filter] = @parms_filter_dt.value
915
+ @request_filter[:negate_parms_filter] = @neg_parms_filter_cb.checked?
916
+
917
+ @response_filter[:content_type_filter] = @content_type_filter_dt.value
918
+ @response_filter[:negate_content_type_filter] = @neg_ctype_filter_cb.checked?
919
+
920
+ @response_filter[:response_code_filter] = @rcode_filter_dt.value
921
+ @response_filter[:negate_response_code_filter] = @neg_rcode_filter_cb.checked?
922
+
923
+ getApp().stopModal(self, 1)
924
+ self.hide()
925
+ return 1
926
+ end
927
+
928
+ def updateRequestFilterFrame()
929
+ @parms_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
930
+ @url_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
931
+ @ftype_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
932
+ @method_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
933
+ end
934
+
935
+ def updateResponseFilterFrame()
936
+ @content_type_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
937
+ @rcode_filter.handle(self, FXSEL(SEL_UPDATE, 0), nil)
938
+ # @neg_rcode_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
939
+ # @neg_ctype_filter_cb.handle(self, FXSEL(SEL_UPDATE, 0), nil)
940
+ end
941
+
942
+ def initResponseFilterFrame()
943
+
944
+ gbframe = FXGroupBox.new(@resp_opt_frame, "Content Type", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
945
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
946
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
947
+ fxtext.backColor = fxtext.parent.backColor
948
+ fxtext.disable
949
+ text = "Regular expression for HTTP Content-Type. E.g., '(text|script)'"
950
+ fxtext.setText(text)
951
+ @content_type_filter_dt = FXDataTarget.new('')
952
+ @content_type_filter_dt.value = @response_filter[:content_type_filter]
953
+ @content_type_filter = FXTextField.new(frame, 20, :target => @content_type_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
954
+ @neg_ctype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
955
+ #@neg_method_filter_cb.checkState = false
956
+ @neg_ctype_filter_cb.checkState = @response_filter[:negate_content_type_filter]
957
+
958
+ gbframe = FXGroupBox.new(@resp_opt_frame, "Response Code", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
959
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
960
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
961
+ fxtext.backColor = fxtext.parent.backColor
962
+ fxtext.disable
963
+ text = "Regular expression for HTTP Content-Type. E.g., '200'"
964
+ fxtext.setText(text)
965
+ @rcode_filter_dt = FXDataTarget.new('')
966
+ @rcode_filter_dt.value = @response_filter[:response_code_filter]
967
+
968
+ @rcode_filter = FXTextField.new(frame, 20, :target => @rcode_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
969
+ @neg_rcode_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
970
+ #@neg_method_filter_cb.checkState = false
971
+ @neg_rcode_filter_cb.checkState = @response_filter[:negate_response_code_filter]
972
+
973
+ end
974
+
975
+ def initRequestFilterFrame()
976
+ gbframe = FXGroupBox.new(@req_opt_frame, "URL Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
977
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
978
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
979
+ fxtext.backColor = fxtext.parent.backColor
980
+ fxtext.disable
981
+ text = "Regular Expression Filter For URL. E.g., '.*www.mysite.com.*login.php'"
982
+ fxtext.setText(text)
983
+
984
+ @url_filter_dt = FXDataTarget.new('')
985
+ @url_filter_dt.value = @request_filter[:url_filter]
986
+ @url_filter = FXTextField.new(frame, 20, :target => @url_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
987
+ @neg_url_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
988
+ #@neg_url_filter_cb.checkState = false
989
+ @neg_url_filter_cb.checkState = @request_filter[:negate_url_filter]
990
+
991
+ gbframe = FXGroupBox.new(@req_opt_frame, "Method Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
992
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
993
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
994
+ fxtext.backColor = fxtext.parent.backColor
995
+ fxtext.disable
996
+ text = "Regular expression for HTTP method. E.g., '(get|PoSt)'"
997
+ fxtext.setText(text)
998
+ @method_filter_dt = FXDataTarget.new('')
999
+ @method_filter_dt.value = @request_filter[:method_filter]
1000
+ @method_filter = FXTextField.new(frame, 20, :target => @method_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
1001
+ @neg_method_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
1002
+ #@neg_method_filter_cb.checkState = false
1003
+ @neg_method_filter_cb.checkState = @request_filter[:negate_method_filter]
1004
+
1005
+ gbframe = FXGroupBox.new(@req_opt_frame, "Parm Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
1006
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
1007
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
1008
+ fxtext.backColor = fxtext.parent.backColor
1009
+ fxtext.disable
1010
+ text = "Regular Expression Filter For Parameter Names. E.g., for intercepting requests containing parameters beginning with 'act' use the regex pattern '^act.*' (without single quotes)"
1011
+ fxtext.setText(text)
1012
+ @parms_filter_dt = FXDataTarget.new('')
1013
+ @parms_filter_dt.value = @request_filter[:parms_filter]
1014
+ @parms_filter = FXTextField.new(frame, 20, :target => @parms_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
1015
+ @neg_parms_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
1016
+ #@neg_parm_filter_cb.checkState = false
1017
+ @neg_parms_filter_cb.checkState = @request_filter[:negate_parms_filter]
1018
+
1019
+ gbframe = FXGroupBox.new(@req_opt_frame, "File Type Filter", LAYOUT_SIDE_RIGHT|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
1020
+ frame = FXVerticalFrame.new(gbframe, :opts => LAYOUT_FILL_X, :padding => 0)
1021
+ fxtext = FXText.new(frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
1022
+ fxtext.backColor = fxtext.parent.backColor
1023
+ fxtext.disable
1024
+ text = "Regular expression for file types by its extension. E.g., for intercepting requests where file type is PHP use '^php$' (without single quotes)"
1025
+ fxtext.setText(text)
1026
+ @ftype_filter_dt = FXDataTarget.new('')
1027
+ @ftype_filter_dt.value = @request_filter[:file_type_filter]
1028
+ @ftype_filter = FXTextField.new(frame, 20, :target => @ftype_filter_dt, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X)
1029
+ @neg_ftype_filter_cb = FXCheckButton.new(frame, "Negate Filter", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
1030
+ #@neg_parm_filter_cb.checkState = false
1031
+ @neg_ftype_filter_cb.checkState = @request_filter[:negate_file_type_filter]
1032
+ end
1033
+ end
1034
+ #
1035
+ end
1036
+ end
1037
+
1038
+ if __FILE__ == $0
1039
+ class TestGui < FXMainWindow
1040
+ def initialize(app)
1041
+ # Call base class initializer first
1042
+ super(app, "Test Application", :width => 800, :height => 600)
1043
+ frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE)
1044
+ Watobo::Gui::InterceptorUI.new(frame, nil, nil)
1045
+ end
1046
+
1047
+ # Create and show the main window
1048
+ def create
1049
+ super # Create the windows
1050
+ show(PLACEMENT_SCREEN) # Make the main window appear
1051
+
1052
+ end
1053
+ end
1054
+ # application = FXApp.new('LayoutTester', 'FoxTest')
1055
+ TestGui.new($application)
1056
+ $application.create
1057
+ $application.run
1058
+ end