Copyright | (c) The University of Glasgow 2001 (c) Bjorn Bringert 2004-2006 (c) Ian Lynagh 2005 (c) Jeremy Shaw 2005 |
---|---|
License | BSD-style |
Maintainer | John Chee <cheecheeo@gmail.com> |
Stability | experimental |
Portability | non-portable (uses Control.Monad.State) |
Safe Haskell | None |
Language | Haskell98 |
Simple Library for writing CGI programs. See https://web.archive.org/web/20100109233524/http://hoohoo.ncsa.illinois.edu/cgi/interface.html for the CGI specification.
This version of the library is for systems with version 2.0 or greater of the network package. This includes GHC 6.6 and later. For older systems, see http://www.cs.chalmers.se/~bringert/darcs/cgi-compat/doc/
Based on the original Haskell binding for CGI:
Original Version by Erik Meijer mailto:erik@cs.ruu.nl. Further hacked on by Sven Panne mailto:sven.panne@aedion.de. Further hacking by Andy Gill mailto:andy@galconn.com. A new, hopefully more flexible, interface and support for file uploads by Bjorn Bringert mailto:bjorn@bringert.net.
Here is a simple example, including error handling (not that there is much that can go wrong with Hello World):
import Network.CGI cgiMain :: CGI CGIResult cgiMain = output "Hello World!" main :: IO () main = runCGI (handleErrors cgiMain)
- class Monad m => MonadCGI m
- data CGIT m a
- data CGIResult
- type CGI a = CGIT IO a
- class Monad m => MonadIO m where
- liftIO :: MonadIO m => forall a. IO a -> m a
- runCGI :: MonadIO m => CGIT m CGIResult -> m ()
- throwCGI :: (MonadCGI m, MonadThrow m) => SomeException -> m a
- catchCGI :: (MonadCGI m, MonadCatch m) => m a -> (SomeException -> m a) -> m a
- tryCGI :: (Functor m, MonadCGI m, MonadCatch m) => m a -> m (Either SomeException a)
- handleExceptionCGI :: (MonadCGI m, MonadCatch m) => m a -> (SomeException -> m a) -> m a
- handleErrors :: (MonadCGI m, MonadCatch m, MonadIO m) => m CGIResult -> m CGIResult
- logCGI :: MonadIO m => String -> m ()
- output :: MonadCGI m => String -> m CGIResult
- outputFPS :: MonadCGI m => ByteString -> m CGIResult
- outputNothing :: MonadCGI m => m CGIResult
- redirect :: MonadCGI m => String -> m CGIResult
- setHeader :: MonadCGI m => String -> String -> m ()
- setStatus :: MonadCGI m => Int -> String -> m ()
- outputError :: (MonadCGI m, MonadIO m) => Int -> String -> [String] -> m CGIResult
- outputException :: (MonadCGI m, MonadIO m) => SomeException -> m CGIResult
- outputNotFound :: (MonadIO m, MonadCGI m) => String -> m CGIResult
- outputMethodNotAllowed :: (MonadIO m, MonadCGI m) => [String] -> m CGIResult
- outputInternalServerError :: (MonadIO m, MonadCGI m) => [String] -> m CGIResult
- getInput :: MonadCGI m => String -> m (Maybe String)
- getInputFPS :: MonadCGI m => String -> m (Maybe ByteString)
- readInput :: (Read a, MonadCGI m) => String -> m (Maybe a)
- getBody :: MonadCGI m => m String
- getBodyFPS :: MonadCGI m => m ByteString
- getInputs :: MonadCGI m => m [(String, String)]
- getInputsFPS :: MonadCGI m => m [(String, ByteString)]
- getInputNames :: MonadCGI m => m [String]
- getMultiInput :: MonadCGI m => String -> m [String]
- getMultiInputFPS :: MonadCGI m => String -> m [ByteString]
- getInputFilename :: MonadCGI m => String -> m (Maybe String)
- getInputContentType :: MonadCGI m => String -> m (Maybe String)
- getVar :: MonadCGI m => String -> m (Maybe String)
- getVarWithDefault :: MonadCGI m => String -> String -> m String
- getVars :: MonadCGI m => m [(String, String)]
- serverName :: MonadCGI m => m String
- serverPort :: MonadCGI m => m Int
- requestMethod :: MonadCGI m => m String
- pathInfo :: MonadCGI m => m String
- pathTranslated :: MonadCGI m => m String
- scriptName :: MonadCGI m => m String
- queryString :: MonadCGI m => m String
- remoteHost :: MonadCGI m => m (Maybe String)
- remoteAddr :: MonadCGI m => m String
- authType :: MonadCGI m => m (Maybe String)
- remoteUser :: MonadCGI m => m (Maybe String)
- requestContentType :: MonadCGI m => m (Maybe String)
- requestContentLength :: MonadCGI m => m (Maybe Int)
- requestHeader :: MonadCGI m => String -> m (Maybe String)
- progURI :: MonadCGI m => m URI
- queryURI :: MonadCGI m => m URI
- requestURI :: MonadCGI m => m URI
- class Eq a => Acceptable a
- data Accept a
- newtype Charset = Charset String
- newtype ContentEncoding = ContentEncoding String
- newtype Language = Language String
- requestAccept :: MonadCGI m => m (Maybe (Accept ContentType))
- requestAcceptCharset :: MonadCGI m => m (Maybe (Accept Charset))
- requestAcceptEncoding :: MonadCGI m => m (Maybe (Accept ContentEncoding))
- requestAcceptLanguage :: MonadCGI m => m (Maybe (Accept Language))
- negotiate :: Acceptable a => [a] -> Maybe (Accept a) -> [a]
- data ContentType :: * = ContentType {}
- showContentType :: ContentType -> String
- parseContentType :: Monad m => String -> m ContentType
- data Cookie = Cookie {}
- newCookie :: String -> String -> Cookie
- getCookie :: MonadCGI m => String -> m (Maybe String)
- readCookie :: (Read a, MonadCGI m) => String -> m (Maybe a)
- setCookie :: MonadCGI m => Cookie -> m ()
- deleteCookie :: MonadCGI m => Cookie -> m ()
- formEncode :: [(String, String)] -> String
- urlEncode :: String -> String
- formDecode :: String -> [(String, String)]
- urlDecode :: String -> String
- module Network.CGI.Compat
CGI monad
class Monad m => MonadCGI m Source #
The class of CGI monads. Most CGI actions can be run in any monad which is an instance of this class, which means that you can use your own monad transformers to add extra functionality.
The CGIT monad transformer.
MonadTrans CGIT Source # | |
MonadCatch m => MonadError SomeException (CGIT m) Source # | |
Monad m => Monad (CGIT m) Source # | |
(Functor m, Monad m) => Functor (CGIT m) Source # | |
(Applicative m, Monad m) => Applicative (CGIT m) Source # | |
MonadIO m => MonadIO (CGIT m) Source # | |
MonadThrow m => MonadThrow (CGIT m) Source # | |
MonadCatch m => MonadCatch (CGIT m) Source # | |
MonadMask m => MonadMask (CGIT m) Source # | |
Monad m => MonadCGI (CGIT m) Source # | |
The result of a CGI program.
runCGI :: MonadIO m => CGIT m CGIResult -> m () Source #
Run a CGI action. Typically called by the main function. Reads input from stdin and writes to stdout. Gets CGI environment variables from the program environment.
Error handling
throwCGI :: (MonadCGI m, MonadThrow m) => SomeException -> m a Source #
Throw an exception in a CGI monad. The monad is required to be
a MonadThrow
, so that we can use throwM
to guarantee ordering.
catchCGI :: (MonadCGI m, MonadCatch m) => m a -> (SomeException -> m a) -> m a Source #
Catches any expection thrown by a CGI action, and uses the given exception handler if an exception is thrown.
tryCGI :: (Functor m, MonadCGI m, MonadCatch m) => m a -> m (Either SomeException a) Source #
Catches any exception thrown by an CGI action, and returns either the exception, or if no exception was raised, the result of the action.
handleExceptionCGI :: (MonadCGI m, MonadCatch m) => m a -> (SomeException -> m a) -> m a Source #
handleErrors :: (MonadCGI m, MonadCatch m, MonadIO m) => m CGIResult -> m CGIResult Source #
Catches any exception thrown by the given CGI action, returns an error page with a 500 Internal Server Error, showing the exception information, and logs the error.
Typical usage:
cgiMain :: CGI CGIResult cgiMain = ... main :: IO () main = runCGI (handleErrors cgiMain)
Logging
logCGI :: MonadIO m => String -> m () Source #
Logs some message using the server's logging facility. FIXME: does this have to be more general to support FastCGI etc? Maybe we should store log messages in the CGIState?
Output
:: MonadCGI m | |
=> ByteString | The string to output. |
-> m CGIResult |
Output a ByteString
. The output is assumed to be text/html,
encoded using ISO-8859-1. To change this, set the
Content-type header using setHeader
.
outputNothing :: MonadCGI m => m CGIResult Source #
Do not output anything (except headers).
Redirect to some location.
Add a response header. Example:
setHeader "Content-type" "text/plain"
Set the HTTP response status.
Error pages
:: (MonadCGI m, MonadIO m) | |
=> Int | HTTP Status code |
-> String | Status message |
-> [String] | Error information |
-> m CGIResult |
Output an error page to the user, with the given
HTTP status code in the response. Also logs the error information
using logCGI
.
outputException :: (MonadCGI m, MonadIO m) => SomeException -> m CGIResult Source #
Output a 500 Internal Server Error with information from
an Exception
.
Use outputError
to output and log a 404 Not Found error.
outputMethodNotAllowed Source #
Use outputError
to output and log a 405 Method Not Allowed error.
outputInternalServerError Source #
Use outputError
to output and log a 500 Internal Server Error.
Input
:: MonadCGI m | |
=> String | The name of the variable. |
-> m (Maybe String) | The value of the variable, or Nothing, if it was not set. |
Get the value of an input variable, for example from a form. If the variable has multiple values, the first one is returned. Example:
query <- getInput "query"
:: MonadCGI m | |
=> String | The name of the variable. |
-> m (Maybe ByteString) | The value of the variable, or Nothing, if it was not set. |
Like getInput
, but returns a ByteString
.
:: (Read a, MonadCGI m) | |
=> String | The name of the variable. |
-> m (Maybe a) |
|
Same as getInput
, but tries to read the value to the desired type.
getBodyFPS :: MonadCGI m => m ByteString Source #
Get the uninterpreted request body as lazy ByteString
getInputs :: MonadCGI m => m [(String, String)] Source #
Get the names and values of all inputs. Note: the same name may occur more than once in the output, if there are several values for the name.
getInputsFPS :: MonadCGI m => m [(String, ByteString)] Source #
Get the names and values of all inputs. Note: the same name may occur more than once in the output, if there are several values for the name.
getInputNames :: MonadCGI m => m [String] Source #
Get the names of all input variables.
:: MonadCGI m | |
=> String | The name of the variable. |
-> m [String] | The values of the variable, or the empty list if the variable was not set. |
Get all the values of an input variable, for example from a form. This can be used to get all the values from form controls which allow multiple values to be selected. Example:
vals <- getMultiInput "my_checkboxes"
:: MonadCGI m | |
=> String | The name of the variable. |
-> m [ByteString] | The values of the variable, or the empty list if the variable was not set. |
Same as getMultiInput
but using ByteString
s.
:: MonadCGI m | |
=> String | The name of the variable. |
-> m (Maybe String) | The file name corresponding to the input, if there is one. |
Get the file name of an input.
:: MonadCGI m | |
=> String | The name of the variable. |
-> m (Maybe String) | The content type, formatted as a string. |
Get the content-type of an input, if the input exists, e.g. "image/jpeg".
For non-file inputs, this function returns "text/plain".
You can use parseContentType
to get a structured
representation of the the content-type value.
Environment
Get the value of a CGI environment variable. Example:
remoteAddr <- getVar "REMOTE_ADDR"
getVars :: MonadCGI m => m [(String, String)] Source #
Get all CGI environment variables and their values.
Request information
serverName :: MonadCGI m => m String Source #
The server's hostname, DNS alias, or IP address as it would appear in self-referencing URLs.
serverPort :: MonadCGI m => m Int Source #
The port number to which the request was sent.
requestMethod :: MonadCGI m => m String Source #
The method with which the request was made. For HTTP, this is "GET", "HEAD", "POST", etc.
pathInfo :: MonadCGI m => m String Source #
The extra path information, as given by the client.
This is any part of the request path that follows the
CGI program path.
If the string returned by this function is not empty,
it is guaranteed to start with a '/'
.
Note that this function returns an unencoded string.
Make sure to percent-encode any characters
that are not allowed in URI paths before using the result of
this function to construct a URI.
See progURI
, queryURI
and requestURI
for a higher-level
interface.
pathTranslated :: MonadCGI m => m String Source #
The path returned by pathInfo
, but with virtual-to-physical
mapping applied to it.
scriptName :: MonadCGI m => m String Source #
A virtual path to the script being executed, used for self-referencing URIs.
Note that this function returns an unencoded string.
Make sure to percent-encode any characters
that are not allowed in URI paths before using the result of
this function to construct a URI.
See progURI
, queryURI
and requestURI
for a higher-level
interface.
queryString :: MonadCGI m => m String Source #
The information which follows the ? in the URL which referenced
this program. This is the percent-encoded query information.
For most normal uses, getInput
and friends are probably
more convenient.
remoteHost :: MonadCGI m => m (Maybe String) Source #
The hostname making the request. If the server does not have
this information, Nothing is returned. See also remoteAddr
.
remoteAddr :: MonadCGI m => m String Source #
The IP address of the remote host making the request.
authType :: MonadCGI m => m (Maybe String) Source #
If the server supports user authentication, and the script is protected, this is the protocol-specific authentication method used to validate the user.
remoteUser :: MonadCGI m => m (Maybe String) Source #
If the server supports user authentication, and the script is protected, this is the username they have authenticated as.
requestContentType :: MonadCGI m => m (Maybe String) Source #
For queries which have attached information, such as
HTTP POST and PUT, this is the content type of the data.
You can use parseContentType
to get a structured
representation of the the content-type value.
requestContentLength :: MonadCGI m => m (Maybe Int) Source #
For queries which have attached information, such as HTTP POST and PUT, this is the length of the content given by the client.
requestHeader :: MonadCGI m => String -> m (Maybe String) Source #
Gets the value of the request header with the given name. The header name is case-insensitive. Example:
requestHeader "User-Agent"
Program and request URI
progURI :: MonadCGI m => m URI Source #
Attempts to reconstruct the absolute URI of this program.
This does not include
any extra path information or query parameters. See
queryURI
for that.
If the server is rewriting request URIs, this URI can
be different from the one requested by the client.
See also requestURI
.
Characters in the components of the returned URI are escaped when needed, as required by Network.URI.
queryURI :: MonadCGI m => m URI Source #
Like progURI
, but the returned URI
also includes
any extra path information, and any query parameters.
If the server is rewriting request URIs, this URI can
be different from the one requested by the client.
See also requestURI
.
Characters in the components of the returned URI are escaped when needed, as required by Network.URI.
requestURI :: MonadCGI m => m URI Source #
Attempts to reconstruct the absolute URI requested by the client,
including extra path information and query parameters.
If no request URI rewriting is done, or if the web server does not
provide the information needed to reconstruct the request URI,
this function returns the same value as queryURI
.
Characters in the components of the returned URI are escaped when needed, as required by Network.URI.
Content negotiation
class Eq a => Acceptable a Source #
includes, top
Show a => Show (Accept a) Source # | |
HeaderValue a => HeaderValue (Accept a) Source # | |
newtype ContentEncoding Source #
requestAccept :: MonadCGI m => m (Maybe (Accept ContentType)) Source #
requestAcceptEncoding :: MonadCGI m => m (Maybe (Accept ContentEncoding)) Source #
Content type
data ContentType :: * #
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.
ContentType | |
|
showContentType :: ContentType -> String #
parseContentType :: Monad m => String -> m ContentType #
Parse the standard representation of a content-type.
If the input cannot be parsed, this function calls
fail
with a (hopefully) informative error message.
Cookies
Contains all information about a cookie set by the server.
Cookie | |
|
Construct a cookie with only name and value set. This client will expire when the browser sessions ends, will only be sent to the server and path which set it and may be sent using any means.
:: MonadCGI m | |
=> String | The name of the cookie. |
-> m (Maybe String) |
|
Get the value of a cookie.
:: (Read a, MonadCGI m) | |
=> String | The name of the cookie. |
-> m (Maybe a) |
|
Same as getCookie
, but tries to read the value to the desired type.
deleteCookie :: MonadCGI m => Cookie -> m () Source #
Delete a cookie from the client
URL encoding
formEncode :: [(String, String)] -> String Source #
Formats name-value pairs as application/x-www-form-urlencoded.
urlEncode :: String -> String Source #
Converts a single value to the application/x-www-form-urlencoded encoding.
formDecode :: String -> [(String, String)] Source #
Gets the name-value pairs from application/x-www-form-urlencoded data.
urlDecode :: String -> String Source #
Converts a single value from the application/x-www-form-urlencoded encoding.
Compatibility with the old API
module Network.CGI.Compat