From 000490af664818300a24868020ddcd8559fd0e72 Mon Sep 17 00:00:00 2001 From: Michael Snoyman Date: Wed, 14 Jan 2015 12:20:45 +0200 Subject: [PATCH] Trailing slashes for non-root apps #325 --- wai-app-static/ChangeLog.md | 4 ++++ .../Network/Wai/Application/Static.hs | 24 +++++++++++++++---- wai-app-static/wai-app-static.cabal | 2 +- wai-extra/ChangeLog.md | 4 ++++ wai-extra/Network/Wai/UrlMap.hs | 2 +- wai-extra/wai-extra.cabal | 2 +- 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/wai-app-static/ChangeLog.md b/wai-app-static/ChangeLog.md index 760d9a9a..e15a9684 100644 --- a/wai-app-static/ChangeLog.md +++ b/wai-app-static/ChangeLog.md @@ -1,3 +1,7 @@ +## 3.0.0.6 + +Fix trailing slashes for `UrlMap` and other non-root setups [#325](https://github.com/yesodweb/wai/issues/325) + ## 3.0.0.4 Add missing trailing slashes [#312](https://github.com/yesodweb/wai/issues/312) diff --git a/wai-app-static/Network/Wai/Application/Static.hs b/wai-app-static/Network/Wai/Application/Static.hs index ccf07dae..b48eb9f9 100644 --- a/wai-app-static/Network/Wai/Application/Static.hs +++ b/wai-app-static/Network/Wai/Application/Static.hs @@ -52,6 +52,7 @@ import Network.Mime (MimeType) data StaticResponse = -- | Just the etag hash or Nothing for no etag hash Redirect Pieces (Maybe ByteString) + | RawRedirect ByteString | NotFound | FileResponse File H.ResponseHeaders | NotModified @@ -79,15 +80,15 @@ serveFolder ss@StaticSettings {..} pieces req folder@Folder {..} = let pieces' = setLast pieces index in case () of () | ssRedirectToIndex -> return $ Redirect pieces' Nothing - | noTrailingSlash pieces, Just trailing <- toPiece "" -> - return $ Redirect (pieces ++ [trailing]) Nothing + | Just path <- addTrailingSlash req -> + return $ RawRedirect path | otherwise -> -- start the checking process over, with a new set checkPieces ss pieces' req Nothing -> case ssListing of - Just _ | noTrailingSlash pieces, Just trailing <- toPiece "" -> - return $ Redirect (pieces ++ [trailing]) Nothing + Just _ | Just path <- addTrailingSlash req -> + return $ RawRedirect path Just listing -> do -- directory listings turned on, display it builder <- listing pieces folder @@ -104,6 +105,15 @@ serveFolder ss@StaticSettings {..} pieces req folder@Folder {..} = | fromPiece t == "" = [x] setLast (a:b) x = a : setLast b x + addTrailingSlash :: W.Request -> Maybe ByteString + addTrailingSlash req + | S8.null rp = Just "/" + | rp == "/" = Nothing + | S8.last rp == '/' = Nothing + | otherwise = Just $ S8.snoc rp '/' + where + rp = W.rawPathInfo req + noTrailingSlash :: Pieces -> Bool noTrailingSlash [] = False noTrailingSlash [x] = fromPiece x /= "" @@ -250,6 +260,12 @@ staticAppPieces ss rawPieces req sendResponse = liftIO $ do , ("Location", S8.append loc $ H.renderQuery True qString) ] "Redirect" + response (RawRedirect path) = + sendResponse $ W.responseLBS H.status301 + [ ("Content-Type", "text/plain") + , ("Location", path) + ] "Redirect" + response NotFound = sendResponse $ W.responseLBS H.status404 [ ("Content-Type", "text/plain") ] "File not found" diff --git a/wai-app-static/wai-app-static.cabal b/wai-app-static/wai-app-static.cabal index 9deab81e..7b73c405 100644 --- a/wai-app-static/wai-app-static.cabal +++ b/wai-app-static/wai-app-static.cabal @@ -1,5 +1,5 @@ name: wai-app-static -version: 3.0.0.5 +version: 3.0.0.6 license: MIT license-file: LICENSE author: Michael Snoyman diff --git a/wai-extra/ChangeLog.md b/wai-extra/ChangeLog.md index 0b459789..bf0fdd75 100644 --- a/wai-extra/ChangeLog.md +++ b/wai-extra/ChangeLog.md @@ -1,3 +1,7 @@ +## 3.0.4.2 + +* `UrlMap`: do not modify `rawPathInfo`, see [#325](https://github.com/yesodweb/wai/issues/325) + ## 3.0.4.1 Fix compilation failure on Windows [#321](https://github.com/yesodweb/wai/issues/321) diff --git a/wai-extra/Network/Wai/UrlMap.hs b/wai-extra/Network/Wai/UrlMap.hs index 6bee1c1b..0c2a29f0 100644 --- a/wai-extra/Network/Wai/UrlMap.hs +++ b/wai-extra/Network/Wai/UrlMap.hs @@ -88,7 +88,7 @@ instance ToApplication UrlMap where case try (pathInfo req) (unUrlMap urlMap) of Just (newPath, app) -> app (req { pathInfo = newPath - , rawPathInfo = makeRaw newPath + --, rawPathInfo = makeRaw newPath }) sendResponse Nothing -> sendResponse $ responseLBS diff --git a/wai-extra/wai-extra.cabal b/wai-extra/wai-extra.cabal index 55b9e912..400612ca 100644 --- a/wai-extra/wai-extra.cabal +++ b/wai-extra/wai-extra.cabal @@ -1,5 +1,5 @@ Name: wai-extra -Version: 3.0.4.1 +Version: 3.0.4.2 Synopsis: Provides some basic WAI handlers and middleware. description: API docs and the README are available at . License: MIT