aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy/addon.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/hydrilla/proxy/addon.py')
-rw-r--r--src/hydrilla/proxy/addon.py96
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