Support :index-files in create-resource-handler

This commit is contained in:
Tommi Reiman 2018-04-29 16:49:05 +03:00
parent d502529bf3
commit 0b711b2560
5 changed files with 29 additions and 10 deletions

View file

@ -0,0 +1 @@
<h1>hello</h1>

View file

@ -54,10 +54,11 @@ A better way to serve files from conflicting paths, e.g. `"/*"`, is to serve the
| :root | optional resource root, defaults to `"public"`
| :path | optional path to mount the handler to. Works only if mounted outside of a router.
| :loader | optional class loader to resolve the resources
| :index-files | optional vector of index-files to look in a resource directory, defaults to `["index.html"]`
| :allow-symlinks? | allow symlinks that lead to paths outside the root classpath directories, defaults to `false`
### TODO
* support for things like `:cache`, `:etag`, `:last-modified?`, `:index-files` and `:gzip`
* support for things like `:cache`, `:etag`, `:last-modified?`, and `:gzip`
* support for ClojureScript
* serve from file-system

View file

@ -17,7 +17,7 @@ http GET :3000/api/swagger.json
```
* swagger.json: http://localhost:3000/api/swagger.json
* swagger-ui: http://localhost:3000/api-docs/index.html
* swagger-ui: http://localhost:3000/api-docs/
<img src="https://raw.githubusercontent.com/metosin/reitit/master/examples/ring-swagger/swagger-ui.png" />

View file

@ -68,6 +68,7 @@
(respond (not-found request)))))))
#?(:clj
;; TODO: optimize for perf
(defn create-resource-handler
"A ring handler for serving classpath resources, configured via options:
@ -77,29 +78,39 @@
| :root | optional resource root, defaults to `\"public\"`
| :path | optional path to mount the handler to. Works only if mounted outside of a router.
| :loader | optional class loader to resolve the resources
| :index-files | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]`
| :allow-symlinks? | allow symlinks that lead to paths outside the root classpath directories, defaults to `false`"
([]
(create-resource-handler nil))
([{:keys [parameter root path loader allow-symlinks?]
([{:keys [parameter root path loader allow-symlinks? index-files]
:or {parameter (keyword "")
root "public"}}]
root "public"
index-files ["index.html"]}}]
(let [options {:root root, :loader loader, :allow-symlinks? allow-symlinks?}
path-size (count path)
create (fn [handler]
(fn
([request] (handler request))
([request respond _] (respond (handler request)))))
response (fn [path]
(if-let [response (response/resource-response path options)]
(response/content-type response (mime-type/ext-mime-type path))))
resource-response (fn [path accept]
(if-let [path (accept path)]
(if-let [response (response/resource-response path options)]
(response/content-type response (mime-type/ext-mime-type path)))))
path-or-index-response (fn [path accept]
(or (resource-response path accept)
(loop [[file & files] index-files]
(if file
(or (resource-response (str path "/" file) accept)
(recur files))))))
handler (if path
(fn [request]
(let [uri (:uri request)]
(if (>= (count uri) path-size)
(response (subs uri path-size)))))
(path-or-index-response uri (fn [path]
(if (>= (count path) path-size)
(subs path path-size))))))
(fn [request]
(let [path (-> request :path-params parameter)]
(or (response path) {:status 404}))))]
(or (path-or-index-response path identity) {:status 404}))))]
(create handler)))))
(defn ring-handler

View file

@ -293,6 +293,12 @@
(is (get-in response [:headers "Last-Modified"]))
(is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
(testing "index-files"
(let [response (app {:uri "/files/docs", :request-method :get})]
(is (= "text/html" (get-in response [:headers "Content-Type"])))
(is (get-in response [:headers "Last-Modified"]))
(is (= "<h1>hello</h1>\n" (slurp (:body response))))))
(testing "not found"
(let [response (app {:uri "/files/not-found", :request-method :get})]
(is (= 404 (:status response)))))