Merge pull request #725 from agorgl/index-redirect

Add option to allow serving index files without redirect
This commit is contained in:
Joel Kaasinen 2025-03-26 11:08:54 +02:00 committed by GitHub
commit 2f1defe3cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 41 additions and 8 deletions

View file

@ -61,6 +61,7 @@ This way, they are only served if none of the actual routes have matched.
| :path | path to mount the handler to. Required when mounted outside of a router, does not work inside a router. | :path | path to mount the handler to. Required when mounted outside of a router, does not work inside a router.
| :loader | optional class loader to resolve the resources | :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\"]` | :index-files | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]`
| :index-redirect? | optional boolean: if true (default), redirect to index file, if false serve it directly
| :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)

View file

@ -227,18 +227,20 @@
;; TODO: ring.middleware.head/wrap-head ;; TODO: ring.middleware.head/wrap-head
;; TODO: handle etags ;; TODO: handle etags
(defn -create-file-or-resource-handler (defn -create-file-or-resource-handler
[response-fn {:keys [parameter root path loader allow-symlinks? index-files paths not-found-handler] [response-fn {:keys [parameter root path loader allow-symlinks? index-files index-redirect? paths not-found-handler]
:or {parameter (keyword "") :or {parameter (keyword "")
root "public" root "public"
index-files ["index.html"] index-files ["index.html"]
paths (constantly nil) index-redirect? true
not-found-handler (if path paths (constantly nil)}}]
(constantly nil)
(constantly {:status 404, :body "", :headers {}}))}}]
(let [options {:root root (let [options {:root root
:loader loader :loader loader
:index-files? false :index-files? false
:allow-symlinks? allow-symlinks?} :allow-symlinks? allow-symlinks?}
not-found-handler (or not-found-handler
(if path
(constantly nil)
(constantly {:status 404, :body "", :headers {}})))
path-size (count path) path-size (count path)
create (fn [handler] create (fn [handler]
(fn (fn
@ -254,8 +256,10 @@
(or (response path) (or (response path)
(loop [[file & files] index-files] (loop [[file & files] index-files]
(if file (if file
(if (response (join-paths path file)) (if-let [resp (response (join-paths path file))]
(response/redirect (join-paths uri file)) (if index-redirect?
(response/redirect (join-paths uri file))
resp)
(recur files)))))) (recur files))))))
handler (if path handler (if path
(fn [request] (fn [request]
@ -281,6 +285,7 @@
| :path | path to mount the handler to. Required when mounted outside of a router, does not work inside a router. | :path | path to mount the handler to. Required when mounted outside of a router, does not work inside a router.
| :loader | optional class loader to resolve the resources | :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\"]` | :index-files | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]`
| :index-redirect? | optional boolean: if true (default), redirect to index file, if false serve it directly
| :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)"
([] ([]
(create-resource-handler nil)) (create-resource-handler nil))
@ -298,6 +303,7 @@
| :path | path to mount the handler to. Required when mounted outside of a router, does not work inside a router. | :path | path to mount the handler to. Required when mounted outside of a router, does not work inside a router.
| :loader | optional class loader to resolve the resources | :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\"]` | :index-files | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]`
| :index-redirect? | optional boolean: if true (default), redirect to index file, if false serve it directly
| :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)"
([] ([]
(create-file-handler nil)) (create-file-handler nil))

View file

@ -671,7 +671,33 @@
(app (request "/hello.xml") respond raise) (app (request "/hello.xml") respond raise)
(is (= "text/xml" (get-in @result [:headers "Content-Type"]))) (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
(is (get-in @result [:headers "Last-Modified"])) (is (get-in @result [:headers "Last-Modified"]))
(is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result)))))))))))))) (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result)))))))))
(testing "with index-redirect"
(let [app (ring/ring-handler
(ring/router
["/*" (create {:index-redirect? true})])
(ring/create-default-handler))]
(testing "index-files"
(let [response (app (request "/docs"))]
(is (= (redirect "/docs/index.html") response)))
(let [response (app (request "/docs/"))]
(is (= (redirect "/docs/index.html") response))))))
(testing "without index-redirect"
(let [app (ring/ring-handler
(ring/router
["/*" (create {:index-redirect? false})])
(ring/create-default-handler))]
(testing "index-files"
(let [response (app (request "/docs"))]
(is (= 200 (:status response)))
(is (= "<h1>hello</h1>\n" (slurp (:body response)))))
(let [response (app (request "/docs/"))]
(is (= 200 (:status response)))
(is (= "<h1>hello</h1>\n" (slurp (:body response)))))))))))))
#?(:clj #?(:clj
(deftest file-resource-handler-not-found-test (deftest file-resource-handler-not-found-test