From 5e7e0a4c7ef326e34930d5cb1218e7abd985aa35 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Tue, 19 Jan 2021 02:06:14 -0800 Subject: [PATCH] fix: improve redirect behavior in protocol module (#26297) * fix: improve redirect behavior in protocol module * Add test for redirection Co-authored-by: Cheng Zhao --- .../net/electron_url_loader_factory.cc | 36 +++++++++++++------ spec-main/api-protocol-spec.ts | 20 +++++++++++ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/shell/browser/net/electron_url_loader_factory.cc b/shell/browser/net/electron_url_loader_factory.cc index c6a35d6ed5d8..fb79875b0036 100644 --- a/shell/browser/net/electron_url_loader_factory.cc +++ b/shell/browser/net/electron_url_loader_factory.cc @@ -17,6 +17,7 @@ #include "mojo/public/cpp/system/string_data_source.h" #include "net/base/filename_util.h" #include "net/http/http_status_code.h" +#include "net/url_request/redirect_util.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "shell/browser/api/electron_api_session.h" @@ -29,6 +30,7 @@ #include "shell/common/gin_converters/gurl_converter.h" #include "shell/common/gin_converters/net_converter.h" #include "shell/common/gin_converters/value_converter.h" +#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" #include "shell/common/node_includes.h" @@ -262,18 +264,30 @@ void ElectronURLLoaderFactory::StartLoading( // API in WebRequestProxyingURLLoaderFactory. std::string location; if (head->headers->IsRedirect(&location)) { - GURL new_location = GURL(location); - net::SiteForCookies new_site_for_cookies = - net::SiteForCookies::FromUrl(new_location); - network::ResourceRequest new_request = request; - new_request.url = new_location; - new_request.site_for_cookies = new_site_for_cookies; + // If the request is a MAIN_FRAME request, the first-party URL gets + // updated on redirects. + const net::RedirectInfo::FirstPartyURLPolicy first_party_url_policy = + request.resource_type == + static_cast(blink::mojom::ResourceType::kMainFrame) + ? net::RedirectInfo::FirstPartyURLPolicy::UPDATE_URL_ON_REDIRECT + : net::RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL; + + net::RedirectInfo redirect_info = net::RedirectInfo::ComputeRedirectInfo( + request.method, request.url, request.site_for_cookies, + first_party_url_policy, request.referrer_policy, + request.referrer.GetAsReferrer().spec(), head->headers->response_code(), + request.url.Resolve(location), + net::RedirectUtil::GetReferrerPolicyHeader(head->headers.get()), false); + + network::ResourceRequest new_request = request; + new_request.method = redirect_info.new_method; + new_request.url = redirect_info.new_url; + new_request.site_for_cookies = redirect_info.new_site_for_cookies; + new_request.referrer = GURL(redirect_info.new_referrer); + new_request.referrer_policy = redirect_info.new_referrer_policy; + + DCHECK(client.is_valid()); - net::RedirectInfo redirect_info; - redirect_info.status_code = head->headers->response_code(); - redirect_info.new_method = request.method; - redirect_info.new_url = new_location; - redirect_info.new_site_for_cookies = new_site_for_cookies; mojo::Remote client_remote( std::move(client)); diff --git a/spec-main/api-protocol-spec.ts b/spec-main/api-protocol-spec.ts index 5b65b1e78a8a..ddf086023a24 100644 --- a/spec-main/api-protocol-spec.ts +++ b/spec-main/api-protocol-spec.ts @@ -671,6 +671,26 @@ describe('protocol module', () => { const r = await ajax('http://fake-host'); expect(r.data).to.equal('redirect'); }); + + it('should discard post data after redirection', async () => { + interceptStreamProtocol('http', (request, callback) => { + if (request.url.indexOf('http://fake-host') === 0) { + setTimeout(() => { + callback({ + statusCode: 302, + headers: { + Location: 'http://fake-redirect' + } + }); + }, 300); + } else { + expect(request.url.indexOf('http://fake-redirect')).to.equal(0); + callback(getStream(3, request.method)); + } + }); + const r = await ajax('http://fake-host', { type: 'POST', data: postData }); + expect(r.data).to.equal('GET'); + }); }); describe('protocol.uninterceptProtocol', () => {