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,68 @@ 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
+ 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
+
76
151
@ Override
77
152
public long addAuthenticationHandler (UsernameAndPassword usernameAndPassword ) {
78
153
return addAuthenticationHandler (url -> true , usernameAndPassword );
@@ -97,6 +172,24 @@ public void clearAuthenticationHandlers() {
97
172
authHandlers .clear ();
98
173
}
99
174
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
+
100
193
private class AuthDetails {
101
194
private final Predicate <URI > filter ;
102
195
private final UsernameAndPassword usernameAndPassword ;
@@ -114,4 +207,22 @@ public UsernameAndPassword getUsernameAndPassword() {
114
207
return usernameAndPassword ;
115
208
}
116
209
}
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
+ }
117
228
}
0 commit comments