I have the following endpoint handler (using clj/ring), and it works fine, but it doesn't include a Content Type header in the response, which might be a reason why the returned video does not play in iOS/Safari.
(def stream-partial-media
{:summary "Stream partial media referenced by file-key"
:parameters {:path {:file-key uuid?}}
:handler (fn [{{{:keys [file-key]} :path} :parameters}]
(let [file-key-res (file-keys/READ-UNEXPIRED file-key)]
(if (nil? file-key-res)
{:status 404
:body {:message "file-key not found"}}
(let [user-res (users/READ (:user-id file-key-res))]
(if (or (:dev env) (:prod env))
(log-ut/log-media-access {:file-id (str (:file-id file-key-res))
:username (:username user-res)}))
(file-response (utils/file-id-to-path (:file-id file-key-res)))))))})
I want to make the endpoint dynamically return a Content Type, based on the extension of the requested file (mp4/mp3/etc.). I found that ring has a built in wrap-content-type function that uses the file's extension to add a Content Type header, but I do not know where to implement it. I tried putting it in a few different places, but still have no Content Type header.
I would like to know either how to correct implement this wrapper, or how to check the file extension and manually add a header on that basis: mp4=>video/mp4, mp3=>audio/mp3.
From the request you have to get the filename, from which you can get the extension. Then based on the extension you can add the
"Content-Disposition"to the headers map. Note that Ring request is just a map and the response as well. Something like this might work:Above Ring's
(header "Content-Type" <value>)just adds{:header {"Content-Type" <value>}to the response. The assumption is the:filenamekey is available in therequest.I would also add some extra check to see if the filename is correct, and otherwise return an error.