I would like to be able to serve a file with Caveman2. The reason I want a way to return it from a controller and not make a static route available to anyone is to be able to only serve the file to authenticated users that have the permission level required.
I found this answer, including it here for reference: Serving Static Files with Common Lisp , and while I found that my quicklisp had already included usocket
and flexi-streams
, I did not follow exactly how to do it. Which socket should I use? Is that the correct way of doing it? Is that what's supposed to be done from Caveman2
From here How do I force files to open in the browser instead of downloading (PDF)? it seems that for the browser to handle the response correctly I need to set certain headers.
So this seems to be just a question of how to return a file to the browser.
Since this seems like such a standard operation I image there's a standard way of doing it and I don't want to reinvent the wheel over here, just couldn't find it in the docs...
Thanks in advance
The way to solve the problem was to return a sequence. First read the file into a sequence and then return it.
As included in the question, the correct headers need to be set.
Content-Type
is set like this:
(setf (getf (caveman2:response-headers caveman2:*response*) :content-type) "image/png")
.
This example has "image/png"
but you can set it up depending on whatever the file is. (setf
(getf (caveman2:response-headers caveman2:*response*) :content-disposition)
"attachment; filename=\"filename.png\"")
You can replace attachment
in the code above with inline
and it will prompt for a file download instead of an in browser render.
Finally, and the main answer to the question, is to return a sequence of the byte-vector.
(alexandria:read-stream-content-into-byte-vector STREAM)
In my case, since I'm using mito-attachment, I'm including the code here for reference:
(alexandria:read-stream-content-into-byte-vector
(mito-attachment:get-object
(mito:find-dao 'class-name :file-key file-key)))