Add 'pipe' for proxying assets

This commit is contained in:
Omar Roth 2019-07-03 13:22:52 -05:00
parent 857c57daba
commit f7dbf2bdd4
No known key found for this signature in database
GPG key ID: B8254FB7EC3D37F2

View file

@ -638,29 +638,44 @@ def cache_annotation(db, id, annotations)
end end
def proxy_file(response, env) def proxy_file(response, env)
if !response.body_io?
return
end
if response.headers.includes_word?("Content-Encoding", "gzip") if response.headers.includes_word?("Content-Encoding", "gzip")
Gzip::Writer.open(env.response) do |deflate| Gzip::Writer.open(env.response) do |deflate|
copy_in_chunks(response.body_io, deflate) response.pipe(deflate)
end end
elsif response.headers.includes_word?("Content-Encoding", "deflate") elsif response.headers.includes_word?("Content-Encoding", "deflate")
Flate::Writer.open(env.response) do |deflate| Flate::Writer.open(env.response) do |deflate|
copy_in_chunks(response.body_io, deflate) response.pipe(deflate)
end end
else else
copy_in_chunks(response.body_io, env.response) response.pipe(env.response)
end end
end end
# https://stackoverflow.com/a/44802810 <3 class HTTP::Client::Response
def copy_in_chunks(input, output, chunk_size = 4096) def pipe(io)
size = 1 HTTP.serialize_body(io, headers, @body, @body_io, @version)
while size > 0 end
size = IO.copy(input, output, chunk_size) end
Fiber.yield
# Supports serialize_body without first writing headers
module HTTP
def self.serialize_body(io, headers, body, body_io, version)
if body
io << body
elsif body_io
content_length = content_length(headers)
if content_length
copied = IO.copy(body_io, io)
if copied != content_length
raise ArgumentError.new("Content-Length header is #{content_length} but body had #{copied} bytes")
end
elsif Client::Response.supports_chunked?(version)
headers["Transfer-Encoding"] = "chunked"
serialize_chunked_body(io, body_io)
else
io << body
end
end
end end
end end