diff --git a/Readme.md b/Readme.md index 85736f6..b8aa80a 100644 --- a/Readme.md +++ b/Readme.md @@ -16,13 +16,13 @@ fastify.register(require('@fastify/url-data')) fastify.get('/foo', (req, reply) => { const urlData = req.urlData() - req.log.info(urlData.path) // '/foo' - req.log.info(urlData.query) // 'a=b&c=d' - req.log.info(urlData.host) // '127.0.0.1' + req.log.info(urlData.pathname) // '/foo' + req.log.info(urlData.search) // '?a=b&c=d' + req.log.info(urlData.hostname) // '127.0.0.1' req.log.info(urlData.port) // 8080 // if you just need single data: - req.log.info(req.urlData('path')) // '/foo' + req.log.info(req.urlData('pathname')) // '/foo' reply.send({hello: 'world'}) }) diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js new file mode 100644 index 0000000..741503c --- /dev/null +++ b/benchmark/benchmark.js @@ -0,0 +1,45 @@ +const benchmark = require('benchmark') +const Fastify = require('fastify') +const plugin = require('../plugin') + +async function getFastify () { + const fastify = Fastify() + fastify.register(plugin).after((err) => { + if (err) console.error(err) + }) + + fastify.get('/one', (req, reply) => { + req.urlData() + reply.send() + }) + + try { + await fastify.listen({ port: 3000 }) + } catch (err) { + process.exit(1) + } + + return fastify +} + +const bench = async () => { + const fastify = await getFastify() + + new benchmark.Suite() + .add('urlData', async function () { + await fastify.inject({ + method: 'GET', + url: '/one?a=b&c=d#foo' + }) + }) + .on('cycle', function (event) { + console.log(String(event.target)) + }) + .on('complete', function () { + console.log('Fastest is ' + this.filter('fastest').map('name')) + fastify.close() + }) + .run({ async: true }) +} + +bench() diff --git a/package.json b/package.json index 985ac70..db752a6 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "devDependencies": { "@fastify/pre-commit": "^2.0.2", "@types/node": "^20.1.0", + "benchmark": "^2.1.4", "fastify": "^4.0.0-rc.2", "h2url": "^0.2.0", "semver": "^7.3.2", @@ -40,7 +41,6 @@ "tsd": "~0.30.0" }, "dependencies": { - "fast-uri": "^2.2.0", "fastify-plugin": "^4.0.0" }, "publishConfig": { diff --git a/plugin.js b/plugin.js index fec8923..09bf80f 100644 --- a/plugin.js +++ b/plugin.js @@ -1,16 +1,16 @@ 'use strict' const fp = require('fastify-plugin') -const fastUri = require('fast-uri') function fastifyUrlData (fastify, options, next) { fastify.decorateRequest('urlData', function (key) { const scheme = this.headers[':scheme'] ? this.headers[':scheme'] : this.protocol const host = this.hostname const path = this.headers[':path'] || this.raw.url - const urlData = fastUri.parse(scheme + '://' + host + path) - if (key) return urlData[key] - return urlData + const url = new URL(scheme + '://' + host + path) + + if (key) return url[key] + return url }) next() } diff --git a/test/tests.test.js b/test/tests.test.js index c8c69b0..813d01f 100644 --- a/test/tests.test.js +++ b/test/tests.test.js @@ -12,12 +12,12 @@ const urlHost = 'localhost' const urlForwardedHost = 'example.com' const urlPath = '/one' const urlQuery = 'a=b&c=d' -const httpScheme = 'http' -const httpsScheme = 'https' +const httpScheme = 'http:' +const httpsScheme = 'https:' test('parses a full URI', (t) => { t.plan(10) - let port + let port = '' const fastify = Fastify() fastify @@ -28,16 +28,16 @@ test('parses a full URI', (t) => { fastify.get(urlPath, (req, reply) => { const uriData = req.urlData() - t.equal(uriData.host, urlHost) + t.equal(uriData.hostname, urlHost) t.equal(uriData.port, port) - t.equal(uriData.path, urlPath) - t.equal(uriData.query, urlQuery) - t.equal(uriData.scheme, httpScheme) - t.equal(req.urlData('host'), urlHost) + t.equal(uriData.pathname, urlPath) + t.equal(uriData.search, `?${urlQuery}`) + t.equal(uriData.protocol, httpScheme) + t.equal(req.urlData('hostname'), urlHost) t.equal(req.urlData('port'), port) - t.equal(req.urlData('path'), urlPath) - t.equal(req.urlData('query'), urlQuery) - t.equal(req.urlData('scheme'), httpScheme) + t.equal(req.urlData('pathname'), urlPath) + t.equal(req.urlData('search'), `?${urlQuery}`) + t.equal(req.urlData('protocol'), httpScheme) reply.send() }) @@ -45,7 +45,7 @@ test('parses a full URI', (t) => { fastify.server.unref() if (err) t.threw(err) - port = fastify.server.address().port + port = fastify.server.address().port.toString() http .get(`http://${urlHost}:${port}${urlPath}?${urlQuery}#foo`, () => {}) .on('error', t.threw) @@ -59,7 +59,7 @@ test('parses a full URI in HTTP2', { skip: semver.lt(process.versions.node, '8.8 const h2url = require('h2url') - let port + let port = '' let fastify try { fastify = Fastify({ @@ -82,16 +82,16 @@ test('parses a full URI in HTTP2', { skip: semver.lt(process.versions.node, '8.8 fastify.get(urlPath, (req, reply) => { const uriData = req.urlData() - t.equal(uriData.host, urlHost) + t.equal(uriData.hostname, urlHost) t.equal(uriData.port, port) - t.equal(uriData.path, urlPath) - t.equal(uriData.query, urlQuery) - t.equal(uriData.scheme, httpsScheme) - t.equal(req.urlData('host'), urlHost) + t.equal(uriData.pathname, urlPath) + t.equal(uriData.search, `?${urlQuery}`) + t.equal(uriData.protocol, httpsScheme) + t.equal(req.urlData('hostname'), urlHost) t.equal(req.urlData('port'), port) - t.equal(req.urlData('path'), urlPath) - t.equal(req.urlData('query'), urlQuery) - t.equal(req.urlData('scheme'), httpsScheme) + t.equal(req.urlData('pathname'), urlPath) + t.equal(req.urlData('search'), `?${urlQuery}`) + t.equal(req.urlData('protocol'), httpsScheme) reply.send() }) @@ -99,7 +99,7 @@ test('parses a full URI in HTTP2', { skip: semver.lt(process.versions.node, '8.8 fastify.server.unref() if (err) t.threw(err) - port = fastify.server.address().port + port = fastify.server.address().port.toString() h2url.concat({ url: `https://${urlHost}:${port}${urlPath}?${urlQuery}#foo` }).then(() => {}) }) @@ -108,7 +108,7 @@ test('parses a full URI in HTTP2', { skip: semver.lt(process.versions.node, '8.8 test('parses a full URI using X-Forwarded-Host when trustProxy is set', (t) => { t.plan(10) - let port + let port = '' const fastify = Fastify({ trustProxy: true }) // Setting trustProxy true will use X-Forwarded-Host header if set fastify @@ -119,16 +119,16 @@ test('parses a full URI using X-Forwarded-Host when trustProxy is set', (t) => { fastify.get(urlPath, (req, reply) => { const uriData = req.urlData() - t.equal(uriData.host, urlForwardedHost) + t.equal(uriData.hostname, urlForwardedHost) t.equal(uriData.port, port) - t.equal(uriData.path, urlPath) - t.equal(uriData.query, urlQuery) - t.equal(uriData.scheme, httpScheme) - t.equal(req.urlData('host'), urlForwardedHost) + t.equal(uriData.pathname, urlPath) + t.equal(uriData.search, `?${urlQuery}`) + t.equal(uriData.protocol, httpScheme) + t.equal(req.urlData('hostname'), urlForwardedHost) t.equal(req.urlData('port'), port) - t.equal(req.urlData('path'), urlPath) - t.equal(req.urlData('query'), urlQuery) - t.equal(req.urlData('scheme'), httpScheme) + t.equal(req.urlData('pathname'), urlPath) + t.equal(req.urlData('search'), `?${urlQuery}`) + t.equal(req.urlData('protocol'), httpScheme) reply.send() }) @@ -136,7 +136,7 @@ test('parses a full URI using X-Forwarded-Host when trustProxy is set', (t) => { fastify.server.unref() if (err) t.threw(err) - port = fastify.server.address().port + port = fastify.server.address().port.toString() http .get(`http://${urlHost}:${port}${urlPath}?${urlQuery}#foo`, { headers: { 'X-Forwarded-Host': `${urlForwardedHost}:${port}` } }, () => {}) .on('error', t.threw) @@ -147,7 +147,7 @@ test('parses a full URI using X-Forwarded-Host when trustProxy is set', (t) => { test('parses a full URI ignoring X-Forwarded-Host when trustProxy is not set', (t) => { t.plan(10) - let port + let port = '' const fastify = Fastify() fastify @@ -158,16 +158,16 @@ test('parses a full URI ignoring X-Forwarded-Host when trustProxy is not set', ( fastify.get(urlPath, (req, reply) => { const uriData = req.urlData() - t.equal(uriData.host, urlHost) + t.equal(uriData.hostname, urlHost) t.equal(uriData.port, port) - t.equal(uriData.path, urlPath) - t.equal(uriData.query, urlQuery) - t.equal(uriData.scheme, httpScheme) - t.equal(req.urlData('host'), urlHost) + t.equal(uriData.pathname, urlPath) + t.equal(uriData.search, `?${urlQuery}`) + t.equal(uriData.protocol, httpScheme) + t.equal(req.urlData('hostname'), urlHost) t.equal(req.urlData('port'), port) - t.equal(req.urlData('path'), urlPath) - t.equal(req.urlData('query'), urlQuery) - t.equal(req.urlData('scheme'), httpScheme) + t.equal(req.urlData('pathname'), urlPath) + t.equal(req.urlData('search'), `?${urlQuery}`) + t.equal(req.urlData('protocol'), httpScheme) reply.send() }) @@ -175,7 +175,7 @@ test('parses a full URI ignoring X-Forwarded-Host when trustProxy is not set', ( fastify.server.unref() if (err) t.threw(err) - port = fastify.server.address().port + port = fastify.server.address().port.toString() http .get(`http://${urlHost}:${port}${urlPath}?${urlQuery}#foo`, { headers: { 'X-Forwarded-Host': `${urlForwardedHost}:${port}` } }, () => {}) .on('error', t.threw) diff --git a/types/fastify-url-data.d.ts b/types/fastify-url-data.d.ts index b72f8f7..7fca6a7 100644 --- a/types/fastify-url-data.d.ts +++ b/types/fastify-url-data.d.ts @@ -1,12 +1,11 @@ import { FastifyPluginCallback } from 'fastify'; -import { URIComponent } from 'fast-uri' type FastifyUrlData = FastifyPluginCallback declare module 'fastify' { interface FastifyRequest { - urlData(target: K): URIComponent[K] - urlData(): URIComponent + urlData(target: K): URL[K] + urlData(): URL } } diff --git a/types/fastify-url-data.test-d.ts b/types/fastify-url-data.test-d.ts index 8c49353..0c3ed65 100644 --- a/types/fastify-url-data.test-d.ts +++ b/types/fastify-url-data.test-d.ts @@ -7,14 +7,13 @@ const server = fastify(); server.register(urlData) server.get('/data', (req, reply) => { - console.log(req.urlData) - expectType(req.urlData().path); - expectType(req.urlData().host); - expectType(req.urlData().port); - expectType(req.urlData().query); + expectType(req.urlData().pathname); + expectType(req.urlData().hostname); + expectType(req.urlData().port); + expectType(req.urlData().search); - expectType(req.urlData('path')); - expectType(req.urlData('port')); + expectType(req.urlData('pathname')); + expectType(req.urlData('port')); reply.send({msg: 'ok'}) })