1

Is there a way with QWebEngineView to intercept an http request, and to serve it server-less from the app ?

I heard about QWebEngineUrlRequestInterceptor and acceptNavigationRequest(), but they provide only inspection on requests, and redirection for get... But I would like to make the http response from the Qt app.

(I added pyqt in the tags because I would use it from python, but a c++ answer is acceptable too)

hl037_
  • 3,520
  • 1
  • 27
  • 58

2 Answers2

0

To intercept http request you will need to use this code:

// on app startup
QWebEngineProfile.defaultProfile().installUrlSchemeHandler(new 
         QByteArray("https"), new QWebEngineUrlSchemeHandler() {
            @Override public void requestStarted(QWebEngineUrlRequestJob job) {
                final String url = job.requestUrl().url();
                if (**some url not ok condition**) {
                    job.fail(QWebEngineUrlRequestJob.Error.UrlInvalid);
                }
                String data = loadSomeData();
                if (data != null) {
                  QBuffer buffer = new QBuffer();
                  // this is IMPORTANT! or you will have memory leaks
                  job.destroyed.connect(buffer::disposeLater);
                  buffer.open(QIODeviceBase.OpenModeFlag.WriteOnly);
                  buffer.write(data.getBytes(StandardCharsets.UTF_8));
                  buffer.close();
                  job.reply(new QByteArray("text/html"), buffer);
                }
            }
        });

My versions is for QTJambi(Java), but it's not hard to convert it to C++/Python

maxpovver
  • 1,580
  • 14
  • 25
0

The qt documentation says the redirection is only for GET request. However, when trying it out (PyQt6==6.4.0) we found out that this is actually not true. If you redirect a POST request in the WebEngine to a local webserver listening on localhost, you will actually receive the request including the payload.

Perhaps this is because Webkit doesn't include the payload for redirect and Chromium does? (I couldn't find docs stating the difference.)

from PyQt6.QtCore import QUrl
from PyQt6.QtWebEngineCore import QWebEngineUrlRequestInterceptor


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def interceptRequest(self, info):
        method = info.requestMethod()
        if method == "POST":
            if info.requestUrl().url() == "https://my-url-to-something":
                info.redirect(QUrl("http://127.0.0.1:8000"))
Sam vL
  • 81
  • 1
  • 6