Skip to content

Commit a8f531a

Browse files
authored
add support for trustProxy option (#769)
1 parent 381e810 commit a8f531a

File tree

4 files changed

+125
-10
lines changed

4 files changed

+125
-10
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ You can pass the following options via CLI arguments. You can also use `--config
171171
| Set the plugin timeout | `-T` | `--plugin-timeout` | `FASTIFY_PLUGIN_TIMEOUT` |
172172
| Defines the maximum payload, in bytes,<br>that the server is allowed to accept | | `--body-limit` | `FASTIFY_BODY_LIMIT` |
173173
| Set the maximum ms delay before forcefully closing pending requests after receiving SIGTERM or SIGINT signals; and uncaughtException or unhandledRejection errors (default: 500) | `-g` | `--close-grace-delay` | `FASTIFY_CLOSE_GRACE_DELAY` |
174+
| Set the boolean value for `trustProxy` (1st precedence) | | `--trust-proxy-enabled` | `FASTIFY_TRUST_PROXY_ENABLED` |
175+
| Set the IP/CIDR value for `trustProxy` (2nd precedence) | | `--trust-proxy-ips` | `FASTIFY_TRUST_PROXY_IPS` |
176+
| Set the nth hop value for `trustProxy` (3rd precedence) | | `--trust-proxy-hop` | `FASTIFY_TRUST_PROXY_HOP` |
174177

175178
By default `fastify-cli` runs [`dotenv`](https://www.npmjs.com/package/dotenv), so it will load all the env variables stored in `.env` in your current working directory.
176179

args.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ module.exports = function parseArgs (args) {
2727
configuration: {
2828
'populate--': true
2929
},
30-
number: ['port', 'inspect-port', 'body-limit', 'plugin-timeout', 'close-grace-delay'],
31-
string: ['log-level', 'address', 'socket', 'prefix', 'ignore-watch', 'logging-module', 'debug-host', 'lang', 'require', 'import', 'config', 'method'],
32-
boolean: ['pretty-logs', 'options', 'watch', 'verbose-watch', 'debug', 'standardlint', 'common-prefix', 'include-hooks'],
30+
number: ['port', 'inspect-port', 'body-limit', 'plugin-timeout', 'close-grace-delay', 'trust-proxy-hop'],
31+
string: ['log-level', 'address', 'socket', 'prefix', 'ignore-watch', 'logging-module', 'debug-host', 'lang', 'require', 'import', 'config', 'method', 'trust-proxy-ips'],
32+
boolean: ['pretty-logs', 'options', 'watch', 'verbose-watch', 'debug', 'standardlint', 'common-prefix', 'include-hooks', 'trust-proxy-enabled'],
3333
envPrefix: 'FASTIFY_',
3434
alias: {
3535
port: ['p'],
@@ -67,6 +67,12 @@ module.exports = function parseArgs (args) {
6767
// Merge objects from lower to higher priority
6868
const parsedArgs = { ...DEFAULT_ARGUMENTS, ...configFileOptions, ...commandLineArguments }
6969

70+
// Set `trustProxy` with enabled taking precedence, followed by IPs and finally hop count
71+
const trustProxyEnabled = parsedArgs.trustProxyEnabled === undefined
72+
? undefined
73+
: parsedArgs.trustProxyEnabled === true || parsedArgs.trustProxyEnabled === 'true'
74+
const trustProxy = trustProxyEnabled || parsedArgs.trustProxyIps || parsedArgs.trustProxyHop
75+
7076
return {
7177
_: parsedArgs._,
7278
'--': additionalArgs,
@@ -93,6 +99,7 @@ module.exports = function parseArgs (args) {
9399
lang: parsedArgs.lang,
94100
method: parsedArgs.method,
95101
commonPrefix: parsedArgs.commonPrefix,
96-
includeHooks: parsedArgs.includeHooks
102+
includeHooks: parsedArgs.includeHooks,
103+
trustProxy
97104
}
98105
}

start.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ async function runFastify (args, additionalOptions, serverOptions) {
165165
options = deepmerge(options, file.options)
166166
}
167167

168+
if (opts.trustProxy) {
169+
options.trustProxy = opts.trustProxy
170+
}
171+
168172
const fastify = Fastify(options)
169173

170174
if (opts.prefix) {

test/args.test.js

Lines changed: 107 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ test('should parse args correctly', t => {
2626
'--debug-port', 1111,
2727
'--debug-host', '1.1.1.1',
2828
'--logging-module', './custom-logger.js',
29+
'--trust-proxy-enabled', 'true',
2930
'app.js'
3031
]
3132
const parsedArgs = parseArgs(argv)
@@ -56,7 +57,8 @@ test('should parse args correctly', t => {
5657
lang: 'js',
5758
method: undefined,
5859
commonPrefix: false,
59-
includeHooks: undefined
60+
includeHooks: undefined,
61+
trustProxy: true
6062
})
6163
})
6264

@@ -83,6 +85,7 @@ test('should parse args with = assignment correctly', t => {
8385
'--debug-port', 1111,
8486
'--debug-host', '1.1.1.1',
8587
'--logging-module', './custom-logger.js',
88+
'--trust-proxy-hop', '2',
8689
'app.js'
8790
]
8891
const parsedArgs = parseArgs(argv)
@@ -113,7 +116,8 @@ test('should parse args with = assignment correctly', t => {
113116
lang: 'js',
114117
method: undefined,
115118
commonPrefix: false,
116-
includeHooks: undefined
119+
includeHooks: undefined,
120+
trustProxy: 2
117121
})
118122
})
119123

@@ -139,6 +143,7 @@ test('should parse env vars correctly', t => {
139143
process.env.FASTIFY_DEBUG_PORT = '1111'
140144
process.env.FASTIFY_DEBUG_HOST = '1.1.1.1'
141145
process.env.FASTIFY_LOGGING_MODULE = './custom-logger.js'
146+
process.env.FASTIFY_TRUST_PROXY_ENABLED = 'true'
142147

143148
t.after(() => {
144149
delete process.env.FASTIFY_PORT
@@ -159,6 +164,7 @@ test('should parse env vars correctly', t => {
159164
delete process.env.FASTIFY_DEBUG
160165
delete process.env.FASTIFY_DEBUG_PORT
161166
delete process.env.FASTIFY_LOGGING_MODULE
167+
delete process.env.FASTIFY_TRUST_PROXY_ENABLED
162168
})
163169

164170
const parsedArgs = parseArgs([])
@@ -189,7 +195,8 @@ test('should parse env vars correctly', t => {
189195
lang: 'js',
190196
method: undefined,
191197
commonPrefix: false,
192-
includeHooks: undefined
198+
includeHooks: undefined,
199+
trustProxy: true
193200
})
194201
})
195202

@@ -283,7 +290,8 @@ test('should parse custom plugin options', t => {
283290
lang: 'js',
284291
method: undefined,
285292
commonPrefix: false,
286-
includeHooks: undefined
293+
includeHooks: undefined,
294+
trustProxy: undefined
287295
})
288296
})
289297

@@ -322,7 +330,8 @@ test('should parse config file correctly and prefer config values over default o
322330
lang: 'js',
323331
method: undefined,
324332
commonPrefix: false,
325-
includeHooks: undefined
333+
includeHooks: undefined,
334+
trustProxy: undefined
326335
})
327336
})
328337

@@ -365,6 +374,98 @@ test('should prefer command line args over config file options', t => {
365374
lang: 'js',
366375
method: undefined,
367376
commonPrefix: false,
368-
includeHooks: undefined
377+
includeHooks: undefined,
378+
trustProxy: undefined
379+
})
380+
})
381+
382+
test('should favor trust proxy enabled over trust proxy ips and trust proxy hop', t => {
383+
t.plan(1)
384+
385+
const argv = [
386+
'--port', '4000',
387+
'--close-grace-delay', '30000',
388+
'--debug-port', '1111',
389+
'--debug-host', '1.1.1.1',
390+
'--trust-proxy-enabled', 'true',
391+
'--trust-proxy-ips', '127.0.0.1',
392+
'--trust-proxy-hop', '2',
393+
'app.js'
394+
]
395+
const parsedArgs = parseArgs(argv)
396+
397+
t.assert.deepStrictEqual(parsedArgs, {
398+
_: ['app.js'],
399+
'--': [],
400+
port: 4000,
401+
bodyLimit: undefined,
402+
pluginTimeout: 10000,
403+
closeGraceDelay: 30000,
404+
pluginOptions: {},
405+
prettyLogs: false,
406+
options: false,
407+
watch: false,
408+
debug: false,
409+
debugPort: 1111,
410+
debugHost: '1.1.1.1',
411+
ignoreWatch: 'node_modules build dist .git bower_components logs .swp .nyc_output',
412+
verboseWatch: false,
413+
logLevel: 'fatal',
414+
address: undefined,
415+
socket: undefined,
416+
require: undefined,
417+
import: undefined,
418+
prefix: undefined,
419+
loggingModule: undefined,
420+
lang: 'js',
421+
method: undefined,
422+
commonPrefix: false,
423+
includeHooks: undefined,
424+
trustProxy: true
425+
})
426+
})
427+
428+
test('should favor trust proxy ips over trust proxy hop', t => {
429+
t.plan(1)
430+
431+
const argv = [
432+
'--port', '4000',
433+
'--close-grace-delay', '30000',
434+
'--debug-port', '1111',
435+
'--debug-host', '1.1.1.1',
436+
'--trust-proxy-ips', '127.0.0.1',
437+
'--trust-proxy-hop', '2',
438+
'app.js'
439+
]
440+
const parsedArgs = parseArgs(argv)
441+
442+
t.assert.deepStrictEqual(parsedArgs, {
443+
_: ['app.js'],
444+
'--': [],
445+
port: 4000,
446+
bodyLimit: undefined,
447+
pluginTimeout: 10000,
448+
closeGraceDelay: 30000,
449+
pluginOptions: {},
450+
prettyLogs: false,
451+
options: false,
452+
watch: false,
453+
debug: false,
454+
debugPort: 1111,
455+
debugHost: '1.1.1.1',
456+
ignoreWatch: 'node_modules build dist .git bower_components logs .swp .nyc_output',
457+
verboseWatch: false,
458+
logLevel: 'fatal',
459+
address: undefined,
460+
socket: undefined,
461+
require: undefined,
462+
import: undefined,
463+
prefix: undefined,
464+
loggingModule: undefined,
465+
lang: 'js',
466+
method: undefined,
467+
commonPrefix: false,
468+
includeHooks: undefined,
469+
trustProxy: '127.0.0.1'
369470
})
370471
})

0 commit comments

Comments
 (0)