@@ -23,7 +23,7 @@ Echoサーバとは、送られてきたリクエストの内容をそのまま
2323```
2424
2525` app.use(middleware) ` という形で、_ middleware_と呼ばれる関数には` request ` や` response ` といったオブジェクトが渡されます。
26- そのため、リクエストみてフィルタリングしたり 、任意のレスポンスを返したり出来るようになっています。
26+ この ` request ` や ` response ` を_middleware_で処理することでログを取ったり 、任意のレスポンスを返したり出来るようになっています。
2727
2828Echoサーバでは ` req.pipe(res); ` という形でリクエストをそのままレスポンスとして流す事で実現されています。
2929
@@ -47,4 +47,69 @@ Echoサーバでは `req.pipe(res);` という形でリクエストをそのま
4747基本的にどの_middleware_も` app.use(middleware) ` という形で拡張でき、
4848モジュールとして実装すれば再利用もしやすい形となっています。
4949
50- > ** Note** _ middleware_となる関数の引数が4つであると、それはエラーハンドリングの_middleware_とするという、Connectの独自のルールがあります。
50+ > ** Note** _ middleware_となる関数の引数が4つであると、それはエラーハンドリングの_middleware_とするという、Connect独自のルールがあります。
51+
52+ ## どういう仕組み
53+
54+ Connectの_middleware_がどのような仕組みで動いているのかを見ていきます。
55+
56+ ` app ` に登録した_middleware_は、リクエスト時に呼び出されています。
57+ そのため、` app ` のどこかに利用する_middleware_を保持していることは推測できると思います。
58+
59+ Connectでは` app.stack ` に_middleware_を配列として保持しています。
60+ 次のようにして` app.stack ` の中身を表示してみると、_ middleware_が登録順で保持されていることがわかります。
61+
62+ [ import connect-trace-example.js] ( ../../src/connect/connect-trace-example.js )
63+
64+ Connectが登録された_middleware_をどう処理するかというと、
65+ サーバがリクエストを受け取った時に、それぞれ順番に呼び出しています。
66+
67+ 上記の例だと以下の順番で_middleware_が呼び出されることになります。
68+
69+ - errorHandler
70+ - nosniff
71+ - hello
72+
73+ エラーハンドリングの_middleware_は処理中にエラーが起きた時のみ呼ばれます。
74+
75+ そのため、通常は [ nosniff.js] ( #nosniff.js ) -> [ hello.js] ( #hello.js ) の順で呼び出されます。
76+
77+ [ import nosniff.js] ( ../../src/connect/nosniff.js )
78+
79+ ` nosniff.js ` は、HTTPヘッダを設定し終わったら` next() ` を呼び出していて、
80+ この` next() ` が次の_middleware_へ行くという意味になります。
81+
82+ 次に、` hello.js ` を見てみると、` next() ` がないことがわかります。
83+
84+ [ import hello.js] ( ../../src/connect/hello.js )
85+
86+ ` next() ` がないということは` hello.js ` がこの連続する_middleware_の最後となっていることがわかります。
87+ 仮に、これより先に_middleware_が登録されていたとしても無視されます。
88+
89+ つまり、処理的には以下のようにstackを先頭から一個づつ取り出して、処理していくという方法が取られています。
90+
91+ Connectの行っている処理を抽象的なコードで書くと以下のような形となっています。
92+
93+ ``` js
94+ let req = " ..." ,
95+ res = " ..." ;
96+ function next (){
97+ let middleware = app .stack .shift ();
98+ // nextが呼ばれれば次のmiddleware
99+ middleware (req, res, next);
100+ }
101+ next ();// 初回
102+ ```
103+
104+
105+ このような_middleware_を繋げた形を_middleware stack_と呼ぶことがあります。
106+
107+ _ middleware stack_で構成されるHTTPサーバとして、PythonのWSGI MiddlewareやRubyのRackなどがあります。
108+ ConnectはRackと同じく` use ` で_middleware_を指定することからも分かりますが、
109+ Rackを参考にして実装されています。
110+
111+ - [ Ruby - Rack解説 - Rackの構造とRack DSL - Qiita] ( http://qiita.com/higuma/items/838f4f58bc4a0645950a#2-5 " Ruby - Rack解説 - Rackの構造とRack DSL - Qiita ")
112+
113+ 次は、先ほど抽象的なコードとなっていたものを、具体的な実装にしていきます。
114+
115+ ## 実装してみよう
0 commit comments