Rack::Server.build_app如何添加中间件?

How does Rack::Server.build_app add middleware?

我正在尝试了解 Rack 的工作原理。

lib/rack/server.rb 中有这一行 (344)...

https://github.com/rack/rack/blob/master/lib/rack/server.rb

middleware = middleware.call(self) if middleware.respond_to?(:call)

... 看起来该行的一部分相当于:

Rack::ContentLength.call(Rack::Server)

...如果我们使用 Rack::ContentLength 作为示例默认中间件(看起来应该是一个)。

https://github.com/rack/rack/blob/master/lib/rack/content_length.rb (第 14 行)

我没看错,还是漏掉了什么?看起来 Rack::ContentLength a) 想要先初始化,b) 想要 call 的不同参数,这就是我感到困惑的原因。

看起来我例子中的Rack::ContentLength class 到达server.rb 的第344 行时将在一个数组中。该数组通过向 respond_to?(:call) 返回 false 来控制流。另一方面,logging_middleware 不在数组中,它定义了一个 lambda 对象,它将 respond_to?(:call).

  def default_middleware_by_environment
     m = Hash.new {|h,k| h[k] = []}
     m["deployment"] = [
       [Rack::ContentLength],
       [Rack::Chunked],
       logging_middleware,
       [Rack::TempfileReaper]
     ]
     m["development"] = [
       [Rack::ContentLength],
       [Rack::Chunked],
       logging_middleware,
       [Rack::ShowExceptions],
       [Rack::Lint]

我将不得不进一步挖掘以了解 where/how 处理了它们自己数组中的那些 classes,但看起来它不在 Rack::Server.[=24= 中].