Опубликовать запрос с body_stream и параметрами - PullRequest
5 голосов
/ 12 апреля 2010

Я создаю какой-то прокси.
Когда я вызываю какой-либо 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, только к телу.

Есть ли более простой способ проксировать запрос стойки таким образом? Или чистый способ добавить мои параметры в мой запрос?

Ответы [ 2 ]

3 голосов
/ 18 апреля 2010

Ну, как я понимаю, это нормальное поведение. Я объясню почему. Если у вас есть только доступ к 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 и добавить в конце потока свои собственные параметры. Однако это не тривиально и не целесообразно.

0 голосов
/ 13 июля 2011

Возможно, будет на один год позже, но у меня возникла та же проблема с проверкой IPN Paypal. Я хотел перенаправить запрос IPN в Paypal для проверки, но мне нужно было добавить: cmd => '_notify-validate'.

Вместо изменения основного потока или тела я добавил его как часть URL-пути, например:

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

Это кажется чем-то вроде взлома, но я думаю, что оно того стоит, если вы не собираетесь использовать его для чего-либо еще.

...