packages feed

happstack-server 7.4.6.4 → 7.5.0

raw patch · 7 files changed

+57/−7 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Happstack.Server.Internal.Monads: escapeHTTP :: (ServerMonad m, MonadIO m) => (TimeoutIO -> IO ()) -> m a
+ Happstack.Server.Internal.TimeoutIO: [toGet] :: TimeoutIO -> IO (Maybe ByteString)
+ Happstack.Server.Internal.TimeoutSocket: sGet :: Handle -> Socket -> IO (Maybe ByteString)
+ Happstack.Server.Internal.Types: EscapeHTTP :: (TimeoutIO -> IO ()) -> EscapeHTTP
+ Happstack.Server.Internal.Types: data EscapeHTTP
+ Happstack.Server.Internal.Types: instance GHC.Exception.Exception Happstack.Server.Internal.Types.EscapeHTTP
+ Happstack.Server.Internal.Types: instance GHC.Show.Show Happstack.Server.Internal.Types.EscapeHTTP
+ Happstack.Server.Monads: escapeHTTP :: (ServerMonad m, MonadIO m) => (TimeoutIO -> IO ()) -> m a
- Happstack.Server.Internal.TimeoutIO: TimeoutIO :: Handle -> (ByteString -> IO ()) -> (ByteString -> IO ()) -> IO ByteString -> (FilePath -> Offset -> ByteCount -> IO ()) -> IO () -> Bool -> TimeoutIO
+ Happstack.Server.Internal.TimeoutIO: TimeoutIO :: Handle -> (ByteString -> IO ()) -> (ByteString -> IO ()) -> IO (Maybe ByteString) -> IO ByteString -> (FilePath -> Offset -> ByteCount -> IO ()) -> IO () -> Bool -> TimeoutIO

Files

