- type FastCGI = ReaderT FastCGIState IO
- data FastCGIState
- class MonadIO m => MonadFastCGI m where
- getFastCGIState :: m FastCGIState
- implementationThrowFastCGI :: Exception e => e -> m a
- implementationCatchFastCGI :: Exception e => m a -> (e -> m a) -> m a
- implementationBlockFastCGI :: m a -> m a
- implementationUnblockFastCGI :: m a -> m a
- acceptLoop :: (IO () -> IO ThreadId) -> FastCGI () -> IO ()
- fLog :: MonadFastCGI m => String -> m ()
- getRequestVariable :: MonadFastCGI m => String -> m (Maybe String)
- getAllRequestVariables :: MonadFastCGI m => m [(String, String)]
- data Header
- = HttpAccept
- | HttpAcceptCharset
- | HttpAcceptEncoding
- | HttpAcceptLanguage
- | HttpAuthorization
- | HttpExpect
- | HttpFrom
- | HttpHost
- | HttpIfMatch
- | HttpIfModifiedSince
- | HttpIfNoneMatch
- | HttpIfRange
- | HttpIfUnmodifiedSince
- | HttpMaxForwards
- | HttpProxyAuthorization
- | HttpRange
- | HttpReferer
- | HttpTE
- | HttpUserAgent
- | HttpAcceptRanges
- | HttpAge
- | HttpETag
- | HttpLocation
- | HttpProxyAuthenticate
- | HttpRetryAfter
- | HttpServer
- | HttpVary
- | HttpWWWAuthenticate
- | HttpAllow
- | HttpContentEncoding
- | HttpContentLanguage
- | HttpContentLength
- | HttpContentLocation
- | HttpContentMD5
- | HttpContentRange
- | HttpContentType
- | HttpExpires
- | HttpLastModified
- | HttpExtensionHeader String
- | HttpConnection
- | HttpCookie
- | HttpSetCookie
- getRequestHeader :: MonadFastCGI m => Header -> m (Maybe String)
- getAllRequestHeaders :: MonadFastCGI m => m [(Header, String)]
- data Cookie = Cookie {}
- getCookie :: MonadFastCGI m => String -> m (Maybe Cookie)
- getAllCookies :: MonadFastCGI m => m [Cookie]
- getCookieValue :: MonadFastCGI m => String -> m (Maybe String)
- getDocumentRoot :: MonadFastCGI m => m (Maybe String)
- getGatewayInterface :: MonadFastCGI m => m (Maybe String)
- getPathInfo :: MonadFastCGI m => m (Maybe String)
- getPathTranslated :: MonadFastCGI m => m (Maybe String)
- getQueryString :: MonadFastCGI m => m (Maybe String)
- getRedirectStatus :: MonadFastCGI m => m (Maybe Int)
- getRedirectURI :: MonadFastCGI m => m (Maybe String)
- getRemoteAddress :: MonadFastCGI m => m (Maybe HostAddress)
- getRemotePort :: MonadFastCGI m => m (Maybe Int)
- getRemoteHost :: MonadFastCGI m => m (Maybe String)
- getRemoteIdent :: MonadFastCGI m => m (Maybe String)
- getRemoteUser :: MonadFastCGI m => m (Maybe String)
- getRequestMethod :: MonadFastCGI m => m (Maybe String)
- getRequestURI :: MonadFastCGI m => m (Maybe String)
- getScriptFilename :: MonadFastCGI m => m (Maybe String)
- getScriptName :: MonadFastCGI m => m (Maybe String)
- getServerAddress :: MonadFastCGI m => m (Maybe HostAddress)
- getServerName :: MonadFastCGI m => m (Maybe String)
- getServerPort :: MonadFastCGI m => m (Maybe Int)
- getServerProtocol :: MonadFastCGI m => m (Maybe String)
- getServerSoftware :: MonadFastCGI m => m (Maybe String)
- getAuthenticationType :: MonadFastCGI m => m (Maybe String)
- getContentLength :: MonadFastCGI m => m (Maybe Int)
- getContentType :: MonadFastCGI m => m (Maybe String)
- fGet :: MonadFastCGI m => Int -> m ByteString
- fGetNonBlocking :: MonadFastCGI m => Int -> m ByteString
- fGetContents :: MonadFastCGI m => m ByteString
- fIsReadable :: MonadFastCGI m => m Bool
- setResponseStatus :: MonadFastCGI m => Int -> m ()
- getResponseStatus :: MonadFastCGI m => m Int
- setResponseHeader :: MonadFastCGI m => Header -> String -> m ()
- unsetResponseHeader :: MonadFastCGI m => Header -> m ()
- getResponseHeader :: MonadFastCGI m => Header -> m (Maybe String)
- setCookie :: MonadFastCGI m => Cookie -> m ()
- unsetCookie :: MonadFastCGI m => String -> m ()
- mkSimpleCookie :: String -> String -> Cookie
- mkCookie :: String -> String -> Maybe String -> Maybe String -> Maybe Int -> Bool -> Cookie
- permanentRedirect :: MonadFastCGI m => String -> m ()
- seeOtherRedirect :: MonadFastCGI m => String -> m ()
- sendResponseHeaders :: MonadFastCGI m => m ()
- responseHeadersSent :: MonadFastCGI m => m Bool
- fPut :: MonadFastCGI m => ByteString -> m ()
- fPutStr :: MonadFastCGI m => String -> m ()
- fCloseOutput :: MonadFastCGI m => m ()
- fIsWritable :: MonadFastCGI m => m Bool
- data FastCGIException
- fThrow :: (Exception e, MonadFastCGI m) => e -> m a
- fCatch :: (Exception e, MonadFastCGI m) => m a -> (e -> m a) -> m a
- fBlock :: MonadFastCGI m => m a -> m a
- fUnblock :: MonadFastCGI m => m a -> m a
- fBracket :: MonadFastCGI m => m a -> (a -> m b) -> (a -> m c) -> m c
- fFinally :: MonadFastCGI m => m a -> m b -> m a
- fTry :: (Exception e, MonadFastCGI m) => m a -> m (Either e a)
- fHandle :: (Exception e, MonadFastCGI m) => (e -> m a) -> m a -> m a
- fOnException :: MonadFastCGI m => m a -> m b -> m a
The monad
type FastCGI = ReaderT FastCGIState IOSource
The monad within which each single connection from the web server is handled.
data FastCGIState Source
An opaque type representing the state of a single connection from the web server.
class MonadIO m => MonadFastCGI m whereSource
The class of monads within which the FastCGI calls are valid. You may wish to create your own monad implementing this class.
getFastCGIState :: m FastCGIStateSource
Returns the opaque FastCGIState
object representing the state of the
FastCGI client.
Should not be called directly by user code, except implementations of
MonadFastCGI
; exported so that
user monads can implement the interface.
implementationThrowFastCGISource
:: Exception e | |
=> e | The exception to throw |
-> m a |
Throws an exception in the monad.
Should not be called directly by user code; exported so that
user monads can implement the interface. See fThrow
.
implementationCatchFastCGISource
:: Exception e | |
=> m a | The action to run with the exception handler binding in scope. |
-> (e -> m a) | The exception handler to bind. |
-> m a |
Perform an action in the monad, with a given exception-handler action bound.
Should not be called directly by user code; exported so that
user monads can implement the interface. See fCatch
.
implementationBlockFastCGISource
:: m a | The action to run with exceptions blocked. |
-> m a |
Block exceptions within an action.
Should not be called directly by user code; exported so that
user monads can implement the interface. See fBlock
.
implementationUnblockFastCGISource
:: m a | The action to run with exceptions unblocked. |
-> m a |
Unblock exceptions within an action.
Should not be called directly by user code; exported so that
user monads can implement the interface. See fUnblock
.
Accepting requests
:: (IO () -> IO ThreadId) | |
-> FastCGI () | A handler which is invoked once for each incoming connection. |
-> IO () | Never actually returns. |
Takes a forking primitive, such as forkIO
or forkOS
, and a handler, and
concurrently accepts requests from the web server, forking with the primitive
and invoking the handler in the forked thread inside the FastCGI
monad for each
one.
It is valid to use a custom forking primitive, such as one that attempts to pool OS threads, but the primitive must actually provide concurrency - otherwise there will be a deadlock. There is no support for single-threaded operation.
Note that although there is no mechanism to substitute another type of monad for
FastCGI, you can enter your own monad within the handler, much as you would enter
your own monad within IO. You simply have to implement the MonadFastCGI
class.
Any exceptions not caught within the handler are caught by concurrentAcceptLoop
,
and cause the termination of that handler, but not of the accept loop.
Furthermore, the exception is logged through the FastCGI protocol if at all
possible.
In the event that the program was not invoked according to the FastCGI protocol, returns.
Logging
fLog :: MonadFastCGI m => String -> m ()Source
Logs a message using the web server's logging facility.
Request information
It is common practice for web servers to make their own extensions to
the CGI/1.1 set of defined variables. For example, REMOTE_PORT
is
not defined by the specification, but often seen in the wild.
Furthermore, it is also common for user agents to make their own
extensions to the HTTP/1.1 set of defined headers. Therefore, there
are two levels of call available. Defined variables and headers may
be interrogated directly, and in addition, there are higher-level
calls which give convenient names and types to the same information.
Cookies may also be manipulated through HTTP headers directly; the functions here are provided only as a convenience.
:: MonadFastCGI m | |
=> String | The name of the request variable to query. |
-> m (Maybe String) | The value of the request variable, if the web server provided one. |
Queries the value from the web server of the CGI/1.1 request variable with the given name for this request.
getAllRequestVariables :: MonadFastCGI m => m [(String, String)]Source
Returns an association list of name-value pairs of all the CGI/1.1 request variables from the web server.
Headers are classified by HTTP/1.1 as request headers, response headers, or entity headers.
:: MonadFastCGI m | |
=> Header | The header to query. Must be a request or entity header. |
-> m (Maybe String) | The value of the header, if the user agent provided one. |
Queries the value from the user agent of the given HTTP/1.1 header.
getAllRequestHeaders :: MonadFastCGI m => m [(Header, String)]Source
Returns an association list of name-value pairs of all the HTTP/1.1 request or entity headers from the user agent.
Cookie | |
|
:: MonadFastCGI m | |
=> String | The name of the cookie to look for. |
-> m (Maybe Cookie) | The cookie, if the user agent provided it. |
Returns a Cookie
object for the given name, if the user agent provided one
in accordance with RFC 2109.
getAllCookies :: MonadFastCGI m => m [Cookie]Source
Returns all Cookie
objects provided by the user agent in accordance
RFC 2109.
:: MonadFastCGI m | |
=> String | The name of the cookie to look for. |
-> m (Maybe String) | The value of the cookie, if the user agent provided it. |
getDocumentRoot :: MonadFastCGI m => m (Maybe String)Source
Return the document root, as provided by the web server, if it was provided.
getGatewayInterface :: MonadFastCGI m => m (Maybe String)Source
Return the gateway interface, as provided by the web server, if it was provided.
getPathInfo :: MonadFastCGI m => m (Maybe String)Source
Return the path info, as provided by the web server, if it was provided.
getPathTranslated :: MonadFastCGI m => m (Maybe String)Source
Return the path-translated value, as provided by the web server, if it was provided.
getQueryString :: MonadFastCGI m => m (Maybe String)Source
Return the query string, as provided by the web server, if it was provided.
getRedirectStatus :: MonadFastCGI m => m (Maybe Int)Source
Return the redirect status, as provided by the web server, if it was provided.
getRedirectURI :: MonadFastCGI m => m (Maybe String)Source
Return the redirect URI, as provided by the web server, if it was provided.
getRemoteAddress :: MonadFastCGI m => m (Maybe HostAddress)Source
Return the remote address, as provided by the web server, if it was provided.
getRemotePort :: MonadFastCGI m => m (Maybe Int)Source
Return the remote port, as provided by the web server, if it was provided.
getRemoteHost :: MonadFastCGI m => m (Maybe String)Source
Return the remote hostname, as provided by the web server, if it was provided.
getRemoteIdent :: MonadFastCGI m => m (Maybe String)Source
Return the remote ident value, as provided by the web server, if it was provided.
getRemoteUser :: MonadFastCGI m => m (Maybe String)Source
Return the remote user name, as provided by the web server, if it was provided.
getRequestMethod :: MonadFastCGI m => m (Maybe String)Source
Return the request method, as provided by the web server, if it was provided.
getRequestURI :: MonadFastCGI m => m (Maybe String)Source
Return the request URI, as provided by the web server, if it was provided.
getScriptFilename :: MonadFastCGI m => m (Maybe String)Source
Return the script filename, as provided by the web server, if it was provided.
getScriptName :: MonadFastCGI m => m (Maybe String)Source
Return the script name, as provided by the web server, if it was provided.
getServerAddress :: MonadFastCGI m => m (Maybe HostAddress)Source
Return the server address, as provided by the web server, if it was provided.
getServerName :: MonadFastCGI m => m (Maybe String)Source
Return the server name, as provided by the web server, if it was provided.
getServerPort :: MonadFastCGI m => m (Maybe Int)Source
Return the server port, as provided by the web server, if it was provided.
getServerProtocol :: MonadFastCGI m => m (Maybe String)Source
Return the server protocol, as provided by the web server, if it was provided.
getServerSoftware :: MonadFastCGI m => m (Maybe String)Source
Return the server software name and version, as provided by the web server, if it was provided.
getAuthenticationType :: MonadFastCGI m => m (Maybe String)Source
Return the authentication type, as provided by the web server, if it was provided.
getContentLength :: MonadFastCGI m => m (Maybe Int)Source
Return the content length, as provided by the web server, if it was provided.
getContentType :: MonadFastCGI m => m (Maybe String)Source
Return the content type, as provided by the web server, if it was provided.
Request content data
At the moment the handler is invoked, all request headers have been received, but content data has not necessarily been. Requests to read content data block the handler (but not other concurrent handlers) until there is enough data in the buffer to satisfy them, or until timeout where applicable.
fGet :: MonadFastCGI m => Int -> m ByteStringSource
Reads up to a specified amount of data from the input stream of the current request,
and interprets it as binary data. This is the content data of the HTTP request,
if any. If input has been closed, returns an empty bytestring. If insufficient
input is available, blocks until there is enough. If output has been closed,
causes an OutputAlreadyClosed
exception.
fGetNonBlocking :: MonadFastCGI m => Int -> m ByteStringSource
Reads up to a specified amount of data from the input stream of the curent request,
and interprets it as binary data. This is the content data of the HTTP request,
if any. If input has been closed, returns an empty bytestring. If insufficient
input is available, returns any input which is immediately available, or an empty
bytestring if there is none, never blocking. If output has been closed, causes an
OutputAlreadyClosed
exception.
fGetContents :: MonadFastCGI m => m ByteStringSource
Reads all remaining data from the input stream of the current request, and
interprets it as binary data. This is the content data of the HTTP request, if
any. Blocks until all input has been read. If input has been closed, returns an
empty bytestring. If output has been closed, causes an OutputAlreadyClosed
exception.
fIsReadable :: MonadFastCGI m => m BoolSource
Returns whether the input stream of the current request potentially has data remaining, either in the buffer or yet to be read. This is the content data of the HTTP request, if any.
Response information and content data
When the handler is first invoked, neither response headers nor content data have been sent to the client. Setting of response headers is lazy, merely setting internal variables, until something forces them to be output. For example, attempting to send content data will force response headers to be output first. It is not necessary to close the output stream explicitly, but it may be desirable, for example to continue processing after returning results to the user.
There is no reason that client scripts cannot use any encoding they wish, including the chunked encoding, if they have set appropriate headers. This package, however, does not explicitly support that, because client scripts can easily implement it for themselves.
At the start of each request, the response status is set to 200 OK
and the only response header set is Content-Type: text/html
. These
may be overridden by later calls, at any time before headers have
been sent.
Cookies may also be manipulated through HTTP headers directly; the functions here are provided only as a convenience.
:: MonadFastCGI m | |
=> Int | The HTTP/1.1 status code to set. |
-> m () |
Sets the response status which will be sent with the response headers. If the
response headers have already been sent, causes a ResponseHeadersAlreadySent
exception.
:: MonadFastCGI m | |
=> m Int | The HTTP/1.1 status code. |
Returns the response status which will be or has been sent with the response headers.
:: MonadFastCGI m | |
=> Header | The header to set. Must be a response header or an entity header. |
-> String | The value to set. |
-> m () |
Sets the given HttpHeader
response header to the given string value, overriding
any value which has previously been set. If the response headers have already
been sent, causes a ResponseHeadersAlreadySent
exception. If the header is not
an HTTP/1.1 or extension response or entity header, ie, is not valid as part of
a response, causes a NotAResponseHeader
exception.
If a value is set for the HttpSetCookie
header, this overrides all cookies set
for this request with setCookie
.
:: MonadFastCGI m | |
=> Header | The header to unset. Must be a response header or an entity header. |
-> m () |
Causes the given HttpHeader
response header not to be sent, overriding any value
which has previously been set. If the response headers have already been sent,
causes a ResponseHeadersAlreadySent
exception. If the header is not an HTTP/1.1
or extension response or entity header, ie, is not valid as part of a response,
causes a NotAResponseHeader
exception.
Does not prevent the HttpSetCookie
header from being sent if cookies have been
set for this request with setCookie
.
:: MonadFastCGI m | |
=> Header | The header to query. Must be a response header or an entity header. |
-> m (Maybe String) | The value of the queried header. |
Returns the value of the given header which will be or has been sent with the
response headers. If the header is not an HTTP/1.1 or extension response or entity
header, ie, is not valid as part of a response, causes a NotAResponseHeader
exception.
:: MonadFastCGI m | |
=> Cookie | The cookie to set. |
-> m () |
Causes the user agent to record the given cookie and send it back with future
loads of this page. Does not take effect instantly, but rather when headers are
sent. Cookies are set in accordance with RFC 2109.
If an HttpCookie
header is set for this request by a call to setResponseHeader
,
this function has no effect.
If the response headers have already been sent,
causes a ResponseHeadersAlreadySent
exception.
If the name is not a possible name for a cookie, causes a CookieNameInvalid
exception.
:: MonadFastCGI m | |
=> String | The name of the cookie to unset. |
-> m () |
Causes the user agent to unset any cookie applicable to this page with the
given name. Does not take effect instantly, but rather when headers are sent.
If an HttpCookie
header is set for this request by a call to setResponseHeader
,
this function has no effect.
If the response headers have already been sent,
causes a ResponseHeadersAlreadySent
exception.
If the name is not a possible name for a cookie, causes a CookieNameInvalid
exception.
:: String | The name of the cookie to construct. |
-> String | The value of the cookie to construct. |
-> Cookie | A cookie with the given name and value. |
Constructs a cookie with the given name and value. Version is set to 1;
path, domain, and maximum age are set to Nothing
; and the secure flag is
set to False
. Constructing the cookie does not cause it to be set; to do
that, call setCookie
on it.
:: String | The name of the cookie to construct. |
-> String | The value of the cookie to construct. |
-> Maybe String | The path of the cookie to construct. |
-> Maybe String | The domain of the cookie to construct. |
-> Maybe Int | The maximum age of the cookie to construct, in seconds. |
-> Bool | Whether to flag the cookie to construct as secure. |
-> Cookie | A cookie with the given parameters. |
Constructs a cookie with the given parameters. Version is set to 1.
Constructing the cookie does not cause it to be set; to do that, call setCookie
on it.
:: MonadFastCGI m | |
=> String | The URL to redirect to, as a string. |
-> m () |
Sets the HTTP/1.1 return status to 301 and sets the HttpLocation
header to
the provided URL. This has the effect of issuing a permanent redirect to the
user agent. Permanent redirects, as opposed to temporary redirects, may cause
bookmarks or incoming links to be updated. If the response headers have already
been sent, causes a ResponseHeadersAlreadySent
exception.
:: MonadFastCGI m | |
=> String | The URL to redirect to, as a string. |
-> m () |
Sets the HTTP/1.1 return status to 303 and sets the HttpLocation
header to
the provided URL. This has the effect of issuing a see-other or temporary
redirect to the user agent. Temporary redirects, as opposed to permanent redirects,
do not cause bookmarks or incoming links to be updated. If the response headers
have already been sent, causes a ResponseHeadersAlreadySent
exception.
sendResponseHeaders :: MonadFastCGI m => m ()Source
Ensures that the response headers have been sent. If they are already sent, does
nothing. If output has already been closed, causes an OutputAlreadyClosed
exception.
responseHeadersSent :: MonadFastCGI m => m BoolSource
Returns whether the response headers have been sent.
fPut :: MonadFastCGI m => ByteString -> m ()Source
Sends data. This is the content data of the HTTP response. If the response
headers have not been sent, first sends them. If output has already been closed,
causes an OutputAlreadyClosed
exception.
fPutStr :: MonadFastCGI m => String -> m ()Source
Sends text, encoded as UTF-8. This is the content data of the HTTP response.
if the response headers have not been sent, first sends them. If output has
already been closed, causes an OutputAlreadyClosed
exception.
fCloseOutput :: MonadFastCGI m => m ()Source
Informs the web server and the user agent that the request has completed. As
a side-effect, any unread input is discarded and no more can be read. This is
implicitly called, if it has not already been, after the handler returns; it
may be useful within a handler if the handler wishes to return results and then
perform time-consuming computations before exiting. If output has already been
closed, causes an OutputAlreadyClosed
exception.
fIsWritable :: MonadFastCGI m => m BoolSource
Returns whether it is possible to write more data; ie, whether output has not
yet been closed as by fCloseOutput
.
Exceptions
data FastCGIException Source
An exception originating within the FastCGI infrastructure or the web server.
ResponseHeadersAlreadySent | An exception thrown by operations which require the response headers not to have been sent yet. |
OutputAlreadyClosed | An exception thrown by operations which produce output when output has
been closed, as by |
NotAResponseHeader Header | An exception thrown by operations which are given a header that does not meet their requirement of being valid in a response. |
CookieNameInvalid String | An exception thrown by operations which are given cookie names that do not meet the appropriate syntax requirements. |
:: (Exception e, MonadFastCGI m) | |
=> e | The exception to throw. |
-> m a |
Throw an exception in any MonadFastCGI
monad.
:: (Exception e, MonadFastCGI m) | |
=> m a | The action to run with the exception handler binding in scope. |
-> (e -> m a) | The exception handler to bind. |
-> m a |
Perform an action, with a given exception-handler action bound. See
Control.Exception.catch
. The type of exception to catch is determined by the
type signature of the handler.
:: MonadFastCGI m | |
=> m a | The action to run with exceptions blocked. |
-> m a |
Block exceptions within an action, as per the discussion in Control.Exception
.
:: MonadFastCGI m | |
=> m a | The action to run with exceptions unblocked. |
-> m a |
Unblock exceptions within an action, as per the discussion in Control.Exception
.
:: MonadFastCGI m | |
=> m a | The action to acquire the resource. |
-> (a -> m b) | The action to release the resource. |
-> (a -> m c) | The action to perform using the resource. |
-> m c | The return value of the perform-action. |
Acquire a resource, perform computation with it, and release it; see the description
of Control.Exception.bracket
. If an exception is raised during the computation,
fBracket
will re-raise it after running the release function, having the effect
of propagating the exception further up the call stack.
:: MonadFastCGI m | |
=> m a | The action to perform. |
-> m b | The cleanup action. |
-> m a | The return value of the perform-action. |
Perform an action, with a cleanup action bound to always occur; see the
description of Control.Exception.finally
. If an exception is raised during the
computation, fFinally
will re-raise it after running the cleanup action, having
the effect of propagating the exception further up the call stack. If no
exception is raised, the cleanup action will be invoked after the main action is
performed.
:: (Exception e, MonadFastCGI m) | |
=> m a | The action to perform. |
-> m (Either e a) |
:: (Exception e, MonadFastCGI m) | |
=> (e -> m a) | The exception handler to bind. |
-> m a | The action to run with the exception handler binding in scope. |
-> m a |
As fCatch
, but with the arguments in the other order.
:: MonadFastCGI m | |
=> m a | The action to perform. |
-> m b | The cleanup action. |
-> m a | The return value of the perform-action. |
Perform an action, with a cleanup action bound to occur if and only if an exception
is raised during the action; see the description of Control.Exception.finally
.
If an exception is raised during the computation, fFinally
will re-raise it
after running the cleanup action, having the effect of propagating the exception
further up the call stack. If no exception is raised, the cleanup action will not
be invoked.