1 |
|
-module(chrme_session). |
2 |
|
-export([start/4, start_link/4, attach/4, await_start/1, stop/1]). |
3 |
|
|
4 |
|
-export_type([name/0, session/0]). |
5 |
|
-type name() :: chrme_ws_apic:name(). |
6 |
|
-type session() :: #{ |
7 |
|
name := name(), |
8 |
|
host := klsn:binstr(), |
9 |
|
port := integer(), |
10 |
|
target_id := klsn:binstr() |
11 |
|
}. |
12 |
|
|
13 |
|
%% Start a new Chrome debugging session by creating a new target and opening a WebSocket |
14 |
|
start(Name, Host, Port, Url) -> |
15 |
:-( |
start_(Name, Host, Port, Url, false). |
16 |
|
|
17 |
|
|
18 |
|
start_link(Name, Host, Port, Url) -> |
19 |
4 |
start_(Name, Host, Port, Url, true). |
20 |
|
|
21 |
|
start_(Name, Host, Port, Url, IsLink) -> |
22 |
4 |
case chrme_http_apic:new_target(Host, Port, Url) of |
23 |
|
{ok, TargetMap} -> |
24 |
4 |
Id = maps:get(<<"id">>, TargetMap), |
25 |
4 |
WsUrl = maps:get(<<"webSocketDebuggerUrl">>, TargetMap), |
26 |
4 |
{WsHost, WsPort, WsPath} = chrme_util:parse_ws_url(WsUrl), |
27 |
4 |
WsOpts = #{name => Name, host => WsHost, port => WsPort, uri => WsPath}, |
28 |
4 |
{ok, _Pid} = case IsLink of |
29 |
|
true -> |
30 |
4 |
chrme_ws_apic:start_link(WsOpts); |
31 |
|
false -> |
32 |
:-( |
chrme_ws_apic:start(WsOpts) |
33 |
|
end, |
34 |
4 |
{ok, #{name => Name, host => WsHost, port => WsPort, target_id => Id}}; |
35 |
|
Error -> |
36 |
:-( |
Error |
37 |
|
end. |
38 |
|
|
39 |
|
%% Attach to an existing debugging target by its ID |
40 |
|
-spec attach(name(), klsn:binstr(), integer(), klsn:binstr()) -> {ok, session()} | {error, term()}. |
41 |
|
attach(Name, Host, Port, TargetId) -> |
42 |
:-( |
case chrme_http_apic:list_targets(Host, Port) of |
43 |
|
{ok, Targets} -> |
44 |
:-( |
case [M || M <- Targets, maps:get(<<"id">>, M) =:= TargetId] of |
45 |
|
[TargetMap] -> |
46 |
:-( |
WsUrl = maps:get(<<"webSocketDebuggerUrl">>, TargetMap), |
47 |
:-( |
{WsHost, WsPort, WsPath} = chrme_util:parse_ws_url(WsUrl), |
48 |
:-( |
WsOpts = #{name => Name, host => WsHost, port => WsPort, uri => WsPath}, |
49 |
:-( |
{ok, _Pid} = chrme_ws_apic:start(WsOpts), |
50 |
:-( |
{ok, #{name => Name, host => WsHost, port => WsPort, target_id => TargetId}}; |
51 |
|
[] -> |
52 |
:-( |
{error, {no_such_target, TargetId}}; |
53 |
|
_ -> |
54 |
:-( |
{error, {ambiguous_targets, TargetId}} |
55 |
|
end; |
56 |
|
Error -> |
57 |
:-( |
Error |
58 |
|
end. |
59 |
|
|
60 |
|
-spec await_start(name()) -> ok. |
61 |
|
await_start(Name) -> |
62 |
18378 |
case chrme_ws_apic:is_connected(Name) of |
63 |
|
true -> |
64 |
4 |
ok; |
65 |
|
false -> |
66 |
18374 |
await_start(Name) |
67 |
|
end. |
68 |
|
|
69 |
|
%% Stop the debugging session, close WebSocket and target |
70 |
|
stop(#{name := Name, host := Host, port := Port, target_id := Id}) -> |
71 |
4 |
chrme_ws_apic:stop(Name), |
72 |
4 |
chrme_http_apic:close_target(Host, Port, Id), |
73 |
4 |
ok. |