This commit is contained in:
Michael Snoyman 2013-08-19 12:51:47 +03:00
parent 01738f354f
commit 2d0f560bea
7 changed files with 84 additions and 18 deletions

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
@ -229,11 +230,19 @@ runRequestBody = do
Just rbc -> return rbc Just rbc -> return rbc
Nothing -> do Nothing -> do
rr <- waiRequest rr <- waiRequest
#if MIN_VERSION_wai(0, 2, 0)
rbc <- liftIO $ rbHelper upload rr
#else
rbc <- liftResourceT $ rbHelper upload rr rbc <- liftResourceT $ rbHelper upload rr
#endif
put x { ghsRBC = Just rbc } put x { ghsRBC = Just rbc }
return rbc return rbc
#if MIN_VERSION_wai(2, 0, 0)
rbHelper :: FileUpload -> W.Request -> IO RequestBodyContents
#else
rbHelper :: FileUpload -> W.Request -> ResourceT IO RequestBodyContents rbHelper :: FileUpload -> W.Request -> ResourceT IO RequestBodyContents
#endif
rbHelper upload = rbHelper upload =
case upload of case upload of
FileUploadMemory s -> rbHelper' s mkFileInfoLBS FileUploadMemory s -> rbHelper' s mkFileInfoLBS
@ -243,7 +252,11 @@ rbHelper upload =
rbHelper' :: NWP.BackEnd x rbHelper' :: NWP.BackEnd x
-> (Text -> Text -> x -> FileInfo) -> (Text -> Text -> x -> FileInfo)
-> W.Request -> W.Request
#if MIN_VERSION_wai(2, 0, 0)
-> IO ([(Text, Text)], [(Text, FileInfo)])
#else
-> ResourceT IO ([(Text, Text)], [(Text, FileInfo)]) -> ResourceT IO ([(Text, Text)], [(Text, FileInfo)])
#endif
rbHelper' backend mkFI req = rbHelper' backend mkFI req =
(map fix1 *** mapMaybe fix2) <$> (NWP.parseRequestBody backend req) (map fix1 *** mapMaybe fix2) <$> (NWP.parseRequestBody backend req)
where where
@ -916,7 +929,7 @@ selectRep w = do
]) reps ]) reps
-- match on the type for sub-type wildcards. -- match on the type for sub-type wildcards.
-- If the accept is text/* it should match a provided text/html -- If the accept is text/ * it should match a provided text/html
mainTypeMap = Map.fromList $ reverse $ map mainTypeMap = Map.fromList $ reverse $ map
(\v@(ProvidedRep ct _) -> (fst $ contentTypeTypes ct, v)) reps (\v@(ProvidedRep ct _) -> (fst $ contentTypeTypes ct, v)) reps
@ -972,7 +985,13 @@ provideRepType ct handler =
rawRequestBody :: MonadHandler m => Source m S.ByteString rawRequestBody :: MonadHandler m => Source m S.ByteString
rawRequestBody = do rawRequestBody = do
req <- lift waiRequest req <- lift waiRequest
transPipe liftResourceT $ W.requestBody req transPipe
#if MIN_VERSION_wai(0, 2, 0)
liftIO
#else
liftResourceT
#endif
(W.requestBody req)
-- | Stream the data from the file. Since Yesod 1.2, this has been generalized -- | Stream the data from the file. Since Yesod 1.2, this has been generalized
-- to work in any @MonadResource@. -- to work in any @MonadResource@.

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-} {-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RankNTypes #-}
@ -12,6 +13,11 @@ import qualified Data.ByteString.Char8 as S8
import Data.CaseInsensitive (CI) import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Network.Wai import Network.Wai
#if MIN_VERSION_wai(2, 0, 0)
import Data.Conduit (transPipe)
import Control.Monad.Trans.Resource (runInternalState)
import Network.Wai.Internal
#endif
import Prelude hiding (catch) import Prelude hiding (catch)
import Web.Cookie (renderSetCookie) import Web.Cookie (renderSetCookie)
import Yesod.Core.Content import Yesod.Core.Content
@ -30,9 +36,10 @@ yarToResponse :: Monad m
=> YesodResponse => YesodResponse
-> (SessionMap -> m [Header]) -- ^ save session -> (SessionMap -> m [Header]) -- ^ save session
-> YesodRequest -> YesodRequest
-> Request
-> m Response -> m Response
yarToResponse (YRWai a) _ _ = return a yarToResponse (YRWai a) _ _ _ = return a
yarToResponse (YRPlain s' hs ct c newSess) saveSession yreq = do yarToResponse (YRPlain s' hs ct c newSess) saveSession yreq req = do
extraHeaders <- do extraHeaders <- do
let nsToken = maybe let nsToken = maybe
newSess newSess
@ -47,7 +54,11 @@ yarToResponse (YRPlain s' hs ct c newSess) saveSession yreq = do
let hs' = maybe finalHeaders finalHeaders' mlen let hs' = maybe finalHeaders finalHeaders' mlen
in ResponseBuilder s hs' b in ResponseBuilder s hs' b
go (ContentFile fp p) = ResponseFile s finalHeaders fp p go (ContentFile fp p) = ResponseFile s finalHeaders fp p
#if MIN_VERSION_wai(0, 2, 0)
go (ContentSource body) = ResponseSource s finalHeaders $ transPipe (flip runInternalState $ resourceInternalState req) body
#else
go (ContentSource body) = ResponseSource s finalHeaders body go (ContentSource body) = ResponseSource s finalHeaders body
#endif
go (ContentDontEvaluate c') = go c' go (ContentDontEvaluate c') = go c'
return $ go c return $ go c
where where

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-} {-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RankNTypes #-}
@ -15,7 +16,7 @@ import Control.Monad.IO.Class (MonadIO)
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Control.Monad.Logger (LogLevel (LevelError), LogSource, import Control.Monad.Logger (LogLevel (LevelError), LogSource,
liftLoc) liftLoc)
import Control.Monad.Trans.Resource (runResourceT, withInternalState, runInternalState) import Control.Monad.Trans.Resource (runResourceT, withInternalState, runInternalState, getInternalState)
import qualified Data.ByteString as S import qualified Data.ByteString as S
import qualified Data.ByteString.Char8 as S8 import qualified Data.ByteString.Char8 as S8
import qualified Data.IORef as I import qualified Data.IORef as I
@ -31,6 +32,9 @@ import Data.Text.Encoding.Error (lenientDecode)
import Language.Haskell.TH.Syntax (Loc, qLocation) import Language.Haskell.TH.Syntax (Loc, qLocation)
import qualified Network.HTTP.Types as H import qualified Network.HTTP.Types as H
import Network.Wai import Network.Wai
#if MIN_VERSION_wai(0, 2, 0)
import Network.Wai.Internal
#endif
import Prelude hiding (catch) import Prelude hiding (catch)
import System.Log.FastLogger (Logger) import System.Log.FastLogger (Logger)
import System.Log.FastLogger (LogStr, toLogStr) import System.Log.FastLogger (LogStr, toLogStr)
@ -161,9 +165,16 @@ runFakeHandler fakeSessionMap logger site handler = liftIO $ do
ret <- I.newIORef (Left $ InternalError "runFakeHandler: no result") ret <- I.newIORef (Left $ InternalError "runFakeHandler: no result")
let handler' = do liftIO . I.writeIORef ret . Right =<< handler let handler' = do liftIO . I.writeIORef ret . Right =<< handler
return () return ()
#if MIN_VERSION_wai(0, 2, 0)
let yapp internalState = runHandler
#else
let yapp = runHandler let yapp = runHandler
#endif
RunHandlerEnv RunHandlerEnv
{ rheRender = yesodRender site $ resolveApproot site fakeWaiRequest { rheRender = yesodRender site $ resolveApproot site $ fakeWaiRequest
#if MIN_VERSION_wai(0, 2, 0)
internalState
#endif
, rheRoute = Nothing , rheRoute = Nothing
, rheSite = site , rheSite = site
, rheUpload = fileUpload site , rheUpload = fileUpload site
@ -179,14 +190,22 @@ runFakeHandler fakeSessionMap logger site handler = liftIO $ do
typePlain typePlain
(toContent ("runFakeHandler: errHandler" :: S8.ByteString)) (toContent ("runFakeHandler: errHandler" :: S8.ByteString))
(reqSession req) (reqSession req)
fakeWaiRequest = fakeWaiRequest
#if MIN_VERSION_wai(0, 2, 0)
internalState
#endif
=
Request Request
{ requestMethod = "POST" { requestMethod = "POST"
, httpVersion = H.http11 , httpVersion = H.http11
, rawPathInfo = "/runFakeHandler/pathInfo" , rawPathInfo = "/runFakeHandler/pathInfo"
, rawQueryString = "" , rawQueryString = ""
#if MIN_VERSION_wai(0, 2, 0)
, resourceInternalState = internalState
#else
, serverName = "runFakeHandler-serverName" , serverName = "runFakeHandler-serverName"
, serverPort = 80 , serverPort = 80
#endif
, requestHeaders = [] , requestHeaders = []
, isSecure = False , isSecure = False
, remoteHost = error "runFakeHandler-remoteHost" , remoteHost = error "runFakeHandler-remoteHost"
@ -196,17 +215,30 @@ runFakeHandler fakeSessionMap logger site handler = liftIO $ do
, vault = mempty , vault = mempty
, requestBodyLength = KnownLength 0 , requestBodyLength = KnownLength 0
} }
#if MIN_VERSION_wai(0, 2, 0)
fakeRequest internalState =
#else
fakeRequest = fakeRequest =
#endif
YesodRequest YesodRequest
{ reqGetParams = [] { reqGetParams = []
, reqCookies = [] , reqCookies = []
, reqWaiRequest = fakeWaiRequest , reqWaiRequest = fakeWaiRequest
#if MIN_VERSION_wai(0, 2, 0)
internalState
#endif
, reqLangs = [] , reqLangs = []
, reqToken = Just "NaN" -- not a nonce =) , reqToken = Just "NaN" -- not a nonce =)
, reqAccept = [] , reqAccept = []
, reqSession = fakeSessionMap , reqSession = fakeSessionMap
} }
#if MIN_VERSION_wai(0, 2, 0)
_ <- runResourceT $ do
is <- getInternalState
yapp is $ fakeRequest is
#else
_ <- runResourceT $ yapp fakeRequest _ <- runResourceT $ yapp fakeRequest
#endif
I.readIORef ret I.readIORef ret
{-# WARNING runFakeHandler "Usually you should *not* use runFakeHandler unless you really understand how it works and why you need it." #-} {-# WARNING runFakeHandler "Usually you should *not* use runFakeHandler unless you really understand how it works and why you need it." #-}
@ -243,8 +275,12 @@ yesodRunner handler' YesodRunnerEnv {..} route req
rhe = rheSafe rhe = rheSafe
{ rheOnError = runHandler rheSafe . errorHandler { rheOnError = runHandler rheSafe . errorHandler
} }
yar <- runHandler rhe handler yreq yar <-
liftIO $ yarToResponse yar saveSession yreq #if MIN_VERSION_wai(0, 2, 0)
flip runInternalState (resourceInternalState req) $
#endif
runHandler rhe handler yreq
liftIO $ yarToResponse yar saveSession yreq req
where where
mmaxLen = maximumContentLength yreSite route mmaxLen = maximumContentLength yreSite route
handler = yesodMiddleware handler' handler = yesodMiddleware handler'

View File

@ -26,8 +26,8 @@ library
build-depends: base >= 4.3 && < 5 build-depends: base >= 4.3 && < 5
, time >= 1.1.4 , time >= 1.1.4
, yesod-routes >= 1.2 && < 1.3 , yesod-routes >= 1.2 && < 1.3
, wai >= 1.4 && < 1.5 , wai >= 1.4
, wai-extra >= 1.3 && < 1.4 , wai-extra >= 1.3
, bytestring >= 0.9.1.4 , bytestring >= 0.9.1.4
, text >= 0.7 && < 0.12 , text >= 0.7 && < 0.12
, template-haskell , template-haskell

View File

@ -30,8 +30,8 @@ library
build-depends: base >= 4 && < 5 build-depends: base >= 4 && < 5
, yesod-core == 1.2.* , yesod-core == 1.2.*
, conduit >= 0.5 && < 1.1 , conduit >= 0.5 && < 1.1
, wai >= 1.3 && < 1.5 , wai >= 1.3
, wai-eventsource >= 1.3 && < 1.4 , wai-eventsource >= 1.3
, blaze-builder , blaze-builder
, transformers , transformers
exposed-modules: Yesod.EventSource exposed-modules: Yesod.EventSource

View File

@ -30,8 +30,8 @@ library
, template-haskell , template-haskell
, directory >= 1.0 , directory >= 1.0
, transformers >= 0.2.2 , transformers >= 0.2.2
, wai-app-static >= 1.3 && < 1.4 , wai-app-static >= 1.3
, wai >= 1.3 && < 1.5 , wai >= 1.3
, text >= 0.9 , text >= 0.9
, file-embed >= 0.0.4.1 && < 0.5 , file-embed >= 0.0.4.1 && < 0.5
, http-types >= 0.7 , http-types >= 0.7

View File

@ -28,12 +28,12 @@ library
, yesod-form >= 1.3 && < 1.4 , yesod-form >= 1.3 && < 1.4
, monad-control >= 0.3 && < 0.4 , monad-control >= 0.3 && < 0.4
, transformers >= 0.2.2 && < 0.4 , transformers >= 0.2.2 && < 0.4
, wai >= 1.3 && < 1.5 , wai >= 1.3
, wai-extra >= 1.3 && < 1.4 , wai-extra >= 1.3
, hamlet >= 1.1 && < 1.2 , hamlet >= 1.1 && < 1.2
, shakespeare-js >= 1.0.2 && < 1.2 , shakespeare-js >= 1.0.2 && < 1.2
, shakespeare-css >= 1.0 && < 1.1 , shakespeare-css >= 1.0 && < 1.1
, warp >= 1.3 && < 1.4 , warp >= 1.3
, blaze-html >= 0.5 , blaze-html >= 0.5
, blaze-markup >= 0.5.1 , blaze-markup >= 0.5.1
, aeson , aeson