Skip to content

Trailing slash on origin causes interceptors to not match #3649

@tswaters

Description

@tswaters

Bug Description

Let me first say, I'm not sure if this is a bug exactly, but it did cause me a headache for an hour or two while I was trying to figure it out.

Reproducible By

const { MockAgent } = require('undici')

const undiciGlobalDispatcherSymbol = Symbol.for('undici.globalDispatcher.1')
const undiciGlobalDispatcher = global[undiciGlobalDispatcherSymbol]
if (!undiciGlobalDispatcher) throw new Error('Could not find the global Undici dispatcher')

const mockAgent = new MockAgent();
mockAgent.disableNetConnect();
global[undiciGlobalDispatcherSymbol] = mockAgent;

const pool = mockAgent.get("https://localhost");

pool.intercept({ path: "/api/some-path" }).reply(200, { ok: true });

const res = await fetch(new URL("/api/some-path", "https://localhost"));
const data = await res.json();

console.log(data);

// restore
global[undiciGlobalDispatcherSymbol] = undiciGlobalDispatcher;

Expected Behavior

Some kind of error or warning saying it's unexpected behaviour, or maybe just removing it for the user?

Logs & Screenshots

The above code will output:

TypeError: fetch failed
    at node:internal/deps/undici/undici:13178:13
    at async main (/home/local.epicure.ca/tyler.waters/code/GITHUB/undici-global-node-fetch-interceptor/index.js:19:17) {
  [cause]: MockNotMatchedError: Mock dispatch not matched for path '/api/some-path': subsequent request to origin https://localhost was not allowed (net.connect disabled)
      at MockPool.dispatch (/home/local.epicure.ca/tyler.waters/code/GITHUB/undici-global-node-fetch-interceptor/node_modules/undici/lib/mock/mock-utils.js:313:19)
      at [dispatch] (/home/local.epicure.ca/tyler.waters/code/GITHUB/undici-global-node-fetch-interceptor/node_modules/undici/lib/dispatcher/agent.js:105:23)
      at Intercept (/home/local.epicure.ca/tyler.waters/code/GITHUB/undici-global-node-fetch-interceptor/node_modules/undici/lib/interceptor/redirect-interceptor.js:11:16)
      at [Intercepted Dispatch] (/home/local.epicure.ca/tyler.waters/code/GITHUB/undici-global-node-fetch-interceptor/node_modules/undici/lib/dispatcher/dispatcher-base.js:156:12)
      at Agent.dispatch (/home/local.epicure.ca/tyler.waters/code/GITHUB/undici-global-node-fetch-interceptor/node_modules/undici/lib/dispatcher/dispatcher-base.js:177:40)
      at MockAgent.dispatch (/home/local.epicure.ca/tyler.waters/code/GITHUB/undici-global-node-fetch-interceptor/node_modules/undici/lib/mock/mock-agent.js:55:25)
      at node:internal/deps/undici/undici:10827:55
      at new Promise (<anonymous>)
      at dispatch (node:internal/deps/undici/undici:10827:16)
      at httpNetworkFetch (node:internal/deps/undici/undici:10724:73) {
    code: 'UND_MOCK_ERR_MOCK_NOT_MATCHED'
  }
}

Removing the trailing slash results in:

{ ok: true }

Environment

+ uname -srvmo
Linux 6.10.10-100.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Sep 12 16:02:41 UTC 2024 x86_64 GNU/Linux
+ npm -v
10.8.1
+ node -p process.versions
{
  node: '20.16.0',
  acorn: '8.11.3',
  ada: '2.8.0',
  ares: '1.31.0',
  base64: '0.5.2',
  brotli: '1.1.0',
  cjs_module_lexer: '1.2.2',
  cldr: '45.0',
  icu: '75.1',
  llhttp: '8.1.2',
  modules: '115',
  napi: '9',
  nghttp2: '1.61.0',
  nghttp3: '0.7.0',
  ngtcp2: '1.1.0',
  openssl: '3.0.13+quic',
  simdutf: '5.2.8',
  tz: '2024a',
  undici: '6.19.2',
  unicode: '15.1',
  uv: '1.46.0',
  uvwasi: '0.0.21',
  v8: '11.3.244.8-node.23',
  zlib: '1.3.0.1-motley-209717d'
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmocksIssues/PRs related to mocks feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions