koajs/koa

Allow non-standard http status codes to be used

Closed this issue ยท 13 comments

Koa throws when a status code not defined in the statuses package is used in response:

assert(statuses[code], `invalid status code: ${code}`);

However, the HTTP RFC does not prevent custom status codes to be used:
http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-25.html#rfc.section.6.p.2

I can understand why status code validation might be useful for people just starting with http protocols, but for people who actually need to use custom codes, this is very limiting.

Proposal

There are several options that the Koa team could choose to remediate the problem:

  • Do not throw an error and just emit a warning
  • Keep throwing but add a configuration flag to disable the check (ie. koa.validateStatus = false)
  • Allow adding custom http status codes to Koa so that it accepts them (ie. koa.AddStatus(440, 'Invalid Chicken'))

I personally like the second and third approach. Currently the third approach is possible, albeit in a hacky way:

import statuses from 'statuses'

// Add a hypothetical "invalid chicken" response code
statuses[440] = 'Invalid chicken'
statuses.codes.push(440)
statuses['Invalid chicken'] = 440
fl0w commented

Last option, which I would prefer, is not to expose an API for handling statuses but rather to expose the validation fn, which can be overloaded/replaced as needed.

what about passing your own version of statuses? app.statuses = statuses.

this will need some way of subclassing statuses

erf commented

how about removing the dependency, and people can add it as a middleware if needed ( in good Koa spirit )

fl0w commented

@jonathanong if your solution is the approach you'd favour, it would (to my understanding) require:

  • expose statuses in koa/Application
  • to avoid semver major, expose populateStatusesMap in jshttp/statuses

For which the end result for Koa developer would become something pseudo alike:

const app = new Koa()
const statuses = require('statuses')

statuses.mergeStatusesMap({
  440: 'invalid chicken'
})

app.statuses = statuses

Did I follow you correctly here?

@fl0w @jonathanong Is this still needed?

EDIT: Modifyjshttp/statuses seems not to be an option. Can I tackle this by adding all the logic in Koa side?

What about just validating that the status code is a number as per the HTTP spec?

The status-code element is a three-digit integer code giving the
result of the attempt to understand and satisfy the request.

Another use-case for this is Cloudflare using its own set of non-RFC status codes - https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#Cloudflare

Can I tackle this by adding all the logic in Koa side?

No, that's gross :)

honestly, i would just add my custom status codes to statuses. yes, it's monkey patching, so i'd pin the statuses version in my deps

Hi,

As mentionned by @fl0w, here I'm currently developing an app which needs the usage of the non-standard code 449 introduced by Microsoft. Maybe we need to discuss about introducing non-standard codes

I'm working on it.

devuo commented

Hey this has been more than a year now. We're hacking our way to achieve this, I've just checked the PR what's missing from it?

actually I'd like to only check the status code is a three-digit integer, there is no need to prevent developers using custom statuses which RFC allowed:

The status-code element is a three-digit integer code giving the result of the attempt to understand and satisfy the request.

HTTP status codes are extensible. HTTP clients are not required to understand the meaning of all registered status codes, though such understanding is obviously desirable.

closes via #1308