2012-02-16 6 views
5

非標準のHTTPメソッド(動詞)を使用してリクエストに応答するHTTPサーバーを作成したいと思います。たとえば、クライアントはFOO/HTTP/.1.1のような要求を行います。そして、サーバ側で、この要求のようなものによって処理される: ExpressJSを使用した非標準HTTPメソッドの処理

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

私はExpressJSのlib/router/methods.jsでエクスポート配列に私の非標準的な方法を追加しました。これにより、サーバーコードを期待どおりに書くことができます。 express.methodOverride()POSTリクエストを_method=fooで使用すると動作します。実際のFOOリクエストは機能しません。私はExpressJSとし、そのコアファイルをハッキング回避せずにこれを実装できるようにしたいと思い

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

:とすぐにクライアントとして接続がサーバーによって閉じられたリクエストの最初の行を送信します。

これが可能かどうか、考えてください。

答えて

4

短い回答:いいえ、不可能です。独自のHTTPモジュールを実装する必要はありません。テストするには

は、...必要最小限のHTTPサーバを起動すると

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

それにTelnet接続し、GETや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. 

$ 
ノードコンソールで

あなたは

GET 

...しかし、無FOOが表示されます。したがって、Expressが使用するノードのネイティブHTTPモジュールは、これらの要求を使用可能にしません。

+3

現在のノード(4.6)とexpress(4)のバージョンでは、カスタムHTTP動詞を扱うことができます。 'app.all'を聞いて、コールバックで' req.method'をチェックすると動作します。 – MatsLindh

-1

本当に重要な目的はありますか?あなた自身のHTTPサーバとクライアントだけがお互いに話すことができ、非常に小さな利益のために多大な努力のように思えます。どのようにしてstandard HTTP verbsが失敗しますか?

Expressにハッキングする必要があるかどうかについては、に問い合わせる必要があります。 Express requirehttpモジュールであり、少なくとも自分のもので上書きする必要があります。 Node.jsにはcore modules are always checked firstが組み込まれているので、モジュールに同じ名前を付けることはできません。

+0

私が実装したい非標準の動詞は、キャッシュからオブジェクトを削除するためにSquidとVarnishがサポートするPURGEメソッドです(cf. http://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache .3Fとhttps://www.varnish-cache.org/docs/trunk/tutorial/purging.html) –

+3

まあ、私はちょうど基本的なHTTPサーバーオブジェクトのテストを行ったとあなたが記述する動作は間違いなくノードによって引き起こされます。 js 'のhttpサーバーであり、明示的には追加されません。これを変更することについてJoyentにバグを提出する必要があります(標準では非標準動詞を禁止することについて何も言わないので、ユーザーがその上で機能を実装したい場合は意味があります)。 (あなたが彼らを説得した後で)自分自身にパッチを当てれば、彼らはそれを承認する可能性がより高いかもしれません。それがうまくいかない場合は、httpライブラリとexpressの両方をforkして、必要なことをする必要があります。 –

0

Node.jsのHTTPサーバライブラリは、特定の動詞だけを受け入れるように設定されています。 Ben Noordiusの提案では、Parsleyも使用できません。なぜなら、そのライブラリはより小さな動詞のホワイトリストを受け入れるからです。 (これもかなりの時間は維持されていません)

この段階では、奇妙な要求をサポートしたい場合は、より徹底的な対策を講じなければなりません。ダックが内部的な振る舞いに打ち勝つことを含む、あなたのためのすてきな醜いハックがあります。これはNode.jsのv0.10.xで動作しますが、新しいバージョンが利用可能になると慎重にテストします。

私の場合、私はだけでなく、非標準的な動詞をサポートするために必要な、しかし、非標準プロトコルバージョン識別子だけでなく、とIcecastのソースストリームの行方不明Content-Lengthヘッダー:

SOURCE /live ICE/1.0 

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

醜いですが、動作します。私はそれについて特に満足しているわけではありませんが、大まかに組み立てられたHTTPパーサーを構築するか、既存のHTTPパーサーを調整する場合は、このインスタンスを調整することを選択します。

1

ノードは、カスタム動詞を受け入れるためにはC.

hard-coded whitelist of acceptable HTTP verbsを持っている、あなたは、HTTPパーサーを変更し、ノードを再コンパイルする必要があります。あなたはv0.7.5でのホワイトリストにaddedPURGEを実装しようとしている


あなたmentioned

関連する問題