1

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:

  1. 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
  2. Add an additional header to the redirected request

Unfortunately, I am having trouble achieving either of the following with Chrome's declarativeNetRequest APIs:

  1. Apply two different rules (in this case, modifyHeaders and redirect) for the same request, OR
  2. 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?

  • It's likely https://crbug.com/1247400. Use an external tool like Fiddler/Charles/WireShark to verify the presence of the header. P.S. Instead of regex, which is super inefficient, use requestDomains in condition and [transform](https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/#property-Redirect-transform) in action. – wOxxOm May 19 '23 at 18:59
  • Thank you for the quick comment - however I have confirmed that for request headers, they do indeed apply/show up, and thus this bug does not appear to apply in this case (which is only for response headers). I will play around with the requestDomains though, thanks :) – Reggie Miller May 19 '23 at 20:26
  • Just because the report describes one case doesn't mean the same underlying problem doesn't apply to another case. BTW it may be a limitation of the API, maybe it can't apply multiple rules to one request. – wOxxOm May 20 '23 at 05:21
  • As I mentioned in my previous comment, I have confirmed that request headers do get appended in isolation so that bug is indeed not applicable here. You've also gotten to the crux of my question - I'm hoping to find out if this is: A) A limitation of the API, or B) Possible, and if so, how – Reggie Miller May 23 '23 at 16:03
  • What if the bug manifests only in some cases? To investigate what happens you need to establish the facts and not logical constructions based on inference. Anyway, the API would greatly benefit from the ability to declare multiple actions in one rule, so consider opening a feature request on https://crbug.com. – wOxxOm May 23 '23 at 16:40

0 Answers0