lib/falcon/adapters/rack.rb in falcon-0.27.0 vs lib/falcon/adapters/rack.rb in falcon-0.28.0

- old
+ new

@@ -21,10 +21,11 @@ require 'rack' require_relative 'input' require_relative 'response' require_relative 'early_hints' +require_relative 'hijack' require 'async/logger' module Falcon module Adapters @@ -109,16 +110,10 @@ if remote_address = request.remote_address env[REMOTE_ADDR] = remote_address.ip_address if remote_address.ip? end end - def make_response(request, status, headers, body) - # @logger.debug(request) {"Rack response: #{status} #{headers.inspect} #{body.class}"} - - return Response.wrap(status, headers, body) - end - def call(request) request_path, query_string = request.path.split('?', 2) server_name, server_port = (request.authority || '').split(':', 2) env = { @@ -155,51 +150,44 @@ RACK_URL_SCHEME => request.scheme, # I'm not sure what sane defaults should be here: SERVER_NAME => server_name || '', SERVER_PORT => server_port || '', + + # We support both request and response hijack. + RACK_IS_HIJACK => true, } self.unwrap_request(request, env) if request.push? env[RACK_EARLY_HINTS] = EarlyHints.new(request) end + full_hijack = false + if request.hijack? - env[RACK_IS_HIJACK] = true - env[RACK_HIJACK] = lambda do - wrapper = request.hijack + wrapper = request.hijack! + full_hijack = true # We dup this as it might be taken out of the normal control flow, and the io will be closed shortly after returning from this method. io = wrapper.io.dup wrapper.close # This is implicitly returned: env[RACK_HIJACK_IO] = io end - else - env[RACK_IS_HIJACK] = false end status, headers, body = @app.call(env) - # Partial hijack is not supported/tested. - # if hijack = headers.delete('rack.hijack') - # body = Async::HTTP::Body::Writable.new - # - # Task.current.async do - # hijack.call(body) - # end - # return nil - # end - - # if env['rack.hijack_io'] - # return nil - # end - - return make_response(request, status, headers, body) + # If there was a full hijack: + if full_hijack + return nil + else + return Response.wrap(status, headers, body, request, env) + end rescue => exception @logger.error(self) {exception} return failure_response(exception) end