Delay in navigation DNR

218 views
Skip to first unread message

Manuel Delgado

unread,
Sep 6, 2023, 2:35:56 AM9/6/23
to Chromium Extensions
HI, 

I open this thread in relationship to conversation previous. 

I add the last message posted.
 
I add code:

Although i save information in session storage, i work with variables local. I save information in session because i have a contentScript in other use case need the information. But now not affecting. I am going to try test to document_start to ContentScript.

let flagActivated = false;
let flagClearSession = true;
let removeTabs = {};
let tabUrls = {};

let tabsBlock = {};
let tabsRedirect = {};
let lastValue = 0;

chrome.tabs.onCreated.addListener((tab) => {
  console.log("tabsReditect onCreated", tabsRedirect);
  tabsRedirect[tab.id] = lastValue;
  applyRulesRedirect(lastValue);
  saveTabsInStorageRedirect(tabsRedirect, lastValue);
  flagActivated = true;
  lastValue++;
});

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  tabUrls[tabId] = tab.pendingUrl ? tab.pendingUrl : tab.url;
  console.log("onUpdated tabsUrls ", tabUrls);
  const url = tab.pendingUrl ? tab.pendingUrl : tab.url;
  if (
    Object.keys(tabsBlock).length + 1 <= MAX_TABS &&
    SITE_RULES.some((rule) => rule.test(url))
  ) {
    tabsBlock[tabId] = true;
    saveTabsInStorage(tabsBlock);
  }
});

chrome.tabs.onActivated.addListener((activeInfo) => {
  const tabId = activeInfo.tabId;

  if (!flagActivated) {
    console.log("He cambiado de pestaña");
    //REDIRECT
    applyRulesRedirect(tabsRedirect[tabId]);
  }

  flagActivated = false;

  // BLOCK
  console.log("onActivate ", tabsBlock[tabId]);
  if (Object.keys(tabsBlock).length >= MAX_TABS) {
    tabsBlock[tabId] === undefined
      ? applyRulesBlock(true)
      : applyRulesBlock(false);
  }
});

chrome.tabs.onRemoved.addListener(async (tabId, removeInfo) => {
  const actualTabs = await chrome.tabs.query({});
  const url = tabUrls[tabId];
  removeTabs[tabId] = url;
  delete tabUrls[tabId];
  console.log("onRemoved removeTabs ", removeTabs);
  if (!existTab(tabId, tabsBlock)) return;
  tabsBlock = deleteTab({
    myTabs: tabsBlock,
    isRedirect: false,
    actualTabs: actualTabs,
    lastValue: lastValue,
  });
  if (Object.keys(tabsBlock).length <= MAX_TABS) {
    applyRulesBlock(false);
  }
  tabsRedirect = deleteTab({
    myTabs: tabsRedirect,
    isRedirect: true,
    actualTabs: actualTabs,
    lastValue: lastValue,
  });
  if (flagClearSession) {
    flagClearSession = false;
    setTimeout(() => {
      console.log("clearSession ", removeTabs);
      clearSession(removeTabs);
      removeTabs = {};
      flagClearSession = true;
    }, 500);
  }
});

Manuel Delgado

unread,
Sep 6, 2023, 2:51:24 AM9/6/23
to Chromium Extensions, Manuel Delgado, wox...@gmail.com, Oliver Dunk
i tried change load of contentScript, document_idle to document_start, how you indicated in the other message. But, not working. The browser on going with delay sometimes, therefore, he applys the rules incorrects if you change between tabs when he been delay.

wOxxOm

unread,
Sep 6, 2023, 3:03:42 AM9/6/23
to Chromium Extensions, Manuel Delgado, wox...@gmail.com, Oliver Dunk
It's unclear what happens because we don't see the entire code, but it won't be strange if there's no solution because declarativeNetRequest is intentionally a very simplistic API that was never designed to replace webRequest in general, it was designed for just one use case, which is processing of simple rules used by AdBlock.

Manuel Delgado

unread,
Sep 6, 2023, 4:01:57 AM9/6/23
to Chromium Extensions, wOxxOm, Manuel Delgado, Oliver Dunk
Ok, i going to trying explain better the code. You will see i don't use async/await for avoid slowness. I only use async await in remove event, because i need know the tabs open at the moment.

