1
{-# LANGUAGE OverloadedStrings #-}
2
module Network.Wai.Middleware.Debug
7
import Network.Wai (Request(..), Middleware)
8
import Network.Wai.Parse (parseRequestBody, lbsSink, fileName, Param, File)
9
import Data.ByteString.Char8 (unpack)
10
import qualified Data.ByteString as S
11
import qualified Data.ByteString.Lazy as L
12
import System.IO (hPutStrLn, stderr)
13
import Control.Monad.IO.Class (liftIO)
14
import qualified Data.Text.Lazy as T
15
import Data.Enumerator (run_, ($$), enumList)
16
import Data.Enumerator.List (consume)
19
debug = debugHandle $ hPutStrLn stderr . T.unpack
21
debugHandle :: (T.Text -> IO ()) -> Middleware
22
debugHandle cb app req = do
24
postParams <- if any (requestMethod req ==) ["GET", "HEAD"]
26
else do postParams <- liftIO $ allPostParams req body
27
return $ collectPostParams postParams
28
let getParams = map emptyGetParam $ queryString req
30
liftIO $ cb $ T.pack $ concat
31
[ unpack $ requestMethod req
33
, unpack $ rawPathInfo req
35
, (++) "Accept: " $ maybe "" unpack $ lookup "Accept" $ requestHeaders req
36
, paramsToStr "GET " getParams
37
, paramsToStr "POST " postParams
39
-- we just consumed the body- fill the enumerator back up so it is available again
40
liftIO $ run_ $ enumList 1 body $$ app req
42
paramsToStr prefix params = if null params then "" else "\n" ++ prefix ++ (show params)
44
allPostParams req' body = run_ $ enumList 1 body $$ parseRequestBody lbsSink req'
46
emptyGetParam :: (S.ByteString, Maybe S.ByteString) -> (S.ByteString, S.ByteString)
47
emptyGetParam (k, Just v) = (k,v)
48
emptyGetParam (k, Nothing) = (k,"")
50
collectPostParams :: ([Param], [File L.ByteString]) -> [Param]
51
collectPostParams (postParams, files) = postParams ++
52
(map (\(k,v) -> (k, S.append "FILE: " (fileName v))) files)