@caiser

Работа Rack без middleware?

require "net/http"
require "stringio"

class Worker
def call(env)
  request = Rack::Request.new(env)
  case request.request_method
  when "POST"
    [200,{"Content-Type"=>"text/plain"},StringIO.new("")]
  when "GET", "PUT", "DELETE", "OPTION", "HEAD"
    [404,{"Content-Type"=>"text/plain"}, StringIO.new("Not Found")]
  end
 create_response(request.body.read)
end

def create_response(body)
  uri = URI("server2")
  res = Net::HTTP::Post.new(uri.request_uri)
  res.content_type = 'text/plain'
  Net::HTTP.start(uri.hostname, uri.port) {|http| http.request(res, body) }
  return [200,{"Content-Type"=>"text/plain"},StringIO.new("")] # если не возвращать эту строку rack'y - будет ошибка
end
end

run Worker.new



Следующий код запускаю через rackup.


Как работает(схема 1): имитирую(предположим, от server2) POST запрос отправляя его через curl с опцией -d, в качестве тела указываю любое значение. Полученный запрос rack отдает(server1) на обработку методу create_response, где в качестве аргумента передает значение тела запроса. Тот в свою очередь отправляет свой POST(server1 к server2) и в ответ получает 200 OK, далее rack отправляет 200 OK клиенту, где был запущен curl.


Как хочу чтобы работало(схема 2):

Код выше — это S2. Для S1 код будет примерно такой же, за некоторыми исключениями, предположим S1 всегда выступает инициатором всей схемы.

При получении запроса(шаг 1), если это POST, сразу отправлять(шаг 2) 200 OK, в других случаях 404 Not Found и на этом завершать. После этого от S2 к S1(шаг 3) отправляется POST и получаем(шаг 4) ответ.


Пробовал реализовать это через
lambda { |env| [200,{"Content-Type"=>"text/plain"},StringIO.new("")] }


Такая же ситуация.

В обоих случая в качестве web-сервера использовался Thin.


Вопрос: Как это сделать? Буду рад любым подсказкам.
  • Вопрос задан
  • 2896 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы