簡體   English   中英

Rack::Deflater 和 Rack::URLMap

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM