watobo 0.9.21 → 0.9.23

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