diff --git a/happstack-server.cabal b/happstack-server.cabal
--- a/happstack-server.cabal
+++ b/happstack-server.cabal
@@ -1,5 +1,5 @@
 Name:                happstack-server
-Version:             6.1.0
+Version:             6.1.2
 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
diff --git a/src/Happstack/Server.hs b/src/Happstack/Server.hs
--- a/src/Happstack/Server.hs
+++ b/src/Happstack/Server.hs
@@ -76,6 +76,7 @@
                                          , simpleHTTPWithSocket
                                          , simpleHTTPWithSocket'
                                          , bindPort
+                                         , bindIPv4
                                          , parseConfig)
 import Happstack.Server.FileServe
 import Happstack.Server.Monads
diff --git a/src/Happstack/Server/Internal/Listen.hs b/src/Happstack/Server/Internal/Listen.hs
--- a/src/Happstack/Server/Internal/Listen.hs
+++ b/src/Happstack/Server/Internal/Listen.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-}
-module Happstack.Server.Internal.Listen(listen, listen',listenOn) where
+module Happstack.Server.Internal.Listen(listen, listen',listenOn,listenOnIPv4) where
 
 import Happstack.Server.Internal.Types          (Conf(..), Request, Response)
 import Happstack.Server.Internal.Handler        (request)
@@ -15,7 +15,7 @@
                                  SocketOption(..), SockAddr(..), 
                                  iNADDR_ANY, maxListenQueue, SocketType(..), 
                                  bindSocket)
-import qualified Network.Socket                 as Socket (listen)
+import qualified Network.Socket                 as Socket (listen, inet_addr)
 import System.IO.Error                          (isFullError)
 {-
 #ifndef mingw32_HOST_OS
@@ -48,6 +48,21 @@
             return sock
         )
 
+listenOnIPv4 :: String  -- ^ IP address to listen on (must be an IP address not a host name)
+             -> Int     -- ^ port number to listen on
+             -> IO Socket
+listenOnIPv4 ip portm = do
+    proto <- getProtocolNumber "tcp"
+    hostAddr <- Socket.inet_addr ip
+    E.bracketOnError
+        (socket AF_INET Stream proto)
+        (sClose)
+        (\sock -> do
+            setSocketOption sock ReuseAddr 1
+            bindSocket sock (SockAddrInet (fromIntegral portm) hostAddr)
+            Socket.listen sock (max 1024 maxListenQueue)
+            return sock
+        )
 
 -- | Bind and listen port
 listen :: Conf -> (Request -> IO Response) -> IO ()
diff --git a/src/Happstack/Server/Response.hs b/src/Happstack/Server/Response.hs
--- a/src/Happstack/Server/Response.hs
+++ b/src/Happstack/Server/Response.hs
@@ -14,6 +14,7 @@
     , unauthorized
     , forbidden
     , notFound
+    , requestEntityTooLarge
     , seeOther
     , found
     , movedPermanently
@@ -32,7 +33,7 @@
 import qualified Data.Text.Encoding              as T
 import qualified Data.Text.Lazy                  as LT
 import qualified Data.Text.Lazy.Encoding         as LT
-import           Happstack.Server.Monads         (FilterMonad(composeFilter))
+import           Happstack.Server.Internal.Monads         (FilterMonad(composeFilter))
 import           Happstack.Server.Types          (Response(..), Request(..), nullRsFlags, getHeader, noContentLength, redirect, result, setHeader, setHeaderBS)
 import           Happstack.Server.SURI           (ToSURI)
 import           System.Locale                   (defaultTimeLocale)
@@ -253,6 +254,12 @@
 -- > main = simpleHTTP nullConf $ notFound "What you are looking for has not been found."
 notFound :: (FilterMonad Response m) => a -> m a
 notFound = resp 404
+
+-- | Respond with @413 Request Entity Too Large@.
+--
+-- > main = simpleHTTP nullConf $ requestEntityTooLarge "That's too big for me to handle."
+requestEntityTooLarge :: (FilterMonad Response m) => a -> m a
+requestEntityTooLarge = resp 413
 
 -- | Respond with @303 See Other@.
 --
diff --git a/src/Happstack/Server/RqData.hs b/src/Happstack/Server/RqData.hs
--- a/src/Happstack/Server/RqData.hs
+++ b/src/Happstack/Server/RqData.hs
@@ -70,9 +70,10 @@
 import           Data.Text.Lazy                 (Text)
 import qualified Data.Text.Lazy.Encoding        as Text
 import Happstack.Server.Cookie 			(Cookie (cookieValue))
-import Happstack.Server.Internal.Monads         (ServerMonad(askRq, localRq), ServerPartT)
-import Happstack.Server.Types                   (ContentType(..), Input(inputValue, inputFilename, inputContentType), Request(rqInputsQuery, rqInputsBody, rqCookies, rqMethod), Method(POST,PUT), readInputsBody)
+import Happstack.Server.Internal.Monads         (ServerMonad(askRq, localRq), FilterMonad, WebMonad, ServerPartT, escape)
+import Happstack.Server.Types                   (ContentType(..), Input(inputValue, inputFilename, inputContentType), Response, Request(rqInputsQuery, rqInputsBody, rqCookies, rqMethod), Method(POST,PUT), readInputsBody)
 import Happstack.Server.Internal.MessageWrap    (BodyPolicy(..), bodyInput, defaultBodyPolicy)
+import Happstack.Server.Response                (internalServerError, requestEntityTooLarge, toResponse)
 
 newtype ReaderError r e a = ReaderError { unReaderError :: ReaderT r (Either e) a }
     deriving (Functor, Monad, MonadPlus)
@@ -147,7 +148,7 @@
                            then readInputsBody rq
                            else return (Just [])
            case mbi of
-             Nothing   -> fail "askRqEnv failed because the request body has not been decoded yet. Try using 'decodeBody'."
+             Nothing   -> escape $ internalServerError (toResponse "askRqEnv failed because the request body has not been decoded yet. Try using 'decodeBody'.")
              (Just bi) -> return (rqInputsQuery rq, bi, rqCookies rq)
     rqDataError e = mzero
     localRqEnv f m =
@@ -447,13 +448,13 @@
 -- Only the first call to 'decodeBody' will have any effect. Calling
 -- it a second time, even with different quota values, will do
 -- nothing.
-decodeBody :: (ServerMonad m, MonadPlus m, MonadIO m) => BodyPolicy -> m ()
+decodeBody :: (ServerMonad m, MonadPlus m, MonadIO m, FilterMonad Response m, WebMonad Response m) => BodyPolicy -> m ()
 decodeBody bp =
     do rq <- askRq
        (_, me) <- bodyInput bp rq
        case me of
          Nothing -> return ()
-         Just e  -> fail e -- FIXME: is this the best way to report the error
+         Just e  -> escape $ requestEntityTooLarge (toResponse e) -- FIXME: is this the best way to report the error
 
 -- | run 'RqData' in a 'ServerMonad'.
 --
diff --git a/src/Happstack/Server/SimpleHTTP.hs b/src/Happstack/Server/SimpleHTTP.hs
--- a/src/Happstack/Server/SimpleHTTP.hs
+++ b/src/Happstack/Server/SimpleHTTP.hs
@@ -42,6 +42,7 @@
     , simpleHTTPWithSocket
     , simpleHTTPWithSocket'
     , bindPort
+    , bindIPv4
     , parseConfig
     -- * Re-exported modules
     -- ** Basic ServerMonad functionality
@@ -84,7 +85,7 @@
 import Data.Maybe                                (fromMaybe)
 import qualified Data.Version                    as DV
 import Happstack.Server.Internal.Monads          (FilterFun, WebT(..), UnWebT, unFilterFun, mapServerPartT, runServerPartT, ununWebT)
-import qualified Happstack.Server.Internal.Listen as Listen (listen, listen',listenOn) -- So that we can disambiguate 'Writer.listen'
+import qualified Happstack.Server.Internal.Listen as Listen (listen, listen',listenOn, listenOnIPv4) -- So that we can disambiguate 'Writer.listen'
 import Happstack.Server.Types                    (Conf(port, validator), Request, Response(rsBody, rsCode), nullConf, setHeader)
 import Network                                   (Socket)
 import qualified Paths_happstack_server          as Cabal
@@ -153,6 +154,8 @@
 --
 -- Note: It's important to use the same conf (or at least the same
 -- port) for 'bindPort' and 'simpleHTTPWithSocket'.
+--
+-- see also: 'bindPort', 'bindIPv4'
 simpleHTTPWithSocket :: (ToMessage a) => Socket -> Conf -> ServerPartT IO a -> IO ()
 simpleHTTPWithSocket = simpleHTTPWithSocket' id
 
@@ -162,11 +165,26 @@
 simpleHTTPWithSocket' toIO socket conf hs =
     Listen.listen' socket conf (\req -> runValidator (fromMaybe return (validator conf)) =<< (simpleHTTP'' (mapServerPartT toIO hs) req))
 
--- | Bind port and return the socket for 'simpleHTTPWithSocket'. This
+-- | 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.
 bindPort :: Conf -> IO Socket
 bindPort conf = Listen.listenOn (port conf)
+
+-- | 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)
+bindIPv4 :: String  -- ^ IP address to bind to (must be an IP address and not a host name)
+         -> Int     -- ^ port number to bind to
+         -> IO Socket
+bindIPv4 addr prt = Listen.listenOnIPv4 addr prt
 
 -- | Takes your 'WebT', if it is 'mempty' it returns 'Nothing' else it
 -- converts the value to a 'Response' and applies your filter to it.
