diff --git a/packages/url/index.js b/packages/url/index.js index a7c4322..2631601 100644 --- a/packages/url/index.js +++ b/packages/url/index.js @@ -21,8 +21,8 @@ export function parse(req, toDecode) { let raw = req.url; if (raw == null) return; - let prev = req._parsedUrl; - if (prev && prev.raw === raw) return prev; + let prev=req._parsedUrl, encoded=!req._decoded; + if (prev && prev.raw === raw && !toDecode === encoded) return prev; let pathname=raw, search='', query; @@ -37,7 +37,7 @@ export function parse(req, toDecode) { } } - if (!!toDecode && !req._decoded) { + if (!!toDecode && encoded) { req._decoded = true; if (pathname.indexOf('%') !== -1) { try { pathname = decodeURIComponent(pathname) } diff --git a/packages/url/test/index.js b/packages/url/test/index.js index 694ae16..d9646af 100644 --- a/packages/url/test/index.js +++ b/packages/url/test/index.js @@ -210,4 +210,60 @@ test('url :: decode :: URI malformed', () => { }); }); +test('url :: decode :: cache :: hit', () => { + /** @type any */ + let req = { url: '/foo/hell%C3%B6' }; + let out1 = parse(req, true); + + // @ts-ignore + out1.foobar = 123; + + let out2 = parse(req, true); + + // @ts-ignore + assert.is(out2.foobar, 123); + assert.is(out1, out2, 'referential'); + assert.is(out1.pathname, '/foo/hellö'); +}); + +test('url :: decode :: cache :: miss #1', () => { + /** @type any */ + let req = { url: '/foo/hell%C3%B6?fizz=buzz' }; + let out1 = parse(req); + + assert.is(req._parsedUrl, out1); + assert.is(out1.pathname, '/foo/hell%C3%B6'); + + // @ts-ignore + out1.foobar = 123; + + let out2 = parse(req, true); + + // @ts-ignore + assert.is(out2.foobar, undefined); + assert.is.not(req._parsedUrl, out1); + assert.is.not(out1, out2, 'referential'); + assert.is(out2.pathname, '/foo/hellö'); +}); + +test('url :: decode :: cache :: miss #2', () => { + /** @type any */ + let req = { url: '/foo/hell%C3%B6?fizz=buzz' }; + let out1 = parse(req, true); + + assert.is(req._parsedUrl, out1); + assert.is(out1.pathname, '/foo/hellö'); + + // @ts-ignore + out1.foobar = 123; + + let out2 = parse(req); + + // @ts-ignore + assert.is(out2.foobar, undefined); + assert.is.not(req._parsedUrl, out1); + assert.is.not(out1, out2, 'referential'); + assert.is(out2.pathname, '/foo/hell%C3%B6'); +}); + test.run();