class Goliath::RackProxy
Public Class Methods
Rack app to proxy the incoming requests to.
# File lib/goliath/rack_proxy.rb, line 10 def self.rack_app(app) rack_proxy_options[:rack_app] = app end
Custom user-defined options.
# File lib/goliath/rack_proxy.rb, line 20 def self.rack_proxy_options @rack_proxy_options ||= {} end
Whether the request body should be rewindable.
# File lib/goliath/rack_proxy.rb, line 15 def self.rewindable_input(value) rack_proxy_options[:rewindable_input] = value end
Public Instance Methods
Resumes the Rack request with the received request body data.
# File lib/goliath/rack_proxy.rb, line 34 def on_body(env, data) env["rack_proxy.call"].resume(data, on_response: -> (response) { send_response(response, env) }) end
Resumes the Rack request with no more data.
# File lib/goliath/rack_proxy.rb, line 39 def on_close(env) env["rack_proxy.call"].resume end
Starts the request to the given Rack application.
# File lib/goliath/rack_proxy.rb, line 25 def on_headers(env, headers) rack_app = self.class.rack_proxy_options.fetch(:rack_app) rewindable_input = self.class.rack_proxy_options.fetch(:rewindable_input, true) env["rack_proxy.call"] = RackCall.new(rack_app, env, rewindable_input: rewindable_input) env["rack_proxy.call"].resume(on_response: -> (response) { send_response(response, env) }) end
Resumes the Rack request with no more data.
# File lib/goliath/rack_proxy.rb, line 44 def response(env) env["rack_proxy.call"].resume(on_response: -> (response) { send_response(response, env) }) nil end
Private Instance Methods
The env proc wraps sending response data in a Goliath::Request#callback, which gets executed after the whole request body has been received.
This is not ideal for apps that receive large uploads, as when they validate request headers, they likely want to return error responses immediately. It's not good user experience to require the user to upload a large file, only to have the request fail with a validation error.
To work around that, we mark the request as succeeded before sending the response, so that the response is sent immediately.
# File lib/goliath/rack_proxy.rb, line 62 def send_response(response, env) request = env[STREAM_SEND].binding.receiver # hack to get the Goliath::Request object request.succeed # makes it so that response is sent immediately env[ASYNC_CALLBACK].call(response) end