NAME
EV::WebKit::Control - drive a running EV::WebKit instance from another process
SYNOPSIS
use EV; use EV::WebKit; use EV::WebKit::Control;
my $b = EV::WebKit->new(chrome => 1, on_close => sub { EV::break });
my $ctl = EV::WebKit::Control->listen($b, path => "$ENV{XDG_RUNTIME_DIR}/evwk.sock");
EV::run;
Then, from anywhere else:
use v5.10; # for say()
use EV::WebKit::Client;
my $c = EV::WebKit::Client->connect("$ENV{XDG_RUNTIME_DIR}/evwk.sock");
$c->go('https://example.com');
say $c->title;
DESCRIPTION
An EV::WebKit instance can otherwise only be driven by the process that created it, which makes a visible browser window a dead end: you can watch it, but nothing can ask it anything. EV::WebKit::Control puts it on a unix socket.
The server is a plain consumer of EV::WebKit's public API -- it calls the same methods you would -- so it can do nothing to the browser that your own code could not.
Every request is answered. A malformed one -- an unknown method, a stale element handle, the wrong number of arguments, an argument the method itself rejects -- comes back as an error rather than silence, because a dropped request is a hung client, and that is the one failure mode this protocol must not have. Argument counts are checked against each method's real signature before dispatch, so a trailing null where a callback would go can never displace the server's own reply callback. Most methods refuse such a call outright; the few that take trailing key/value options absorb it as an option instead, and answer.
METHODS
listen
my $ctl = EV::WebKit::Control->listen($browser, path => $path);
Starts serving $browser on a unix socket at $path. Croaks if the containing directory is world-writable without the sticky bit, or if a live process already serves that path. A stale socket file left by a crashed process is removed.
path
The socket path.
close
Closes every client connection, stops listening, and removes the socket file. Idempotent, and run automatically on destruction.
SECURITY
Anyone who can connect to this socket can run arbitrary JavaScript in this browser and read every cookie it holds. That is what the tool is for.
The socket is therefore the authentication boundary: it is created mode 0600, and listen refuses a world-writable directory unless it is also sticky -- so /tmp is accepted. The sticky bit is what stops another user replacing your socket, and refusing /tmp outright would only push callers somewhere worse. There is deliberately no TCP listener -- that would turn a local privilege into a network-reachable one.
A client that stops reading is dropped once its unsent output passes 64 MiB. The page controls that volume -- console output is broadcast to every connected client -- so a suspended or wedged client could otherwise inflate the browser process until it died. Losing one backlogged client is the cheaper failure. The client side bounds what it buffers for the same reason -- see "Blocking mode (the default)" in EV::WebKit::Client.