Service-worker
let flagActivated = false;
let flagClearSession = true;
let removeTabs = {};
let tabUrls = {};

let tabsBlock = {};
let tabsRedirect = {};
let lastValue = 0;

chrome.tabs.onCreated.addListener((tab) => {
  console.log("tabsReditect onCreated", tabsRedirect);
  tabsRedirect[tab.id] = lastValue;//save a relationship tabId -> numercialValue
  applyRulesRedirect(lastValue);// applies rules DNR Redirect
  saveTabsInStorageRedirect(tabsRedirect, lastValue);// save information in session storage
  flagActivated = true;
  lastValue++;
});

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  tabUrls[tabId] = tab.pendingUrl ? tab.pendingUrl : tab.url;// Here relationship all tabs open with your url.
  console.log("onUpdated tabsUrls ", tabUrls);
  const url = tab.pendingUrl ? tab.pendingUrl : tab.url;
  if (
    Object.keys(tabsBlock).length + 1 <= MAX_TABS &&
    SITE_RULES.some((rule) => rule.test(url))
  ) {
    tabsBlock[tabId] = true; // i save tabId that pass the filter previous.
    saveTabsInStorage(tabsBlock);// i save information in session storage
  }
});

chrome.tabs.onActivated.addListener((activeInfo) => {
  // Procesamiento bloqueo y redirección.
  const tabId = activeInfo.tabId;

  if (!flagActivated) {//This flag prevents rules redirect has been executed twice.
    //REDIRECT
    applyRulesRedirect(tabsRedirect[tabId]);
  }

  flagActivated = false;

  // BLOCK
  console.log("onActivate ", tabsBlock[tabId]);
  if (Object.keys(tabsBlock).length >= MAX_TABS) {
    tabsBlock[tabId] === undefined
      ? applyRulesBlock(true)
      : applyRulesBlock(false);
  }
});

chrome.tabs.onRemoved.addListener(async (tabId, removeInfo) => {
  const actualTabs = await chrome.tabs.query({});
  const url = tabUrls[tabId];
  removeTabs[tabId] = url;
  delete tabUrls[tabId];
  console.log("onRemoved removeTabs ", removeTabs);
  if (!existTab(tabId, tabsBlock)) return;
  tabsBlock = deleteTab({//this method deletes the tabs closed.
    myTabs: tabsBlock,
    isRedirect: false,
    actualTabs: actualTabs,
    lastValue: lastValue,
  });
  if (Object.keys(tabsBlock).length <= MAX_TABS) {
    applyRulesBlock(false);
  }
  tabsRedirect = deleteTab({//this method deletes the tabs closed.
    myTabs: tabsRedirect,
    isRedirect: true,
    actualTabs: actualTabs,
    lastValue: lastValue,
  });
  if (flagClearSession) {
    flagClearSession = false; // This flag prevents rules redirect has been executed twice.
    setTimeout(() => {// timeout allow wait enough time to all tabs deleted will be in the variable, removeTabs.
      console.log("clearSession ", removeTabs);
      clearSession(removeTabs); //invoke a service
      removeTabs = {};
      flagClearSession = true;
    }, 500);
  }
});


DeleteTab
export const deleteTab = (infoTabs) => {
  let { myTabs, isRedirect, actualTabs, lastValue } = infoTabs;
  const tabsIds = actualTabs.map((tab) => tab.id);
  const tabsIdsInStorage = Object.keys(myTabs).map((tabId) => parseInt(tabId));
  const tabsIdsToDelete = tabsIdsInStorage.filter(
    (tabId) => !tabsIds.includes(tabId)
  );

  if (tabsIdsToDelete) {
    tabsIdsToDelete.forEach((tabId) => delete myTabs[tabId]);
    if (isRedirect) {
      saveTabsInStorageRedirect(myTabs, lastValue - 1);
      return myTabs;
    } else {
      saveTabsInStorage(myTabs);
      return myTabs;
    }
  }
};


