watobo 0.9.21 → 0.9.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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