diff options
Diffstat (limited to 'src/hydrilla/proxy/addon.py')
-rw-r--r-- | src/hydrilla/proxy/addon.py | 96 |
1 files changed, 81 insertions, 15 deletions
diff --git a/src/hydrilla/proxy/addon.py b/src/hydrilla/proxy/addon.py index 328d4a1..cca7924 100644 --- a/src/hydrilla/proxy/addon.py +++ b/src/hydrilla/proxy/addon.py @@ -48,6 +48,7 @@ from ..exceptions import HaketiloException from ..translations import smart_gettext as _ from ..url_patterns import parse_url, ParsedUrl from .state_impl import ConcreteHaketiloState +from . import state from . import policies from . import http_messages @@ -83,27 +84,47 @@ class MitmproxyHeadersWrapper(): return self.headers.items(multi=True) +class LoggerToMitmproxy(state.Logger): + def warn(self, msg: str) -> None: + ctx.log.warn(f'Haketilo: {msg}') + + @dc.dataclass(frozen=True) class FlowHandlingData: request_url: ParsedUrl policy: policies.Policy +@dc.dataclass +class PassedOptions: + haketilo_dir: t.Optional[str] = None + haketilo_listen_host: t.Optional[str] = None + haketilo_listen_port: t.Optional[int] = None + haketilo_launch_browser: t.Optional[bool] = None + + @property + def fully_configured(self) -> bool: + return (self.haketilo_dir is not None and + self.haketilo_listen_host is not None and + self.haketilo_listen_port is not None and + self.haketilo_launch_browser is not None) + + magical_mitm_it_url_reg = re.compile(r'^http://mitm.it(/.*)?$') dummy_url = parse_url('http://dummy.replacement.url') @dc.dataclass class HaketiloAddon: - """ - ....... - """ - configured: bool = False - configured_lock: Lock = dc.field(default_factory=Lock) + initial_options: PassedOptions = PassedOptions() + configured: bool = False + configured_lock: Lock = dc.field(default_factory=Lock) flows_data: dict[int, FlowHandlingData] = dc.field(default_factory=dict) flows_data_lock: Lock = dc.field(default_factory=Lock) + logger: LoggerToMitmproxy = dc.field(default_factory=LoggerToMitmproxy) + state: t.Optional[ConcreteHaketiloState] = None def load(self, loader: addonmanager.Loader) -> None: @@ -112,29 +133,74 @@ class HaketiloAddon: name = 'haketilo_dir', typespec = str, default = '~/.haketilo/', - help = "Point to a Haketilo data directory to use", + help = "Point to a Haketilo data directory to use" + ) + loader.add_option( + name = 'haketilo_listen_host', + typespec = str, + default = '127.0.0.1', + help = "Specify the address proxy listens on" + ) + loader.add_option( + name = 'haketilo_listen_port', + typespec = int, + default = 8080, + help = "Specify the port listens on" + ) + loader.add_option( + name = 'haketilo_launch_browser', + typespec = bool, + default = True, + help = "Specify whether to attempt to open a browser window with Haketilo page displayed inside" ) def configure(self, updated: set[str]) -> None: - """....""" - if 'haketilo_dir' not in updated: - return - with self.configured_lock: - if self.configured: - ctx.log.warn(_('haketilo_dir_already_configured')) + val_names = ('dir', 'listen_host', 'listen_port', 'launch_browser') + for val_name in val_names: + key = f'haketilo_{val_name}' + + if key not in updated: + continue + + if getattr(self.initial_options, key) is not None: + fmt = _('warn.proxy.setting_already_configured_{}') + self.logger.warn(fmt.format(key)) + continue + + new_val = getattr(ctx.options, key) + setattr(self.initial_options, key, new_val) + + if self.configured or not self.initial_options.fully_configured: return try: - haketilo_dir = Path(ctx.options.haketilo_dir) - - self.state = ConcreteHaketiloState.make(haketilo_dir / 'store') + haketilo_dir = self.initial_options.haketilo_dir + listen_host = self.initial_options.haketilo_listen_host + listen_port = self.initial_options.haketilo_listen_port + + self.state = ConcreteHaketiloState.make( + store_dir = Path(t.cast(str, haketilo_dir)) / 'store', + listen_host = t.cast(str, listen_host), + listen_port = t.cast(int, listen_port), + logger = self.logger + ) except Exception as e: tb.print_exception(None, e, e.__traceback__) sys.exit(1) self.configured = True + def running(self) -> None: + with self.configured_lock: + assert self.configured + + assert self.state is not None + + if self.initial_options.haketilo_launch_browser: + if not self.state.launch_browser(): + self.logger.warn(_('warn.proxy.couldnt_launch_browser')) + def get_handling_data(self, flow: http.HTTPFlow) -> FlowHandlingData: policy: policies.Policy |