Skip to content

Commit

Permalink
feat(response) add sendFile method to download files
Browse files Browse the repository at this point in the history
also rewrites writeFile to take a filename instead of a file
descriptor.
  • Loading branch information
Tieske committed Feb 22, 2023
1 parent 5278b92 commit 325e911
Showing 1 changed file with 46 additions and 6 deletions.
52 changes: 46 additions & 6 deletions src/pegasus/response.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local mimetypes = require 'mimetypes'

local function toHex(dec)
local charset = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }
local tmp = {}
Expand Down Expand Up @@ -202,20 +204,58 @@ function Response:write(body, stayOpen)
return self
end

function Response:writeFile(file, contentType)
self:contentType(contentType)
self:statusCode(200)
local value = file:read('*a')
local function readfile(filename)
local file, err = io.open(filename, 'rb')
if not file then
return nil, err
end

local value, err = file:read('*a')
file:close()
self:write(value)
return value, err
end

-- return nil+err if not ok
function Response:writeFile(filename, contentType)
if type(filename) ~= "string" then
-- deprecated backward compatibility; file is a file-descriptor
self:contentType(contentType)
self:statusCode(200)
local value = filename:read('*a')
filename:close()
self:write(value)
return self
end

local contents, err = readfile(filename)
if not contents then
return nil, err
end

self:statusCode(200)
self:contentType(contentType or mimetypes.guess(filename))
self:write(contents)
return self
end

-- download by browser, return nil+err if not ok
function Response:sendFile(path)
local filename = path:match("[^/]*$") -- only filename, no path
self:addHeader('Content-Disposition', 'attachment; filename="' .. filename .. '"')

local ok, err = self:writeFile(path, 'application/octet-stream')
if not ok then
self:addHeader('Content-Disposition', nil)
return nil, err
end

return self
end

function Response:redirect(location, temporary)
self:statusCode(temporary and 302 or 301)
self:addHeader('Location', location)
self.client:sendOnlyHeaders()
self:sendOnlyHeaders()
return self
end

Expand Down

0 comments on commit 325e911

Please sign in to comment.