From 4d855014adab3fddc997710ad805e5d6c0f1ac2f Mon Sep 17 00:00:00 2001 From: Robin Richtsfeld Date: Mon, 5 Jul 2021 01:31:18 +0200 Subject: [PATCH] fix(requestinterception): fix font loading issue --- .../Messaging/FetchRequestPausedResponse.cs | 2 + lib/PuppeteerSharp/NetworkManager.cs | 95 +++++++++++-------- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/lib/PuppeteerSharp/Messaging/FetchRequestPausedResponse.cs b/lib/PuppeteerSharp/Messaging/FetchRequestPausedResponse.cs index 71376252b..26c6ff1d4 100644 --- a/lib/PuppeteerSharp/Messaging/FetchRequestPausedResponse.cs +++ b/lib/PuppeteerSharp/Messaging/FetchRequestPausedResponse.cs @@ -4,6 +4,8 @@ internal class FetchRequestPausedResponse { public string RequestId { get; set; } + public Payload Request { get; set; } + public string NetworkId { get; set; } } } diff --git a/lib/PuppeteerSharp/NetworkManager.cs b/lib/PuppeteerSharp/NetworkManager.cs index f38b34564..c338a7902 100644 --- a/lib/PuppeteerSharp/NetworkManager.cs +++ b/lib/PuppeteerSharp/NetworkManager.cs @@ -15,11 +15,16 @@ internal class NetworkManager #region Private members private readonly CDPSession _client; - private readonly ConcurrentDictionary _requestIdToRequest = new ConcurrentDictionary(); + + private readonly ConcurrentDictionary _requestIdToRequest = + new ConcurrentDictionary(); + private readonly ConcurrentDictionary _requestIdToRequestWillBeSentEvent = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _requestIdToInterceptionId = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _requestIdToRequestPausedEvent = + new ConcurrentDictionary(); + private readonly ILogger _logger; private Dictionary _extraHTTPHeaders; private Credentials _credentials; @@ -142,7 +147,7 @@ internal Task SetRequestInterceptionAsync(bool value) private Task UpdateProtocolCacheDisabledAsync() => _client.SendAsync("Network.setCacheDisabled", new NetworkSetCacheDisabledRequest { - CacheDisabled = _userCacheDisabled || _userRequestInterceptionEnabled + CacheDisabled = _userCacheDisabled }); private async void Client_MessageReceived(object sender, MessageEventArgs e) @@ -190,12 +195,8 @@ private void OnLoadingFailed(LoadingFailedResponse e) { request.Failure = e.ErrorText; request.Response?.BodyLoadedTaskWrapper.TrySetResult(true); - _requestIdToRequest.TryRemove(request.RequestId, out _); - if (request.InterceptionId != null) - { - _attemptedAuthentications.Remove(request.InterceptionId); - } + ForgetRequest(request, true); RequestFailed?.Invoke(this, new RequestEventArgs { @@ -211,12 +212,8 @@ private void OnLoadingFinished(LoadingFinishedResponse e) if (_requestIdToRequest.TryGetValue(e.RequestId, out var request)) { request.Response?.BodyLoadedTaskWrapper.TrySetResult(true); - _requestIdToRequest.TryRemove(request.RequestId, out _); - if (request.InterceptionId != null) - { - _attemptedAuthentications.Remove(request.InterceptionId); - } + ForgetRequest(request, true); RequestFinished?.Invoke(this, new RequestEventArgs { @@ -225,6 +222,22 @@ private void OnLoadingFinished(LoadingFinishedResponse e) } } + private void ForgetRequest(Request request, bool events) + { + _requestIdToRequest.TryRemove(request.RequestId, out _); + + if (request.InterceptionId != null) + { + _attemptedAuthentications.Remove(request.InterceptionId); + } + + if (events) + { + _requestIdToRequestWillBeSentEvent.TryRemove(request.RequestId, out _); + _requestIdToRequestPausedEvent.TryRemove(request.RequestId, out _); + } + } + private void OnResponseReceived(ResponseReceivedResponse e) { // FileUpload sends a response without a matching request. @@ -296,16 +309,31 @@ private async Task OnRequestPausedAsync(FetchRequestPausedResponse e) var requestId = e.NetworkId; var interceptionId = e.RequestId; - if (!string.IsNullOrEmpty(requestId)) + if (string.IsNullOrEmpty(requestId)) { - if (_requestIdToRequestWillBeSentEvent.TryRemove(requestId, out var requestWillBeSentEvent)) - { - await OnRequestAsync(requestWillBeSentEvent, interceptionId).ConfigureAwait(false); - } - else - { - _requestIdToInterceptionId[requestId] = interceptionId; - } + return; + } + + var hasRequestWillBeSentEvent = _requestIdToRequestWillBeSentEvent.TryGetValue(requestId, out var requestWillBeSentEvent); + + // redirect requests have the same `requestId` + + if (hasRequestWillBeSentEvent && + (requestWillBeSentEvent.Request.Url != e.Request.Url || + requestWillBeSentEvent.Request.Method != e.Request.Method)) + { + _requestIdToRequestWillBeSentEvent.TryRemove(requestId, out _); + hasRequestWillBeSentEvent = false; + } + + if (hasRequestWillBeSentEvent) + { + await OnRequestAsync(requestWillBeSentEvent, interceptionId).ConfigureAwait(false); + _requestIdToRequestWillBeSentEvent.TryRemove(requestId, out _); + } + else + { + _requestIdToRequestPausedEvent[requestId] = e; } } @@ -365,15 +393,7 @@ private void HandleRequestRedirect(Request request, ResponsePayload responseMess response.BodyLoadedTaskWrapper.TrySetException( new PuppeteerException("Response body is unavailable for redirect responses")); - if (request.RequestId != null) - { - _requestIdToRequest.TryRemove(request.RequestId, out _); - } - - if (request.InterceptionId != null) - { - _attemptedAuthentications.Remove(request.InterceptionId); - } + ForgetRequest(request, false); Response?.Invoke(this, new ResponseCreatedEventArgs { @@ -391,15 +411,16 @@ private async Task OnRequestWillBeSentAsync(RequestWillBeSentPayload e) // Request interception doesn't happen for data URLs with Network Service. if (_userRequestInterceptionEnabled && !e.Request.Url.StartsWith("data:", StringComparison.InvariantCultureIgnoreCase)) { - if (_requestIdToInterceptionId.TryRemove(e.RequestId, out var interceptionId)) + var hasRequestPausedEvent = _requestIdToRequestPausedEvent.TryGetValue(e.RequestId, out var requestPausedEvent); + _requestIdToRequestWillBeSentEvent.TryAdd(e.RequestId, e); + + if (hasRequestPausedEvent) { + var interceptionId = requestPausedEvent.RequestId; await OnRequestAsync(e, interceptionId).ConfigureAwait(false); + _requestIdToRequestPausedEvent.TryRemove(e.RequestId, out _); } - else - { - // Under load, we may get to this section more than once - _requestIdToRequestWillBeSentEvent.TryAdd(e.RequestId, e); - } + return; } await OnRequestAsync(e, null).ConfigureAwait(false);