Can I use declarativeNetRequest to set headers dynamically by using regex

392 views
Skip to first unread message

Lu Xu

unread,
Apr 11, 2024, 11:46:00 PM4/11/24
to Chromium Extensions
Hi,
I have a question for setting headers by DNR, looking at the redirect action, we can use regexSubstitution, can we use similar approach for setting headers, like

chrome.declarativeNetRequest.updateSessionRules({
removeRuleIds: ['one-good-rule'],
addRules: [{
id: 'one-good-rule',
action: {
type: 'modifyHeaders',
requestHeaders: [
{ header: 'my-domain-test', operation: 'set', value: '\\1' },
]
},
condition: {
regexFilter: '^(.*)/my/specific/path',
resourceTypes: ['xmlhttprequest'],
}
}]
})

I tried it, but it doesn't work. But this would be very helpful since the static rules would be verbose to update, and not flexible.
For example, if the domain is dynamic, then I can not set the header, I think can workaround it by keep adding session rules of fixed domains, like
 
var sessionRuleCount = get all sessions rules count
chrome.declarativeNetRequest.updateSessionRules({
addRules: [{
id: sessionRuleCount + 1,
action: {
type: 'modifyHeaders',
requestHeaders: [
{ header: 'my-domain-test', operation: 'set', value: 'https://mydomain1.com' },
]
},
condition: {
resourceTypes: ['xmlhttprequest'],
}
}]
})
However, the session rules has maximum number, the regex approach looks very neat if it works

I would be very appreciated for any ideas or suggestions, Thank you!

wOxxOm

unread,
Apr 12, 2024, 7:15:13 AM4/12/24
to Chromium Extensions, Lu Xu
It's not implemented, see https://crbug.com/40794461.
Meanwhile the workaround would be to patch XMLHttpRequest.prototype.send in the MAIN world at document_start.

{
  const p = XMLHttpRequest.prototype;
  const setRequestHeader = Function.prototype.call.bind(p.setRequestHeader);
  const {apply} = Reflect;
  p.send = new Proxy(p.send, {
    apply(fn, me, argArray) {
      setRequestHeader(me, 'my-domain-test', location.origin);
      return apply(fn, me, argArray);
    },
  });
}

wOxxOm

unread,
Apr 12, 2024, 7:15:58 AM4/12/24
to Chromium Extensions, wOxxOm, Lu Xu
...and similarly for window.fetch = new Proxy(window.fetch, .......

Lu Xu

unread,
Apr 12, 2024, 8:11:55 PM4/12/24
to wOxxOm, Chromium Extensions
Thanks a lot wOxxOm for the bug link
Actually I am making this request in service-worker, there is no XMLHttpRequest, and it seems impossible to patch fetch like XMLHttpRequest.
But I can go with the workaround that sets up a certain amount of session rules, e.g 100 rules, and replace the old rules before making new domain requests, it is quite impossible there are 100+ different domain requests at the same time, so it should suffice.

wOxxOm

unread,
Apr 12, 2024, 8:14:03 PM4/12/24
to Chromium Extensions, Lu Xu, Chromium Extensions, wOxxOm
What I suggested is not done in the service worker. It's in the content script that runs in the MAIN world at document_start, here's the link again: https://stackoverflow.com/a/9517879
You can either declare it in manifest.json or register dynamically using chrome.scripting.registerContentScripts

Lu Xu

unread,
Apr 12, 2024, 8:27:49 PM4/12/24
to wOxxOm, Chromium Extensions
My goal is making the requests in service-worker, so we can achieve some tasks entirely from the background, with no dependency on the browser tab.
But I see your idea, we can dynamically register a content script, patch the XMLHttpRequest or fetch, and make the request.
This is definitely an option as well, I will think about it
Thanks a lot!

wOxxOm

unread,
Apr 12, 2024, 8:30:10 PM4/12/24
to Chromium Extensions, Lu Xu, Chromium Extensions, wOxxOm
For your own extension's requests you can set this header explicitly in parameters of fetch() or XMLHttpRequest (in other pages), so there's no need to use declarativeNetRequest unless it's a forbidden header, so I assumed you want to patch requests from the web pages.

Lu Xu

unread,
Apr 12, 2024, 8:38:57 PM4/12/24
to wOxxOm, Chromium Extensions
Actually it is a forbidden header, it is the 'Origin' header, I should have used 'Origin' in my example at the beginning...
Yeah, that's a good reminder, I guess the patch won't work, I have to use DNR to achieve this.

wOxxOm

unread,
Apr 12, 2024, 8:41:45 PM4/12/24
to Chromium Extensions, Lu Xu, Chromium Extensions, wOxxOm
Can you just call updateSessionRules right before making the request and add a rule for this request's origin and then remove it?

Lu Xu

unread,
Apr 12, 2024, 8:53:17 PM4/12/24
to wOxxOm, Chromium Extensions
Yes, that is my current implementation, but I was thinking of some concurrent case, like,
multiple requests happen at the same time, to be safe, I should set up separate rules for them, then I need some code to maintain and remove these session rule IDs, but should not be complicated.
If we can do it in a regex, then we can just use one rule and no need to worry about maintaining the rules
Reply all
Reply to author
Forward
0 new messages