代码之家  ›  专栏  ›  技术社区  ›  Damien MATHIEU

带有body_流和参数的post请求

  •  5
  • Damien MATHIEU  · 技术社区  · 14 年前

    我正在建立某种代理。
    当我调用框架应用程序中的某个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_流请求添加参数,只允许向body_流请求添加参数。

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

    2 回复  |  直到 13 年前
        1
  •  3
  •   Vlad Zloteanu    14 年前

    好。。在我看来,这是正常的行为。我来解释原因。如果您只能访问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(您的参数)

    2. 您可以尝试在stringio对象上创建一个包装器,并在流的末尾添加自己的参数。然而,这不是小事,也不可取。

        2
  •  0
  •   Jaryl    13 年前

    可能是一年太晚,但我有相同的问题验证PayPal IPN。我想将IPN请求转发回PayPal进行验证,但需要添加:CMD=& gt;

    我没有修改body流或body,而是将其作为url路径的一部分追加,如下所示:

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

    这似乎有点老生常谈,但我认为如果你不打算把它用在其他任何事情上,它是值得的。