JBrowser Source Docs
You are reading the documentation for JBrowser 1.4.1. The newest release is 1.5.4. Go to the latest documentation

The request pipeline

Qt WebEngine lets an application inspect every network request before Chromium sends it. JBrowser uses two QWebEngineUrlRequestInterceptors, both in services/privacy.py, and both delegate their decisions to PrivacyService:

page request
   │
   ▼
ProfileInterceptor (one per space)      rewrite():   developer host → redirect
   │                                                  tracking parameters → redirect to the clean URL
   │                                                  http → https (HTTPS-first) → redirect
   │                                    otherwise:   add DNT: 1 and Sec-GPC: 1 headers
   ▼
PageInterceptor (one per card)          should_block(): block, and count it on the card
   │                                    (a WebSocket request is noted for the memory saver)
   ▼
Chromium's network service

Qt calls the profile interceptor first, then the page's own. Both run on the UI thread for every request, so they must be fast and must never raise: each wraps its work in try/except and logs failures.

rewrite(): redirects#

In order, the first rule that applies wins:

  1. Developer hosts. A request to a mapped name (app.test) is redirected to its local target (http://127.0.0.1:3000), keeping the path and query. See networking.
  2. Link cleaning (privacy.strip_tracking, on by default). For top-level and frame GET navigations, strip_tracking() removes known tracking parameters: utm_*, fbclid, gclid, msclkid, mc_eid and about 40 more, plus site-specific ones such as YouTube's si or Amazon's ref_. Allowed sites are skipped.
  3. HTTPS-first (privacy.https_upgrade, off by default). A main-frame http:// navigation to a public host is redirected to https://. If the site bounces back to http within 4 seconds, or the https version fails to load or has a certificate error, JBrowser opens the original http page instead, shows a "not encrypted" warning, and doesn't try that host again this session.

If nothing redirects, the interceptor adds DNT: 1 (privacy.dnt) and Sec-GPC: 1 (privacy.gpc).

should_block(): blocking#

  1. Main-frame navigations and local hosts are never blocked here.
  2. Threats: sub-resources and frames from known phishing or malware hosts are always blocked.
  3. With privacy.block_trackers off, stop here.
  4. When the first party is on privacy.allowlist, nothing is blocked.
  5. Third-party requests to a domain on the blocklist (the built-in list plus the whole-domain rules extracted from the downloaded lists) are blocked, as are a few built-in path rules.

This version blocks by domain only. URL-pattern rules, exceptions and element hiding came with the filter engine in 1.5.0.

A blocked request increments tab.blocked, which the shield button in the address pill shows.

Cookies#

Each profile's cookie store has a filter, PrivacyService.allow_cookie(). With privacy.block_third_party_cookies on (the default), third-party cookies are refused, except:

  • on sites where protection is switched off (the allowed list).

Adding a rule#

  • Something that changes the URL: add it to rewrite(), keep it cheap, and return None quickly for the common case.
  • Something that blocks: put it in should_block() at the right place in the order above, and make sure it can't block main-frame navigations.
  • Always test with a page that makes many requests (a news site) and watch the log for exceptions.