-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Web related tools and services. -- -- Web framework @package happstack-server @version 0.3.1 module Happstack.Server.SURI -- | Retrieves the path component from the URI path :: SURI -> String -- | Retrieves the query component from the URI query :: SURI -> String -- | Retrieves the scheme component from the URI scheme :: SURI -> String -- | Modifies the scheme component of the URI using the provided function u_scheme :: (String -> String) -> SURI -> SURI -- | Modifies the path component of the URI using the provided function u_path :: (String -> String) -> SURI -> SURI -- | Sets the scheme component of the URI a_scheme :: String -> SURI -> SURI -- | Sets the path component of the URI a_path :: String -> SURI -> SURI unEscape :: String -> String escape :: String -> String -- | Returns true if the URI is absolute isAbs :: SURI -> Bool newtype SURI SURI :: URI -> SURI suri :: SURI -> URI -- | Render should be used for prettyprinting URIs. render :: (ToSURI a) => a -> String -- | Parses a URI from a String. Returns Nothing on failure. parse :: String -> Maybe SURI -- | Convenience class for converting data types to URIs class ToSURI x toSURI :: (ToSURI x) => x -> SURI class FromPath x fromPath :: (FromPath x) => String -> x instance [overlap ok] Typeable SURI instance [overlap ok] Eq SURI instance [overlap ok] Data SURI instance [overlap ok] ToSURI String instance [overlap ok] ToSURI URI instance [overlap ok] ToSURI SURI instance [overlap ok] Ord SURI instance [overlap ok] Read SURI instance [overlap ok] Show SURI module Happstack.Server.MinHaXML type StyleURL = String data StyleSheet NoStyle :: StyleSheet CSS :: StyleURL -> StyleSheet styleURL :: StyleSheet -> StyleURL XSL :: StyleURL -> StyleSheet styleURL :: StyleSheet -> StyleURL hasStyleURL :: StyleSheet -> Bool type Element = Element isCSS :: StyleSheet -> Bool isXSL :: StyleSheet -> Bool t :: Name -> [(Name, String)] -> CharData -> Element l :: Name -> [(Name, String)] -> [Element] -> Element e :: Name -> [(Name, String)] -> Element (<) :: Name -> [(Name, String)] -> [Element] -> Element (<>) :: Name -> [(Name, String)] -> CharData -> Element xmlElem :: (t -> [Content]) -> Name -> [(Name, String)] -> t -> Element textElem :: Name -> [(Name, String)] -> CharData -> Element emptyElem :: Name -> [(Name, String)] -> Element listElem :: Name -> [(Name, String)] -> [Element] -> Element cdataElem :: CharData -> Content simpleDocOld :: StyleSheet -> Element -> String simpleDoc :: StyleSheet -> Element -> String simpleDoc' :: StyleSheet -> Element -> String xmlEscaper :: XmlEscaper xmlStdEscape :: Element -> Element verbim :: (Verbatim a) => a -> String simpleProlog :: StyleSheet -> Prolog nonEmpty :: Name -> String -> Maybe Element getRoot :: Document -> Element data XML a XML :: StyleSheet -> a -> XML a class ToElement x toElement :: (ToElement x) => x -> Element wrapElem :: (ToElement x) => Name -> x -> Element elF :: (ToElement b) => Name -> (a -> b) -> a -> Element attrF :: t1 -> (t -> String) -> t -> (t1, String) attrFS :: (Show a) => t1 -> (t -> a) -> t -> (t1, String) attrFMb :: (a -> String) -> String -> (a1 -> Maybe a) -> a1 -> (String, String) quoteEsc :: String -> String recToEl :: Name -> [a -> (String, String)] -> [a -> Element] -> a -> Element listToEl :: (ToElement a) => Name -> [(Name, String)] -> [a] -> Element toAttrs :: t -> [(t1, t -> t2)] -> [(t1, t2)] newtype ElString ElString :: String -> ElString elString :: ElString -> String instance [overlap ok] Eq ElString instance [overlap ok] Ord ElString instance [overlap ok] Read ElString instance [overlap ok] Show ElString instance [overlap ok] Read StyleSheet instance [overlap ok] Show StyleSheet instance [overlap ok] (Xml a) => ToElement a instance [overlap ok] ToElement Double instance [overlap ok] ToElement Float instance [overlap ok] ToElement Integer instance [overlap ok] ToElement Int instance [overlap ok] ToElement CalendarTime instance [overlap ok] ToElement Element instance [overlap ok] ToElement String instance [overlap ok] (ToElement x) => ToElement (Maybe x) module Happstack.Server.XSLT -- | Note that the xsl file must have .xsl suffix. xsltFile :: XSLPath -> FilePath -> FilePath -> IO () -- | Uses the provided xsl file to transform the given string. This -- function creates temporary files during its execution, but guarantees -- their cleanup. xsltString :: XSLPath -> String -> String -- | Uses xsltString to transform the given XML Element into -- a a String. xsltElem :: XSLPath -> Element -> String -- | Performs an XSL transformation with lists of ByteStrings instead of a -- String. xsltFPS :: XSLPath -> [ByteString] -> [ByteString] -- | Equivalent to xsltFPS but does not hide the inherent IO of the -- low-level ByteString operations. xsltFPSIO :: XSLPath -> [ByteString] -> IO [ByteString] type XSLPath = FilePath -- | Use xsltproc to transform XML. xsltproc :: XSLTCmd -- | Use saxon to transform XML. saxon :: XSLTCmd procFPSIO :: XSLTCommand -> XSLPath -> [ByteString] -> IO [ByteString] procLBSIO :: XSLTCmd -> XSLPath -> ByteString -> IO ByteString type XSLTCommand = XSLPath -> FilePath -> FilePath -> (FilePath, [String]) data XSLTCmd instance [overlap ok] Data XSLTCmd instance [overlap ok] Show XSLTCmd instance [overlap ok] Read XSLTCmd instance [overlap ok] Eq XSLTCmd instance [overlap ok] Ord XSLTCmd instance [overlap ok] (Sat (ctx XSLTCmd)) => Data ctx XSLTCmd instance [overlap ok] Typeable XSLTCmd instance [overlap ok] Default XSLTCmd module Happstack.Server.Cookie data Cookie Cookie :: String -> String -> String -> String -> String -> Cookie cookieVersion :: Cookie -> String cookiePath :: Cookie -> String cookieDomain :: Cookie -> String cookieName :: Cookie -> String cookieValue :: Cookie -> String -- | Creates a cookie with a default version of 1 and path of / mkCookie :: String -> String -> Cookie -- | Set a Cookie in the Result. The values are escaped as per RFC 2109, -- but some browsers may have buggy support for cookies containing e.g. -- '"' or ' '. mkCookieHeader :: Seconds -> Cookie -> String -- | Get all cookies from the HTTP request. The cookies are ordered per RFC -- from the most specific to the least specific. Multiple cookies with -- the same name are allowed to exist. getCookies :: (Monad m) => ByteString -> m [Cookie] -- | Get the most specific cookie with the given name. Fails if there is no -- such cookie or if the browser did not escape cookies in a proper -- fashion. Browser support for escaping cookies properly is very -- diverse. getCookie :: (Monad m) => String -> ByteString -> m Cookie getCookies' :: (Monad m) => ByteString -> m (Either String [Cookie]) getCookie' :: (Monad m) => String -> ByteString -> m (Either String Cookie) -- | Not an supported api. Takes a cookie header and returns either a -- String error message or an array of parsed cookies parseCookies :: String -> Either String [Cookie] -- | not a supported api. A parser for RFC 2109 cookies cookiesParser :: GenParser Char st [Cookie] instance [overlap ok] Typeable Cookie instance [overlap ok] Show Cookie instance [overlap ok] Eq Cookie instance [overlap ok] Read Cookie instance [overlap ok] Data Cookie module Happstack.Server.HTTP.Types data Request Request :: Method -> [String] -> String -> String -> [(String, Input)] -> [(String, Cookie)] -> Version -> Headers -> RqBody -> Host -> Request rqMethod :: Request -> Method rqPaths :: Request -> [String] rqUri :: Request -> String rqQuery :: Request -> String rqInputs :: Request -> [(String, Input)] rqCookies :: Request -> [(String, Cookie)] rqVersion :: Request -> Version rqHeaders :: Request -> Headers rqBody :: Request -> RqBody rqPeer :: Request -> Host data Response Response :: Int -> Headers -> RsFlags -> ByteString -> Maybe (Response -> IO Response) -> Response rsCode :: Response -> Int rsHeaders :: Response -> Headers rsFlags :: Response -> RsFlags rsBody :: Response -> ByteString rsValidator :: Response -> Maybe (Response -> IO Response) newtype RqBody Body :: ByteString -> RqBody data Input Input :: ByteString -> Maybe String -> ContentType -> Input inputValue :: Input -> ByteString inputFilename :: Input -> Maybe String inputContentType :: Input -> ContentType data HeaderPair HeaderPair :: ByteString -> [ByteString] -> HeaderPair hName :: HeaderPair -> ByteString hValue :: HeaderPair -> [ByteString] -- | Converts a Request into a String representing the corresponding URL rqURL :: Request -> String -- | Takes a list of (key,val) pairs and converts it into Headers. The keys -- will be converted to lowercase mkHeaders :: [(String, String)] -> Headers -- | Lookup header value. Key is case-insensitive. getHeader :: (HasHeaders r) => String -> r -> Maybe ByteString -- | Lookup header value. Key is a case-insensitive bytestring. getHeaderBS :: (HasHeaders r) => ByteString -> r -> Maybe ByteString -- | Lookup header value with a case-sensitive key. The key must be -- lowercase. getHeaderUnsafe :: (HasHeaders r) => ByteString -> r -> Maybe ByteString -- | Returns True if the associated key is found in the Headers. The lookup -- is case insensitive. hasHeader :: (HasHeaders r) => String -> r -> Bool -- | Acts as hasHeader with ByteStrings hasHeaderBS :: (HasHeaders r) => ByteString -> r -> Bool -- | Acts as hasHeaderBS but the key is case sensitive. It should be -- in lowercase. hasHeaderUnsafe :: (HasHeaders r) => ByteString -> r -> Bool -- | Associates the key/value pair in the headers. Forces the key to be -- lowercase. setHeader :: (HasHeaders r) => String -> String -> r -> r -- | Acts as setHeader but with ByteStrings. setHeaderBS :: (HasHeaders r) => ByteString -> ByteString -> r -> r -- | Sets the key to the HeaderPair. This is the only way to associate a -- key with multiple values via the setHeader* functions. Does not force -- the key to be in lowercase or guarantee that the given key and the key -- in the HeaderPair will match. setHeaderUnsafe :: (HasHeaders r) => ByteString -> HeaderPair -> r -> r -- | Add a key/value pair to the header. If the key already has a value -- associated with it, then the value will be appended. Forces the key to -- be lowercase. addHeader :: (HasHeaders r) => String -> String -> r -> r -- | Acts as addHeader except for ByteStrings addHeaderBS :: (HasHeaders r) => ByteString -> ByteString -> r -> r -- | Add a key/value pair to the header using the underlying HeaderPair -- data type. Does not force the key to be in lowercase or guarantee that -- the given key and the key in the HeaderPair will match. addHeaderUnsafe :: (HasHeaders r) => ByteString -> HeaderPair -> r -> r -- | Sets the Response status code to the provided Int and lifts the -- computation into a Monad. setRsCode :: (Monad m) => Int -> Response -> m Response -- | HTTP configuration data Conf Conf :: Int -> Maybe (Response -> IO Response) -> Conf -- | Port for the server to listen on. port :: Conf -> Int validator :: Conf -> Maybe (Response -> IO Response) -- | Default configuration contains no validator and the port is set to -- 8000 nullConf :: Conf -- | Creates a Response with the given Int as the status code and the -- provided String as the body of the Response result :: Int -> String -> Response -- | Acts as result but works with ByteStrings directly. resultBS :: Int -> ByteString -> Response -- | Sets the Response's status code to the given Int and redirects to the -- given URI redirect :: (ToSURI s) => Int -> s -> Response -> Response -- | Result flags data RsFlags RsFlags :: Bool -> RsFlags -- | whether a content-length header will be added to the result. rsfContentLength :: RsFlags -> Bool -- | Default RsFlags that will include the content-length header nullRsFlags :: RsFlags -- | Don't display a Content-Lenght field for the Result. noContentLength :: Response -> Response -- | HTTP version data Version Version :: Int -> Int -> Version -- | HTTP request method data Method GET :: Method HEAD :: Method POST :: Method PUT :: Method DELETE :: Method TRACE :: Method OPTIONS :: Method CONNECT :: Method -- | Combined headers. type Headers = Map ByteString HeaderPair -- | Should the connection be used for further messages after this. | -- isHTTP1_0 && hasKeepAlive || isHTTP1_1 && -- hasNotConnectionClose continueHTTP :: Request -> Response -> Bool type Host = (String, Int) -- | A MIME media type value. The Show instance is derived -- automatically. Use showContentType to obtain the standard -- string representation. See http://www.ietf.org/rfc/rfc2046.txt -- for more information about MIME media types. data ContentType ContentType :: String -> String -> [(String, String)] -> ContentType -- | The top-level media type, the general type of the data. Common -- examples are "text", "image", "audio", "video", "multipart", and -- "application". ctType :: ContentType -> String -- | The media subtype, the specific data format. Examples include "plain", -- "html", "jpeg", "form-data", etc. ctSubtype :: ContentType -> String -- | Media type parameters. On common example is the charset parameter for -- the "text" top-level type, e.g. ("charset","ISO-8859-1"). ctParameters :: ContentType -> [(String, String)] instance [overlap ok] Typeable RqBody instance [overlap ok] Typeable Request instance [overlap ok] Typeable Response instance [overlap ok] Typeable Input instance [overlap ok] Typeable RsFlags instance [overlap ok] Read RqBody instance [overlap ok] Show RqBody instance [overlap ok] Show Request instance [overlap ok] Read Request instance [overlap ok] Show Response instance [overlap ok] Show Input instance [overlap ok] Read Input instance [overlap ok] Show RsFlags instance [overlap ok] Read RsFlags instance [overlap ok] Read HeaderPair instance [overlap ok] Show HeaderPair instance [overlap ok] Show Method instance [overlap ok] Read Method instance [overlap ok] Eq Method instance [overlap ok] Read Version instance [overlap ok] Eq Version instance [overlap ok] HasHeaders Headers instance [overlap ok] HasHeaders Request instance [overlap ok] HasHeaders Response instance [overlap ok] Show Version module Happstack.Server.MessageWrap queryInput :: SURI -> [(String, Input)] bodyInput :: Request -> [(String, Input)] -- | Decodes application/x-www-form-urlencoded inputs. formDecode :: String -> [(String, Input)] decodeBody :: Maybe ContentType -> ByteString -> [(String, Input)] -- | Decodes multipart/form-data input. multipartDecode :: [(String, String)] -> ByteString -> [(String, Input)] bodyPartToInput :: BodyPart -> (String, Input) -- | Packs a string into an Input of type text/plain simpleInput :: String -> Input -- | The default content-type for variables. defaultInputType :: ContentType -- | Get the path components from a String. pathEls :: String -> [String] -- | Like Read except Strings and Chars not quoted. class (Read a) => ReadString a readString :: (ReadString a) => String -> a instance [overlap ok] ReadString Char instance [overlap ok] ReadString [Char] instance [overlap ok] ReadString SURI instance [overlap ok] ReadString Float instance [overlap ok] ReadString Double instance [overlap ok] ReadString Int module Happstack.Server.HTTP.Client -- | Sends the serialized request to the host defined in the request and -- attempts to parse response upon arrival. getResponse :: Request -> IO (Either String Response) unproxify :: Request -> Request unrproxify :: String -> [(String, String)] -> Request -> Request module Happstack.Server.HTTP.LowLevel request :: Conf -> Handle -> Host -> (Request -> IO Response) -> IO () -- | Unserializes the bytestring into a response. If there is an error it -- will return Left msg. parseResponse :: ByteString -> Either String Response -- | Serializes the request to the given handle putRequest :: Handle -> Request -> IO () listen :: Conf -> (Request -> IO Response) -> IO () -- | SimpleHTTP provides a back-end independent API for handling HTTP -- requests. -- -- By default, the built-in HTTP server will be used. However, other -- back-ends like CGI/FastCGI can used if so desired. -- -- So the general nature of simpleHTTP is no different than what -- you'd expect from a web application container. First you figure out -- when function is going to process your request, process the request to -- generate a response, then return that response to the client. The web -- application container is started with simpleHTTP, which takes a -- configuration and a response-building structure (ServerPartT -- which I'll return too in a moment), and picks the first handler that -- is willing to accept the request, passes the request into the handler. -- A simple hello world style HAppS simpleHTTP server looks like: -- --
-- main = simpleHTTP nullConf $ return "Hello World!" ---- -- simpleHTTP nullConf creates a HTTP server on port 8000. -- return "Hello World!" creates a serverPartT that just returns that -- text. -- -- ServerPartT is the basic response builder. As you might expect, -- it's a container for a function that takes a Request and converts it a -- response suitable for sending back to the server. Most of the time -- though you don't even need to worry about that as ServerPartT hides -- almost all the machinery for building your response by exposing a few -- type classes. -- -- ServerPartT is a pretty rich monad. You can interact with your -- request, your response, do IO, etc. Here is a do block that validates -- basic authentication It takes a realm name as a string, a Map of -- username to password and a server part to run if authentication fails. -- -- basicAuth' acts like a guard, and only produces a response -- when authentication fails. So put it before any ServerPartT you want -- to demand authentication for in any collection of ServerPartTs. -- --
-- main = simpleHTTP nullConf $ myAuth, return "Hello World!"
-- where
-- myAuth = basicAuth' "Test"
-- (M.fromList [("hello", "world")]) (return "Login Failed")
--
-- basicAuth' realmName authMap unauthorizedPart =
-- do
-- let validLogin name pass = M.lookup name authMap == Just pass
-- let parseHeader = break (':'==) . Base64.decode . B.unpack . B.drop 6
-- authHeader <- getHeaderM "authorization"
-- case authHeader of
-- Nothing -> err
-- Just x -> case parseHeader x of
-- (name, ':':pass) | validLogin name pass -> mzero
-- | otherwise -> err
-- _ -> err
-- where
-- err = do
-- unauthorized ()
-- setHeaderM headerName headerValue
-- unauthorizedPart
-- headerValue = "Basic realm=\"" ++ realmName ++ "\""
-- headerName = "WWW-Authenticate"
--
--
-- Here is another example that uses liftIO to embed IO in a request
-- process
--
-- -- main = simpleHTTP nullConf $ myPart -- myPart = do -- line <- liftIO $ do -- IO -- putStr "return? " -- getLine -- when (take 2 line /= "ok") $ (notfound () >> return "refused") -- return "Hello World!" ---- -- This example will ask in the console "return? " if you type "ok" it -- will show "Hello World!" and if you type anything else it will return -- a 404. module Happstack.Server.SimpleHTTP -- | Use the built-in web-server to serve requests according to a -- ServerPartT. Use msum to pick the first handler from a list of -- handlers that doesn't call noHandle. simpleHTTP :: (ToMessage a) => Conf -> ServerPartT IO a -> IO () -- | a combination of simpleHTTP and mapServerPartT. See -- mapServerPartT for a discussion of the first argument of this -- function. simpleHTTP' :: (ToMessage b, Monad m, Functor m) => (UnWebT m a -> UnWebT IO b) -> Conf -> ServerPartT m a -> IO () -- | parseConfig tries to parse your command line options into a Conf. parseConfig :: [String] -> Either [String] Conf -- | ServerPartT is a container for processing requests and returning -- results newtype ServerPartT m a ServerPartT :: ReaderT Request (WebT m) a -> ServerPartT m a unServerPartT :: ServerPartT m a -> ReaderT Request (WebT m) a -- | An alias for using ServerPartT when using the IO type ServerPart a = ServerPartT IO a -- | particularly useful when combined with runWebT to produce a m -- (Maybe Response) from a request. runServerPartT :: ServerPartT m a -> Request -> WebT m a -- | Used to manipulate the containing monad. Very useful when embedding a -- monad into a ServerPartT, since simpleHTTP requires a ServerPartT -- IO a. Refer to WebT for an explanation of the structure of -- the monad. -- -- Here is an example. Suppose you want to embed an ErrorT into your -- ServerPartT to enable throwError and catchError in your Monad. -- --
-- type MyServerPartT e m a = ServerPartT (ErrorT e m) a ---- -- Now suppose you want to pass MyServerPartT into a function that -- demands a ServerPartT IO a (e.g. simpleHTTP). You can provide -- the function: -- --
-- unpackErrorT:: (Monad m, Show e) => UnWebT (ErrorT e m) a -> UnWebT m a
-- unpackErrorT handler et = do
-- eitherV <- runErrorT et
-- case eitherV of
-- Left err -> return $ Just (Left Catastrophic failure ++ show e, Set $ Endo r -> r{rsCode = 500})
-- Right x -> return x
--
--
-- With unpackErrorT you can now call simpleHTTP. Just wrap your
-- ServerPartT list.
--
-- -- simpleHTTP nullConf $ mapServerPartT unpackErrorT (myPart `catchError` myHandler) ---- -- Or alternatively: -- --
-- simpleHTTP' unpackErrorT nullConf (myPart `catchError` myHandler) ---- -- Also see spUnwrapErrorT for a more sophisticated version of -- this function mapServerPartT :: (UnWebT m a -> UnWebT n b) -> (ServerPartT m a -> ServerPartT n b) -- | A varient of mapServerPartT where the first argument, also takes a -- request. useful if you want to runServerPartT on a different -- ServerPartT inside your monad (see spUnwrapErrorT) mapServerPartT' :: (Request -> UnWebT m a -> UnWebT n b) -> (ServerPartT m a -> ServerPartT n b) withRequest :: (Request -> WebT m a) -> ServerPartT m a -- | a constructor for a ServerPartT when you don't care about the request anyRequest :: (Monad m) => WebT m a -> ServerPartT m a -- | The basic response building object. newtype WebT m a WebT :: ErrorT Response (FilterT (Response) (MaybeT m)) a -> WebT m a unWebT :: WebT m a -> ErrorT Response (FilterT (Response) (MaybeT m)) a -- | It is worth discussing the unpacked structure of WebT a bit as it's -- exposed in mapServerPartT and mapWebT. -- -- A fully unpacked WebT has a structure that looks like: -- --
-- ununWebT $ WebT m a :: m (Maybe (Either Response a, FilterFun Response)) ---- -- So, ignoring m, as it is just the containing Monad, the outermost -- layer is a Maybe. This is Nothing if mzero was called or -- Just (Either Response a, SetAppend (Endo Response)) if -- mzero wasn't called. Inside the Maybe, there is a pair. The -- second element of the pair is our filter function FilterFun -- Response. FilterFun Response is a type alias for -- SetAppend (Dual (Endo Response)). This is just a wrapper for -- a Response->Response function with a particular Monoid -- behavior. The value -- --
-- Append (Dual (Endo f)) ---- -- Causes f to be composed with the previous filter. -- --
-- Set (Dual (Endo f)) ---- -- Causes f to not be composed with the previous filter. -- -- Finally, the first element of the pair is either Left -- Response or Right a. -- -- Another way of looking at all these pieces is from the behaviors they -- control. The Maybe controls the mzero behavior. Set (Endo f) -- comes from the setFilter behavior. Likewise, Append (Endo f) -- is from composeFilter. Left Response is what you get when you -- call finishWith and Right a is the normal exit. -- -- An example case statement looks like: ex1 webt = do val <- -- ununWebT webt case val of Nothing -> Nothing -- this is the -- interior value when mzero was used Just (Left r, f) -> Just (Left -- r, f) -- r is the value that was passed into finishWith -- f is -- our filter function Just (Right a, f) -> Just (Right a, f) -- a is -- our normal monadic value -- f is still our filter function type UnWebT m a = m (Maybe (Either Response a, FilterFun Response)) -- | FilterFun is a lot more fun to type than SetAppend (Dual -- (Endo a)) type FilterFun a = SetAppend (Dual (Endo a)) -- | An alias for WebT when using IO type Web a = WebT IO a -- | for wrapping a WebT back up. mkWebT . ununWebT = id mkWebT :: UnWebT m a -> WebT m a -- | for when you really need to unpack a WebT entirely (and not just -- unwrap the first layer with unWebT) ununWebT :: WebT m a -> UnWebT m a -- | takes your WebT, if it is mempty it returns Nothing else it -- converts the value to a Response and applies your filter to it. runWebT :: (Functor m, ToMessage b) => WebT m b -> m (Maybe Response) -- | see mapServerPartT for a discussion of this function mapWebT :: (UnWebT m a -> UnWebT n b) -> (WebT m a -> WebT n b) -- | This class is used by path to parse a path component into a -- value. At present, the instances for number types (Int, Float, etc) -- just call readM. The instance for String however, just -- passes the path component straight through. This is so that you can -- read a path component which looks like this as a String: -- -- /somestring/ -- -- instead of requiring the path component to look like: -- -- /somestring/ class FromReqURI a fromReqURI :: (FromReqURI a) => String -> Maybe a -- | Minimal definition: toMessage -- -- Used to convert arbitrary types into an HTTP response. You need to -- implement this if you want to pass ServerPartT m containing -- your type into simpleHTTP class ToMessage a toContentType :: (ToMessage a) => a -> ByteString toMessage :: (ToMessage a) => a -> ByteString toResponse :: (ToMessage a) => a -> Response -- | Useful for withData and getData' implement this on your preferred type -- to use those functions class FromData a fromData :: (FromData a) => RqData a -- | yes, this is exactly like ReaderT with new names. Why you ask? -- Because ServerT can lift up a ReaderT. If you did that, it would -- shadow ServerT's behavior as a ReaderT, thus meaning if you lifted the -- ReaderT you could no longer modify the Request. This way you can add a -- ReaderT to your monad stack without any trouble. class (Monad m) => ServerMonad m askRq :: (ServerMonad m) => m Request localRq :: (ServerMonad m) => (Request -> Request) -> m a -> m a type RqData a = ReaderT ([(String, Input)], [(String, Cookie)]) Maybe a -- | deprecated. use mzero noHandle :: (MonadPlus m) => m a -- | Get a header out of the request getHeaderM :: (ServerMonad m) => String -> m (Maybe ByteString) -- | Used to ignore all your filters and immediately end the computation. A -- combination of ignoreFilters and finishWith escape :: (WebMonad a m, FilterMonad a m) => m a -> m b -- | An alternate form of escape that can be easily used within a do -- block. escape' :: (WebMonad a m, FilterMonad a m) => a -> m b -- | deprecated. Just use msum multi :: (Monad m) => [ServerPartT m a] -> ServerPartT m a -- | A set of functions for manipulating filters. A ServerPartT implements -- FilterMonad Response so these methods are the fundamental ways of -- manipulating the response object, especially before you've converted -- your monadic value to a Response class (Monad m) => FilterMonad a m | m -> a setFilter :: (FilterMonad a m) => (a -> a) -> m () composeFilter :: (FilterMonad a m) => (a -> a) -> m () getFilter :: (FilterMonad a m) => m b -> m (b, a -> a) -- | An alias for setFilter id It resets all your filters ignoreFilters :: (FilterMonad a m) => m () -- | A monoid operation container. If a is a monoid, then SetAppend is a -- monoid with the following behaviors: -- --
-- Set x mappend Append y = Set (x mappend y) -- Append x mappend Append y = Append (x mappend y) -- _ mappend Set y = Set y ---- -- A simple way of sumerizing this is, if the right side is Append, then -- the right is appended to the left. If the right side is Set, then the -- right side is ignored. data SetAppend a Set :: a -> SetAppend a Append :: a -> SetAppend a newtype FilterT a m b FilterT :: WriterT (FilterFun a) m b -> FilterT a m b unFilterT :: FilterT a m b -> WriterT (FilterFun a) m b class (Monad m) => WebMonad a m | m -> a finishWith :: (WebMonad a m) => a -> m b -- | Respond with 200 OK. ok :: (FilterMonad Response m) => a -> m a -- | deprecated. Same as composeFilter modifyResponse :: (FilterMonad a m) => (a -> a) -> m () -- | sets the return code in your response setResponseCode :: (FilterMonad Response m) => Int -> m () -- | Responds with 502 Bad Gateway badGateway :: (FilterMonad Response m) => a -> m a -- | Respond with 500 Interal Server Error internalServerError :: (FilterMonad Response m) => a -> m a -- | Respond with 400 Bad Request. badRequest :: (FilterMonad Response m) => a -> m a -- | Respond with 401 Unauthorized. unauthorized :: (FilterMonad Response m) => a -> m a -- | Respond with 403 Forbidden. forbidden :: (FilterMonad Response m) => a -> m a -- | Respond with 404 Not Found. notFound :: (FilterMonad Response m) => a -> m a -- | Respond with 303 See Other. seeOther :: (FilterMonad Response m, ToSURI uri) => uri -> res -> m res -- | Respond with 302 Found. found :: (FilterMonad Response m, ToSURI uri) => uri -> res -> m res -- | Respond with 301 Moved Permanently. movedPermanently :: (FilterMonad Response m, ToSURI a) => a -> res -> m res -- | Respond with 307 Temporary Redirect. tempRedirect :: (FilterMonad Response m, ToSURI a) => a -> res -> m res -- | adds the cookie with a timeout to the response addCookie :: (FilterMonad Response m) => Seconds -> Cookie -> m () -- | adds the list of cookie timeout pairs to the response addCookies :: (FilterMonad Response m) => [(Seconds, Cookie)] -> m () -- | adds headers into the response. This method does not overwrite any -- existing header of the same name, hence the name addHeaderM. If you -- want to replace a header use setHeaderM. addHeaderM :: (FilterMonad Response m) => String -> String -> m () -- | sets a header into the response. This will replace an existing header -- of the same name. Use addHeaderM, if you want to add more than one -- header of the same name. setHeaderM :: (FilterMonad Response m) => String -> String -> m () -- | guard using an arbitrary function on the request guardRq :: (ServerMonad m, MonadPlus m) => (Request -> Bool) -> m () -- | Pop a path element and run the ServerPartT if it matches the -- given string. dir :: (ServerMonad m, MonadPlus m) => String -> m a -> m a -- | Guard against the method. Note, this function also guards against any -- remaining path segments. This function id deprecated. You can probably -- just use methodSP (or methodM) now. method :: (MatchMethod method, Monad m) => method -> WebT m a -> ServerPartT m a -- | Guard against the method. Note, this function also guards against any -- remaining path segments. methodSP :: (ServerMonad m, MonadPlus m, MatchMethod method) => method -> m b -> m b -- | Guard against the method. This function also guards against any -- remaining path segments. See methodOnly for the version that guards -- only by method methodM :: (ServerMonad m, MonadPlus m, MatchMethod method) => method -> m () -- | guard against the method only. (as opposed to methodM) methodOnly :: (ServerMonad m, MonadPlus m, MatchMethod method) => method -> m () -- | Guard against non-empty remaining path segments nullDir :: (ServerMonad m, MonadPlus m) => m () -- | Pop a path element and parse it using the fromReqURI in the -- FromReqURI class. path :: (FromReqURI a, MonadPlus m, ServerMonad m) => (a -> m b) -> m b -- | pops any path element and ignores when chosing a ServerPartT to handle -- the -- -- request. anyPath :: (ServerMonad m, MonadPlus m) => m r -> m r -- | Deprecated. Use anyPath. anyPath' :: (ServerMonad m, MonadPlus m) => m r -> m r -- | Retrieve data from the input query or the cookies. withData :: (FromData a, MonadPlus m, ServerMonad m) => (a -> m r) -> m r -- | withDataFn is like with data, but you pass in a RqData monad for -- reading. withDataFn :: (MonadPlus m, ServerMonad m) => RqData a -> (a -> m r) -> m r -- | used to read parse your request with a RqData (a ReaderT, basically) -- For example here is a simple GET or POST variable based authentication -- guard. It handles the request with errorHandler if authentication -- fails. -- --
-- myRqData = do -- username <- lookInput "username" -- password <- lookInput "password" -- return (username, password) -- checkAuth errorHandler = do -- d <- getData myRqDataA -- case d of -- Nothing -> errorHandler -- Just a | isValid a -> mzero -- Just a | otherwise -> errorHandler --getDataFn :: (ServerMonad m) => RqData a -> m (Maybe a) -- | An varient of getData that uses FromData to chose your RqData for you. -- The example from getData becomes: -- --
-- myRqData = do -- username <- lookInput "username" -- password <- lookInput "password" -- return (username, password) -- instance FromData (String,String) where -- fromData = myRqData -- checkAuth errorHandler = do -- d <- getData' -- case d of -- Nothing -> errorHandler -- Just a | isValid a -> mzero -- Just a | otherwise -> errorHandler --getData :: (ServerMonad m, FromData a) => m (Maybe a) -- | Run an IO action and, if it returns Just, pass it to the -- second argument. require :: (MonadIO m, MonadPlus m) => IO (Maybe a) -> (a -> m r) -> m r -- | A varient of require that can run in any monad, not just IO requireM :: (MonadTrans t, Monad m, MonadPlus (t m)) => m (Maybe a) -> (a -> t m r) -> t m r -- | a simple HTTP basic authentication guard basicAuth :: (WebMonad Response m, ServerMonad m, FilterMonad Response m, MonadPlus m) => String -> Map String String -> m a -> m a -- | grabs the rest of the URL (dirs + query) and passes it to your handler uriRest :: (ServerMonad m) => (String -> m a) -> m a -- | flatten turns your arbitrary m a and converts it too a m -- Response with toResponse flatten :: (ToMessage a, Functor f) => f a -> f Response -- | This is kinda like a very oddly shaped mapServerPartT or mapWebT You -- probably want one or the other of those. localContext :: (Monad m) => (WebT m a -> WebT m' a) -> ServerPartT m a -> ServerPartT m' a -- | proxyServe is for creating ServerPartT's that proxy. The sole argument -- [String] is a list of allowed domains for proxying. This matches the -- domain part of the request and the wildcard * can be used. E.g. -- --
-- simpleHTTP conf $ mapServerPartT' (spUnWrapErrorT failurePart) $ myPart `catchError` errorPart ---- -- Note that failurePart will only be run if errorPart threw an -- error so it doesn't have to be very complex. spUnwrapErrorT :: (Monad m) => (e -> ServerPartT m a) -> Request -> UnWebT (ErrorT e m) a -> UnWebT m a -- | Set the validator which should be used for this particular -- Response when validation is enabled. -- -- Calling this function does not enable validation. That can only be -- done by enabling the validation in the Conf that is passed to -- simpleHTTP. -- -- You do not need to call this function if the validator set in -- Conf does what you want already. -- -- Example: (use noopValidator instead of the default supplied by -- validateConf) -- --
-- simpleHTTP validateConf . anyRequest $ ok . setValidator noopValidator =<< htmlPage ---- -- See also: validateConf, wdgHTMLValidator, -- noopValidator, lazyProcValidator setValidator :: (Response -> IO Response) -> Response -> Response -- | ServerPart version of setValidator -- -- Example: (Set validator to noopValidator) -- --
-- simpleHTTP validateConf $ setValidatorSP noopValidator (dir ajax ... ) ---- -- See also: setValidator setValidatorSP :: (Monad m, ToMessage r) => (Response -> IO Response) -> m r -> m Response -- | This extends nullConf by enabling validation and setting -- wdgHTMLValidator as the default validator for -- text/html. -- -- Example: -- --
-- simpleHTTP validateConf . anyRequest $ ok htmlPage --validateConf :: Conf -- | Actually perform the validation on a Response -- -- Run the validator specified in the Response. If none is provide -- use the supplied default instead. -- -- Note: This function will run validation unconditionally. You probably -- want setValidator or validateConf. runValidator :: (Response -> IO Response) -> Response -> IO Response -- | Validate text/html content with WDG HTML Validator. -- -- This function expects the executable to be named validate and -- it must be in the default PATH. -- -- See also: setValidator, validateConf, -- lazyProcValidator wdgHTMLValidator :: (MonadIO m, ToMessage r) => r -> m Response -- | A validator which always succeeds. -- -- Useful for selectively disabling validation. For example, if you are -- sending down HTML fragments to an AJAX application and the default -- validator only understands complete documents. noopValidator :: Response -> IO Response -- | Validate the Response using an external application. -- -- If the external application returns 0, the original response is -- returned unmodified. If the external application returns non-zero, a -- Response containing the error messages and original response -- body is returned instead. -- -- This function also takes a predicate filter which is applied to the -- content-type of the response. The filter will only be applied if the -- predicate returns true. -- -- NOTE: This function requirse the use of -threaded to avoid blocking. -- However, you probably need that for Happstack anyway. -- -- See also: wdgHTMLValidator lazyProcValidator :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> (Maybe ByteString -> Bool) -> Response -> IO Response instance [overlap ok] (MonadIO m) => MonadIO (WebT m) instance [overlap ok] (Monad m) => Functor (WebT m) instance [overlap ok] (Monad m) => Monad (FilterT a m) instance [overlap ok] MonadTrans (FilterT a) instance [overlap ok] (Monad m) => Functor (FilterT a m) instance [overlap ok] (MonadIO m) => MonadIO (FilterT a m) instance [overlap ok] (Eq a) => Eq (SetAppend a) instance [overlap ok] (Show a) => Show (SetAppend a) instance [overlap ok] (Monad m) => Monad (ServerPartT m) instance [overlap ok] (MonadIO m) => MonadIO (ServerPartT m) instance [overlap ok] (Monad m) => MonadPlus (ServerPartT m) instance [overlap ok] (Monad m) => Functor (ServerPartT m) instance [overlap ok] MatchMethod () instance [overlap ok] MatchMethod (Method -> Bool) instance [overlap ok] MatchMethod [Method] instance [overlap ok] MatchMethod Method instance [overlap ok] (Xml a) => ToMessage a instance [overlap ok] ToMessage Response instance [overlap ok] ToMessage Html instance [overlap ok] ToMessage Html instance [overlap ok] (ToMessage a) => ToMessage (Maybe a) instance [overlap ok] ToMessage Integer instance [overlap ok] ToMessage String instance [overlap ok] ToMessage () instance [overlap ok] ToMessage [Element] instance [overlap ok] (FromData a) => FromData (Maybe a) instance [overlap ok] (FromData a, FromData b, FromData c, FromData d) => FromData (a, b, c, d) instance [overlap ok] (FromData a, FromData b, FromData c) => FromData (a, b, c) instance [overlap ok] (FromData a, FromData b) => FromData (a, b) instance [overlap ok] (Eq a, Show a, Xml a, Data a) => FromData a instance [overlap ok] FromReqURI Double instance [overlap ok] FromReqURI Float instance [overlap ok] FromReqURI Integer instance [overlap ok] FromReqURI Int instance [overlap ok] FromReqURI String instance [overlap ok] (MonadWriter w m) => MonadWriter w (WebT m) instance [overlap ok] (MonadError e m) => MonadError e (WebT m) instance [overlap ok] (MonadState st m) => MonadState st (WebT m) instance [overlap ok] (MonadReader r m) => MonadReader r (WebT m) instance [overlap ok] (Monad m, Functor m) => Applicative (WebT m) instance [overlap ok] (Monad m) => Monoid (WebT m a) instance [overlap ok] (Monad m) => FilterMonad Response (WebT m) instance [overlap ok] (Monad m) => MonadPlus (WebT m) instance [overlap ok] MonadTrans WebT instance [overlap ok] (Monad m) => WebMonad Response (WebT m) instance [overlap ok] Error Response instance [overlap ok] (Monad m) => Monad (WebT m) instance [overlap ok] (Monad m) => FilterMonad a (FilterT a m) instance [overlap ok] Functor SetAppend instance [overlap ok] (Monoid a) => Monoid (SetAppend a) instance [overlap ok] (Monad m) => ServerMonad (ServerPartT m) instance [overlap ok] (Monad m) => WebMonad Response (ServerPartT m) instance [overlap ok] (Monad m) => FilterMonad Response (ServerPartT m) instance [overlap ok] (Monad m, MonadReader r m) => MonadReader r (ServerPartT m) instance [overlap ok] (Monad m, MonadError e m) => MonadError e (ServerPartT m) instance [overlap ok] (Monad m, MonadWriter w m) => MonadWriter w (ServerPartT m) instance [overlap ok] (Monad m, Functor m) => Applicative (ServerPartT m) instance [overlap ok] (Monad m) => Monoid (ServerPartT m a) instance [overlap ok] MonadTrans ServerPartT module Happstack.Server.HTTP.FileServe type MimeMap = Map String String -- | Prevents files of the form '.foo' or 'bar/.foo' from being served blockDotFiles :: (Request -> IO Response) -> Request -> IO Response doIndex :: (ServerMonad m, FilterMonad Response m, MonadIO m) => [String] -> MimeMap -> String -> m Response -- | A variant of doIndex that relies on getFileStrict doIndexStrict :: (ServerMonad m, FilterMonad Response m, MonadIO m) => [String] -> MimeMap -> String -> m Response errorwrapper :: (MonadIO m, MonadPlus m, FilterMonad Response m) => String -> String -> m Response -- | Serve a file (lazy version). For efficiency reasons when serving large -- files, will escape the computation early if a file is successfully -- served, to prevent filters from being applied; if a filter were -- applied, we would need to compute the content-length (thereby forcing -- the spine of the ByteString into memory) rather than reading it from -- the filesystem. -- -- Note that using lazy fileServe can result in some filehandles staying -- open until the garbage collector gets around to closing them. fileServe :: (WebMonad Response m, ServerMonad m, FilterMonad Response m, MonadIO m) => [FilePath] -> FilePath -> m Response -- | Serve a file (strict version). Reads the entire file strictly into -- memory, and ensures that the handle is properly closed. Unlike lazy -- fileServe, this function doesn't shortcut the computation early, and -- it allows for filtering (ex: gzip compression) to be applied fileServeStrict :: (ServerMonad m, FilterMonad Response m, MonadIO m) => [FilePath] -> FilePath -> m Response -- | Returns True if the given String either starts with a . or is of the -- form foo/.bar, e.g. the typical *nix convention for hidden -- files. isDot :: String -> Bool -- | Ready collection of common mime types. mimeTypes :: MimeMap module Happstack.Server.StdConfig -- | Is equal to haskell/Main binarylocation :: String -- | Is equal to public/log loglocation :: String -- | Convenience function around errorwrapper with the default -- binary location set to binarylocation and the log location set -- to loglocation. errWrap :: (MonadPlus m, FilterMonad Response m, MonadIO m) => m Response module Happstack.Server.Parts -- | reads the "Accept-Encoding" header. Then, if possible will compress -- the response body with methods gzip or deflate -- -- Returns the name of the coding chosen compressedResponseFilter :: (FilterMonad Response m, MonadPlus m, WebMonad Response m, ServerMonad m) => m String -- | compresses the body of the response with gzip. does not set any -- headers. gzipFilter :: (FilterMonad Response m) => m () -- | compresses the body of the response with zlib's deflate method does -- not set any headers. deflateFilter :: (FilterMonad Response m) => m () -- | unsupported: a parser for the Accept-Encoding header encodings :: GenParser Char st [([Char], Maybe Double)] module Happstack.Server