[英]Rack::Deflater and Rack::URLMap
我想根據響應正文的大小有條件地啟用Rack::Deflater
,如下所示:
use Rack::Deflater, :if => lambda { |*, body| body.map(&:bytesize).reduce(0, :+) > 512 }
如果我在我的一個 Rack 應用程序中插入Rack::Deflater
中間件,這個 lambda 工作正常; body
是一個字符串數組。 但是,如果我在Rack::URLMap
(在config.ru
)之前插入Rack::Deflater
中間件,則不會; 因為body
現在是一個Rack::BodyProxy
對象。
我查看了Rack::BodyProxy
定義,它似乎有點不透明。 沒有明確的方法可以從該對象解析實際主體; body.body
返回nil
。 在這種情況下,除了將Rack::Deflater
中間件移動到我的每個 Rack 應用程序中之外,確定響應主體大小的最簡單/最好的方法是什么?
tl;dr :如何確定給定Rack::BodyProxy
對象的響應主體的大小?
看起來Rack::BodyProxy
確實提供了一個#each
方法作為問題rack/rack#434的解決方法。 此方法返回私有@body
ivar 元素的枚舉數。 在調用鏈中添加一個.each
可以解決Rack::BodyProxy
對象的這個問題,並且它對於更普通的基於數組的主體來說是一個空操作,所以現在這讓我得到了我需要的地方。 但是,我仍然想了解為什么我會得到這些對象,以及是否有更好的方法來處理它們。
這是修改后的工作解決方案:
use Rack::Deflater, :if => lambda { |*, body|
body.each.map(&:bytesize).reduce(0, :+) > 512
}
更新: Hrrm,有時body
是一個Rack::BodyProxy
對象,而body.body
是一個Rack::Response
對象。 這有點失控了......! 這是我現在使用的解決方案:
use Rack::Deflater, :if => lambda { |*, body|
body.map(&:bytesize).reduce(0, :+) > 512 \
if body.respond_to?(:map) \
or body.respond_to?(:each) and (body = body.each).respond_to?(:map)
}
遠非優雅...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.