From b201823b6c0425bbe9cb5c02e88e2a0e01b5eb58 Mon Sep 17 00:00:00 2001 From: Stefan van den Oord Date: Wed, 8 Dec 2021 09:07:00 +0100 Subject: [PATCH] Fix wrap-content-type for requests of directories When the request points to a directory and the body of the response is a file (i.e. index.html or something like that), take the mime type of that file. This fixes the case where previously requesting "/" would serve "index.html" with content type "application/octet-stream". --- ring-core/src/ring/middleware/content_type.clj | 13 ++++++++++--- .../test/ring/middleware/test/content_type.clj | 15 ++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ring-core/src/ring/middleware/content_type.clj b/ring-core/src/ring/middleware/content_type.clj index 83bef8138..eb018af6a 100644 --- a/ring-core/src/ring/middleware/content_type.clj +++ b/ring-core/src/ring/middleware/content_type.clj @@ -1,7 +1,12 @@ (ns ring.middleware.content-type "Middleware for automatically adding a content type to response maps." (:require [ring.util.mime-type :refer [ext-mime-type]] - [ring.util.response :refer [content-type get-header]])) + [ring.util.response :refer [content-type get-header]]) + (:import [java.io File])) + +(defn- mime-type-from-response-body [response mime-types] + (when (instance? File (:body response)) + (ext-mime-type (.getAbsolutePath (:body response)) mime-types))) (defn content-type-response "Adds a content-type header to response. See: wrap-content-type." @@ -12,8 +17,10 @@ (if response (if (get-header response "Content-Type") response - (let [mime-type (ext-mime-type (:uri request) (:mime-types options))] - (content-type response (or mime-type "application/octet-stream"))))))) + (let [mime-type (or (ext-mime-type (:uri request) (:mime-types options)) + (mime-type-from-response-body response (:mime-types options)) + "application/octet-stream")] + (content-type response mime-type)))))) (defn wrap-content-type "Middleware that adds a content-type header to the response if one is not diff --git a/ring-core/test/ring/middleware/test/content_type.clj b/ring-core/test/ring/middleware/test/content_type.clj index 54c37d5f8..174354445 100644 --- a/ring-core/test/ring/middleware/test/content_type.clj +++ b/ring-core/test/ring/middleware/test/content_type.clj @@ -1,6 +1,10 @@ (ns ring.middleware.test.content-type (:require [clojure.test :refer :all] - [ring.middleware.content-type :refer :all])) + [ring.middleware.content-type :refer :all]) + (:import [java.io File])) + +(def public-dir "test/ring/assets") +(def index-html (File. ^String public-dir "index.html")) (deftest wrap-content-type-test (testing "response without content-type" @@ -10,6 +14,15 @@ {:headers {"Content-Type" "image/png"}})) (is (= (handler {:uri "/foo/bar.txt"}) {:headers {"Content-Type" "text/plain"}})))) + + (testing "response body is java.io.File" + (let [response {:headers {} + :body index-html} + handler (wrap-content-type (constantly response))] + (is (= (get-in (handler {:uri "/index.html"}) [:headers "Content-Type"]) + "text/html")) + (is (= (get-in (handler {:uri "/"}) [:headers "Content-Type"]) + "text/html")))) (testing "response with content-type" (let [response {:headers {"Content-Type" "application/x-foo"}}