allow to set filename for send_file
if the disposition type matches "attachment", this indicates that the recipient should prompt the user to save the response locally, rather than process it normally
This commit is contained in:
parent
a5d8df7382
commit
6f111ffbb0
2 changed files with 52 additions and 17 deletions
|
@ -1,4 +1,5 @@
|
|||
require "./spec_helper"
|
||||
require "./handler_spec"
|
||||
|
||||
describe "Macros" do
|
||||
describe "#public_folder" do
|
||||
|
@ -114,6 +115,17 @@ describe "Macros" do
|
|||
response.headers["Content-Type"].should eq("application/octet-stream")
|
||||
response.headers["Content-Length"].should eq("6")
|
||||
end
|
||||
|
||||
it "sends file with given path and given filename" do
|
||||
get "/" do |env|
|
||||
send_file env, "./spec/asset/hello.ecr", filename: "image.jpg"
|
||||
end
|
||||
|
||||
request = HTTP::Request.new("GET", "/")
|
||||
response = call_request_on_app(request)
|
||||
response.status_code.should eq(200)
|
||||
response.headers["Content-Disposition"].should eq("attachment; filename=\"image.jpg\"")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#gzip" do
|
||||
|
|
|
@ -109,7 +109,13 @@ end
|
|||
# ```
|
||||
# send_file env, "./path/to/file", "image/jpeg"
|
||||
# ```
|
||||
def send_file(env : HTTP::Server::Context, path : String, mime_type : String? = nil)
|
||||
#
|
||||
# Also you can set the filename and the disposition
|
||||
#
|
||||
# ```
|
||||
# send_file env, "./path/to/file", filename: "image.jpg", disposition: "attachment"
|
||||
# ```
|
||||
def send_file(env : HTTP::Server::Context, path : String, mime_type : String? = nil, *, filename : String? = nil, disposition : String? = nil)
|
||||
config = Kemal.config.serve_static
|
||||
file_path = File.expand_path(path, Dir.current)
|
||||
mime_type ||= Kemal::Utils.mime_type(file_path)
|
||||
|
@ -120,6 +126,7 @@ def send_file(env : HTTP::Server::Context, path : String, mime_type : String? =
|
|||
request_headers = env.request.headers
|
||||
filesize = File.size(file_path)
|
||||
filestat = File.info(file_path)
|
||||
attachment(env, filename, disposition)
|
||||
|
||||
Kemal.config.static_headers.try(&.call(env.response, file_path, filestat))
|
||||
|
||||
|
@ -147,6 +154,31 @@ def send_file(env : HTTP::Server::Context, path : String, mime_type : String? =
|
|||
return
|
||||
end
|
||||
|
||||
# Send a file with given data and default `application/octet-stream` mime_type.
|
||||
#
|
||||
# ```
|
||||
# send_file env, data_slice
|
||||
# ```
|
||||
#
|
||||
# Optionally you can override the mime_type
|
||||
#
|
||||
# ```
|
||||
# send_file env, data_slice, "image/jpeg"
|
||||
# ```
|
||||
#
|
||||
# Also you can set the filename and the disposition
|
||||
#
|
||||
# ```
|
||||
# send_file env, data_slice, filename: "image.jpg", disposition: "attachment"
|
||||
# ```
|
||||
def send_file(env : HTTP::Server::Context, data : Slice(UInt8), mime_type : String? = nil, *, filename : String? = nil, disposition : String? = nil)
|
||||
mime_type ||= "application/octet-stream"
|
||||
env.response.content_type = mime_type
|
||||
env.response.content_length = data.bytesize
|
||||
attachment(env, filename, disposition)
|
||||
env.response.write data
|
||||
end
|
||||
|
||||
private def multipart(file, env : HTTP::Server::Context)
|
||||
# See http://httpwg.org/specs/rfc7233.html
|
||||
fileb = file.size
|
||||
|
@ -188,22 +220,13 @@ private def multipart(file, env : HTTP::Server::Context)
|
|||
end
|
||||
end
|
||||
|
||||
# Send a file with given data and default `application/octet-stream` mime_type.
|
||||
#
|
||||
# ```
|
||||
# send_file env, data_slice
|
||||
# ```
|
||||
#
|
||||
# Optionally you can override the mime_type
|
||||
#
|
||||
# ```
|
||||
# send_file env, data_slice, "image/jpeg"
|
||||
# ```
|
||||
def send_file(env : HTTP::Server::Context, data : Slice(UInt8), mime_type : String? = nil)
|
||||
mime_type ||= "application/octet-stream"
|
||||
env.response.content_type = mime_type
|
||||
env.response.content_length = data.bytesize
|
||||
env.response.write data
|
||||
# Set the Content-Disposition to "attachment" with the specified filename,
|
||||
# instructing the user agents to prompt to save.
|
||||
private def attachment(env : HTTP::Server::Context, filename : String? = nil, disposition : String? = nil)
|
||||
disposition = "attachment" if disposition.nil? && filename
|
||||
if disposition && filename
|
||||
env.response.headers["Content-Disposition"] = "#{disposition}; filename=\"#{File.basename(filename)}\""
|
||||
end
|
||||
end
|
||||
|
||||
# Configures an `HTTP::Server::Response` to compress the response
|
||||
|
|
Loading…
Reference in a new issue