bgrcs/chrome-header-modifier

Simple Chrome extension that allows modifying request headers

★ 0Forks 0JavaScriptGitHub ↗Compare

README

Header Modifier

A small, dependency-free Chrome extension (Manifest V3) that sets or removes request headers on matching requests — including the Host header, which pages themselves are never allowed to touch.

Built for testing gateways and virtual hosts locally: browse to http://localhost:9999 while the gateway receives Host: acme.dev and routes accordingly. It ships with exactly that rule so it works out of the box.

Light Dark
popup popup, dark

Install

  1. Open chrome://extensions.
  2. Enable Developer mode (top right).
  3. Click Load unpacked and select this folder.
  4. Pin the icon — the badge shows how many rules are active.

Usage

  • Each rule reads like the header line it produces: Host: acme.dev, applied on a URL filter.
  • set writes the header (adding it if absent); remove strips it.
  • Rules apply to every request type — page loads, fetch/XHR, scripts, images, WebSockets.
  • Changes apply as you type (about 300 ms after you stop). No save button.
  • The switch in the top bar pauses everything; the per-rule checkbox disables one rule.
  • If two enabled rules touch the same header on the same request, the rule higher in the list wins.
  • Rows with problems are outlined in red (hover for the reason) and simply skipped — they never block other rules.

URL filter cheatsheet

Plain text is a substring match against the full URL. Leave the filter empty to match every URL. Special tokens (full syntax):

Filter Matches
(empty) every URL
localhost:9999 any URL containing that text
||acme.dev acme.dev and its subdomains
|http:// URLs starting with http://
^ a separator: end of host/port, /, ?, or end of URL
* any number of characters

Tighter version of the example rule: ||localhost:9999^. Filters must be ASCII — use punycode for international domains.

Verifying it works — read this first

DevTools' Network panel can show headers as the page sent them, before the extension's rewrite. Trust the server, not DevTools. This repo includes an echo server for that:

python3 scripts/echo_server.py     # listens on http://127.0.0.1:9999

Open http://localhost:9999/ — the page and the terminal both report the Host header that actually arrived (acme.dev with the stock rule). Hard reload (⌘⇧R) if you suspect the cache.

For a fully automated check (scratch browser profile, real requests, on/off/on toggle):

scripts/verify.sh              # headless; HEADFUL=1 to watch

Note: verify.sh needs Chromium or Chrome for Testing — branded Google Chrome ≥ 137 ignores --load-extension. Installing via Load unpacked (above) works fine in any Chrome; this only affects the scripted check.

Caveats

  • HTTP/2 and HTTP/3 derive the :authority pseudo-header from the URL, so Host overrides only affect plain-HTTP/1.1 traffic — which is exactly the local-gateway case. Other headers are unaffected by this.
  • The value is sent verbatim: if your gateway matches on host and port, include the port (acme.dev:8443).
  • Auto-apply means a valid prefix can be live for a moment while you type the rest of a value. Everything settles ~300 ms after you stop.
  • Rules live in chrome.storage.local and survive browser restarts.

Development

manifest.json            permissions and wiring
shared.js                validation + DNR rule compilation (used by popup and worker)
background.js            storage → declarativeNetRequest sync, badge
popup.html/css/js        the UI
scripts/gen_icons.py     regenerates icons/ (stdlib only)
scripts/echo_server.py   local Host-header oracle
scripts/verify.sh        end-to-end check
scripts/cdp.mjs          DevTools-protocol helper used by verify.sh

The popup only reads/writes chrome.storage.local; the service worker owns compiling that state into declarativeNetRequest dynamic rules (one storage rule → one DNR rule, all 15 resource types listed explicitly — omitting resourceTypes would silently exclude page navigations).

To debug matching, add "declarativeNetRequestFeedback" to permissions in the manifest and use chrome.declarativeNetRequest.onRuleMatchedDebug in the service-worker console (unpacked extensions only).

Contributors

bgrcs

Issues