-
Notifications
You must be signed in to change notification settings - Fork 215
Description
In tus-ruby-server I'm handling large file uploads. When the user makes a PATCH request with a chunk of the file, the app first validates request headers, and if they're invalid it returns, it returns an error response without even reading the request body.
I'm using goliath-rack_proxy as a glue between Goliath and the tus-ruby-server Rack app, and I'm trying to figure out how to return the response early with Goliath. The reason I want that is because I would like to avoid happily accepting multiple gigabytes of request body from a client, only to return an error response because the request headers were invalid. I would like to utilize Goliath's ability to act as soon as request headers are received.
The problem is that .succeed is called on the Goliath::Request only after all request body has been receved, and all of the env[ASYNC_*] procs use callback { }, which means they will send the response only after all request data has been received (e.g. I tried using env[ASYNC_CALLBACK]). I wrote the following proof-of-concept, which uses hacks to access the Goliath::Request object (already discussed in #341) and use Goliath::Connection#send_data directly:
require "goliath"
class App < Goliath::API
def on_headers(env, headers)
request = env[ASYNC_CALLBACK].receiver
connection = request.conn
response = request.response
response.status = 200
response.headers = { "Foo" => "Bar" }
response.body = "This is a response"
response.each { |data| connection.send_data(data) }
connection.terminate_request(false)
end
def response(env)
end
endI'm pretty sure that returning a response early is valid HTTP interaction, because curl-ing this app returns the response without any errors.
Are you open to support this in Goliath? If yes, I could come up with a PR.