Copyright | (c) Happstack.com 2010; (c) HAppS Inc 2007 |
---|---|
License | BSD3 |
Maintainer | Happstack team <happs@googlegroups.com> |
Stability | provisional |
Portability | GHC-only, Windows, Linux, FreeBSD, OS X |
Safe Haskell | None |
Language | Haskell2010 |
Happstack.Server provides a self-contained HTTP server and a rich collection of types and functions for routing Requests, generating Responses, working with query parameters, form data, and cookies, serving files and more.
A very simple, "Hello World!" web app looks like:
import Happstack.Server main = simpleHTTP nullConf $ ok "Hello World!"
By default the server will listen on port 8000. Run the app and point your browser at: http://localhost:8000/
At the core of the Happstack server we have the simpleHTTP
function which starts the HTTP server:
simpleHTTP :: ToMessage a => Conf -> ServerPart a -> IO ()
and we have the user supplied ServerPart
(also known as,
ServerPartT
IO
), which generates a Response
for each incoming
Request
.
A trivial HTTP app server might just take a user supplied function like:
myApp :: Request -> IO Response
For each incoming Request
the server would fork a new thread, run
myApp
to generate a Response
, and then send the Response
back to
the client. But, that would be a pretty barren wasteland to work in.
The model for ServerPart
is essential the same, except we use the
much richer ServerPart
monad instead of the IO
monad.
For in-depth documentation and runnable examples I highly recommend The Happstack Crash Course http://happstack.com/docs/crashcourse/index.html.
Synopsis
- parseConfig :: [String] -> Either [String] Conf
- simpleHTTP :: ToMessage a => Conf -> ServerPartT IO a -> IO ()
- simpleHTTP' :: (ToMessage b, Monad m, Functor m) => (UnWebT m a -> UnWebT IO b) -> Conf -> ServerPartT m a -> IO ()
- simpleHTTP'' :: (ToMessage b, Monad m, Functor m) => ServerPartT m b -> Request -> m Response
- simpleHTTPWithSocket :: ToMessage a => Socket -> Conf -> ServerPartT IO a -> IO ()
- simpleHTTPWithSocket' :: (ToMessage b, Monad m, Functor m) => (UnWebT m a -> UnWebT IO b) -> Socket -> Conf -> ServerPartT m a -> IO ()
- bindPort :: Conf -> IO Socket
- bindIPv4 :: String -> Int -> IO Socket
- waitForTermination :: IO ()
- module Happstack.Server.Routing
- module Happstack.Server.Response
- module Happstack.Server.RqData
- module Happstack.Server.Cookie
- module Happstack.Server.FileServe
- module Happstack.Server.Auth
- module Happstack.Server.Error
- module Happstack.Server.I18N
- module Happstack.Server.Monads
- module Happstack.Server.Validation
- module Happstack.Server.Types
HTTP Server
simpleHTTP :: ToMessage a => Conf -> ServerPartT IO a -> IO () Source #
start the server, and handle requests using the supplied
ServerPart
.
This function will not return, though it may throw an exception.
NOTE: The server will only listen on IPv4 due to portability issues
in the Network module. For IPv6 support, use
simpleHTTPWithSocket
with custom socket.
simpleHTTP' :: (ToMessage b, Monad m, Functor m) => (UnWebT m a -> UnWebT IO b) -> Conf -> ServerPartT m a -> IO () Source #
A combination of simpleHTTP''
and mapServerPartT
. See
mapServerPartT
for a discussion of the first argument of this
function.
NOTE: This function always binds to IPv4 ports until Network
module is fixed to support IPv6 in a portable way. Use
simpleHTTPWithSocket
with custom socket if you want different
behaviour.
simpleHTTP'' :: (ToMessage b, Monad m, Functor m) => ServerPartT m b -> Request -> m Response Source #
Generate a result from a ServerPartT
and a Request
. This is
mainly used by CGI (and fast-cgi) wrappers.
simpleHTTPWithSocket :: ToMessage a => Socket -> Conf -> ServerPartT IO a -> IO () Source #
Run simpleHTTP
with a previously bound socket. Useful if you
want to run happstack as user on port 80. Use something like this:
import System.Posix.User (setUserID, UserEntry(..), getUserEntryForName) main = do let conf = nullConf { port = 80 } socket <- bindPort conf -- do other stuff as root here getUserEntryForName "www" >>= setUserID . userID -- finally start handling incoming requests tid <- forkIO $ simpleHTTPWithSocket socket Nothing conf impl
Note: It's important to use the same conf (or at least the same
port) for bindPort
and simpleHTTPWithSocket
.
simpleHTTPWithSocket' :: (ToMessage b, Monad m, Functor m) => (UnWebT m a -> UnWebT IO b) -> Socket -> Conf -> ServerPartT m a -> IO () Source #
Like simpleHTTP'
with a socket.
bindPort :: Conf -> IO Socket Source #
Bind port and return the socket for use with simpleHTTPWithSocket
. This
function always binds to IPv4 ports until Network module is fixed
to support IPv6 in a portable way.
:: String | IP address to bind to (must be an IP address and not a host name) |
-> Int | port number to bind to |
-> IO Socket |
Bind to ip and port and return the socket for use with simpleHTTPWithSocket
.
import Happstack.Server main = do let conf = nullConf addr = "127.0.0.1" s <- bindIPv4 addr (port conf) simpleHTTPWithSocket s conf $ ok $ toResponse $ "now listening on ip addr " ++ addr ++ " and port " ++ show (port conf)
waitForTermination :: IO () Source #
Wait for a signal. On unix, a signal is sigINT or sigTERM (aka Control-C).
On windows, the signal is entering: e return
Request Routing
module Happstack.Server.Routing
Creating Responses
module Happstack.Server.Response
Looking up values in Query String, Request Body, and Cookies
module Happstack.Server.RqData
Create and Set Cookies (see also Happstack.Server.RqData)
module Happstack.Server.Cookie
File Serving
module Happstack.Server.FileServe
HTTP Realm Authentication
module Happstack.Server.Auth
Error Handling
module Happstack.Server.Error
I18N
module Happstack.Server.I18N
Web-related Monads
module Happstack.Server.Monads
Output Validation
module Happstack.Server.Validation
HTTP Types
module Happstack.Server.Types