ApplyRules Redirect
export const applyRulesRedirect = async (numericalValue) => {
  chrome.declarativeNetRequest.updateDynamicRules({
    removeRuleIds: SITE.map((rule, index) => index + 100),
    addRules: SITE.map((rule, index) => {
      return {
        id: index + 100,
        priority: 1,
        action: {
          type: "redirect",
          redirect: {
            transform: {
              queryTransform: {
                addOrReplaceParams: [
                  {
                    key: "value",
                    value: `${numericalValue}`,
                  },
                ],
              },
            },
          },
        },
        condition: {
          urlFilter: rule,
          resourceTypes: ["main_frame"],
        },
      };
    }),
  });
};

wOxxOm

unread,
Sep 6, 2023, 6:05:25 AM9/6/23
to Chromium Extensions, Manuel Delgado, wOxxOm, Oliver Dunk
Thing is, the updateDynamicRules API doesn't apply the rules synchronously. First, the API sends the new rules to the browser process via IPC, which takes time, then the process must finish its current job, which may be navigating the newly created tab, then the new rules are applied, but it's already too late.

Manuel Delgado

unread,
Sep 7, 2023, 4:36:50 AM9/7/23
to Chromium Extensions, wOxxOm, Manuel Delgado, Oliver Dunk
OK, How to can i control when a request is slowness that other request? Can i avoid that user open a new tab or change until that this request be sended?

This way, i will sure that rule applied is the correct.

Thanks.

wOxxOm

unread,
Sep 7, 2023, 4:39:34 AM9/7/23
to Chromium Extensions, Manuel Delgado, wOxxOm, Oliver Dunk
I don't see where you make the request...

Manuel Delgado

unread,
Sep 7, 2023, 4:44:46 AM9/7/23
to Chromium Extensions, wOxxOm, Manuel Delgado, Oliver Dunk
It's an supposed, any user is doing click a link or write to url in toolbar browser and navigate. At that moment, if the request is slowness than other, How to can i to control?

Manuel Delgado

unread,
Sep 7, 2023, 5:01:07 AM9/7/23
to Chromium Extensions, Manuel Delgado, wOxxOm, Oliver Dunk
The extension control any request is doing in the browser with redirect rules. If my problem is that a navigation is slownees than other, and this to cause that the redirect rules is not correct when change the tab. How to can i to control?

Do you understand?

Thanks.

Oliver Dunk

unread,
Sep 7, 2023, 6:38:46 AM9/7/23
to Manuel Delgado, Chromium Extensions, wOxxOm
Hi Manuel,

It would be really great if you're able to share the actual URLs you are using and the use case, or at least a higher level description of why you need to dynamically change the rules.

As wOxxOm mentioned, this isn't really how the declarativeNetRequest API is intended to be used. There may be a better API entirely for your situation but it's hard to say in the abstract.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

Manuel Delgado

unread,
Sep 7, 2023, 9:28:32 AM9/7/23
to Chromium Extensions, Oliver Dunk, Chromium Extensions, wOxxOm, Manuel Delgado
Hi Oliver,

I am sorry, but i can not share URL by security. I can explain to high level my case.

I attach a schema for explain the functionality.
schema_inject_url.PNG
I need inject always the numerical value assigned previous, because this way i can to differentiate beetwen two request of a same application. The applications is webapp running in Weblogic.

Thanks.

Oliver Dunk

unread,
Sep 7, 2023, 9:33:07 AM9/7/23
to Manuel Delgado, Chromium Extensions, wOxxOm
Thanks for sharing.

What the is the ID used for? Does the extension rely on this for tracking something or is it read by the website? What is the purpose of that?
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

Manuel Delgado

unread,
Sep 8, 2023, 5:20:11 AM9/8/23
to Chromium Extensions, Oliver Dunk, Chromium Extensions, wOxxOm, Manuel Delgado
Hi Oliver,

I answer the questions previous.

What the is the ID used for? 

The ID is neccesary to differentiate two request (or more) to an same application.

Does the extension rely on this for tracking something or is it read by the website?

The extension inject this param for been treated in the server. This way inside of a same session the server can keep separate the request. If I don't inject this param in any request, the request will cross. Crossing the request to same application between tabs.

schema_handler_memory_server.PNG
What is the purpose of that?

