Skip to content

Commit 4b87813

Browse files
authored
fix: avoid trailing ? when queryString option resolves to empty string (#459)
1 parent f883886 commit 4b87813

3 files changed

Lines changed: 88 additions & 2 deletions

File tree

index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,13 @@ const fastifyReplyFrom = fp(function from (fastify, opts, next) {
250250

251251
function getQueryString (search, reqUrl, opts, request) {
252252
if (typeof opts.queryString === 'function') {
253-
return '?' + opts.queryString(search, reqUrl, request)
253+
const qs = opts.queryString(search, reqUrl, request)
254+
return qs ? '?' + qs : ''
254255
}
255256

256257
if (opts.queryString) {
257-
return '?' + querystring.stringify(opts.queryString)
258+
const qs = querystring.stringify(opts.queryString)
259+
return qs ? '?' + qs : ''
258260
}
259261

260262
if (search.length > 0) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict'
2+
3+
const t = require('node:test')
4+
const Fastify = require('fastify')
5+
const { request } = require('undici')
6+
const From = require('..')
7+
const http = require('node:http')
8+
9+
const instance = Fastify()
10+
11+
t.test('queryString empty object should not append trailing ?', async (t) => {
12+
t.plan(4)
13+
t.after(() => instance.close())
14+
15+
const target = http.createServer((req, res) => {
16+
t.assert.ok('request proxied')
17+
t.assert.strictEqual(req.url, '/world')
18+
res.statusCode = 200
19+
res.setHeader('Content-Type', 'text/plain')
20+
res.end('hello world')
21+
})
22+
23+
instance.get('/hello', (_request, reply) => {
24+
reply.from(`http://localhost:${target.address().port}/world`, {
25+
queryString: {}
26+
})
27+
})
28+
29+
t.after(() => target.close())
30+
31+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
32+
33+
instance.register(From)
34+
35+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
36+
37+
const result = await request(`http://localhost:${instance.server.address().port}/hello`)
38+
39+
t.assert.strictEqual(result.statusCode, 200)
40+
t.assert.strictEqual(await result.body.text(), 'hello world')
41+
})
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict'
2+
3+
const t = require('node:test')
4+
const Fastify = require('fastify')
5+
const { request } = require('undici')
6+
const From = require('..')
7+
const http = require('node:http')
8+
9+
const instance = Fastify()
10+
11+
t.test('queryString function returning empty string should not append trailing ?', async (t) => {
12+
t.plan(4)
13+
t.after(() => instance.close())
14+
15+
const target = http.createServer((req, res) => {
16+
t.assert.ok('request proxied')
17+
t.assert.strictEqual(req.url, '/world')
18+
res.statusCode = 200
19+
res.setHeader('Content-Type', 'text/plain')
20+
res.end('hello world')
21+
})
22+
23+
instance.get('/hello', (_request, reply) => {
24+
reply.from(`http://localhost:${target.address().port}/world`, {
25+
queryString () {
26+
return ''
27+
}
28+
})
29+
})
30+
31+
t.after(() => target.close())
32+
33+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
34+
35+
instance.register(From)
36+
37+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
38+
39+
const result = await request(`http://localhost:${instance.server.address().port}/hello`)
40+
41+
t.assert.strictEqual(result.statusCode, 200)
42+
t.assert.strictEqual(await result.body.text(), 'hello world')
43+
})

0 commit comments

Comments
 (0)