1818package  org .openqa .selenium .remote ;
1919
2020import  java .net .URI ;
21+ import  java .util .ArrayList ;
22+ import  java .util .List ;
2123import  java .util .Map ;
2224import  java .util .Optional ;
2325import  java .util .concurrent .ConcurrentHashMap ;
2426import  java .util .concurrent .atomic .AtomicLong ;
2527import  java .util .function .Predicate ;
28+ import  java .util .function .UnaryOperator ;
2629import  org .openqa .selenium .Beta ;
2730import  org .openqa .selenium .UsernameAndPassword ;
2831import  org .openqa .selenium .WebDriver ;
2932import  org .openqa .selenium .bidi .BiDi ;
3033import  org .openqa .selenium .bidi .HasBiDi ;
3134import  org .openqa .selenium .bidi .network .AddInterceptParameters ;
35+ import  org .openqa .selenium .bidi .network .BytesValue ;
36+ import  org .openqa .selenium .bidi .network .ContinueRequestParameters ;
37+ import  org .openqa .selenium .bidi .network .Header ;
3238import  org .openqa .selenium .bidi .network .InterceptPhase ;
39+ import  org .openqa .selenium .bidi .network .RequestData ;
40+ import  org .openqa .selenium .remote .http .Contents ;
41+ import  org .openqa .selenium .remote .http .HttpMethod ;
42+ import  org .openqa .selenium .remote .http .HttpRequest ;
3343
3444@ Beta 
3545class  RemoteNetwork  implements  Network  {
@@ -39,13 +49,16 @@ class RemoteNetwork implements Network {
3949
4050  private  final  Map <Long , AuthDetails > authHandlers  = new  ConcurrentHashMap <>();
4151
52+   private  final  Map <Long , RequestDetails > requestHandlers  = new  ConcurrentHashMap <>();
53+ 
4254  private  final  AtomicLong  callBackId  = new  AtomicLong (1 );
4355
4456  public  RemoteNetwork (WebDriver  driver ) {
4557    this .biDi  = ((HasBiDi ) driver ).getBiDi ();
4658    this .network  = new  org .openqa .selenium .bidi .module .Network (driver );
4759
4860    interceptAuthTraffic ();
61+     interceptRequest ();
4962  }
5063
5164  private  void  interceptAuthTraffic () {
@@ -73,6 +86,68 @@ private Optional<UsernameAndPassword> getAuthCredentials(URI uri) {
7386        .findFirst ();
7487  }
7588
89+   private  void  interceptRequest () {
90+     this .network .addIntercept (new  AddInterceptParameters (InterceptPhase .BEFORE_REQUEST_SENT ));
91+ 
92+     this .network .onBeforeRequestSent (
93+         beforeRequestSent  -> {
94+           String  requestId  = beforeRequestSent .getRequest ().getRequestId ();
95+           URI  uri  = URI .create (beforeRequestSent .getRequest ().getUrl ());
96+ 
97+           ContinueRequestParameters  continueRequestParameters  =
98+               new  ContinueRequestParameters (requestId );
99+ 
100+           Optional <UnaryOperator <HttpRequest >> requestHandler  = getRequestHandler (uri );
101+ 
102+           if  (requestHandler .isPresent ()) {
103+             RequestData  interceptedRequest  = beforeRequestSent .getRequest ();
104+             HttpRequest  originalRequest  =
105+                 new  HttpRequest (
106+                     HttpMethod .getHttpMethod (interceptedRequest .getMethod ()),
107+                     interceptedRequest .getUrl ());
108+ 
109+             interceptedRequest 
110+                 .getHeaders ()
111+                 .forEach (
112+                     header  ->
113+                         originalRequest .addHeader (header .getName (), header .getValue ().getValue ()));
114+ 
115+             HttpRequest  modifiedRequest  = requestHandler .get ().apply (originalRequest );
116+ 
117+             continueRequestParameters .method (modifiedRequest .getMethod ());
118+ 
119+             if  (!uri .toString ().equals (modifiedRequest .getUri ())) {
120+               continueRequestParameters .url (modifiedRequest .getUri ());
121+             }
122+ 
123+             List <Header > headerList  = new  ArrayList <>();
124+             modifiedRequest .forEachHeader (
125+                 (name , value ) ->
126+                     headerList .add (
127+                         new  Header (name , new  BytesValue (BytesValue .Type .STRING , value ))));
128+ 
129+             if  (!headerList .isEmpty ()) {
130+               continueRequestParameters .headers (headerList );
131+             }
132+ 
133+             Contents .Supplier  content  = modifiedRequest .getContent ();
134+ 
135+             if  (content .length () > 0 ) {
136+               continueRequestParameters .body (
137+                   new  BytesValue (BytesValue .Type .STRING , Contents .utf8String (content )));
138+             }
139+           }
140+           network .continueRequest (continueRequestParameters );
141+         });
142+   }
143+ 
144+   private  Optional <UnaryOperator <HttpRequest >> getRequestHandler (URI  uri ) {
145+     return  requestHandlers .values ().stream ()
146+         .filter (requestDetails  -> requestDetails .getFilter ().test (uri ))
147+         .map (RequestDetails ::getHandler )
148+         .findFirst ();
149+   }
150+ 
76151  @ Override 
77152  public  long  addAuthenticationHandler (UsernameAndPassword  usernameAndPassword ) {
78153    return  addAuthenticationHandler (url  -> true , usernameAndPassword );
@@ -97,6 +172,24 @@ public void clearAuthenticationHandlers() {
97172    authHandlers .clear ();
98173  }
99174
175+   @ Override 
176+   public  long  addRequestHandler (Predicate <URI > filter , UnaryOperator <HttpRequest > handler ) {
177+     long  id  = this .callBackId .incrementAndGet ();
178+ 
179+     requestHandlers .put (id , new  RequestDetails (filter , handler ));
180+     return  id ;
181+   }
182+ 
183+   @ Override 
184+   public  void  removeRequestHandler (long  id ) {
185+     requestHandlers .remove (id );
186+   }
187+ 
188+   @ Override 
189+   public  void  clearRequestHandlers () {
190+     requestHandlers .clear ();
191+   }
192+ 
100193  private  class  AuthDetails  {
101194    private  final  Predicate <URI > filter ;
102195    private  final  UsernameAndPassword  usernameAndPassword ;
@@ -114,4 +207,22 @@ public UsernameAndPassword getUsernameAndPassword() {
114207      return  usernameAndPassword ;
115208    }
116209  }
210+ 
211+   private  class  RequestDetails  {
212+     private  final  Predicate <URI > filter ;
213+     private  final  UnaryOperator <HttpRequest > handler ;
214+ 
215+     public  RequestDetails (Predicate <URI > filter , UnaryOperator <HttpRequest > handler ) {
216+       this .filter  = filter ;
217+       this .handler  = handler ;
218+     }
219+ 
220+     public  Predicate <URI > getFilter () {
221+       return  this .filter ;
222+     }
223+ 
224+     public  UnaryOperator <HttpRequest > getHandler () {
225+       return  this .handler ;
226+     }
227+   }
117228}
0 commit comments