334 local handle, ferr = errors.coerce(io.open(filename)); |
334 local handle, ferr = errors.coerce(io.open(filename)); |
335 if not handle then |
335 if not handle then |
336 return ferr or 410; |
336 return ferr or 410; |
337 end |
337 end |
338 |
338 |
|
339 if not filetype then |
|
340 filetype = "application/octet-stream"; |
|
341 end |
339 local disposition = "attachment"; |
342 local disposition = "attachment"; |
340 if safe_types:contains(filetype) or safe_types:contains(filetype:gsub("/.*", "/*")) then |
343 if safe_types:contains(filetype) or safe_types:contains(filetype:gsub("/.*", "/*")) then |
341 disposition = "inline"; |
344 disposition = "inline"; |
342 end |
345 end |
343 |
346 |
344 response.headers.last_modified = last_modified; |
347 response.headers.last_modified = last_modified; |
345 response.headers.content_length = filesize; |
348 response.headers.content_length = filesize; |
346 response.headers.content_type = filetype or "application/octet-stream"; |
349 response.headers.content_type = filetype; |
347 response.headers.content_disposition = string.format("%s; filename=%q", disposition, basename); |
350 response.headers.content_disposition = string.format("%s; filename=%q", disposition, basename); |
348 |
351 |
349 response.headers.cache_control = "max-age=31556952, immutable"; |
352 response.headers.cache_control = "max-age=31556952, immutable"; |
350 response.headers.content_security_policy = "default-src 'none'; frame-ancestors 'none';" |
353 response.headers.content_security_policy = "default-src 'none'; frame-ancestors 'none';" |
351 response.headers.strict_transport_security = "max-age=31556952"; |
354 response.headers.strict_transport_security = "max-age=31556952"; |