Skip to content

Instantly share code, notes, and snippets.

@slyphon
Created January 25, 2011 20:24
Show Gist options
  • Save slyphon/795576 to your computer and use it in GitHub Desktop.
Save slyphon/795576 to your computer and use it in GitHub Desktop.
module DevNull
class FileEachWrapper
def initialize(io)
@io = io
end
def each
end
def method_missing(sym, *a, &b)
@io.__send__(sym, *a, &b)
end
end
class SendfileMiddleware
SENDFILE_HEADER = 'X-Sendfile'
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
if headers.has_key?('X-Sendfile')
path = body.to_path
headers.delete(SENDFILE_HEADER)
if defined?(::JRUBY_VERSION) and defined?(JRuby::Rack) and res.is_a?(JRuby::Rack::Response)
body = []
headers['Forward'] = lambda { |res| SendfileStreamer.new(status, headers, path).respond(res) }
else
body = File.open(path, 'r')
end
end
[status, headers, body]
end
end
# XXX: HACK! copy/paste from jruby-rack-1.0.5
class SendfileStreamer
def initialize(status, headers, path)
@status = status
@headers = headers
@path = path
end
def respond(response)
write_status(response)
write_headers(response)
write_body(response)
end
def write_status(response)
response.setStatus(@status.to_i)
end
def write_headers(response)
@headers.each do |k,v|
case k
when /^Content-Type$/i
response.setContentType(v.to_s)
when /^Content-Length$/i
response.setContentLength(v.to_i)
else
if v.respond_to?(:each_line)
v.each_line {|val| response.addHeader(k.to_s, val.chomp("\n")) }
elsif v.respond_to?(:each)
v.each {|val| response.addHeader(k.to_s, val.chomp("\n")) }
else
case v
when Numeric
response.addIntHeader(k.to_s, v.to_i)
when Time
response.addDateHeader(k.to_s, v.to_i * 1000)
else
response.addHeader(k.to_s, v.to_s)
end
end
end
end
end
def write_body(response)
out = java.nio.channels.Channels.newChannel(response.getOutputStream)
File.open(@path) do |fp|
fp.to_channel.transfer_to(0, fp.stat.size, out)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment