Header Rewrite
Header rewrite rules add, remove or change HTTP headers on requests (before they are sent to the server) or on responses (before they reach the app).
Behavior
Section titled “Behavior”- Every matching header rule runs, in order: your local rules first, then modules from the top of the list down.
- Rules match against the original URL the app requested (see How URLs are matched). Response rules are chosen when the request is seen, using the same URL.
- Request header rewrites run first, before URL rewrite and Map Local. Response header rewrites run before body rewrites and response scripts.
- Header names are compared case-insensitively.
- For decrypted hosts, MeowX also removes the
Alt-Svcresponse header so that apps aren’t steered to HTTP/3 (QUIC), which can’t be decrypted.
| Operation | Effect |
|---|---|
header-add Name value |
Always appends a new Name field, even if one exists. |
header-del Name |
Removes every Name field. |
header-replace Name value |
Replaces the value of every existing Name field. Adds nothing if the header isn’t present. |
header-replace-regex Name regex replacement |
Applies a regex replacement to the value of every existing Name field. $1 … refer to capture groups. |
Surge [Header Rewrite]
Section titled “Surge [Header Rewrite]”[Header Rewrite]# [http-request|http-response] regex operation name [value]http-request ^https:\/\/api\.example\.com\/ header-add X-Debug 1http-request ^https:\/\/api\.example\.com\/ header-del Cookiehttp-response ^https:\/\/api\.example\.com\/ header-replace Cache-Control no-storehttp-request ^https:\/\/api\.example\.com\/ header-replace-regex User-Agent iPhone iPad- The direction is
http-requestorhttp-response. If it is omitted (the older syntax),http-requestis assumed. - The value is the rest of the line and may contain spaces. A value wrapped in double quotes has the quotes removed.
Loon plugins
Section titled “Loon plugins”Classic [Rewrite] header operations
Section titled “Classic [Rewrite] header operations”[Rewrite]^https:\/\/api\.example\.com\/ header-add X-Debug 1 X-Client meowx^https:\/\/api\.example\.com\/ response-header-del Set-Cookie^https:\/\/api\.example\.com\/ header-replace User-Agent My\x20Client| Request | Response | Arguments |
|---|---|---|
header-add |
response-header-add |
name, value |
header-del |
response-header-del |
name |
header-replace |
response-header-replace |
name, value |
header-replace-regex |
response-header-replace-regex |
name, regex, replacement |
One line can change several headers: the arguments are taken in groups (header-add A 1 B 2 adds two headers), and each group becomes its own rule. If one group touches Content-Length or Transfer-Encoding, only that group is rejected. Write spaces inside arguments as \x20.
New syntax
Section titled “New syntax”[Rewrite]request if ${url} ~= /^https:\/\/api\.example\.com\// then request.header.add("X-Debug", "1")response if ${url} ~= /^https:\/\/api\.example\.com\// then response.header.delete("Set-Cookie")request if ${url} ~= /^https:\/\/api\.example\.com\//i then request.header.replace("User-Agent", "MyClient")Supported: request.header.add(name, value), request.header.replace(name, value), request.header.delete(name) (also .del), and the same with response.. Only the ${url} ~= /…/ condition is supported; see URL rewrite.
HTTP/2
Section titled “HTTP/2”Over HTTP/2, header names are sent in lowercase. If a rewrite produces a header that isn’t valid in HTTP/2 (an invalid name, a value containing line breaks or NUL, a connection-specific header such as Connection, or TE with a value other than trailers), that field is dropped.
