Skip to content

Commit

Permalink
fix: return 502 on invalid upstream status code (#386)
Browse files Browse the repository at this point in the history
* fix: return 502 on invalid upstream status code

* chore: move warning log into error handler

Co-authored-by: Dan Castillo <[email protected]>
Signed-off-by: Simon Schoonjans <[email protected]>

* chore: apply suggestion to always map to badGatewayError

---------

Signed-off-by: Simon Schoonjans <[email protected]>
Co-authored-by: Dan Castillo <[email protected]>
  • Loading branch information
simosho and dancastillo authored Nov 18, 2024
1 parent 7a344ea commit b313122
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
11 changes: 9 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const {
ConnectionResetError,
ConnectTimeoutError,
UndiciSocketError,
InternalServerError
InternalServerError,
BadGatewayError
} = require('./lib/errors')

const fastifyReplyFrom = fp(function from (fastify, opts, next) {
Expand Down Expand Up @@ -199,7 +200,13 @@ const fastifyReplyFrom = fp(function from (fastify, opts, next) {
} else {
copyHeaders(rewriteHeaders(res.headers, this.request), this)
}
this.code(res.statusCode)
try {
this.code(res.statusCode)
} catch (err) {
// Since we know `FST_ERR_BAD_STATUS_CODE` will be recieved
onError(this, { error: new BadGatewayError() })
this.request.log.warn(err, 'response has invalid status code')
}
if (onResponse) {
onResponse(this.request, this, res)
} else {
Expand Down
1 change: 1 addition & 0 deletions lib/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ module.exports.ConnectionResetError = createError('ECONNRESET', 'Connection Rese
module.exports.ConnectTimeoutError = createError('UND_ERR_CONNECT_TIMEOUT', 'Connect Timeout Error', 500)
module.exports.UndiciSocketError = createError('UND_ERR_SOCKET', 'Undici Socket Error', 500)
module.exports.InternalServerError = createError('FST_REPLY_FROM_INTERNAL_SERVER_ERROR', '%s', 500)
module.exports.BadGatewayError = createError('FST_REPLY_FROM_BAD_GATEWAY', 'Bad Gateway', 502)
52 changes: 52 additions & 0 deletions test/on-invalid-upstream-response.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict'

const t = require('tap')
const Fastify = require('fastify')
const From = require('..')
const http = require('node:http')
const get = require('simple-get').concat

const instance = Fastify()
instance.register(From)

t.plan(8)
t.teardown(instance.close.bind(instance))

const target = http.createServer((req, res) => {
t.pass('request proxied')
t.equal(req.method, 'GET')
res.statusCode = 888
res.end('non-standard status code')
})

instance.get('/', (_, reply) => {
reply.from(`http://localhost:${target.address().port}`, {
onResponse: (_, reply, res) => {
t.equal(res.statusCode, 888)
}
})
})

t.teardown(target.close.bind(target))

instance.listen({ port: 0 }, (err) => {
t.error(err)

target.listen({ port: 0 }, (err) => {
t.error(err)

get(
`http://localhost:${instance.server.address().port}`,
(err, res, data) => {
t.error(err)
t.equal(res.statusCode, 502)
t.same(JSON.parse(data), {
statusCode: 502,
code: 'FST_REPLY_FROM_BAD_GATEWAY',
error: 'Bad Gateway',
message: 'Bad Gateway'
})
}
)
})
})

0 comments on commit b313122

Please sign in to comment.