Attach debugger to worker from chrome devtools extension

Viewed 428

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.

2 Answers

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

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));
});

Related