diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-04-19 16:01:24 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-06-12 11:46:14 +0000 |
commit | 7b3570a96210d7f08453903be503eb33d43e495c (patch) | |
tree | 03e8775a94dddecbfb2b870990bdd191f96d46d0 /src | |
parent | ba4314a4392ac0e86b7d7b47bf5ef01035628db2 (diff) |
Apply url request interceptor on websocket connect as well
Try to match the types as best as we can, and handle the responses.
Pick-to: 6.4
Fixes: QTBUG-92932
Change-Id: I01bc85668d2540b79fd2a52796f99d05f161e8a5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/api/qwebengineurlrequestinfo.cpp | 1 | ||||
-rw-r--r-- | src/core/api/qwebengineurlrequestinfo.h | 3 | ||||
-rw-r--r-- | src/core/content_browser_client_qt.cpp | 71 | ||||
-rw-r--r-- | src/core/content_browser_client_qt.h | 8 |
4 files changed, 83 insertions, 0 deletions
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp index 10661ec8f..ded836d6b 100644 --- a/src/core/api/qwebengineurlrequestinfo.cpp +++ b/src/core/api/qwebengineurlrequestinfo.cpp @@ -181,6 +181,7 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPriva \value ResourceTypePluginResource A resource requested by a plugin. (Added in Qt 5.7) \value ResourceTypeNavigationPreloadMainFrame A main-frame service worker navigation preload request. (Added in Qt 5.14) \value ResourceTypeNavigationPreloadSubFrame A sub-frame service worker navigation preload request. (Added in Qt 5.14) + \value ResourceTypeWebSocket A WebSocket request. (Added in Qt 6.4) \value ResourceTypeUnknown Unknown request type. \note For forward compatibility all values not matched should be treated as unknown, diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h index 658386632..e67402346 100644 --- a/src/core/api/qwebengineurlrequestinfo.h +++ b/src/core/api/qwebengineurlrequestinfo.h @@ -46,6 +46,7 @@ #include <QtCore/qurl.h> namespace QtWebEngineCore { +class ContentBrowserClientQt; class InterceptedRequest; } // namespace QtWebEngineCore @@ -81,6 +82,7 @@ public: #ifndef Q_QDOC ResourceTypeLast = ResourceTypeNavigationPreloadSubFrame, #endif + ResourceTypeWebSocket = 254, ResourceTypeUnknown = 255 }; @@ -108,6 +110,7 @@ public: void setHttpHeader(const QByteArray &name, const QByteArray &value); private: + friend class QtWebEngineCore::ContentBrowserClientQt; friend class QtWebEngineCore::InterceptedRequest; Q_DISABLE_COPY(QWebEngineUrlRequestInfo) Q_DECLARE_PRIVATE(QWebEngineUrlRequestInfo) diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 01b4fa1f3..1bbac4439 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -76,6 +76,7 @@ #include "services/device/public/cpp/geolocation/geolocation_manager.h" #include "services/network/network_service.h" #include "services/network/public/cpp/web_sandbox_flags.h" +#include "services/network/public/mojom/websocket.mojom.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "ui/base/resource/resource_bundle.h" @@ -117,6 +118,7 @@ #include "web_engine_settings.h" #include "api/qwebenginecookiestore.h" #include "api/qwebenginecookiestore_p.h" +#include "api/qwebengineurlrequestinfo_p.h" #if QT_CONFIG(opengl) #include <QOpenGLContext> @@ -1216,6 +1218,75 @@ bool ContentBrowserClientQt::WillCreateURLLoaderFactory( return true; } +bool ContentBrowserClientQt::WillInterceptWebSocket(content::RenderFrameHost *frame) +{ + Q_UNUSED(frame); + return true; // It is probably not worth it to only intercept when interceptors are installed +} + +QWebEngineUrlRequestInterceptor *getProfileInterceptorFromFrame(content::RenderFrameHost *frame) +{ + ProfileQt *profile = static_cast<ProfileQt *>(frame->GetBrowserContext()); + if (profile) + return profile->profileAdapter()->requestInterceptor(); + return nullptr; +} + +QWebEngineUrlRequestInterceptor *getPageInterceptor(content::WebContents *web_contents) +{ + if (web_contents) { + auto view = static_cast<content::WebContentsImpl *>(web_contents)->GetView(); + if (WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client()) + return client->webContentsAdapter()->requestInterceptor(); + } + return nullptr; +} + +void ContentBrowserClientQt::CreateWebSocket( + content::RenderFrameHost *frame, + WebSocketFactory factory, + const GURL &url, + const net::SiteForCookies &site_for_cookies, + const absl::optional<std::string> &user_agent, + mojo::PendingRemote<network::mojom::WebSocketHandshakeClient> handshake_client) +{ + QWebEngineUrlRequestInterceptor *profileInterceptor = getProfileInterceptorFromFrame(frame); + content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(frame); + QWebEngineUrlRequestInterceptor *pageInterceptor = getPageInterceptor(web_contents); + std::vector<network::mojom::HttpHeaderPtr> headers; + GURL to_url = url; + bool addedUserAgent = false; + if (profileInterceptor || pageInterceptor) { + QUrl initiator = web_contents ? toQt(web_contents->GetURL()) : QUrl(); + auto *infoPrivate = new QWebEngineUrlRequestInfoPrivate( + QWebEngineUrlRequestInfo::ResourceTypeWebSocket, + QWebEngineUrlRequestInfo::NavigationTypeOther, + toQt(url), toQt(site_for_cookies.first_party_url()), initiator, + QByteArrayLiteral("GET")); + QWebEngineUrlRequestInfo requestInfo(infoPrivate); + if (profileInterceptor) { + profileInterceptor->interceptRequest(requestInfo); + pageInterceptor = getPageInterceptor(web_contents); + } + if (pageInterceptor && !requestInfo.changed()) + pageInterceptor->interceptRequest(requestInfo); + if (infoPrivate->shouldBlockRequest) + return; // ### should we call OnFailure on handshake_client? + if (infoPrivate->shouldRedirectRequest) + to_url = toGurl(infoPrivate->url); + for (auto header = infoPrivate->extraHeaders.constBegin(); header != infoPrivate->extraHeaders.constEnd(); ++header) { + std::string h = header.key().toStdString(); + if (base::LowerCaseEqualsASCII(h, net::HttpRequestHeaders::kUserAgent)) + addedUserAgent = true; + headers.push_back(network::mojom::HttpHeader::New(h, header.value().toStdString())); + } + } + if (!addedUserAgent && user_agent) + headers.push_back(network::mojom::HttpHeader::New(net::HttpRequestHeaders::kUserAgent, *user_agent)); + + std::move(factory).Run(to_url, std::move(headers), std::move(handshake_client), mojo::NullRemote(), mojo::NullRemote()); +} + void ContentBrowserClientQt::SiteInstanceGotProcess(content::SiteInstance *site_instance) { #if BUILDFLAG(ENABLE_EXTENSIONS) diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 1784d720d..cea122d6b 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -144,6 +144,14 @@ public: int process_id, int routing_id, mojo::PendingReceiver<network::mojom::RestrictedCookieManager> *receiver) override; + bool WillInterceptWebSocket(content::RenderFrameHost *frame) override; + void CreateWebSocket( + content::RenderFrameHost *frame, + WebSocketFactory factory, + const GURL &url, + const net::SiteForCookies &site_for_cookies, + const absl::optional<std::string> &user_agent, + mojo::PendingRemote<network::mojom::WebSocketHandshakeClient> handshake_client) override; content::AllowServiceWorkerResult AllowServiceWorker( const GURL &scope, |