happstack-server.cabal view
@@ -1,5 +1,5 @@ Name:                happstack-server-Version:             7.4.6.4+Version:             7.5.0 Synopsis:            Web related tools and services. Description:         Happstack Server provides an HTTP server and a rich set of functions for routing requests, handling query parameters, generating responses, working with cookies, serving files, and more. For in-depth documentation see the Happstack Crash Course <http://happstack.com/docs/crashcourse/index.html> License:             BSD3@@ -27,6 +27,7 @@     default: True  Library+  Default-language:    Haskell2010   Exposed-modules:                        Happstack.Server                        Happstack.Server.Auth@@ -129,6 +130,7 @@     buildable: False  Test-Suite happstack-server-tests+  Default-language:    Haskell2010   Type: exitcode-stdio-1.0   Main-Is: Test.hs   GHC-Options: -threaded
src/Happstack/Server/Internal/Handler.hs view
@@ -8,6 +8,7 @@  import qualified Paths_happstack_server as Paths import qualified Data.Version as DV+import Control.Applicative (pure) import Control.Concurrent (newMVar, newEmptyMVar, tryTakeMVar) import Control.Exception.Extensible as E import Control.Monad@@ -56,7 +57,7 @@ rloop timeoutIO mlog host handler inputStr     | L.null inputStr = return ()     | otherwise-    = join $+    = (join $       do let parseRequest                  = do                       (topStr, restStr) <- required "failed to separate request" $ splitAtEmptyLine inputStr@@ -76,7 +77,7 @@          case parseRequest of            Left err -> error $ "failed to parse HTTP request: " ++ err            Right (m, u, cookies, v, headers, body, nextRequest)-               -> return $+              -> pure $                   do bodyRef        <- newMVar (Body body)                      bodyInputRef   <- newEmptyMVar                      let req = Request (toSecure timeoutIO) m (pathEls (path u)) (path u) (query u)@@ -85,7 +86,9 @@                      let ioseq act = act >>= \x -> x `seq` return x                       (res, handlerKilled) <- ((, False) `liftM` ioseq (handler req))-                         `E.catch` \(e::E.SomeException) -> return (failResponse (show e), fromException e == Just ThreadKilled)+                         `E.catches` [ Handler $ \(e::EscapeHTTP)      -> throwIO e -- need to handle this higher up+                                     , Handler $ \(e::E.SomeException) -> pure (failResponse (show e), fromException e == Just ThreadKilled)+                                     ]                       case mlog of                        Nothing -> return ()@@ -106,7 +109,12 @@                      cleanupTempFiles req                      -- do not continue if handler was killed                      when (not handlerKilled && continueHTTP req res) $-                         rloop timeoutIO mlog host handler nextRequest+                         rloop timeoutIO mlog host handler nextRequest) `E.catch` (escapeHttpHandler timeoutIO)++escapeHttpHandler :: TimeoutIO+                  -> EscapeHTTP+                  -> IO ()+escapeHttpHandler tio (EscapeHTTP f) = f tio  -- NOTE: if someone took the inputs and never put them back, then they are responsible for the cleanup cleanupTempFiles :: Request -> IO ()
src/Happstack/Server/Internal/Monads.hs view
@@ -6,6 +6,7 @@ import Control.Applicative                       (Applicative, pure, (<*>), Alternative(empty,(<|>)))  import Control.Concurrent                        (newMVar)+import Control.Exception                         (throwIO)  import Control.Monad                             ( MonadPlus(mzero, mplus), ap, liftM, msum                                                  )@@ -50,7 +51,8 @@  import Happstack.Server.Internal.Cookie          (Cookie) import Happstack.Server.Internal.RFC822Headers   (parseContentType)-import Happstack.Server.Internal.Types           (canHaveBody)+import Happstack.Server.Internal.Types           (EscapeHTTP(..), canHaveBody)+import Happstack.Server.Internal.TimeoutIO       (TimeoutIO) import Happstack.Server.Types import Prelude                                   (Bool(..), Either(..), Eq(..), Functor(..), IO, Monad(..), Char, Maybe(..), String, Show(..), ($), (.), (>), (++), (&&), (||), (=<<), const, concatMap, flip, id, otherwise, zip) @@ -809,3 +811,8 @@  instance WebMonad a m => WebMonad a (ExceptT e m) where     finishWith    = lift . finishWith++escapeHTTP :: (ServerMonad m, MonadIO m) =>+              (TimeoutIO -> IO ())+           -> m a+escapeHTTP h = liftIO (throwIO (EscapeHTTP h))
src/Happstack/Server/Internal/TimeoutIO.hs view
@@ -15,6 +15,7 @@     { toHandle      :: Handle     , toPutLazy     :: L.ByteString -> IO ()     , toPut         :: B.ByteString -> IO ()+    , toGet         :: IO (Maybe B.ByteString)     , toGetContents :: IO L.ByteString     , toSendFile    :: FilePath -> Offset -> ByteCount -> IO ()     , toShutdown    :: IO ()
src/Happstack/Server/Internal/TimeoutSocket.hs view
@@ -4,6 +4,7 @@ -} module Happstack.Server.Internal.TimeoutSocket where +import           Control.Applicative           (pure) import           Control.Concurrent            (threadWaitWrite) import           Control.Exception             as E (catch, throw) import           Control.Monad                 (liftM, when)@@ -34,6 +35,16 @@        return () {-# INLINE sPutTickle #-} +sGet :: TM.Handle+     -> Socket+     -> IO (Maybe B.ByteString)+sGet handle socket =+  do s <- N.recv socket 65536+     TM.tickle handle+     if S.null s+       then pure Nothing+       else pure (Just s)+ sGetContents :: TM.Handle              -> Socket         -- ^ Connected socket              -> IO L.ByteString  -- ^ Data received@@ -79,6 +90,7 @@     TimeoutIO { toHandle      = handle               , toShutdown    = sClose socket               , toPutLazy     = sPutLazyTickle handle socket+              , toGet         = sGet           handle socket               , toPut         = sPutTickle     handle socket               , toGetContents = sGetContents   handle socket               , toSendFile    = sendFileTickle handle socket
src/Happstack/Server/Internal/Types.hs view
@@ -16,9 +16,11 @@      HttpVersion(..), Length(..), Method(..), canHaveBody, Headers, continueHTTP,      Host, ContentType(..),      readDec', fromReadS, readM, FromReqURI(..),-     showRsValidator+     showRsValidator, EscapeHTTP(..)     ) where ++import Control.Exception (Exception, SomeException) import Control.Monad.Error (Error(strMsg)) import Control.Monad.Trans (MonadIO(liftIO)) import qualified Control.Concurrent.Thread.Group as TG@@ -43,6 +45,7 @@ import Happstack.Server.Internal.RFC822Headers ( ContentType(..) ) import Happstack.Server.Internal.Cookie import Happstack.Server.Internal.LogFormat (formatRequestCombined)+import Happstack.Server.Internal.TimeoutIO (TimeoutIO) import Numeric (readDec, readSigned) import System.Log.Logger (Priority(..), logM) @@ -515,3 +518,17 @@       "1"     -> Just True       "true"  -> Just True       _       -> Nothing++------------------------------------------------------------------------------+-- EscapeHTTP - escape hatched use by websockets+------------------------------------------------------------------------------++-- | Escape from the HTTP world and get direct access to the underlying 'TimeoutIO' functions+data EscapeHTTP+  = EscapeHTTP (TimeoutIO -> IO ())+    deriving (Typeable)++instance Exception EscapeHTTP++instance Show EscapeHTTP where+  show (EscapeHTTP {})         = "<EscapeHTTP _>"
src/Happstack/Server/Monads.hs view
@@ -35,6 +35,8 @@       -- * MonadPlus helpers     , require     , requireM+    -- * escapeHTTP+    , escapeHTTP     ) where  import Control.Applicative               (Alternative, Applicative)@@ -109,3 +111,4 @@     case mbVal of         Nothing -> mzero         Just a -> handle a+