From 1a0d338c34a6a8671a8a54cd1321d510da2360ff Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Wed, 26 Feb 2020 18:06:45 +0000 Subject: [PATCH] OK, this is close to good. We're serving the right stuff. --- src/smeagol/finder.clj | 55 ++++++++++++++++++++++++------------- src/smeagol/middleware.clj | 19 ++++++++++++- src/smeagol/routes/wiki.clj | 54 ++++++++++++++++++------------------ 3 files changed, 80 insertions(+), 48 deletions(-) diff --git a/src/smeagol/finder.clj b/src/smeagol/finder.clj index 9b4daa6..851b93e 100644 --- a/src/smeagol/finder.clj +++ b/src/smeagol/finder.clj @@ -5,9 +5,10 @@ (:require [clojure.string :as cs] [me.raynes.fs :as fs] [noir.io :as io] - [noir.response :as response] + [ring.util.mime-type :refer [ext-mime-type]] + [ring.util.response :as response] [smeagol.configuration :refer [config]] - [smeagol.util :refer [local-url-base content-dir]] + [smeagol.util :refer [local-url-base content-dir upload-dir]] [taoensso.timbre :as log])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -85,25 +86,41 @@ paths)))) -(defn find-image-url - "Return a 302 redirect to - 1. The requested file, if available; - 2. This default URL otherwise." - [request requested-name default-url paths] - (let [url (to-url - (find-file-on-paths requested-name paths - [".gif" ".png" ".jpg" ".jpeg" ".svg"]))] - (if url - (log/info "Found image" requested-name "at" url) - (log/warn "Failed to find image matching" requested-name)) - (response/redirect - ;; (str "/" (:servlet-context request) url) ;; TODO: >>> Nasty - (if url - (str (name (:scheme request)) "://" (:host request) ":" (:server-port request) "/" url) - default-url) - :found ))) +(defn with-mime-type-for-file + [response file] + (assoc-in + response + [:headers "Content-Type"] + (ext-mime-type (str file)))) +(defn find-image + "Return the first image file found on these `paths` with this + `requested-name`, if available; this `default-file` otherwise." + [requested-name default-file paths] + (let [file (find-file-on-paths requested-name paths + [".gif" ".png" ".jpg" ".jpeg" ".svg"]) + s (if file (str file) default-file)] + (if file + (log/info "Found image" requested-name "at" s) + (log/warn "Failed to find image matching" requested-name)) + (with-mime-type-for-file + (response/file-response s) + s))) + +(find-image "froboz.jpg" "resources/public/img/Unknown-pin.png" + [;; TODO: should map over the configured + ;; thumbnail paths in ascending order + ;; by size - for map pins, smaller images are + ;; better. + (fs/file upload-dir "map-pin") + (fs/file upload-dir "small") + (fs/file upload-dir "med")]) + + + +;; (response/file-response "resources/public/img/smeagol.png") + ;; (def r {:ssl-client-cert nil, ;; :access-rules [{:redirect "/auth", ;; :rule #object[smeagol.handler$user_access 0x7ee9346 "smeagol.handler$user_access@7ee9346"]}], diff --git a/src/smeagol/middleware.clj b/src/smeagol/middleware.clj index 7d8c4bf..aa0b8e7 100644 --- a/src/smeagol/middleware.clj +++ b/src/smeagol/middleware.clj @@ -48,12 +48,29 @@ wrap-exceptions]) +(defn smeagol-wrap-content-type + "Ring's `wrap-content-type` infers the content type from the *requested* file + name. But because we fuzzy-match images, the file we return may not be the + same type as the file that was requested, in which case we've already set + a content type from the filename extension on the file actually served. Do not + overwrite this!" + [response] + (if-not + (and (map? (:headers response))((:headers response) "Content-Type")) + (wrap-content-type response) + (do + (log/info "Content-type already set as" + ((:headers response) "Content-Type") + "; not overriding") + response))) + + (def production-middleware [#(wrap-internal-error % :log (fn [e] (log/error e))) #(wrap-resource % "public") + smeagol-wrap-content-type #(wrap-file % util/content-dir {:index-files? false :prefer-handler? true}) - wrap-content-type wrap-not-modified]) diff --git a/src/smeagol/routes/wiki.clj b/src/smeagol/routes/wiki.clj index 2933fcb..d529104 100644 --- a/src/smeagol/routes/wiki.clj +++ b/src/smeagol/routes/wiki.clj @@ -18,7 +18,7 @@ [smeagol.authenticate :as auth] [smeagol.configuration :refer [config]] [smeagol.diff2html :as d2h] - [smeagol.finder :refer [find-image-url]] + [smeagol.finder :refer [find-image]] [smeagol.formatting :refer [md->html]] [smeagol.history :as hist] [smeagol.layout :as layout] @@ -467,35 +467,33 @@ (GET "/edit-user" request (route/restricted (admin/edit-user request))) (POST "/edit-user" request (route/restricted (admin/edit-user request))) (GET "/history" request (history-page request)) - (GET "/image/:n" request (find-image-url - request - (-> request :route-params :n) - "http://localhost:3000/img/smeagol.png" - [(fs/file local-url-base "img") - upload-dir - ;; TODO: should map over the configured - ;; thumbnail paths in descending order - ;; by size - generally, bigger images are - ;; better. - (fs/file upload-dir "med") - (fs/file upload-dir "small") - (fs/file upload-dir "map-pin")])) + (GET "/image/:n" [n] (find-image + n + "resources/public/img/smeagol.png" + [(fs/file local-url-base "img") + upload-dir + ;; TODO: should map over the configured + ;; thumbnail paths in descending order + ;; by size - generally, bigger images are + ;; better. + (fs/file upload-dir "med") + (fs/file upload-dir "small") + (fs/file upload-dir "map-pin")])) (GET "/list-uploads" request (route/restricted (list-uploads-page request))) (POST "/list-uploads" request (route/restricted (list-uploads-page request))) - (GET "/map-pin/:n" request (find-image-url - request - (-> request :route-params :n) - "http://localhost:3000/img/Unknown-pin.png" - [(fs/file local-url-base "img") - ;; TODO: should map over the configured - ;; thumbnail paths in ascending order - ;; by size - for map pins, smaller images are - ;; better. - (fs/file upload-dir "map-pin") - (fs/file upload-dir "small") - (fs/file upload-dir "med") - upload-dir - local-url-base])) + (GET "/map-pin/:n" [n] (find-image + n + "resources/public/img/Unknown-pin.png" + [;; TODO: should map over the configured + ;; thumbnail paths in ascending order + ;; by size - for map pins, smaller images are + ;; better. + (fs/file upload-dir "map-pin") + (fs/file upload-dir "small") + (fs/file upload-dir "med") + (fs/file local-url-base "img") + upload-dir + local-url-base])) (GET "/passwd" request (passwd-page request)) (POST "/passwd" request (passwd-page request)) (GET "/upload" request (route/restricted (upload-page request)))