]> gitweb.stoutner.com Git - PrivacyBrowserPC.git/blobdiff - src/interceptors/UrlRequestInterceptor.cpp
Block all CSP requests. https://redmine.stoutner.com/issues/1193
[PrivacyBrowserPC.git] / src / interceptors / UrlRequestInterceptor.cpp
index 2b9bd053e8c0da3c31b7a3c2bb7f5d59a93cd286..b0b40294d90f99eb34d053907928463648afdd6f 100644 (file)
-/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * SPDX-FileCopyrightText: 2022-2025 Soren Stoutner <soren@stoutner.com>
  *
- * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
  *
- * Privacy Browser PC is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
  *
- * Privacy Browser PC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
  *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser PC.  If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
 // Application headers.
 #include "UrlRequestInterceptor.h"
+#include "GlobalVariables.h"
+#include "helpers/FilterListHelper.h"
+#include "structs/RequestStruct.h"
 
-// The default constructor.
-UrlRequestInterceptor::UrlRequestInterceptor(QObject *parentObjectPointer) : QWebEngineUrlRequestInterceptor(parentObjectPointer) {}
+// KDE Framework headers.
+#include <KLocalizedString>
+
+// Construct the class.
+UrlRequestInterceptor::UrlRequestInterceptor(PrivacyWebEngineView *privacyWebEngineViewPointer) :
+                                             QWebEngineUrlRequestInterceptor(privacyWebEngineViewPointer), privacyWebEngineViewPointer(privacyWebEngineViewPointer) {}
 
 void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &urlRequestInfo)
 {
-    // Handle the request according to the navigation type.
-    switch (urlRequestInfo.navigationType())
+    // Clear the requests list if a main frame resource is being loaded.
+    if (urlRequestInfo.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame)
+        Q_EMIT newMainFrameResource();
+
+    // Create a requests struct.
+    RequestStruct *requestStructPointer = new RequestStruct;
+
+    // Store the basic request information.
+    requestStructPointer->navigationTypeInt = urlRequestInfo.navigationType();
+    requestStructPointer->requestMethodString = QLatin1String(urlRequestInfo.requestMethod());
+    requestStructPointer->resourceTypeInt = urlRequestInfo.resourceType();
+    requestStructPointer->urlString = urlRequestInfo.requestUrl().toString();
+    requestStructPointer->webPageUrlString = urlRequestInfo.firstPartyUrl().toString();
+
+    // Create a continue processing flag.
+    bool continueProcessing = true;
+
+    // Block certain resource types.
+    switch (urlRequestInfo.resourceType())
     {
-        case QWebEngineUrlRequestInfo::NavigationTypeLink:
-        case QWebEngineUrlRequestInfo::NavigationTypeTyped:
-        case QWebEngineUrlRequestInfo::NavigationTypeBackForward:
-        case QWebEngineUrlRequestInfo::NavigationTypeRedirect:
+        case QWebEngineUrlRequestInfo::ResourceTypePrefetch:
         {
-            // Only check the hosts if the main URL is changing.
-            if (urlRequestInfo.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame)
-            {
-                // Get the hosts.
-                QString requestingHost = urlRequestInfo.initiator().host();
-                QString requestedHost = urlRequestInfo.requestUrl().host();
+            // Block the request.
+            urlRequestInfo.block(true);
 
-                // Reapply the domain settings if the host is changing.
-                if (requestingHost != requestedHost)
-                {
-                    emit applyDomainSettings(requestedHost);
-                }
-            }
+            // Mark the request struct as blocked.
+            requestStructPointer->dispositionInt = FilterListHelper::BLOCKED;
+
+            // Describe the prefetch request as blocked by the default behavior.
+            requestStructPointer->filterListTitle = i18nc("Default prefetch blocking", "Default blocking of all prefetch requests.");
+
+            // Set the continue processing flag.
+            continueProcessing = false;
 
             break;
         }
 
-        default:
-            // Do nothing.
+        case QWebEngineUrlRequestInfo::ResourceTypeCspReport:
+        {
+            // Block the request.
+            urlRequestInfo.block(true);
+
+            // Mark the request struct as blocked.
+            requestStructPointer->dispositionInt = FilterListHelper::BLOCKED;
+
+            // Describe the CSP request as blocked by the default behavior.
+            requestStructPointer->filterListTitle = i18nc("Default CSP blocking", "Default blocking of all CSP requests.");
+
+            // Set the continue processing flag.
+            continueProcessing = false;
+
             break;
-    }
+        }
 
-    // Handle the request according to the resource type.
-    switch (urlRequestInfo.resourceType())
-    {
-        // A naughty HTTP ping request.
-        case QWebEngineUrlRequestInfo::ResourceTypePing:
+        case QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame:
+        case QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadSubFrame:
         {
-            // Block HTTP ping requests.
+            // Block the request.
             urlRequestInfo.block(true);
 
+            // Mark the request struct as blocked.
+            requestStructPointer->dispositionInt = FilterListHelper::BLOCKED;
+
+            // Describe the preload request as blocked by the default behavior.
+            requestStructPointer->filterListTitle = i18nc("Default preload blocking", "Default blocking of all preload requests.");
+
+            // Set the continue processing flag.
+            continueProcessing = false;
+
             break;
         }
 
@@ -73,4 +110,103 @@ void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &urlReques
             break;
         }
     }
