From e16c95c5b3f8dd72ebb57b4c977cc71bc4b2d861 Mon Sep 17 00:00:00 2001 From: Eva Ogbe Date: Mon, 7 Apr 2025 20:35:58 -0400 Subject: [PATCH] Add mime-types option to static handler --- .gitignore | 1 + dev-resources/public/site.webmanifest | 3 +++ modules/reitit-ring/src/reitit/ring.cljc | 16 ++++++++++------ test/cljc/reitit/ring_test.cljc | 17 ++++++++++++++++- 4 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 dev-resources/public/site.webmanifest diff --git a/.gitignore b/.gitignore index 80a2dd4b..c3904665 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ figwheel_server.log /.idea .clj-kondo .shadow-cljs +.cache diff --git a/dev-resources/public/site.webmanifest b/dev-resources/public/site.webmanifest new file mode 100644 index 00000000..8b20df14 --- /dev/null +++ b/dev-resources/public/site.webmanifest @@ -0,0 +1,3 @@ +{ + "name": "Example" +} diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index ae15ba86..32d3bb44 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -227,7 +227,7 @@ ;; TODO: ring.middleware.head/wrap-head ;; TODO: handle etags (defn -create-file-or-resource-handler - [response-fn {:keys [parameter root path loader allow-symlinks? index-files index-redirect? canonicalize-uris? paths not-found-handler] + [response-fn {:keys [parameter root path loader allow-symlinks? index-files index-redirect? canonicalize-uris? paths not-found-handler mime-types] :or {parameter (keyword "") root "public" index-files ["index.html"] @@ -250,9 +250,11 @@ join-paths (fn [& paths] (str/replace (str/replace (str/join "/" paths) #"([/]+)" "/") #"/$" "")) response (fn [path] - (if-let [response (or (paths (join-paths "/" path)) - (response-fn path options))] - (response/content-type response (mime-type/ext-mime-type path)))) + (when-let [response (or (paths (join-paths "/" path)) + (response-fn path options))] + (if-let [content-type (mime-type/ext-mime-type path mime-types)] + (response/content-type response content-type) + response))) path-or-index-response (fn [path uri] (or (response path) (when (or canonicalize-uris? (str/ends-with? uri "/")) @@ -295,7 +297,8 @@ | :index-files | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]` | :index-redirect? | optional boolean: if true (default false), redirect to index file, if false serve it directly | :canonicalize-uris? | optional boolean: if true (default), try to serve index files for non directory paths (paths that end with slash) - | :not-found-handler | optional handler function to use if the requested resource is missing (404 Not Found)" + | :not-found-handler | optional handler function to use if the requested resource is missing (404 Not Found) + | :mime-types | optional map of filename extensions to mime-types that will be used to guess the content type in addition to the ones defined in ring.util.mime-type/default-mime-types" ([] (create-resource-handler nil)) ([opts] @@ -314,7 +317,8 @@ | :index-files | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]` | :index-redirect? | optional boolean: if true (default false), redirect to index file, if false serve it directly | :canonicalize-uris? | optional boolean: if true (default), try to serve index files for non directory paths (paths that end with slash) - | :not-found-handler | optional handler function to use if the requested resource is missing (404 Not Found)" + | :not-found-handler | optional handler function to use if the requested resource is missing (404 Not Found) + | :mime-types | optional map of filename extensions to mime-types that will be used to guess the content type in addition to the ones defined in ring.util.mime-type/default-mime-types" ([] (create-file-handler nil)) ([opts] diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 27d3aa58..1825dee7 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -742,7 +742,22 @@ (let [response (app (request "/docs/"))] (is (= (redirect "/docs/index.html") response))) (let [response (app (request "/foobar"))] - (is (= 404 (:status response)))))))))))) + (is (= 404 (:status response))))))) + + (testing "with additional mime types" + (let [app (ring/ring-handler + (ring/router + ["/*" (create {:mime-types {"webmanifest" "application/manifest+json"}})]) + (ring/create-default-handler)) + response (app (request "/site.webmanifest"))] + (is (= "application/manifest+json" (get-in response [:headers "Content-Type"]))))) + (testing "when content type cannot be guessed" + (let [app (ring/ring-handler + (ring/router + ["/*" (create nil)]) + (ring/create-default-handler)) + response (app (request "/site.webmanifest"))] + (is (not (contains? (:headers response) "Content-Type")))))))))) #?(:clj (deftest file-resource-handler-not-found-test