I have control and independence the request a same application beetween tabs.

Manuel Delgado

unread,
Sep 8, 2023, 5:28:48 AM9/8/23
to Chromium Extensions, Manuel Delgado, Oliver Dunk, Chromium Extensions, wOxxOm
Is not a option that application inject the param because there are much application and will be very cost changed. But this we wants implement the extension.


Thanks for you support.

Manuel Delgado

unread,
Sep 8, 2023, 5:39:15 AM9/8/23
to Chromium Extensions, Manuel Delgado, Oliver Dunk, Chromium Extensions, wOxxOm
I did a extension in MV2 and with webRequest API works correctly. But in MV3 is not use possible.

Manuel Delgado

unread,
Sep 11, 2023, 3:16:17 AM9/11/23
to Chromium Extensions, Manuel Delgado, Oliver Dunk, Chromium Extensions, wOxxOm
Hi,

Can you review my previous comments?

Thanks.

Oliver Dunk

unread,
Sep 11, 2023, 4:22:42 AM9/11/23
to Manuel Delgado, Chromium Extensions, wOxxOm
Hi Manuel,

This sounds like it might be an enterprise application - is that the case? If so, you could consider installing the extension via. policy: https://support.google.com/chrome/a/answer/7532015. The blocking version of webRequest is still available in MV3 in that case.

Otherwise, a few ideas:
  • Use DNR to block all requests to the app that don't include the query parameter. Force users to open the app using an interaction like clicking your action icon when you can make sure you add it to the initial URL.
  • Use DNR to redirect all requests that don't include the query parameter to a chrome-extension:// page, and then have that page redirect to the app.
  • If you access the app through links, update the links on other sites to include the query parameter.
Do any of those sound like they might help?
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

Message has been deleted
Message has been deleted

Manuel Delgado

unread,
Sep 11, 2023, 5:14:33 AM9/11/23
to Chromium Extensions, Manuel Delgado, Chromium Extensions, wOxxOm
Yes, is a enterprise application.

https://support.google.com/chrome/a/answer/7532015,  is it applicable in Microsoft Edge?

Ok, i going to review the differents options. You don't close this conversation please, for i have others doubts about.



El lunes, 11 de septiembre de 2023 a las 11:11:34 UTC+2, Manuel Delgado escribió:
And yes, is a enterprise application.
El lunes, 11 de septiembre de 2023 a las 11:09:39 UTC+2, Manuel Delgado escribió:
OK, i going to review the differents options.  You don't close this conversation please, for if i have others doubts. Thank you very much for your support.

Oliver Dunk

unread,
Sep 11, 2023, 5:57:56 AM9/11/23
to Manuel Delgado, Chromium Extensions
I'm not familiar with setting policies in Edge, but I expect it would work the same.

Let me know how you get on :)
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

Manuel Delgado

unread,
Sep 11, 2023, 9:28:24 AM9/11/23
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Manuel Delgado
Hi,

This sounds like it might be an enterprise application - is that the case? If so, you could consider installing the extension via. policy: https://support.google.com/chrome/a/answer/7532015. The blocking version of webRequest is still available in MV3 in that case.

I clarify, when i said "I did a extension in MV2 and with webRequest API works correctly. But in MV3 is not use possible." I referenced to redirect. Now, i can not use redirect in the method onBeforeRequest of webRequestApi. Whatever, I don't fully understand how the policy configuration can help me in my problem.


Otherwise, a few ideas:
  • Use DNR to block all requests to the app that don't include the query parameter. Force users to open the app using an interaction like clicking your action icon when you can make sure you add it to the initial URL.
    • I have not this problem, always applies redirect rules. Because, tabs events in service-worker force it.
  • Use DNR to redirect all requests that don't include the query parameter to a chrome-extension:// page, and then have that page redirect to the app.
    • I have not this problem, always applies redirect rules. Because, tabs events in service-worker force it .
  • If you access the app through links, update the links on other sites to include the query parameter.
    • Here, there is a problem i can't assume that modifying links working. Because, there are cases where not always the navigation is by link, also there are buttons, images or forms. I tried in method chrome.tabs.update capture navigation and check if the queryParam value is the same that assigned. Otherwise, i invoke updateDynamicRules assigning the correct value,  after i invoke the method chrome.tabs.update but is did two request. This increments traffict in the server.
