How to use HandleRequestRedirect method of PuppeteerSharp.NetworkManager class

Best Puppeteer-sharp code snippet using PuppeteerSharp.NetworkManager.HandleRequestRedirect

Run Puppeteer-sharp automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

NetworkManager.cs

Source: NetworkManager.cs Github

copy
1using PuppeteerSharp.Helpers;
2using PuppeteerSharp.Helpers.Json;
3using PuppeteerSharp.Messaging;
4using System;
5using System.Collections.Concurrent;
6using System.Collections.Generic;
7using System.Threading.Tasks;
8
9namespace PuppeteerSharp
10{
11    internal class NetworkManager
12    {
13        #region Private members
14
15        private readonly CDPSession _client;
16        private readonly ConcurrentDictionary<string, Request> _requestIdToRequest = new ConcurrentDictionary<string, Request>();
17        private readonly ConcurrentDictionary<string, RequestWillBeSentPayload> _requestIdToRequestWillBeSentEvent =
18            new ConcurrentDictionary<string, RequestWillBeSentPayload>();
19        private readonly ConcurrentDictionary<string, string> _requestIdToInterceptionId = new ConcurrentDictionary<string, string>();
20        private Dictionary<string, string> _extraHTTPHeaders;
21        private bool _offine;
22        private Credentials _credentials;
23        private readonly List<string> _attemptedAuthentications = new List<string>();
24        private bool _userRequestInterceptionEnabled;
25        private bool _protocolRequestInterceptionEnabled;
26        private readonly bool _ignoreHTTPSErrors;
27        private bool _userCacheDisabled;
28        #endregion
29
30        internal NetworkManager(CDPSession client, bool ignoreHTTPSErrors, FrameManager frameManager)
31        {
32            FrameManager = frameManager;
33            _client = client;
34            _ignoreHTTPSErrors = ignoreHTTPSErrors;
35            _client.MessageReceived += Client_MessageReceived;
36        }
37
38        #region Public Properties
39        internal Dictionary<string, string> ExtraHTTPHeaders => _extraHTTPHeaders?.Clone();
40        internal event EventHandler<ResponseCreatedEventArgs> Response;
41        internal event EventHandler<RequestEventArgs> Request;
42        internal event EventHandler<RequestEventArgs> RequestFinished;
43        internal event EventHandler<RequestEventArgs> RequestFailed;
44        internal FrameManager FrameManager { get; set; }
45        #endregion
46
47        #region Public Methods
48
49        internal async Task InitializeAsync()
50        {
51            await _client.SendAsync("Network.enable").ConfigureAwait(false);
52            if (_ignoreHTTPSErrors)
53            {
54                await _client.SendAsync("Security.setIgnoreCertificateErrors", new SecuritySetIgnoreCertificateErrorsRequest
55                {
56                    Ignore = true
57                }).ConfigureAwait(false);
58            }
59        }
60
61        internal Task AuthenticateAsync(Credentials credentials)
62        {
63            _credentials = credentials;
64            return UpdateProtocolRequestInterceptionAsync();
65        }
66
67        internal Task SetExtraHTTPHeadersAsync(Dictionary<string, string> extraHTTPHeaders)
68        {
69            _extraHTTPHeaders = new Dictionary<string, string>();
70
71            foreach (var item in extraHTTPHeaders)
72            {
73                _extraHTTPHeaders[item.Key.ToLower()] = item.Value;
74            }
75            return _client.SendAsync("Network.setExtraHTTPHeaders", new NetworkSetExtraHTTPHeadersRequest
76            {
77                Headers = _extraHTTPHeaders
78            });
79        }
80
81        internal async Task SetOfflineModeAsync(bool value)
82        {
83            if (_offine != value)
84            {
85                _offine = value;
86
87                await _client.SendAsync("Network.emulateNetworkConditions", new NetworkEmulateNetworkConditionsRequest
88                {
89                    Offline = value,
90                    Latency = 0,
91                    DownloadThroughput = -1,
92                    UploadThroughput = -1
93                }).ConfigureAwait(false);
94            }
95        }
96
97        internal Task SetUserAgentAsync(string userAgent)
98            => _client.SendAsync("Network.setUserAgentOverride", new NetworkSetUserAgentOverrideRequest
99            {
100                UserAgent = userAgent
101            });
102
103        internal Task SetCacheEnabledAsync(bool enabled)
104        {
105            _userCacheDisabled = !enabled;
106            return UpdateProtocolCacheDisabledAsync();
107        }
108
109        internal Task SetRequestInterceptionAsync(bool value)
110        {
111            _userRequestInterceptionEnabled = value;
112            return UpdateProtocolRequestInterceptionAsync();
113        }
114
115        #endregion
116
117        #region Private Methods
118
119        private Task UpdateProtocolCacheDisabledAsync()
120            => _client.SendAsync("Network.setCacheDisabled", new NetworkSetCacheDisabledRequest
121            {
122                CacheDisabled = _userCacheDisabled || _protocolRequestInterceptionEnabled
123            });
124
125        private async void Client_MessageReceived(object sender, MessageEventArgs e)
126        {
127            try
128            {
129                switch (e.MessageID)
130                {
131                    case "Fetch.requestPaused":
132                        await OnRequestPausedAsync(e.MessageData.ToObject<FetchRequestPausedResponse>(true)).ConfigureAwait(false);
133                        break;
134                    case "Fetch.authRequired":
135                        await OnAuthRequiredAsync(e.MessageData.ToObject<FetchAuthRequiredResponse>(true)).ConfigureAwait(false);
136                        break;
137                    case "Network.requestWillBeSent":
138                        await OnRequestWillBeSentAsync(e.MessageData.ToObject<RequestWillBeSentPayload>(true)).ConfigureAwait(false);
139                        break;
140                    case "Network.requestServedFromCache":
141                        OnRequestServedFromCache(e.MessageData.ToObject<RequestServedFromCacheResponse>(true));
142                        break;
143                    case "Network.responseReceived":
144                        OnResponseReceived(e.MessageData.ToObject<ResponseReceivedResponse>(true));
145                        break;
146                    case "Network.loadingFinished":
147                        OnLoadingFinished(e.MessageData.ToObject<LoadingFinishedResponse>(true));
148                        break;
149                    case "Network.loadingFailed":
150                        OnLoadingFailed(e.MessageData.ToObject<LoadingFailedResponse>(true));
151                        break;
152                }
153            }
154            catch (Exception ex)
155            {
156                var message = $"NetworkManager failed to process {e.MessageID}. {ex.Message}. {ex.StackTrace}";
157                _client.Close(message);
158            }
159        }
160
161        private void OnLoadingFailed(LoadingFailedResponse e)
162        {
163            // For certain requestIds we never receive requestWillBeSent event.
164            // @see https://crbug.com/750469
165            if (_requestIdToRequest.TryGetValue(e.RequestId, out var request))
166            {
167                request.Failure = e.ErrorText;
168                request.Response?.BodyLoadedTaskWrapper.TrySetResult(true);
169                _requestIdToRequest.TryRemove(request.RequestId, out _);
170
171                if (request.InterceptionId != null)
172                {
173                    _attemptedAuthentications.Remove(request.InterceptionId);
174                }
175
176                RequestFailed?.Invoke(this, new RequestEventArgs
177                {
178                    Request = request
179                });
180            }
181        }
182
183        private void OnLoadingFinished(LoadingFinishedResponse e)
184        {
185            // For certain requestIds we never receive requestWillBeSent event.
186            // @see https://crbug.com/750469
187            if (_requestIdToRequest.TryGetValue(e.RequestId, out var request))
188            {
189                request.Response?.BodyLoadedTaskWrapper.TrySetResult(true);
190                _requestIdToRequest.TryRemove(request.RequestId, out _);
191
192                if (request.InterceptionId != null)
193                {
194                    _attemptedAuthentications.Remove(request.InterceptionId);
195                }
196
197                RequestFinished?.Invoke(this, new RequestEventArgs
198                {
199                    Request = request
200                });
201            }
202        }
203
204        private void OnResponseReceived(ResponseReceivedResponse e)
205        {
206            // FileUpload sends a response without a matching request.
207            if (_requestIdToRequest.TryGetValue(e.RequestId, out var request))
208            {
209                var response = new Response(
210                    _client,
211                    request,
212                    e.Response);
213
214                request.Response = response;
215
216                Response?.Invoke(this, new ResponseCreatedEventArgs
217                {
218                    Response = response
219                });
220            }
221        }
222
223        private async Task OnAuthRequiredAsync(FetchAuthRequiredResponse e)
224        {
225            var response = "Default";
226            if (_attemptedAuthentications.Contains(e.RequestId))
227            {
228                response = "CancelAuth";
229            }
230            else if (_credentials != null)
231            {
232                response = "ProvideCredentials";
233                _attemptedAuthentications.Add(e.RequestId);
234            }
235            var credentials = _credentials ?? new Credentials();
236            try
237            {
238                await _client.SendAsync("Fetch.continueWithAuth", new ContinueWithAuthRequest
239                {
240                    RequestId = e.RequestId,
241                    AuthChallengeResponse = new ContinueWithAuthRequestChallengeResponse
242                    {
243                        Response = response,
244                        Username = credentials.Username,
245                        Password = credentials.Password
246                    }
247                }).ConfigureAwait(false);
248            }
249            catch { }
250        }
251
252        private async Task OnRequestPausedAsync(FetchRequestPausedResponse e)
253        {
254            if (!_userRequestInterceptionEnabled && _protocolRequestInterceptionEnabled)
255            {
256                try
257                {
258                    await _client.SendAsync("Fetch.continueRequest", new FetchContinueRequestRequest
259                    {
260                        RequestId = e.RequestId
261                    }).ConfigureAwait(false);
262                }
263                catch { }
264            }
265
266            var requestId = e.NetworkId;
267            var interceptionId = e.RequestId;
268
269            if (!string.IsNullOrEmpty(requestId))
270            {
271                if (_requestIdToRequestWillBeSentEvent.TryRemove(requestId, out var requestWillBeSentEvent))
272                {
273                    await OnRequestAsync(requestWillBeSentEvent, interceptionId).ConfigureAwait(false);
274                }
275                else
276                {
277                    _requestIdToInterceptionId[requestId] = interceptionId;
278                }
279            }
280        }
281
282        private async Task OnRequestAsync(RequestWillBeSentPayload e, string interceptionId)
283        {
284            Request request;
285            var redirectChain = new List<Request>();
286            if (e.RedirectResponse != null)
287            {
288                _requestIdToRequest.TryGetValue(e.RequestId, out request);
289                // If we connect late to the target, we could have missed the requestWillBeSent event.
290                if (request != null)
291                {
292                    HandleRequestRedirect(request, e.RedirectResponse);
293                    redirectChain = request.RedirectChainList;
294                }
295            }
296            if (!_requestIdToRequest.TryGetValue(e.RequestId, out var currentRequest) ||
297              currentRequest.Frame == null)
298            {
299                var frame = !string.IsNullOrEmpty(e.FrameId) ? await FrameManager.TryGetFrameAsync(e.FrameId).ConfigureAwait(false) : null;
300
301                request = new Request(
302                    _client,
303                    frame,
304                    interceptionId,
305                    _userRequestInterceptionEnabled,
306                    e,
307                    redirectChain);
308
309                _requestIdToRequest[e.RequestId] = request;
310
311                Request?.Invoke(this, new RequestEventArgs
312                {
313                    Request = request
314                });
315            }
316        }
317
318        private void OnRequestServedFromCache(RequestServedFromCacheResponse response)
319        {
320            if (_requestIdToRequest.TryGetValue(response.RequestId, out var request))
321            {
322                request.FromMemoryCache = true;
323            }
324        }
325
326        private void HandleRequestRedirect(Request request, ResponsePayload responseMessage)
327        {
328            var response = new Response(
329                _client,
330                request,
331                responseMessage);
332
333            request.Response = response;
334            request.RedirectChainList.Add(request);
335            response.BodyLoadedTaskWrapper.TrySetException(
336                new PuppeteerException("Response body is unavailable for redirect responses"));
337
338            if (request.RequestId != null)
339            {
340                _requestIdToRequest.TryRemove(request.RequestId, out _);
341            }
342
343            if (request.InterceptionId != null)
344            {
345                _attemptedAuthentications.Remove(request.InterceptionId);
346            }
347
348            Response?.Invoke(this, new ResponseCreatedEventArgs
349            {
350                Response = response
351            });
352
353            RequestFinished?.Invoke(this, new RequestEventArgs
354            {
355                Request = request
356            });
357        }
358
359        private async Task OnRequestWillBeSentAsync(RequestWillBeSentPayload e)
360        {
361            // Request interception doesn't happen for data URLs with Network Service.
362            if (_protocolRequestInterceptionEnabled && !e.Request.Url.StartsWith("data:", StringComparison.InvariantCultureIgnoreCase))
363            {
364                if (_requestIdToInterceptionId.TryRemove(e.RequestId, out string interceptionId))
365                {
366                    await OnRequestAsync(e, interceptionId).ConfigureAwait(false);
367                }
368                else
369                {
370                    // Under load, we may get to this section more than once
371                    _requestIdToRequestWillBeSentEvent.TryAdd(e.RequestId, e);
372                }
373                return;
374            }
375            await OnRequestAsync(e, null).ConfigureAwait(false);
376        }
377
378        private async Task UpdateProtocolRequestInterceptionAsync()
379        {
380            var enabled = _userRequestInterceptionEnabled || _credentials != null;
381
382            if (enabled == _protocolRequestInterceptionEnabled)
383            {
384                return;
385            }
386            _protocolRequestInterceptionEnabled = enabled;
387            if (enabled)
388            {
389                await Task.WhenAll(
390                    UpdateProtocolCacheDisabledAsync(),
391                    _client.SendAsync("Fetch.enable", new FetchEnableRequest
392                    {
393                        HandleAuthRequests = true,
394                        Patterns = new[] { new FetchEnableRequest.Pattern { UrlPattern = "*" } }
395                    })
396                ).ConfigureAwait(false);
397            }
398            else
399            {
400                await Task.WhenAll(
401                    UpdateProtocolCacheDisabledAsync(),
402                    _client.SendAsync("Fetch.disable")
403                ).ConfigureAwait(false);
404            }
405        }
406
407        #endregion
408    }
409}
410
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Trigger HandleRequestRedirect code on LambdaTest Cloud Grid

Execute automation tests with HandleRequestRedirect on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)