2012-02-16 9 views
5

Vorrei scrivere un server HTTP che risponda alla richiesta utilizzando un metodo HTTP non standard (verbo). Ad esempio, il cliente potrebbe effettuare una richiesta come FOO/HTTP/.1.1. E sul lato server, questa richiesta sarebbe stato gestito da qualcosa come: Servizio di metodo HTTP non standard con ExpressJS

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); 

ho accodato il mio metodo non-standard per la matrice esportato in ExpressJS di lib/router/methods.js. Questo mi permette di scrivere il mio codice server come previsto. Quando si utilizza express.methodOverride() e una richiesta POST con _method=foo, funziona. Ma una richiesta effettiva FOO non funziona. Non appena il client invia la prima linea della richiesta la connessione viene chiusa dal server:

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

Mi piacerebbe essere in grado di implementare questo con ExpressJS e senza evitare di hacking in suo file core.

Qualche idea se è possibile e come?

risposta

4

Risposta breve: No, non è possibile. Non senza implementare il tuo modulo HTTP.

Per verificare, avviare un server HTTP barebone ...

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

Allora (come avete già fatto) telnet ad esso ed emettere un GET e richiesta di FOO ...

$ 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. 

$ 

Nella console del nodo vedrete

GET 

... ma nessun FOO. Quindi, il modulo nativo HTTP del nodo, che usa Express, non rende disponibili queste richieste.

+3

Solo per pubblicare un aggiornamento - nelle versioni corrente di nodo (4.6) ed espresso (4), è possibile gestire verbi HTTP personalizzati. Ascoltando 'app.all' e quindi controllando' req.method' nel callback funziona. – MatsLindh

-1

C'è uno scopo veramente significativo in questo? Solo il tuo server e client HTTP sarebbe in grado di parlare tra loro e sembra un grande sforzo per un guadagno molto piccolo. In che modo lo standard HTTP verbs non ti riesce?

Per rispondere alla tua domanda sull'opportunità o meno di eseguire l'hacking in Express: lo richiede di eseguire l'operazione di ricerca. Express require s il modulo http, e avresti bisogno di sovrascriverlo con il tuo, almeno. Il numero core modules are always checked first integrato di Node.js, quindi non puoi dare lo stesso nome al modulo per farlo.

+0

Il verbo non standard che voglio implementare è il metodo SPURGO, come supportato da Squid e Varnish per eliminare un oggetto dalle loro cache (cfr. Http://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache .3F e https://www.varnish-cache.org/docs/trunk/tutorial/purging.html) –

+3

Beh, ho appena fatto un test sull'oggetto base del server http e il comportamento che descrivi è sicuramente causato dal Nodo. js 'http server e non aggiunto da express. Dovresti creare un bug con Joyent su come ottenere questo cambiamento (lo standard non dice nulla su come disabilitare i verbi non standard, quindi se un utente vuole implementare funzionalità su di esso, può avere senso) - se offri di fare il aggiustati (dopo averli persuasi), potrebbero essere più propensi ad approvarlo. Se ciò non dovesse funzionare, dovresti puntare su entrambe le librerie http ed esprimere per fare quello che vuoi. –

0

Come altri hanno già detto, la libreria del server HTTP di Node.js è configurata per accettare solo verbi specifici. Anche il suggerimento di Ben Noordius di usare Parsley non funziona, dal momento che quella libreria accetta una whitelist di verbi ancora più piccola. (Inoltre non è stato mantenuto in un bel po 'di tempo.)

In questa fase, se vogliamo supportare le richieste di oddball, dobbiamo prendere misure più drastiche. Ecco un bel brutto trucco per te che comporta l'anatra che colpisce un comportamento interno. Funziona su v0.10.x di Node.js, ma verifica attentamente le versioni più recenti non appena diventano disponibili.

Nel mio caso, avevo bisogno di sostenere non solo un verbo non standard, ma un identificatore versione del protocollo non standard, come pure, e la mancanza di un Content-Length intestazione per flussi di fonti Icecast:

SOURCE /live ICE/1.0 

Il seguente dovrebbe iniziare:

server.on('connection', function (socket) { 
    var originalOnDataFunction = socket.ondata; 
    var newLineOffset; 
    var receiveBuffer = new Buffer(0); 
    socket.ondata = function (d, start, end) { 
     receiveBuffer = Buffer.concat([receiveBuffer, d.slice(start, end)]); 
     if ((newLineOffset = receiveBuffer.toString('ascii').indexOf('\n')) > -1) { 
      var firstLineParts = receiveBuffer.slice(0, newLineOffset).toString().split(' '); 
      firstLineParts[0] = firstLineParts[0].replace(/^SOURCE$/ig, 'PUT'); 
      firstLineParts[2] = firstLineParts[2].replace(/^ICE\//ig, 'HTTP/'); 
      receiveBuffer = Buffer.concat([ 
       new Buffer(
        firstLineParts.join(' ') + '\r\n' + 
        'Content-Length: 9007199254740992\r\n' 
       ), 
       receiveBuffer.slice(newLineOffset +1) 
      ]); 

      socket.ondata = originalOnDataFunction; 
      socket.ondata.apply(this, [receiveBuffer, 0, receiveBuffer.length]); 
     } 
    }; 
} 

È brutto, ma funziona. Non ne sono particolarmente felice, ma quando scelgo tra un parser HTTP approssimativo costruito da zero o modificando uno esistente, scelgo di modificare questa istanza.

Problemi correlati