Run npm run http
and npm run express
.
Both scripts log INVALID: 400
, instead of 405
.
# Request Method: Response Status
# Allowed methods
GET: 200
POST: 200
# Un-allowed methods
DELETE: 405
PUT: 405
# Invalid method(s)
INVALID: 400
In Node.js, invalid HTTP methods always return 400
.
This behavior cannot be customized, as it is hardcoded.
Example Code with and without using Express.js
Feature | Express.js | HTTP | |
---|---|---|---|
Restrict HTTP Request Methods | ✓ | ✓ | Valid Request Methods Only |
Handle Error with a Custom Function | ✓ |
Request with GET
or POST
→ Respond with 200
and OK
Request with other valid request methods
→ Respond with 405
and Method Not Allowed
Request with any invalid request methods
→ Respond with 400
(related GitHub issue)
Error occurs in Express.js
→ Respond with 500
and Error Occurred
Express.js vs Node.js HTTP
Express.js app.listen()
simply returns a Node.js http.Server
/**
* Listen for connections.
*
* A node `http.Server` is returned, with this
* application (which is a `Function`) as its
* callback. If you wish to create both an HTTP
* and HTTPS server you may do so with the "http"
* and "https" modules as shown here:
*
* var http = require('http')
* , https = require('https')
* , express = require('express')
* , app = express();
*
* http.createServer(app).listen(80);
* https.createServer({ ... }, app).listen(443);
*
* @return {http.Server}
* @public
*/
expressjs / express / lib / application.js, GitHub
Node.js HTTP Parser only considers these methods as valid
HTTP_ACL;
HTTP_BIND;
HTTP_CONNECT;
HTTP_DELETE;
HTTP_GET;
HTTP_HEAD;
HTTP_LOCK;
HTTP_MKCOL;
HTTP_NOTIFY;
HTTP_OPTIONS;
HTTP_POST;
HTTP_REPORT;
HTTP_SUBSCRIBE;
HTTP_TRACE;
HTTP_UNLOCK;
nodejs / http-parser / http_parser.c, GitHub
Other methods are considered invalid and are handled as error
switch (ch) {
case 'A': parser->method = HTTP_ACL; break;
// Other switch cases go here
break;
default:
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
}
nodejs / http-parser / http_parser.c, GitHub
Therefore in Node.js HTTP, invalid HTTP method returns a 400.
const http = require('http');
http.createServer((req, res) => {
res.statusCode = 200;
res.end('OK');
}).listen(80);
// Respond to all requests with `200` and `OK`
// Request using `AAA` method responds with `400`
const express = require('express')
const https = require('https')
const http = require('http')
const app = express()
http.createServer(app).listen(80)
https.createServer(options, app).listen(443)
Express.js 4.x API / app.listen, Express.js Docs
function errorHandler (err, req, res, next) {
if (res.headersSent) {
return next(err)
}
res.status(500)
res.render('error', { error: err })
}