gpt4 book ai didi

ruby - Rack::Deflater 和 Rack::URLMap

转载 作者:太空宇宙 更新时间:2023-11-03 16:21:16 25 4
gpt4 key购买 nike

我想根据响应主体的大小有条件地启用 Rack::Deflater,如下所示:

use Rack::Deflater, :if => lambda { |*, body| body.map(&:bytesize).reduce(0, :+) > 512 }

如果我在我的一个 Rack 应用程序中插入 Rack::Deflater 中间件,这个 lambda 可以正常工作; body 是一个字符串数组。但是,如果我在 Rack::URLMap 之前插入 Rack::Deflater 中间件(在 config.ru 中),它不会;因为 body 现在是一个 Rack::BodyProxy 对象。

我查看了 Rack::BodyProxy 定义,它似乎有点不透明。没有明确的方法从这个对象中解析出实际的 body ; body.body 返回 nil。在这种情况下,除了将 Rack::Deflater 中间件向下移动到我的每个 Rack 应用程序中之外,确定响应主体大小的最简单/最佳方法是什么?

tl;dr:如何确定给定 Rack::BodyProxy 对象的响应主体的大小?

最佳答案

看起来 Rack::BodyProxy 确实提供了一个 #each 方法作为问题 rack/rack#434 的解决方法.此方法返回私有(private) @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)
}

远非优雅...

关于ruby - Rack::Deflater 和 Rack::URLMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33003946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com