6

ある種のプロキシを構築しています。
ラックアプリケーションで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リクエストにパラメータを追加することはできず、本文のリクエストにのみ追加できるようです。

そのようなラックリクエストをプロキシする簡単な方法はありますか?または、リクエストにパラメータを追加するクリーンな方法はありますか?

4

2 に答える 2

4

私が見たように、これは正常な動作です。その理由を説明します。Rack::Request にしかアクセスできない場合 (私は推測します)、ミドルウェアは応答を解析しません ( ActionController::ParamsParserのようなものは含めません)。そのため、パラメーターのハッシュにアクセスできません。ただし、StringIo に。この StringIO は次のようなストリームに対応します:

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 オブジェクトでラッパーを作成し、ストリームの最後に独自のパラメーターを追加することができます。ただし、これは些細なことでもお勧めできることでもありません。

于 2010-04-18T19:39:57.300 に答える
0

1 年遅すぎるかもしれませんが、Paypal の IPN の確認で同じ問題が発生しました。検証のために IPN リクエストを Paypal に転送したかったのですが、:cmd => '_notify-validate' を追加する必要がありました。

ボディ ストリームまたはボディを変更する代わりに、次のように URL パスの一部として追加しました。

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

少しハックのように思えますが、他の目的で使用しないのであれば、それだけの価値があると思います。

于 2011-07-13T04:35:26.130 に答える