2

I was trying to intercept ws messages in my chrome devtools extension.

This question helped me. This is exactly what I need, but the only problem is that it this works only if websocket messeages are sent from the page context (I guess because the debugger is attached to that tab specifically?) but in the page i'm trying to intercept the messages the ws connection is stablished in a web worker.

My main question, is there a way in a chrome devtools extensions to "attach" a debugger to a web-worker? Or maybe I am missing something here?

Thanks for you help.

Pablo Meni
  • 87
  • 9
  • I've created a bug report here: https://bugs.chromium.org/p/chromium/issues/detail?id=1281852#makechanges – teg_brightly Dec 21 '21 at 11:53
  • I've been inspecting CDP commands using protocol monitor and it seems that Debugger has to be attached to workers separately. They are treated as separate targets. DevTools are using Target domain (such as Target.setAutoAttach for example) – teg_brightly Jan 01 '22 at 17:33

2 Answers2

2

Found the reason.

I won't be able to intercept the WebSockets frames in the page I needed with the chrome.debugger API.

Apparently, it seems extensions lack access to contexts loaded via about:, data: and blob: schemes and I wanted to intercept the WebSocket frames establishes the connection in a worker that is loaded via a blob url.

See related Chrome bugs:
https://bugs.chromium.org/p/chromium/issues/detail?id=55084 https://bugs.chromium.org/p/chromium/issues/detail?id=388972

It's also a bug in FF:
https://bugzilla.mozilla.org/show_bug.cgi?id=1475831

Pablo Meni
  • 87
  • 9
1

Workers are treated as different targets related to the tabId target in this case: https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-setAutoAttach

To receive WebSocket events from Workers, one should first send 'Target.setAutoAttach' command, and then listen to 'Target.attachedToTarget' events, and then attach debugger to Workers like this:

const version = '1.3';

async function onAttach(debuggeeId) {
  /** Enable receiving 'Target.attachedToTarget' events */
  await chrome.debugger.sendCommand(debuggeeId, 'Target.setAutoAttach', {
    autoAttach: true,
    waitForDebuggerOnStart: true,
    flatten: true,
  }); //
  /** Enable Network events for the current tab */
  chrome.debugger.sendCommand(debuggeeId, 'Network.enable');
}

function allEventHandler(debuggeeId, message, params) {
  /** When workers are created, 'Target.attachedToTarget' events are fired */
  if (message === 'Target.attachedToTarget') {
    /** Attach debugger to workers */
    chrome.debugger.attach(
      { targetId: params.targetInfo.targetId },
      version,
      () => {
        /** Enable Network for workers to receive WebSocket events */
        chrome.debugger.sendCommand(
          { targetId: params.targetInfo.targetId },
          'Network.enable'
        );
      }
    );
  } else {
    console.log(message, params);
  }
}

chrome.debugger.onEvent.addListener(allEventHandler);

/** Click extension icon to attach debugger to the current tab */
chrome.action.onClicked.addListener(function (tab) {
  const tabId = tab.id;
  const debuggeeId = { tabId };
  chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
});

slhck
  • 36,575
  • 28
  • 148
  • 201
teg_brightly
  • 468
  • 6
  • 20
  • Thanks! This was exactly what I needed. However my code has changed a bit since I made this question and now my worker code is not loaded anymore through a blob url, now the worker code comes form an ordinary http request. But I guess this probably would work in my previous situation too. – Pablo Meni Mar 08 '22 at 11:49