Do you understand the last point ?

Thanks

Manuel Delgado

unread,
Sep 12, 2023, 6:17:14 AM9/12/23
to Chromium Extensions, Manuel Delgado, Oliver Dunk, Chromium Extensions
Can i define redirect rules by tab ?


Manuel Delgado

unread,
Sep 14, 2023, 6:52:01 AM9/14/23
to Chromium Extensions, Manuel Delgado, Oliver Dunk, Chromium Extensions
Hi,

I has created a proxy in the extension. Following the comment.
  • Use DNR to redirect all requests that don't include the query parameter to a chrome-extension:// page, and then have that page redirect to the app.
When i write url in the browser tool bar and navigate. It is redirects to my extension and I inject query params correctly. The problem now is if i do click a link, throw error that say.

bfgienbpfnnfdeoccnjmpbmphdjihhln is blocked Microsoft Edge has blocked this page

in Chrome also.
service-worker

let canal = 0;
let ruleActivated = false;
let tabsRedirect = {};
let urls = {};
chrome.tabs.onCreated.addListener((tab) => {
  if (!ruleActivated) {
    createFirstRule();
    ruleActivated = true;
  }
  tabsRedirect[tab.id] = canal;
  canal++;
});

chrome.webRequest.onBeforeRedirect.addListener(
  (details) => {
    urls[details.tabId] = details.url;
    console.log(urls);
  },
  { urls: ["https://*/path/*"] }
);

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.getTF7Canal) {
    sendResponse({
      canal: tabsRedirect[sender.tab.id],
      url: urls[sender.tab.id],
      tab: sender.tab,
    });
  }
});

const createFirstRule = () => {
  chrome.declarativeNetRequest.updateDynamicRules(
    {
      removeRuleIds: [1, 2],
      addRules: [
        {
          id: 1,
          priority: 1,
          action: {
            type: "allow",
          },
          condition: {
            regexFilter: "https://.*/path/.*value.*",
            resourceTypes: ["main_frame"],
          },
        },
        {
          id: 2,
          priority: 1,
          action: {
            type: "redirect",
            redirect: {
              extensionPath: "/src/views/proxy.html",
            },
          },
          condition: {
            urlFilter: "https://*/path/*",
            resourceTypes: ["main_frame"],
          },
        },
      ],
    },
    () => {
      console.log("active rule");
    }
  );
};



proxy.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Proxy Extension</title>
    <script src="/src/content-script/proxy.js"></script>
  </head>
  <body></body>
</html>


proxy.js
window.onload = async () => {
  console.log("redirecciono");
  const response = await chrome.runtime.sendMessage({ getTF7Canal: true });
  console.log(response);
  chrome.tabs.update(response.tab.id, {
    url: response.url.includes("?")
      ? response.url + "&value=" + response.canal
      : response.url + "?value=" + response.canal,
  });
};

Manuel Delgado

unread,
Sep 14, 2023, 7:58:12 AM9/14/23
to Chromium Extensions, Manuel Delgado, Oliver Dunk, Chromium Extensions
bloqueo_extension.PNG

Chromium Extensions

unread,
Sep 19, 2023, 10:54:03 AM9/19/23
to Chromium Extensions, Manuel Delgado, Oliver Dunk, Chromium Extensions
Hi,

I has solved my problem. I redirect all request without query param "X" to extension's page. 

Here i control and inject the query params correctly. Also, i can show information to user. 

I have two rules, the first rule is "allow" and not redirect the request that contain the query param "X", the second rule redirect all request how i said.

The last problem i haved that i didn't gave  permissons for access to html of my extension. With "web_accessible_resources" i could solved.

Thanks for your support.

Oliver Dunk

unread,
Oct 13, 2023, 9:40:11 AM10/13/23
to Chromium Extensions, Chromium Extensions
Hi Manuel,

Sorry for the late reply but really glad you figured this one out.

Hope the rest of your development goes well :)

Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB
Reply all
Reply to author
Forward
0 new messages