From 99a602b512322cbf4ed1d31dc4c9c0bf52683e97 Mon Sep 17 00:00:00 2001 From: Marco Z Date: Wed, 4 Oct 2023 10:44:15 +0200 Subject: [PATCH] add getResponseHeaders, getResponseStatus, getResponseContent (#327) * add getResponseHeaders, getResponseStatus, getResponseContent * upd changelog --------- Co-authored-by: Marco Zocca --- Web/Scotty.hs | 24 +++++++++++++++++++++--- Web/Scotty/Action.hs | 17 +++++++++++++++++ Web/Scotty/Internal/Types.hs | 5 +++++ Web/Scotty/Trans.hs | 6 ++++-- changelog.md | 2 ++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/Web/Scotty.hs b/Web/Scotty.hs index 09da4a26..e36af5b9 100644 --- a/Web/Scotty.hs +++ b/Web/Scotty.hs @@ -29,13 +29,15 @@ module Web.Scotty -- | Note: only one of these should be present in any given route -- definition, as they completely replace the current 'Response' body. , text, html, file, json, stream, raw + -- ** Accessing the fields of the Response + , getResponseHeaders, getResponseStatus, getResponseContent -- ** Exceptions , raise, raiseStatus, throw, rescue, next, finish, defaultHandler, liftAndCatchIO , StatusError(..) -- * Parsing Parameters , Param, Trans.Parsable(..), Trans.readEither -- * Types - , ScottyM, ActionM, RoutePattern, File, Kilobytes, Handler(..) + , ScottyM, ActionM, RoutePattern, File, Content(..), Kilobytes, Handler(..) , ScottyState, defaultScottyState ) where @@ -47,12 +49,12 @@ import qualified Data.ByteString as BS import Data.ByteString.Lazy.Char8 (ByteString) import Data.Text.Lazy (Text) -import Network.HTTP.Types (Status, StdMethod) +import Network.HTTP.Types (Status, StdMethod, ResponseHeaders) import Network.Socket (Socket) import Network.Wai (Application, Middleware, Request, StreamingBody) import Network.Wai.Handler.Warp (Port) -import Web.Scotty.Internal.Types (ScottyT, ActionT, ErrorHandler, Param, RoutePattern, Options, defaultOptions, File, Kilobytes, ScottyState, defaultScottyState, StatusError(..)) +import Web.Scotty.Internal.Types (ScottyT, ActionT, ErrorHandler, Param, RoutePattern, Options, defaultOptions, File, Kilobytes, ScottyState, defaultScottyState, StatusError(..), Content(..)) import Web.Scotty.Exceptions (Handler(..)) type ScottyM = ScottyT IO @@ -305,6 +307,18 @@ stream = Trans.stream raw :: ByteString -> ActionM () raw = Trans.raw + +-- | Access the HTTP 'Status' of the Response +getResponseStatus :: ActionM Status +getResponseStatus = Trans.getResponseStatus +-- | Access the HTTP headers of the Response +getResponseHeaders :: ActionM ResponseHeaders +getResponseHeaders = Trans.getResponseHeaders +-- | Access the content of the Response +getResponseContent :: ActionM Content +getResponseContent = Trans.getResponseContent + + -- | get = 'addroute' 'GET' get :: RoutePattern -> ActionM () -> ScottyM () get = Trans.get @@ -403,3 +417,7 @@ function = Trans.function -- | Build a route that requires the requested path match exactly, without captures. literal :: String -> RoutePattern literal = Trans.literal + + + + diff --git a/Web/Scotty/Action.hs b/Web/Scotty/Action.hs index a1043e61..75a2bce3 100644 --- a/Web/Scotty/Action.hs +++ b/Web/Scotty/Action.hs @@ -41,6 +41,9 @@ module Web.Scotty.Action , status , stream , text + , getResponseStatus + , getResponseHeaders + , getResponseContent , Param , Parsable(..) -- private to Scotty @@ -350,6 +353,20 @@ paramsWith f = ActionT (f <$> ask) getParams :: ActionEnv -> [Param] getParams e = envCaptureParams e <> envFormParams e <> envQueryParams e + +-- === access the fields of the Response being constructed + +-- | Access the HTTP 'Status' of the Response +getResponseStatus :: (MonadIO m) => ActionT m Status +getResponseStatus = srStatus <$> getResponseAction +-- | Access the HTTP headers of the Response +getResponseHeaders :: (MonadIO m) => ActionT m ResponseHeaders +getResponseHeaders = srHeaders <$> getResponseAction +-- | Access the content of the Response +getResponseContent :: (MonadIO m) => ActionT m Content +getResponseContent = srContent <$> getResponseAction + + -- | Minimum implemention: 'parseParam' class Parsable a where -- | Take a 'T.Text' value and parse it as 'a', or fail with a message. diff --git a/Web/Scotty/Internal/Types.hs b/Web/Scotty/Internal/Types.hs index 2e7721d1..98ec69aa 100644 --- a/Web/Scotty/Internal/Types.hs +++ b/Web/Scotty/Internal/Types.hs @@ -169,6 +169,11 @@ data ActionEnv = Env { envReq :: Request getResponse :: MonadIO m => ActionEnv -> m ScottyResponse getResponse ae = liftIO $ readTVarIO (envResponse ae) +getResponseAction :: (MonadIO m) => ActionT m ScottyResponse +getResponseAction = do + ae <- ask + getResponse ae + modifyResponse :: (MonadIO m) => (ScottyResponse -> ScottyResponse) -> ActionT m () modifyResponse f = do tv <- asks envResponse diff --git a/Web/Scotty/Trans.hs b/Web/Scotty/Trans.hs index 19446fa8..bb3dab21 100644 --- a/Web/Scotty/Trans.hs +++ b/Web/Scotty/Trans.hs @@ -34,13 +34,15 @@ module Web.Scotty.Trans -- | Note: only one of these should be present in any given route -- definition, as they completely replace the current 'Response' body. , text, html, file, json, stream, raw, nested + -- ** Accessing the fields of the Response + , getResponseHeaders, getResponseStatus, getResponseContent -- ** Exceptions , raise, raiseStatus, throw, rescue, next, finish, defaultHandler, liftAndCatchIO , StatusError(..) -- * Parsing Parameters , Param, Parsable(..), readEither -- * Types - , RoutePattern, File, Kilobytes, ErrorHandler, Handler(..) + , RoutePattern, File, Content(..), Kilobytes, ErrorHandler, Handler(..) -- * Monad Transformers , ScottyT, ActionT , ScottyState, defaultScottyState @@ -60,7 +62,7 @@ import Network.Wai.Handler.Warp (Port, runSettings, runSettingsSocket, setPort, import Web.Scotty.Action import Web.Scotty.Route -import Web.Scotty.Internal.Types (ActionT(..), ScottyT(..), defaultScottyState, Application, RoutePattern, Options(..), defaultOptions, RouteOptions(..), defaultRouteOptions, ErrorHandler, Kilobytes, File, addMiddleware, setHandler, updateMaxRequestBodySize, routes, middlewares, ScottyException(..), ScottyState, defaultScottyState, StatusError(..)) +import Web.Scotty.Internal.Types (ActionT(..), ScottyT(..), defaultScottyState, Application, RoutePattern, Options(..), defaultOptions, RouteOptions(..), defaultRouteOptions, ErrorHandler, Kilobytes, File, addMiddleware, setHandler, updateMaxRequestBodySize, routes, middlewares, ScottyException(..), ScottyState, defaultScottyState, StatusError(..), Content(..)) import Web.Scotty.Util (socketDescription) import Web.Scotty.Body (newBodyInfo) import Web.Scotty.Exceptions (Handler(..), catches) diff --git a/changelog.md b/changelog.md index 96b8d7bc..30272693 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,7 @@ ## next [????.??.??] +* add getResponseHeaders, getResponseStatus, getResponseContent (#214) + ## 0.20.1 [2023.10.03] * remove dependencies on 'base-compat' and 'base-compat-batteries' (#318)