1717
1818package org .openqa .selenium .grid .node ;
1919
20+ import static org .openqa .selenium .internal .Debug .getDebugLogLevel ;
21+ import static org .openqa .selenium .remote .http .HttpMethod .GET ;
22+
2023import com .google .common .collect .ImmutableSet ;
2124
2225import org .openqa .selenium .Capabilities ;
4144import java .util .function .Consumer ;
4245import java .util .logging .Level ;
4346import java .util .logging .Logger ;
44-
45- import static org .openqa .selenium .internal .Debug .getDebugLogLevel ;
46- import static org .openqa .selenium .remote .http .HttpMethod .GET ;
47+ import java .util .stream .Stream ;
4748
4849public class ProxyNodeWebsockets implements BiFunction <String , Consumer <Message >,
4950 Optional <Consumer <Message >>> {
5051
5152 private static final UrlTemplate CDP_TEMPLATE = new UrlTemplate ("/session/{sessionId}/se/cdp" );
53+ private static final UrlTemplate FWD_TEMPLATE = new UrlTemplate ("/session/{sessionId}/se/fwd" );
5254 private static final UrlTemplate VNC_TEMPLATE = new UrlTemplate ("/session/{sessionId}/se/vnc" );
5355 private static final Logger LOG = Logger .getLogger (ProxyNodeWebsockets .class .getName ());
5456 private static final ImmutableSet <String > CDP_ENDPOINT_CAPS =
@@ -66,16 +68,20 @@ public ProxyNodeWebsockets(HttpClient.Factory clientFactory, Node node) {
6668
6769 @ Override
6870 public Optional <Consumer <Message >> apply (String uri , Consumer <Message > downstream ) {
71+ UrlTemplate .Match fwdMatch = FWD_TEMPLATE .match (uri );
6972 UrlTemplate .Match cdpMatch = CDP_TEMPLATE .match (uri );
7073 UrlTemplate .Match vncMatch = VNC_TEMPLATE .match (uri );
7174
72- if (cdpMatch == null && vncMatch == null ) {
75+ if (cdpMatch == null && vncMatch == null && fwdMatch == null ) {
7376 return Optional .empty ();
7477 }
7578
76- String sessionId = cdpMatch != null ?
77- cdpMatch .getParameters ().get ("sessionId" ) :
78- vncMatch .getParameters ().get ("sessionId" );
79+ String sessionId = Stream .of (fwdMatch , cdpMatch , vncMatch )
80+ .filter (Objects ::nonNull )
81+ .findFirst ()
82+ .get ()
83+ .getParameters ()
84+ .get ("sessionId" );
7985
8086 LOG .fine ("Matching websockets for session id: " + sessionId );
8187 SessionId id = new SessionId (sessionId );
@@ -89,10 +95,20 @@ public Optional<Consumer<Message>> apply(String uri, Consumer<Message> downstrea
8995 Capabilities caps = session .getCapabilities ();
9096 LOG .fine ("Scanning for endpoint: " + caps );
9197
92- if (cdpMatch != null ) {
98+ if (vncMatch != null ) {
99+ return findVncEndpoint (downstream , caps );
100+ }
101+
102+ // This match happens when a user wants to do CDP over Dynamic Grid
103+ if (fwdMatch != null ) {
104+ LOG .info ("Matched endpoint where CDP connection is being forwarded" );
93105 return findCdpEndpoint (downstream , caps );
94106 }
95- return findVncEndpoint (downstream , caps );
107+ if (caps .getCapabilityNames ().contains ("se:forwardCdp" )) {
108+ LOG .info ("Found endpoint where CDP connection needs to be forwarded" );
109+ return findForwardCdpEndpoint (downstream , caps );
110+ }
111+ return findCdpEndpoint (downstream , caps );
96112 }
97113
98114 private Optional <Consumer <Message >> findCdpEndpoint (Consumer <Message > downstream ,
@@ -109,6 +125,18 @@ private Optional<Consumer<Message>> findCdpEndpoint(Consumer<Message> downstream
109125 return Optional .empty ();
110126 }
111127
128+ private Optional <Consumer <Message >> findForwardCdpEndpoint (Consumer <Message > downstream ,
129+ Capabilities caps ) {
130+ // When using Dynamic Grid, we need to connect to a container before using the debuggerAddress
131+ try {
132+ URI uri = new URI (String .valueOf (caps .getCapability ("se:forwardCdp" )));
133+ return Optional .of (uri ).map (cdp -> createWsEndPoint (cdp , downstream ));
134+ } catch (URISyntaxException e ) {
135+ LOG .warning ("Unable to create URI from: " + caps .getCapability ("se:forwardCdp" ));
136+ return Optional .empty ();
137+ }
138+ }
139+
112140 private Optional <Consumer <Message >> findVncEndpoint (Consumer <Message > downstream ,
113141 Capabilities caps ) {
114142 String vncLocalAddress = (String ) caps .getCapability ("se:vncLocalAddress" );
0 commit comments