Skip to content

[🐛 Bug]: [nodejs] driver.quit() hangs for 30+ seconds or throws when proxy response contains multiple Set-Cookie headers #16778

@kalinichenko

Description

@kalinichenko

Description

When using Firefox with selenium-webdriver configured to route traffic through an HTTP MITM proxy, driver.quit() hangs for approximately 30 seconds if the proxy response contains 2 or more Set-Cookie headers. With 0-1 cookies, driver.quit() completes in <500ms.

This scenario worked previously without issues. As a workaround, we now need to filter out Firefox internal domains (firefox.settings.services.mozilla.com, detectportal.firefox.com, etc.) to prevent cookies from being set on these responses.

Reproducible Code

import selenium from "selenium-webdriver";
import firefox from "selenium-webdriver/firefox.js";
import { Proxy } from "http-mitm-proxy";

import * as http from 'node:http';



// http server
const server = http.createServer((req, res) => {
  res.end('OK')
}).listen(3000);


// proxy
const proxy = new Proxy();
proxy
.onResponse((ctx, callback) => {
  const hostname = ctx.clientToProxyRequest.headers.host.split(':')[0];
  if (hostname !== 'localhost' && hostname !== '127.0.0.1') {
    ctx.proxyToClientResponse.setHeader("Set-Cookie", [
      "proxy_a=1; Path=/",
      "proxy_b=2; Path=/",
    ]);
    console.log('Added cookies to response for ', hostname, ctx.serverToProxyResponse.statusCode);
  }
  callback();
})
.onError((ctx, err, errorKind) => {
  console.error('[PROXY ERROR]', errorKind, err.message);
})
.listen({ port: 3001, host: '127.0.0.1' });

(async () => {


  const firefoxOptions = new firefox.Options()

  // Set custom Firefox binary path (optional)
  // firefoxOptions.setBinary('/Applications/Firefox.app/Contents/MacOS/firefox');


  firefoxOptions.addArguments('--headless')
  firefoxOptions.setPreference('network.proxy.type', 1);              // manual
  firefoxOptions.setPreference('network.proxy.http', '127.0.0.1');
  firefoxOptions.setPreference('network.proxy.http_port', 3001);
  firefoxOptions.setPreference("network.proxy.ssl", "127.0.0.1")
  firefoxOptions.setPreference("network.proxy.ssl_port", 3001)
  firefoxOptions.setPreference("network.proxy.no_proxies_on", "");
  firefoxOptions.setPreference("network.proxy.allow_hijacking_localhost", true);


  const service = new firefox.ServiceBuilder()

  const builder = new selenium.Builder()
    .forBrowser(selenium.Browser.FIREFOX)
    .setFirefoxService(service)

    builder.setFirefoxOptions(firefoxOptions)
    builder.withCapabilities({
      acceptInsecureCerts: true,
    })

  const driver = await builder.build()

  const capabilities = await driver.getCapabilities();
  const browserVersion = capabilities.get('browserVersion');
  console.log('Firefox version:', browserVersion);

  try {
    await driver.get("http://127.0.0.1:3000");

  } finally {
    const now = Date.now();
    console.log('Starting driver.quit()');
    await driver.quit();
    console.log('driver.quit() completed in', Date.now() - now, 'ms');
    proxy.close();
    server.close();
  }
})();

Debugging Logs

======== Works as expected with FF 145 ========
starting server for firefox.settings.services.mozilla.com
https server started for firefox.settings.services.mozilla.com on 60870
Added cookies to response for  firefox.settings.services.mozilla.com 200
Added cookies to response for  detectportal.firefox.com 200
Firefox version: 145.0
Starting driver.quit()
driver.quit() completed in 405 ms

===== Hangs and throws with FF 146 ======
starting server for firefox.settings.services.mozilla.com
https server started for firefox.settings.services.mozilla.com on 60905
Added cookies to response for  firefox.settings.services.mozilla.com 200
Added cookies to response for  detectportal.firefox.com 200
Firefox version: 146.0.1
Starting driver.quit()
node_modules/selenium-webdriver/lib/error.js:523
    let err = new ctor(data.message)
              ^

WebDriverError: Failed to decode response from marionette
    at Object.throwDecodedError (node_modules/selenium-webdriver/lib/error.js:523:15)
    at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:524:13)
    at Executor.execute (node_modules/selenium-webdriver/lib/http.js:456:28)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async Driver.execute (node_modules/selenium-webdriver/lib/webdriver.js:745:17)
    at async Object.thenFinally [as finally] (node_modules/selenium-webdriver/lib/promise.js:100:5)
    at async file://selenium-firefox.js:76:5 {
  remoteStacktrace: ''
}

ℹ️ Last known working version: Firefox 145

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-needs-triagingA Selenium member will evaluate this soon!C-nodejsJavaScript BindingsD-firefoxI-defectSomething is not working as intendedI-regressionSomething was working but we "fixed" itOS-mac

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions