diff --git a/Network/Wai/Application/Classic.hs b/Network/Wai/Application/Classic.hs
--- a/Network/Wai/Application/Classic.hs
+++ b/Network/Wai/Application/Classic.hs
@@ -11,6 +11,9 @@
   , FileInfo(..)
   , FileRoute(..)
   , fileApp
+  -- * Redirect
+  , RedirectRoute(..)
+  , redirectApp
   -- * CGI
   , CgiAppSpec(..)
   , CgiRoute(..)
@@ -28,5 +31,6 @@
 import Network.Wai.Application.Classic.CGI
 import Network.Wai.Application.Classic.File
 import Network.Wai.Application.Classic.Path
+import Network.Wai.Application.Classic.Redirect
 import Network.Wai.Application.Classic.RevProxy
 import Network.Wai.Application.Classic.Types
diff --git a/Network/Wai/Application/Classic/Redirect.hs b/Network/Wai/Application/Classic/Redirect.hs
new file mode 100644
--- /dev/null
+++ b/Network/Wai/Application/Classic/Redirect.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Network.Wai.Application.Classic.Redirect (
+    redirectApp
+  ) where
+
+import Control.Monad.IO.Class (liftIO)
+import Data.ByteString.Char8
+import Network.HTTP.Types
+import Network.Wai
+import Network.Wai.Application.Classic.Field
+import Network.Wai.Application.Classic.Path
+import Network.Wai.Application.Classic.Types
+
+redirectApp :: ClassicAppSpec -> RedirectRoute -> Application
+redirectApp cspec route req = do
+    liftIO $ logger cspec req status Nothing
+    return $ responseLBS status hdr ""
+  where
+    path = fromByteString $ rawPathInfo req
+    src = redirectSrc route
+    dst = redirectDst route
+    rurl = "http://" `append` pathByteString (dst </> (path <\> src))
+    hdr = addServer cspec $ locationHeader rurl
+    status = movedPermanently301
diff --git a/Network/Wai/Application/Classic/Types.hs b/Network/Wai/Application/Classic/Types.hs
--- a/Network/Wai/Application/Classic/Types.hs
+++ b/Network/Wai/Application/Classic/Types.hs
@@ -26,6 +26,7 @@
   | StatusFile Path Integer
   -- | No HTTP status body.
   | StatusNone
+  deriving (Eq,Show)
 
 ----------------------------------------------------------------
 
@@ -43,28 +44,37 @@
     fileInfoName :: Path
   , fileInfoSize :: Integer
   , fileInfoTime :: HTTPDate
-  } deriving Show
+  } deriving (Eq, Show)
 
 data FileRoute = FileRoute {
     -- | Path prefix to be matched to 'rawPathInfo'.
     fileSrc :: Path
     -- | Path prefix to an actual file system.
   , fileDst :: Path
-  }
+  } deriving (Eq,Show)
 
 ----------------------------------------------------------------
 
+data RedirectRoute = RedirectRoute {
+    -- | Path prefix to be matched to 'rawPathInfo'.
+    redirectSrc :: Path
+    -- | Path prefix to an actual file system.
+  , redirectDst :: Path
+  } deriving (Eq,Show)
+
+----------------------------------------------------------------
+
 data CgiAppSpec = CgiAppSpec {
     -- | A file name of the default CGI.
     indexCgi :: Path
-  }
+  } deriving (Eq,Show)
 
 data CgiRoute = CgiRoute {
     -- | Path prefix to be matched to 'rawPathInfo'.
     cgiSrc :: Path
     -- | Path prefix to an actual file system.
   , cgiDst :: Path
-  }
+  } deriving (Eq,Show)
 
 ----------------------------------------------------------------
 
@@ -82,7 +92,7 @@
   , revProxyDomain :: ByteString
     -- | Destination port number.
   , revProxyPort :: Int
-  }
+  } deriving (Eq,Show)
 
 ----------------------------------------------------------------
 
@@ -91,19 +101,21 @@
     rspStatus :: Status
     -- | Response body.
   , rspBody :: RspBody
-  }
+  } deriving (Eq,Show)
 
 data RspBody =
     NoBody
   | BodyStatus
   | BodyFileNoBody ResponseHeaders
   | BodyFile ResponseHeaders Path Range
+  deriving (Eq,Show)
 
 data Range =
     -- | Entire file showing its file size
     Entire Integer
     -- | A part of a file taking offset and length
   | Part Integer Integer
+  deriving (Eq,Show)
 
 ----------------------------------------------------------------
 
diff --git a/wai-app-file-cgi.cabal b/wai-app-file-cgi.cabal
--- a/wai-app-file-cgi.cabal
+++ b/wai-app-file-cgi.cabal
@@ -1,5 +1,5 @@
 Name:                   wai-app-file-cgi
-Version:                0.5.10
+Version:                0.6.0
 Author:                 Kazu Yamamoto <kazu@iij.ad.jp>
 Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>
 License:                BSD3
@@ -24,6 +24,7 @@
                         Network.Wai.Application.Classic.Lang
                         Network.Wai.Application.Classic.Path
                         Network.Wai.Application.Classic.Range
+                        Network.Wai.Application.Classic.Redirect
                         Network.Wai.Application.Classic.RevProxy
                         Network.Wai.Application.Classic.Status
                         Network.Wai.Application.Classic.Types
