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

Networking: DNS, proxies and developer hosts

Everything network-related that isn't blocking lives in services/network.py.

Secure DNS#

DnsManager switches Chromium's resolver between the Windows resolver and DNS-over-HTTPS, at runtime and for the whole process:

network.dns_mode Resolver
system whatever Windows uses
quad9 (default) https://dns.quad9.net/dns-query, which also refuses known malicious domains
cloudflare https://cloudflare-dns.com/dns-query

With network.dns_fallback on, a failing DoH server falls back to the system resolver (SecureWithFallback); otherwise DNS-over-HTTPS is strict (SecureOnly).

Why ctypes

PyQt6 exposes QWebEngineGlobalSettings.DnsMode but not the static setDnsMode(). DnsManager loads Qt6WebEngineCore.dll and calls the exported C++ function by its mangled name. DnsMode is passed by value, which on MSVC x64 means a pointer to a temporary the callee destroys, so the QStringList inside is reference-counted up once beforehand to balance that destructor. If a future Qt build changes the export, available is False and the DNS setting reports that it can't be applied instead of crashing.

The mode is applied at start-up before the first profile touches the network, and again whenever the setting changes.

Proxies#

ProxyManager handles a global proxy (network.proxy) and optional per-space overrides (Space.proxy, edited with Proxy for current space…).

Type How it is applied
HTTP (CONNECT), SOCKS5 QNetworkProxy.setApplicationProxy(), live
System proxy QNetworkProxyFactory.setUseSystemConfiguration(True), live
HTTPS (TLS to the proxy) Chromium's --proxy-server flag, at start-up only (a restart is needed)

Chromium has one network stack per process, so a per-space proxy is really "the proxy of the space in front": AppContext calls proxy.apply(space.proxy) on every space switch. To make Chromium re-read the configuration immediately, _kick() loads a dummy address (http://proxy-refresh.jbrowser.invalid/) in a hidden page for each profile; the request fails harmlessly but resets the network context.

Credentials are stored in settings.json protected with DPAPI (protect_secret() / reveal_secret()), which ties them to the Windows user account. requests_proxies() gives JBrowser's own downloads (filter lists, threat lists) the same route as the pages. Proxy authentication prompts are answered from the stored credentials first.

Localhost developer hosts#

network.dev_hosts maps friendly names to local servers, for example app.test → 127.0.0.1:3000. PrivacyService.rewrite() redirects matching requests to the target (see the request pipeline), looks_like_url() treats those names as addresses in the Lazy Toolbar, and the dev-host dialog manages the list.

DEV_PORTS lists common development ports (3000 React/Next.js, 5173 Vite, 8000 Django/FastAPI, 8080, 4200 Angular, 5000 Flask, 8888 Jupyter). Each has a Lazy Toolbar command that opens localhost:<port>, and PortProbe checks asynchronously, with a QTcpSocket and a 600 ms timeout, whether something is listening, so the UI can show which servers are running.