Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving non-standard HTTP method with ExpressJS

I would like to write an HTTP server that answer to request using a non-standard HTTP method (verb). For instance, the client would make a request like FOO / HTTP/.1.1. And on the server side, this request would be handled by something like:

var express = require('express');

var app = express.createServer();

app.configure(function(){
  app.use(express.logger({ format: ':method :url' }));
  app.use(express.methodOverride());
});

app.foo('/', function(req, res){
    res.send('Hello World');
});

app.listen(3000);

I appended my non-standard method to the array exported in ExpressJS's lib/router/methods.js. This allow me to write my server code as expected. When using express.methodOverride() and a POST request with _method=foo, it works. But an actual FOO request doesn't work. As soon as the client send the first line of the request the connection is closed by the server:

$telnet localhost 3000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
FOO / HTTP/1.1
Connection closed by foreign host.

I would like to be able to implement this with ExpressJS and without avoid hacking into its core file.

Any idea if this is possible and how?

like image 231
Pierre Buyle Avatar asked Feb 16 '12 20:02

Pierre Buyle


People also ask

Which is the HTTP method used in Express JS?

The GET method requests a representation of the specified resource. Requests using GET should only retrieve data and should have no other effect.

Does Expressjs support HTTP 2?

expressjs still does not officially support Node http2 . But you can use node-spdy . With this module, you can create HTTP2 / SPDY servers in node.

Do I need HTTP with Express?

There's really no reason to create your own http server using the http module. Express will just do that for you with app. listen() just fine and save you little bit of typing. If you were creating an https server, then you would need to use the https module and pass security credentials to https.


2 Answers

Short answer: No, it's not possible. Not without implementing your own HTTP module.

To test, start a barebones HTTP server ...

$ node
> require('http').createServer(function(req, res) {
...   console.log(req.method);
...   res.end();
... }).listen(8080);

Then (as you've already done) telnet to it and issue a GET and FOO request ...

$ telnet localhost 8080
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1

HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked

0

FOO / HTTP/1.1
Connection closed by foreign host.

$ 

In node console you'll see

GET

... but no FOO. So, node's native HTTP module, which Express uses, does not make these requests available.

like image 124
broofa Avatar answered Sep 22 '22 06:09

broofa


Node has a hard-coded whitelist of acceptable HTTP verbs in C.

In order to accept custom verbs, you must modify the HTTP parser and recompile node.


You mentioned that you're trying to implement PURGE, which was added to the whitelist in v0.7.5.

like image 36
josh3736 Avatar answered Sep 24 '22 06:09

josh3736