webdev icon indicating copy to clipboard operation
webdev copied to clipboard

DWDS requests are sent to wrong port

Open Wdestroier opened this issue 1 month ago • 6 comments

Hi!

I'm running webdev with the following command: cd dart_app & webdev serve web:7777 --hostname 0.0.0.0 --auto restart --tls-cert-chain=localhost.pem --tls-cert-key=localhost-key.pem. I have a reverse proxy locally to redirect requests where the URL path starts with /a to port 7777 (it also removes the /a).

Proxy configuration Image

For some reason, requests made to /$dwdsSseHandler are being sent directly to port 7777 and the page doesn't load. I created a client-side workaround:

Workaround

index.html:

  <script src="dwds-redirect.js"></script>
  <script defer src="main.dart.js"></script>

dwds-redirect.js:

// Redirect Dart Web Developer Service (DWDS) requests to port 5173.
(function () {
  'use strict';

  if (window.location.port !== '5173') {
    return;
  }

  const TARGET_PORT = 5173;
  const SSE_HANDLER_PATH = '/$dwdsSseHandler';

  // Intercept fetch requests.
  const originalFetch = window.fetch;
  window.fetch = function (input, init) {
    let url = typeof input === 'string' ? input : input.url;

    if (url && url.includes(SSE_HANDLER_PATH)) {
      try {
        const urlObj = new URL(url, window.location.origin);
        if (urlObj.pathname === SSE_HANDLER_PATH || urlObj.pathname.endsWith(SSE_HANDLER_PATH)) {
          urlObj.port = TARGET_PORT;
          urlObj.protocol = window.location.protocol;
          url = urlObj.toString();

          if (typeof input === 'string') {
            input = url;
          } else {
            input = new Request(url, input);
          }
        }
      } catch (e) {
        console.warn('Failed to redirect SSE handler URL:', e);
      }
    }

    return originalFetch.call(this, input, init);
  };

  // Intercept XMLHttpRequest.
  const originalOpen = XMLHttpRequest.prototype.open;
  XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
    if (url && url.includes(SSE_HANDLER_PATH)) {
      try {
        const urlObj = new URL(url, window.location.origin);
        if (urlObj.pathname === SSE_HANDLER_PATH || urlObj.pathname.endsWith(SSE_HANDLER_PATH)) {
          urlObj.port = TARGET_PORT;
          urlObj.protocol = window.location.protocol;
          url = urlObj.toString();
        }
      } catch (e) {
        console.warn('Failed to redirect SSE handler URL:', e);
      }
    }

    return originalOpen.call(this, method, url, async, user, password);
  };

  // Intercept EventSource (for SSE connections).
  const originalEventSource = window.EventSource;
  window.EventSource = function (url, eventSourceInitDict) {
    if (url && url.includes(SSE_HANDLER_PATH)) {
      try {
        const urlObj = new URL(url, window.location.origin);
        if (urlObj.pathname === SSE_HANDLER_PATH || urlObj.pathname.endsWith(SSE_HANDLER_PATH)) {
          urlObj.port = TARGET_PORT;
          urlObj.protocol = window.location.protocol;
          url = urlObj.toString();
        }
      } catch (e) {
        console.warn('Failed to redirect SSE handler URL:', e);
      }
    }

    return new originalEventSource(url, eventSourceInitDict);
  };

  console.log('DWDS SSE handler redirect configured to port ' + TARGET_PORT + '.');
})();

Can DWDS make requests to the correct port? A possible implementation is to try a port and if the request fails try another port.

Ideally I would also want to remove the --tls-cert-chain=localhost.pem --tls-cert-key=localhost-key.pem flags from webdev, but doing so the page stays blank and doesn't load, although all network requests succeed.

Wdestroier avatar Nov 07 '25 01:11 Wdestroier