18
18
package org .openqa .selenium .remote ;
19
19
20
20
import java .net .URI ;
21
+ import java .util .ArrayList ;
22
+ import java .util .List ;
21
23
import java .util .Map ;
22
24
import java .util .Optional ;
23
25
import java .util .concurrent .ConcurrentHashMap ;
24
26
import java .util .concurrent .atomic .AtomicLong ;
25
27
import java .util .function .Predicate ;
28
+ import java .util .function .UnaryOperator ;
26
29
import org .openqa .selenium .Beta ;
27
30
import org .openqa .selenium .UsernameAndPassword ;
28
31
import org .openqa .selenium .WebDriver ;
29
32
import org .openqa .selenium .bidi .BiDi ;
30
33
import org .openqa .selenium .bidi .HasBiDi ;
31
34
import 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 ;
32
38
import 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 ;
33
43
34
44
@ Beta
35
45
class RemoteNetwork implements Network {
@@ -39,13 +49,16 @@ class RemoteNetwork implements Network {
39
49
40
50
private final Map <Long , AuthDetails > authHandlers = new ConcurrentHashMap <>();
41
51
52
+ private final Map <Long , RequestDetails > requestHandlers = new ConcurrentHashMap <>();
53
+
42
54
private final AtomicLong callBackId = new AtomicLong (1 );
43
55
44
56
public RemoteNetwork (WebDriver driver ) {
45
57
this .biDi = ((HasBiDi ) driver ).getBiDi ();
46
58
this .network = new org .openqa .selenium .bidi .module .Network (driver );
47
59
48
60
interceptAuthTraffic ();
61
+ interceptRequest ();
49
62
}
50
63
51
64
private void interceptAuthTraffic () {
@@ -73,6 +86,71 @@ private Optional<UsernameAndPassword> getAuthCredentials(URI uri) {
73
86
.findFirst ();
74
87
}
75
88
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
+
105
+ // Build the originalRequest object from the intercepted request details.
106
+ HttpRequest originalRequest =
107
+ new HttpRequest (
108
+ HttpMethod .getHttpMethod (interceptedRequest .getMethod ()),
109
+ interceptedRequest .getUrl ());
110
+
111
+ // Populate the headers of the original request.
112
+ interceptedRequest
113
+ .getHeaders ()
114
+ .forEach (
115
+ header ->
116
+ originalRequest .addHeader (header .getName (), header .getValue ().getValue ()));
117
+
118
+ HttpRequest modifiedRequest = requestHandler .get ().apply (originalRequest );
119
+
120
+ continueRequestParameters .method (modifiedRequest .getMethod ());
121
+
122
+ if (!uri .toString ().equals (modifiedRequest .getUri ())) {
123
+ continueRequestParameters .url (modifiedRequest .getUri ());
124
+ }
125
+
126
+ List <Header > headerList = new ArrayList <>();
127
+ modifiedRequest .forEachHeader (
128
+ (name , value ) ->
129
+ headerList .add (
130
+ new Header (name , new BytesValue (BytesValue .Type .STRING , value ))));
131
+
132
+ if (!headerList .isEmpty ()) {
133
+ continueRequestParameters .headers (headerList );
134
+ }
135
+
136
+ Contents .Supplier content = modifiedRequest .getContent ();
137
+
138
+ if (content .length () > 0 ) {
139
+ continueRequestParameters .body (
140
+ new BytesValue (BytesValue .Type .STRING , Contents .utf8String (content )));
141
+ }
142
+ }
143
+ network .continueRequest (continueRequestParameters );
144
+ });
145
+ }
146
+
147
+ private Optional <UnaryOperator <HttpRequest >> getRequestHandler (URI uri ) {
148
+ return requestHandlers .values ().stream ()
149
+ .filter (requestDetails -> requestDetails .getFilter ().test (uri ))
150
+ .map (RequestDetails ::getHandler )
151
+ .findFirst ();
152
+ }
153
+
76
154
@ Override
77
155
public long addAuthenticationHandler (UsernameAndPassword usernameAndPassword ) {
78
156
return addAuthenticationHandler (url -> true , usernameAndPassword );
@@ -97,6 +175,24 @@ public void clearAuthenticationHandlers() {
97
175
authHandlers .clear ();
98
176
}
99
177
178
+ @ Override
179
+ public long addRequestHandler (Predicate <URI > filter , UnaryOperator <HttpRequest > handler ) {
180
+ long id = this .callBackId .incrementAndGet ();
181
+
182
+ requestHandlers .put (id , new RequestDetails (filter , handler ));
183
+ return id ;
184
+ }
185
+
186
+ @ Override
187
+ public void removeRequestHandler (long id ) {
188
+ requestHandlers .remove (id );
189
+ }
190
+
191
+ @ Override
192
+ public void clearRequestHandlers () {
193
+ requestHandlers .clear ();
194
+ }
195
+
100
196
private class AuthDetails {
101
197
private final Predicate <URI > filter ;
102
198
private final UsernameAndPassword usernameAndPassword ;
@@ -114,4 +210,22 @@ public UsernameAndPassword getUsernameAndPassword() {
114
210
return usernameAndPassword ;
115
211
}
116
212
}
213
+
214
+ private class RequestDetails {
215
+ private final Predicate <URI > filter ;
216
+ private final UnaryOperator <HttpRequest > handler ;
217
+
218
+ public RequestDetails (Predicate <URI > filter , UnaryOperator <HttpRequest > handler ) {
219
+ this .filter = filter ;
220
+ this .handler = handler ;
221
+ }
222
+
223
+ public Predicate <URI > getFilter () {
224
+ return this .filter ;
225
+ }
226
+
227
+ public UnaryOperator <HttpRequest > getHandler () {
228
+ return this .handler ;
229
+ }
230
+ }
117
231
}
0 commit comments