+
+    // Check the filter lists if it hasn't already been handled.
+    if (continueProcessing)
+        continueProcessing = globalFilterListHelperPointer->checkFilterLists(privacyWebEngineViewPointer, urlRequestInfo, requestStructPointer);
+
+    // Further process the request if it hasn't already been handled.
+    if (continueProcessing) {
+        // Handle the request according to the resource type.
+        switch (urlRequestInfo.resourceType())
+        {
+            // A naughty HTTP ping request.
+            case QWebEngineUrlRequestInfo::ResourceTypePing:
+            {
+                // Block the HTTP ping request.
+                urlRequestInfo.block(true);
+
+                // Mark the request struct as blocked.
+                requestStructPointer->dispositionInt = FilterListHelper::BLOCKED;
+
+                // Describe the ping as blocked by the default behavior.
+                requestStructPointer->filterListTitle = i18nc("Default HTTP ping blocking", "Default blocking of all HTTP ping requests.");
+
+                // Set the continue processing flag.
+                continueProcessing = false;
+
+                // Display the HTTP Ping blocked dialog.
+                Q_EMIT displayHttpPingDialog(urlRequestInfo.requestUrl().toString());
+
+                break;
+            }
+
+            default:
+            {
+                // Do nothing.
+                break;
+            }
+        }
+    }
+
+    // Handle the request according to the navigation type if it hasn't already been handled.
+    if (continueProcessing)
+    {
+        switch (urlRequestInfo.navigationType())
+        {
+            case QWebEngineUrlRequestInfo::NavigationTypeLink:
+            case QWebEngineUrlRequestInfo::NavigationTypeTyped:
+            case QWebEngineUrlRequestInfo::NavigationTypeFormSubmitted:
+            case QWebEngineUrlRequestInfo::NavigationTypeRedirect:
+            case QWebEngineUrlRequestInfo::NavigationTypeOther:
+            {
+                // Only check the hosts if the main URL is changing.
+                if (urlRequestInfo.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame)
+                {
+                    // Get the request URL.
+                    QUrl requestUrl = urlRequestInfo.requestUrl();
+
+                    // Reapply the domain settings if the host is changing.
+                    if (privacyWebEngineViewPointer->currentHost != requestUrl.host())
+                    {
+                        // Apply domain settings, after which the request will be loaded.  `false` indicates that history is not being navigated.
+                        Q_EMIT applyDomainSettings(requestUrl, false);
+
+                        // Block this copy of the request.
+                        urlRequestInfo.block(true);
+                    }
+                }
+
+                break;
+            }
+
+            case QWebEngineUrlRequestInfo::NavigationTypeBackForward:
+            {
+                // Only check the hosts if the main URL is changing.
+                if (urlRequestInfo.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame)
+                {
+                    // Get the request URL.
+                    QUrl requestUrl = urlRequestInfo.requestUrl();
+
+                    // Reapply the domain settings if the host is changing.
+                    if (privacyWebEngineViewPointer->currentHost != requestUrl.host())
+                    {
+                        // Apply domain settings, after which the request will be loaded.  `true` indicates that history is being navigated.
+                        Q_EMIT applyDomainSettings(requestUrl, true);
+                    }
+                }
+
+                break;
+            }
+
+            default:
+            {
+                // Do nothing.
+                break;
+            }
+        }
+    }
+
+    // Send the request struct to the privacy WebEngine view.
+    Q_EMIT requestProcessed(requestStructPointer);
 }