{-# LANGUAGE OverloadedStrings #-}moduleNetwork.Wai.Middleware.RequestLogger(logStdout,logCallback,logStdoutDev,logCallbackDev-- * Deprecated,logHandle,logHandleDev)whereimportSystem.IO(stdout,hFlush)importqualifiedData.ByteStringasBSimportData.ByteString.Char8(pack)importControl.Monad.IO.Class(liftIO)importNetwork.Wai(Request(..),Middleware)importSystem.Log.FastLoggerimportNetwork.HTTP.TypesasHimportNetwork.Wai.Parse(sinkRequestBody,lbsBackEnd,fileName,Param,File,getRequestBodyType)importqualifiedData.ByteString.LazyasLBSimportqualifiedData.ConduitasCimportqualifiedData.Conduit.ListasCLlogHandle::(BS.ByteString->IO())->MiddlewarelogHandle=logCallback{-# DEPRECATED logHandle "Please use logCallback instead." #-}logHandleDev::(BS.ByteString->IO())->MiddlewarelogHandleDev=logCallbackDev{-# DEPRECATED logHandleDev "Please use logCallbackDev instead." #-}-- | Production request logger middleware.-- Implemented on top of "logCallback", but prints to 'stdout'logStdout::MiddlewarelogStdout=logHandle$\bs->hPutLogStrstdout[LBbs]-- | Development request logger middleware.-- Implemented on top of "logCallbackDev", but prints to 'stdout'---- Flushes 'stdout' on each request, which would be inefficient in production use.-- Use "logStdout" in production.logStdoutDev::MiddlewarelogStdoutDev=logHandleDev$\bs->hPutLogStrstdout[LBbs]>>hFlushstdout-- | Prints a message using the given callback function for each request.-- Designed for fast production use at the expense of convenience.-- In particular, no POST parameter information is currently given---- This is lower-level - use "logStdout" unless you need this greater controllogCallback::(BS.ByteString->IO())-- ^ A function that logs the ByteString log message.->MiddlewarelogCallbackcbappreq=doliftIO$cb$BS.concat[requestMethodreq," ",rawPathInforeq,rawQueryStringreq," ","Accept: ",maybe""toBS$lookup"Accept"$requestHeadersreq,"\n"]appreqtoBS::H.Ascii->BS.ByteStringtoBS=id-- | Prints a message using the given callback function for each request.-- This is not for serious production use- it is inefficient.-- It immediately consumes a POST body and fills it back in and is otherwise inefficient---- This is lower-level - use "logStdoutDev" unless you need this greater controllogCallbackDev::(BS.ByteString->IO())-- ^ A function that logs the ByteString log message.->MiddlewarelogCallbackDevcbappreq=dobody<-requestBodyreqC.$$CL.consumepostParams<-ifany(requestMethodreq==)["GET","HEAD"]thenreturn[]elsedopostParams<-liftIO$allPostParamsbodyreturn$collectPostParamspostParamsletgetParams=mapemptyGetParam$queryStringreqliftIO$cb$BS.concat[requestMethodreq," ",rawPathInforeq,"\n","Accept: ",maybe""id$lookup"Accept"$requestHeadersreq,paramsToBS"GET "getParams,paramsToBS"POST "postParams,"\n"]-- The body was consumed. Fill it back up so it is available againappreq{requestBody=CL.sourceListbody}whereparamsToBSprefixparams=ifnullparamsthen""elseBS.concat["\n",prefix,pack(showparams)]allPostParamsbody=casegetRequestBodyTypereqofNothing->return([],[])Justrbt->C.runResourceT$CL.sourceListbodyC.$$sinkRequestBodylbsBackEndrbtemptyGetParam::(BS.ByteString,MaybeBS.ByteString)->(BS.ByteString,BS.ByteString)emptyGetParam(k,Justv)=(k,v)emptyGetParam(k,Nothing)=(k,"")collectPostParams::([Param],[FileLBS.ByteString])->[Param]collectPostParams(postParams,files)=postParams++(map(\(k,v)->(k,BS.append"FILE: "(fileNamev)))files)