Skip to content

feat: add headerOverrides for surgical emulation header replacement#150

Open
DepsCian wants to merge 1 commit into
sqdshguy:masterfrom
DepsCian:feat/header-overrides
Open

feat: add headerOverrides for surgical emulation header replacement#150
DepsCian wants to merge 1 commit into
sqdshguy:masterfrom
DepsCian:feat/header-overrides

Conversation

@DepsCian

@DepsCian DepsCian commented Jun 3, 2026

Copy link
Copy Markdown

Addresses #145 (second part)

Problem

Users who want to replace specific emulation-injected headers (e.g. override Accept while keeping User-Agent, Accept-Language, etc.) currently have no option besides disableDefaultHeaders: true — which strips all emulation headers. This forces manual reconstruction of the entire header set, defeating the purpose of browser fingerprinting.

Solution

Add headerOverrides?: HeadersInit to RequestInit and RequestOptions. Headers listed in headerOverrides replace matching emulation-injected headers by name, while all other emulation headers are preserved.

const response = await fetch("https://example.com", {
  browser: "chrome_142",
  headerOverrides: [
    ["Accept", "text/html"],
    ["Accept-Language", "en-US"],
  ],
});
// User-Agent, Accept-Encoding, Sec-CH-UA, etc. still come from chrome_142
// Only Accept and Accept-Language are replaced

How it works

JS layerheaderOverrides is converted to HeaderTuple[] and threaded through NativeRequestOptions to the Rust native binding.

Rust layerRequestOptions.header_overrides: Vec<(String, String)> is applied in make_request_inner() after headers, using the same request.header(key, value) call which replaces by name. Both headers and header_overrides share a single orig_headers pass to preserve casing.

Changes

File Change
rust/src/client.rs Add header_overrides field to RequestOptions, merge with headers in single orig pass
rust/src/lib.rs Parse headerOverrides from JS object into RequestOptions
src/types.ts Add headerOverrides?: HeadersInit to RequestInit and RequestOptions
src/wreq-js.ts Add to NativeRequestOptions, thread through fetch() and legacy request()
src/test/http/headers.spec.ts 2 new integration tests

Test Results

163/163 pass (full suite with local HTTP server)

New tests:

  • headerOverrides replaces specific emulation headers — verifies Accept is overridden while User-Agent is preserved
  • headerOverrides with headers coexist — verifies custom headers + overrides + emulation all work together

vs disableDefaultHeaders

disableDefaultHeaders: true headerOverrides
Emulation headers All stripped Only specified ones replaced
Custom headers Must reconstruct everything Add alongside as usual
Fingerprint integrity Broken (no UA, no encoding) Preserved (only named overrides)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant