class Sinatra::ExtendedRack
still be able to run.
handler directly. We do this here, so our middleware and middleware set up by the app will
This middleware will detect an extended body object and will make sure it reaches the
some middleware (namely Rack::Lint) will break it by not mirroring the methods in question.
Some Rack handlers implement an extended body object protocol, however,
def after_response(&block)
def after_response(&block) raise NotImplementedError, 'only supports EventMachine at the moment' unless defined? EventMachine EventMachine.next_tick(&block) end
def async?(status, _headers, body)
def async?(status, _headers, body) return true if status == -1 body.respond_to?(:callback) && body.respond_to?(:errback) end
def call(env)
def call(env) result = app.call(env) callback = env['async.callback'] return result unless callback && async?(*result) after_response { callback.call result } setup_close(env, *result) throw :async end
def setup_close(env, _status, _headers, body)
def setup_close(env, _status, _headers, body) return unless body.respond_to?(:close) && env.include?('async.close') env['async.close'].callback { body.close } env['async.close'].errback { body.close } end