【问题标题】:Post request with body_stream and parameters使用 body_stream 和参数发布请求
【发布时间】:2011-02-06 23:54:51
【问题描述】:

我正在构建某种代理。
当我在机架应用程序中调用某个 url 时,我将该请求转发到另一个 url。

我转发的请求是一个带有文件和一些参数的 POST。
我想添加更多参数。
但是文件可能很大。所以我用Net::HTTP#body_stream而不是Net::HTTP#body发送它。

我以Rack::Request 对象的形式收到我的请求,并用它创建了我的 Net::HTTP 对象。

req = Net::HTTP::Post.new(request.path_info)
req.body_stream = request.body
req.content_type = request.content_type
req.content_length = request.content_length

http = Net::HTTP.new(@host, @port)
res = http.request(req)

我尝试了几种添加代理参数的方法。但在 Net::HTTP 中似乎没有任何内容允许将参数添加到 body_stream 请求,只能添加到正文。

有没有更简单的方法来代理这样的机架请求?还是一种将我的参数添加到我的请求的干净方式?

【问题讨论】:

  • 为什么req.set_form_data(:some => 'data') 不起作用?
  • 因为它定义了#body 并重置了#body_stream,所以我丢失了所有之前定义的数据。

标签: ruby http proxy rack


【解决方案1】:

可能晚了一年,但我在验证 Paypal IPN 时遇到了同样的问题。我想将 IPN 请求转发回 Paypal 进行验证,但需要添加 :cmd => '_notify-validate'。

我没有修改正文流或正文,而是将其作为 URL 路径的一部分附加,如下所示:

reply_request = Net::HTTP::Post.new(url.path + '?cmd=_notify-validate')

这似乎有点小技巧,但我认为如果你不打算将它用于其他任何事情,它是值得的。

【讨论】:

    【解决方案2】:

    嗯.. 在我看来,这是正常行为。我会解释为什么。如果您只能访问 Rack::Request,(我猜)您的中间件不会解析响应(您不包括 ActionController::ParamsParser 之类的东西),所以您没有访问参数散列,但访问 StringIo。这个StringIO对应一个流like

    Content-Type: multipart/form-data; boundary=AaB03x
    --AaB03x 
    Content-Disposition: form-data; name="param1" 
    value1
    --AaB03x 
    Content-Disposition: form-data; name="files"; filename="file1.txt" 
    Content-Type: text/plain 
    ... contents of file1.txt ...
    --AaB03x--
    

    您尝试对 Net::HTTP 类执行的操作是:(1)。将请求解析为参数散列; (2)。将参数哈希与您自己的参数合并; (3)。重新创建请求。问题是 Net::HTTP 库不能做 (1),因为它是客户端库,而不是服务器库。

    因此,在添加新参数之前,您无法逃避解析您的请求的一些方式。

    可能的解决方案:

    1. 在中间件之前插入 ActionController::ParamsParser。之后,您可以使用出色的rest-client lib 执行以下操作:

      RestClient.post ('http://your_server' + request.path_info), :params => params.merge(your_params)

    2. 您可以尝试对 StringIO 对象进行包装,并在流的末尾添加您自己的参数。然而,这不是微不足道的,也不是可取的。

    【讨论】:

    • 是的,我收起了第二个。我会尝试第一个。谢谢:)
    • 不客气 :) 但是,通过这种方式解析请求,您必须等待整个内容上传到代理服务器。因此,total_time > time_to_upload_to_proxy + time_to_upload_to_real_server。
    猜你喜欢
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多