I have been working on a Chrome extension for shared internal use to facilitate local development; as such, I need to achieve two separate things on the same request:
- Redirect an XHR from a public domain (specified by the user) to another domain (also specified by the user). Note that since these are defined by the user, I must use dynamic rulesets
- Add an additional header to the redirected request
Unfortunately, I am having trouble achieving either of the following with Chrome's declarativeNetRequest
APIs:
- Apply two different rules (in this case,
modifyHeaders
andredirect
) for the same request, OR - Redirect the request with one rule, and have a second rule match with the "new" (redirected) request.
Can this behaviour be achieved in any way?
For all attempts, here are the relevant segments of my manifest.json
(please note that while I work on this, I'm relaxing my permissions, like host_permissions
below, as much as possible):
{
"manifest_version": 3,
"version": "1.0",
"host_permissions": [
"<all_urls>"
],
"permissions": [
"declarativeNetRequest",
"declarativeNetRequestWithHostAccess",
"declarativeNetRequestFeedback",
"storage"
],
"action": {
"default_title": "Request Redirector",
"default_popup": "index.html"
},
"background": {
"service_worker": "rewrite.js"
}
}
And here are code snippets for my dynamic rules:
RULE 1
const getBaseRedirectRule = (redirectDomain = '', initialDomain = '') => {
return {
id: 1,
priority: 1,
action: {
type: "redirect",
redirect: {
regexSubstitution: `https://${redirectDomain}/\\1`
},
},
condition: {
regexFilter: `^https://${initialDomain.replaceAll('.', '\\.')}/(.*)`,
}
}
}
So an example with substituted inputs is:
{
id: 1,
priority: 1,
action: {
type: "redirect",
redirect: {
regexSubstitution: "https://localhost.subdomain.com:8443/\\1"
},
},
condition: {
regexFilter: `^https://public\\.subdomain\\.com/graphql`,
}
}
RULE 2
const getBaseWriteHeaderRule = (operation = "set", value = '', redirectDomain = '') => {
return {
id: 2,
priority: 1,
action: {
type: "modifyHeaders",
requestHeaders: [{
header: "authorization",
operation,
value,
}]
},
condition: {
urlFilter: `${redirectDomain}/*`
},
}
}
So an example with substituted inputs is:
{
id: 2,
priority: 1,
action: {
type: "modifyHeaders",
requestHeaders: [{
header: "authorization",
operation: "set",
value: "my-auth-value",
}]
},
condition: {
urlFilter: `localhost.subdomain.com:8443/*`
},
}
I have confirmed using chrome.declarativeNetRequest.onRuleMatchedDebug
that these rules, when applied individually, do indeed work, so there is no issue with my regexFilter
or urlFilter
conditions. However, when used in tandem, the second rule is not applied, I presume because it is a redirected request and not one initiated by the document itself.
If I take the second rule above and attempt to modify the headers of the request to the initialDomain
from the first rule instead (public.subdomain.com
in the first rule's example), it will only select ONE of the rules (the redirect), which is as the declarativeNetRequest
API is designed.
Is there any way to both redirect a request and modify the request headers to the new endpoint?