【问题标题】:Add content-type header to file-response将内容类型标头添加到文件响应
【发布时间】:2022-09-26 02:41:07
【问题描述】:

我有以下端点处理程序(使用clj/ring),它工作正常,但它在响应中不包含Content Type 标头,这可能是返回的视频无法播放的原因在 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)))))))})

我想让端点根据请求文件的扩展名(mp4/mp3/等)动态返回Content Type。我发现ring 有一个内置的wrap-content-type 函数,它使用文件的扩展名添加Content Type 标头,但我不知道在哪里实现它。我尝试将它放在几个不同的地方,但仍然没有 Content Type 标头。

我想知道如何更正实现这个包装器,或者如何检查文件扩展名并在此基础上手动添加标题:mp4=>video/mp4mp3=>audio/mp3

  • 你的实际问题是什么?您在将标头添加到响应时遇到问题吗?或者您是否需要一种从文件(名称)中检测 mime 类型的方法?请添加您尝试过的代码,这可能会使问题更清楚。
  • @cfrick 我用更多信息编辑了这个问题,但简短的回答是我需要这两件事。

标签: clojure http-headers ring


【解决方案1】:

从请求中,您必须获取文件名,您可以从中获取扩展名。然后根据扩展名,您可以将"Content-Disposition" 添加到标题映射中。请注意,Ring 请求只是一个映射和响应。像这样的东西可能会起作用:

(require '[ring.util.response :refer [header]])

(defn extension [s]
  (second (re-find #"\.([a-zA-Z0-9]+)$" s)))

(extension "foo.mp3")
;; => "mp3"

(extension "foo.mp4")
;; => "mp4"

(extension "foo")
;; => nil

(def stream-partial-media
  {:summary "Stream partial media referenced by file-key"
   :parameters {:path {:file-key uuid?}}
   :handler (fn [{{{:keys [file-key]} :path} :parameters :as request}]
              (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))]
                    (when (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)))
                        (header "Content-Type"
                                (case (extension (:filename request))
                                  :mp4 "video/mp4"
                                  :mp3 "audio/mp3")))))))})

以上环的(header "Content-Type" <value>) 只是将{:header {"Content-Type" <value>} 添加到响应中。假设:filename 密钥在request 中可用。

我还会添加一些额外的检查以查看文件名是否正确,否则返回错误。

【讨论】:

    猜你喜欢
    • 2011-09-30
    • 2019-08-27
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    相关资源
    最近更新 更多