summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-04-19 16:01:24 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-06-12 11:46:14 +0000
commit7b3570a96210d7f08453903be503eb33d43e495c (patch)
tree03e8775a94dddecbfb2b870990bdd191f96d46d0 /src
parentba4314a4392ac0e86b7d7b47bf5ef01035628db2 (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.cpp1
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h3
-rw-r--r--src/core/content_browser_client_qt.cpp71
-rw-r--r--src/core/content_browser_client_qt.h8
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,