!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                                                                                                         !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~&Safe09:;<=DRT  None09:;<=DRT+Semantically equivalent to break on strings= behaves like breakChar, but from the end of the ByteString. 2breakCharEnd ('b') (pack "aabbcc") == ("aab","cc")!and the following are equivalent: ibreakCharEnd 'c' "abcdef" let (x,y) = break (=='c') (reverse "abcdef") in (reverse (drop 1 y), reverse x)  None09:;<=DRT 3Convenience class for converting data types to URIs)Retrieves the path component from the URI*Retrieves the query component from the URI +Retrieves the scheme component from the URI DModifies the scheme component of the URI using the provided function BModifies the path component of the URI using the provided function $Sets the scheme component of the URI "Sets the path component of the URIpercent decode a Stringe.g. "hello%2Fworld" ->  "hello/world"#Returns true if the URI is absolute.Render should be used for prettyprinting URIs.8Parses a URI from a String. Returns Nothing on failure.    Safe09:;<=DRTA timeout manager(!terminate all threads immediately !"#$%&'(  !"#$%&'(  !"#$%&'(  !"#$%&'(None09:;<=DRT)TimeoutIO is a record which abstracts out all the network IO functions needed by the request handling loop. This allows use to use the same event loop for handle both http:/ and https:/. )*+,-./012 )*+,-./012 )*+,-./012) *+,-./012None09:;<=DRT3456Connected socket Data received789345678934567893456789None09:;<=DRTNone09:;<=DRT:Converts a HostAddress to a String in dot-decimal notation5Converts a IPv6 HostAddress6 to standard hex notation:Dalternative implementation of accept to work around EAI_AGAIN errors:;:;:;:;i(c) Peter Thiemann 2001,2002 (c) Bjorn Bringert 2005-2006 (c) Lemmih 2007 BSD-style lemmih@vo.com experimentalportableSafe09:;<=DRT < A MIME media type value. The + instance is derived automatically. Use 9 to obtain the standard string representation. See  #http://www.ietf.org/rfc/rfc2046.txt0 for more information about MIME media types.>The top-level media type, the general type of the data. Common examples are "text", "image", "audio", "video", "multipart", and "application".?nThe media subtype, the specific data format. Examples include "plain", "html", "jpeg", "form-data", etc.@lMedia type parameters. On common example is the charset parameter for the "text" top-level type, e.g. ("charset","ISO-8859-1").fProduce the standard string representation of a content-type, e.g. "text/html; charset=ISO-8859-1".nParse the standard representation of a content-type. If the input cannot be parsed, this function calls . with a (hopefully) informative error message.RFC 822 LWSP-char"RFC 822 CRLF (but more permissive)One line)<=>?@<=>?@#<=>?@Safe09:;<=DRTABFormat the time as describe in the Apache combined log format. 3http://httpd.apache.org/docs/2.2/logs.html#combinedThe format is: [daymonthyear:hour:minute:second zone] day = 2*digit month = 3*letter year = 4*digit hour = 2*digit minute = 2*digit second = 2*digit zone = ( |  ) 4*digitBEFormat the request as describe in the Apache combined log format. 3http://httpd.apache.org/docs/2.2/logs.html#combinedThe format is: "%h - %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"" %h: This is the IP address of the client (remote host) which made the request to the server. %u: This is the userid of the person requesting the document as determined by HTTP authentication. %t: The time that the request was received. %r: The request line from the client is given in double quotes. %>s: This is the status code that the server sends back to the client. %b: The last part indicates the size of the object returned to the client, not including the response headers. %{Referer}: The RefererO (sic) HTTP request header. %{User-agent}: The User-Agent HTTP request header.ABABABAB Safe09:;<=DRT !None09:;<=DRT         None09:;<=DRT C!Specify the lifetime of a cookie.|Note that we always set the max-age and expires headers because internet explorer does not honor max-age. You can specific E or FZ and the other will be calculated for you. Choose which ever one makes your life easiest.D/session cookie - expires when browser is closedElife time of cookie in secondsFcookie expiration dateGcookie already expiredH/a type for HTTP cookies. Usually created using R.RqCreates a cookie with a default version of 1, empty domain, a path of "/", secure == False and httpOnly == False see also:  addCookieSSet 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 ' '.Also, it seems that chrome, safari, and other webkit browsers do not like cookies which have double quotes around the domain and reject/ignore the cookie. So, we no longer quote the domain.[internet explorer does not honor the max-age directive so we set both max-age and expires.See C and QJ for a convenient way of calculating the first argument to this function.TuNot an supported api. Takes a cookie header and returns either a String error message or an array of parsed cookiesU3not a supported api. A parser for RFC 2109 cookiesVGet 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.WGet 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.CDEFGHIJKLMNOPQR cookie name cookie valueSTUVWXYCDEFGHINJKLMOPQRSTUVWXYHIJKLMNOPCDEFGQRSVWXYTU CDEFGHIJKLMNOPQRSTUVWXYNone09:;<=DORTNbCEscape from the HTTP world and get direct access to the underlying ) functionsdThis class is used by ) to parse a path component into a value. The instances for number types (,  , etc) use  to parse the path component.The instance for <, on the other hand, returns the unmodified path component.gSee the following section of the Happstack Crash Course for detailed instructions using and extending d: Fhttp://www.happstack.com/docs/crashcourse/RouteFilters.html#FromReqURIfThe body of an HTTP i8a class for working with types that contain HTTP headersian HTTP requestkrequest uses https://lrequest methodm%the uri, split on /, and then decodedn the raw rqUriothe QUERY_STRINGp+the QUERY_STRING decoded as key/value pairsq>the request body decoded as key/value pairs (when appropriate)rcookiess HTTP versiontthe HTTP request headersuthe raw, undecoded request bodyv1(hostname, port) of the client making the requestwan HTTP Responsefile handle to send fromoffset to start atnumber of bytes to sendhostname & porta value extract from the  QUERY_STRING or i bodyUIf the input value was a file, then it will be saved to a temporary file on disk and  will contain Left pathToTempFile. Result flagsA flag value set in the w which controls how the Content-Length? header is set, and whether *chunked* output encoding is used. see also: , notContentLength, and automatically add a Content-Length header to the w do not add a Content-Length header. Do use chunked output encoding do not set Content-Length or chunked output encoding.a Map of HTTP headers0the Map key is the header converted to lowercasean HTTP header header nameIheader value (or values if multiple occurances of the header are present)HTTP request methodHTTP configuration!Port for the server to listen on.,a function to validate the output on-the-fly+function to log access requests (see also: );number of seconds to wait before killing an inactive threadAThreadGroup for registering spawned threads for handling requests+function to log access requests (see also: ) type LogAccess time = ( String -- ^ host -> String -- ^ user -> time -- ^ time -> String -- ^ requestLine -> Int -- ^ responseCode -> Integer -- ^ size -> String -- ^ referer -> String -- ^ userAgent -> IO ()) HTTP version if i is HTTP version 1.1 if i is HTTP version 1.0Should the connection be used for further messages after this. isHTTP1_0 && hasKeepAlive || isHTTP1_1 && hasNotConnectionCloseIn addition to this rule All 1xx (informational), 204 (no content), and 304 (not modified) responses MUST NOT include a message-body and therefore are eligible for connection keep-alive.GDefault configuration contains no validator and the port is set to 8000Blog access requests using hslogger and apache-style log formatting see also: 'Does the method support a message body?%For extension methods, we assume yes.#Default RsFlags: automatically use Transfer-Encoding: Chunked.7Do not automatically add a Content-Length field to the waDo not automatically add a Content-Length header. Do automatically use Transfer-Encoding: ChunkedPAutomatically add a Content-Length header. Do not use Transfer-Encoding: ChunkedAget the request body from the Request and replace it with NothingVIMPORTANT: You can really only call this function once. Subsequent calls will return .read the request body inputscThis will only work if the body inputs have already been decoded. Otherwise it will return Nothing.CConverts a Request into a String representing the corresponding URLZSets the Response status code to the provided Int and lifts the computation into a Monad.gTakes a list of (key,val) pairs and converts it into Headers. The keys will be converted to lowercase-Lookup header value. Key is case-insensitive.:Lookup header value. Key is a case-insensitive bytestring.ILookup header value with a case-sensitive key. The key must be lowercase.CLookup header with a case-sensitive key. The key must be lowercase.]Returns True if the associated key is found in the Headers. The lookup is case insensitive.Acts as  with ByteStringsActs as < but the key is case sensitive. It should be in lowercase.OAssociates the key/value pair in the headers. Forces the key to be lowercase.Acts as  but with ByteStrings.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.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.(Acts as addHeader except for ByteStringsAdd 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.mCreates a Response with the given Int as the status code and the provided String as the body of the ResponseActs as % but works with ByteStrings directly.3By default, Transfer-Encoding: chunked will be usedOSets the Response's status code to the given Int and redirects to the given URI Location close  Connection!  Keep-AliveRead in any monad.'convert a 'ReadS a' result to 'Maybe a'bcdefgh"#ijklmnopqrstuvwxyz{|}~(hostname, port)$lowercased name -> (realname, value)$% !n<=>?@bcdefghijmntvsklopqruwxy|z}{~rijklmnopqrstuvwxyz{|}~z{|~fgh<=>?@debcTbcdefgh"#i jklmnopqrstuvwxyz{|}~z{|~ $% ! None09:;<=DRT headers bodysimilar to the normal &c function, except the predicate gets the whole rest of the lazy bytestring, not just one character.*TODO: this function has not been profiled.1Packs a string into an Input of type "text/plain"'The default content-type for variables.WCheck whether a string starts with two dashes followed by the given boundary string./Checks whether a string starts with two dashes.]Split a string at the first CRLF. The CRLF is not included in any of the returned strings.%tempdirquotafilename of fieldcontent to save'truncated?, saved bytes, saved filename     (The boundary, without the initial dashesString to split.Returns  if there is no CRLF.%     %           None09:;<=DRT #see *&)maximum bytes for files uploaded in this i'-maximum bytes for all non-file values in the i body()maximum bytes of overhead for headers in multipart/form-data* create a # for use with decodeBody,bDecodes application/x-www-form-urlencoded inputs. TODO: should any of the [] be error conditions?-bDecodes application/x-www-form-urlencoded inputs. TODO: should any of the [] be error conditions?/"Decodes multipart/form-data input.0&Get the path components from a String.1IRepeadly splits a list by the provided separator and collects the results21Repeatedly splits a list and collects the results39Split is like break, but the matching element is dropped.#$%&'()*$temporary directory for file uploads)maximum bytes for files uploaded in this i-maximum bytes for all non-file values in the i body)maximum bytes of overhead for headers in multipart/form-data+,-./Content-type parameters Request bodyInput variables and values.0123 #$&'(%)*+,-./0123)#$%&'(*+,-./0123 #$%&'()*+,-./0123"None09:;<=DRTi<=>?@defghijmntvsklopqruwxy|z}{~mijklmnopqrstuvwxyz{|}~z{|~fgh<=>?@de None09:;<=?DIORT44? provides a means to end the current computation and return a w immediately. This provides an alternate escape route. In particular it has a monadic value of any type. And unless you call ; '7 first your response filters will be applied normally.Extremely useful when you're deep inside a monad and decide that you want to return a completely different content type, since it doesn't force you to convert all your return types to w early just to accommodate this. see also: X and Y66! is almost exclusively used with P. If you are not using Py then you do not need to wrap your head around this type. If you are -- the type is not as complex as it first appears.1It is worth discussing the unpacked structure of 7 a bit as it's exposed in P and \.A fully unpacked 7! has a structure that looks like: HununWebT $ WebT m a :: m (Maybe (Either Response a, FilterFun Response)) So, ignoring m, as it is just the containing (, the outermost layer is a ) . This is  if * was called or + (, w a, B (- w)) if * wasn't called. Inside the )N, there is a pair. The second element of the pair is our filter function A w. A w is a type alias for B (. (- w))". This is just a wrapper for a w -> w function with a particular / 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.1Finally, the first element of the pair is either 0 w or 1 a.VAnother way of looking at all these pieces is from the behaviors they control. The ) controls the * behavior. C (- f) comes from the ; behavior. Likewise, D (- f) is from <. 0 w is what you get when you call 5 and 1 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 function7 The basic w building object.:,A set of functions for manipulating filters.H implements : w< so these methods are the fundamental ways of manipulating w values.;/Ignores all previous alterations to your filterAs an example: 9do composeFilter f setFilter g return "Hello World"The ; g will cause the first < f to be ignored.<AComposes your filter function with the existing filter function.=*Retrieves the filter from the environment.AA is a lot more fun to type than B (. (- a)).B"A monoid operation container. If a is a monoid, then B* 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 summarizing this is, if the right side is DB, then the right is appended to the left. If the right side is C , then the left side is ignored.EThe E> class provides methods for reading or locally modifying the i2. It is essentially a specialized version of the 2$ class. Providing the unique names, F and G makes it easier to use H and 3 together.HH1 is a rich, featureful monad for web development. see also:  simpleHTTP, E, :, 4, and  HasRqDataK An alias for H 4L An alias for 7 when using 4.M'Particularly useful when combined with runWebT to produce a m () w) from a i.N(function for lifting WebT to ServerPartTBNOTE: This is mostly for internal use. If you want to access the i in user-code see F from E. do request <- askRq ...OA constructor for a H' when you don't care about the request.NOTE: This is mostly for internal use. If you think you need to use it in your own code, you might consider asking on the mailing list or IRC to find out if there is an alternative solution.P2Apply a function to transform the inner monad of H m.*Often used when transforming a monad with H , since  simpleHTTP requires a H 4 a . Refer to 63 for an explanation of the structure of the monad.2Here is an example. Suppose you want to embed an 5 into your H to enable 6 and 7 in your (. 5type MyServerPartT e m a = ServerPartT (ErrorT e m) aNow suppose you want to pass  MyServerPartT! into a function that demands a H 4 a (e.g.  simpleHTTP"). You can provide the function: f unpackErrorT :: (Monad m, Show e) => UnWebT (ErrorT e m) a -> UnWebT m a unpackErrorT et = do eitherV <- runErrorT et return $ case eitherV of Left err -> Just (Left $ toResponse $ "Catastrophic failure " ++ show err , filterFun $ \r -> r{rsCode = 500}) Right x -> xWith  unpackErrorT you can now call  simpleHTTP. Just wrap your H list. R simpleHTTP nullConf $ mapServerPartT unpackErrorT (myPart `catchError` myHandler)Or alternatively: B simpleHTTP' unpackErrorT nullConf (myPart `catchError` myHandler) Also see #4 for a more sophisticated version of this function.Q A variant of P( where the first argument also takes a i. Useful if you want to M on a different H inside your monad (see spUnwrapErrorT).RImplementation of askRqEnv for arbitrary E.SImplementation of  localRqEnv for arbitrary E.TExtract the value from a B. Note that a B is actually a  CoPointed from:  hhttp://hackage.haskell.org/packages/archive/category-extras/latest/doc/html/Control-Functor-Pointed.html. But lets not drag in that dependency. yet...Vturn a function into a A. Primarily used with PW&Resets all your filters. An alias for ; '.XXUsed to ignore all your filters and immediately end the computation. A combination of W and 5.YAn alternate form of X, that can be easily used within a do block.Z%For when you really need to unpack a 75 entirely (and not just unwrap the first layer with 9).[For wrapping a 7 back up. [ . Z = '\See P# for a discussion of this function.]'This is kinda like a very oddly shaped P or \/. You probably want one or the other of those.^Deprecated: use 8._3What is this for, exactly? I don't understand why Show ap is even in the context Deprecated: This function appears to do nothing at all. If it use it, let us know why.y456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~2456789:<;=>?@ABDCEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdeyLKHIJMNOPQEFGRSBCDTAUV>?@:;<=W789645XYZ[\]^_`abcd~}|{zyxwvutsrqponmlkjihgfek456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ None09:;<=DRT will convert a value into a w body, set the  content-type2, and set the default response code for that type.happstack-server Example: 7main = simpleHTTP nullConf $ toResponse "hello, world!"will generate a w with the content-type  text/plain, the response code 200 OK, and the body:  hello, world!. simpleHTTP will call 1 automatically, so the above can be shortened to: ,main = simpleHTTP nullConf $ "hello, world!"happstack-lite Example: 1main = serve Nothing $ toResponse "hello, world!"Minimal definition:  (and usually ). A low-level function to build a w from a content-type and a  ByteString. Creates a w in a manner similar to the 7 class, but without requiring an instance declaration.example: import Data.ByteString.Char8 as C import Data.ByteString.Lazy.Char8 as L import Happstack.Server main = simpleHTTP nullConf $ ok $ toResponseBS (C.pack "text/plain") (L.pack "hello, world")(note: $% and 9@ only work for ascii. For unicode strings you would need to use  utf8-string, text), or something similar to create a valid  ByteString). alias for: fmap toResponseturns m a into m w using . >main = simpleHTTP nullConf $ flatten $ do return "flatten me." Honor an if-modified-since header in a i . If the i includes the if-modified-since header and the wN has not been modified, then return 304 (Not Modified), otherwise return the w.:Deprecated: use <..Set an arbitrary return code in your response.WA filter for setting the response code. Generally you will use a helper function like  or . mmain = simpleHTTP nullConf $ do setResponseCode 200 return "Everything is OK" see also: Same as  status >> return val.ZUse this if you want to set a response code that does not already have a helper function. 8main = simpleHTTP nullConf $ resp 200 "Everything is OK" Respond with 200 OK. 2main = simpleHTTP nullConf $ ok "Everything is OK" Respond with 204 No ContentA 204 No Contenta response may not contain a message-body. If you try to supply one, it will be dutifully ignored. >main = simpleHTTP nullConf $ noContent "This will be ignored." Respond with 301 Moved Permanently. |main = simpleHTTP nullConf $ movedPermanently "http://example.org/" "What you are looking for is now at http://example.org/" Respond with  302 Found.You probably want j. This method is not in popular use anymore, and is generally treated like 303 by most user-agents anyway. Respond with  303 See Other. tmain = simpleHTTP nullConf $ seeOther "http://example.org/" "What you are looking for is now at http://example.org/"NOTE: The second argument of T is the message body which will sent to the browser. According to the HTTP 1.1 spec, dthe entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).lThis is because pre-HTTP/1.1 user agents do not support 303. However, in practice you can probably just use "" as the second argument. Respond with 307 Temporary Redirect. main = simpleHTTP nullConf $ tempRedirect "http://example.org/" "What you are looking for is temporarily at http://example.org/" Respond with 400 Bad Request. 6main = simpleHTTP nullConf $ badRequest "Bad Request." Respond with 401 Unauthorized. Cmain = simpleHTTP nullConf $ unauthorized "You are not authorized." Respond with  403 Forbidden. @main = simpleHTTP nullConf $ forbidden "Sorry, it is forbidden." Respond with  404 Not Found. Tmain = simpleHTTP nullConf $ notFound "What you are looking for has not been found." Respond with 413 Request Entity Too Large. Umain = simpleHTTP nullConf $ requestEntityTooLarge "That's too big for me to handle." Respond with 500 Internal Server Error. ]main = simpleHTTP nullConf $ internalServerError "Sorry, there was an internal server error."Responds with 502 Bad Gateway. 6main = simpleHTTP nullConf $ badGateway "Bad Gateway.""A nicely formatted rendering of a w$ content-type response bodymod-time for the w> (MUST NOT be later than server's time of message origination)6incoming request (used to check for if-modified-since)+Response to send if there are modifications: response code response codevalue to return!: None09:;<=DRT<Set the validator which should be used for this particular w when validation is enabled.kCalling this function does not enable validation. That can only be done by enabling the validation in the  that is passed to  simpleHTTP.?You do not need to call this function if the validator set in  does what you want already.Example: (use % instead of the default supplied by ) FsimpleHTTP validateConf $ ok . setValidator noopValidator =<< htmlPage See also: , , , . ServerPart version of .Example: (Set validator to ) I simpleHTTP validateConf $ setValidatorSP noopValidator (dir "ajax" ... )Extend % by enabling validation and setting  as the default validator for  text/html.Example: 2simpleHTTP validateConf . anyRequest $ ok htmlPage%Actually perform the validation on a w.#Run the validator specified in the w7. If none is provide use the supplied default instead.LNote: This function will run validation unconditionally. You probably want  or . Validate  text/html content with WDG HTML Validator.1This function expects the executable to be named validate and it must be in the default PATH. See also: , , ."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. Validate the w using an external application.If the external application returns 0, the original response is returned unmodified. If the external application returns non-zero, a wO 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 requires the use of -threaded to avoid blocking. However, you probably need that for Happstack anyway. See also: .name of executable#arguments to pass to the executable"optional path to working directory(optional environment (otherwise inherit)content-type filterResponse to validateNone09:;<=DLRTSUnserializes the bytestring into a response. If there is an error it will return Left msg.*Serializes the request to the given handle%;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\%;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\None09:;<=DRTBind and listen port%Use a previously bind port and listen]?IP address to listen on (must be an IP address not a host name)port number to listen on]&None09:;<=DRTu<=>?@bcdefghijmntvsklopqruwxy|z}{~None09:;<=DRTAdd the H to w.example xmain = simpleHTTP nullConf $ do addCookie Session (mkCookie "name" "value") ok $ "You now have a session cookie." see also:  Add the list H to the w. see also: @Expire the named cookie immediately and set the cookie value to "" ^main = simpleHTTP nullConf $ do expireCookie "name" ok $ "The cookie has been expired."CDEFGHINJKLMOPRHIJKLMNOPCDEFGRNone09:;<=DIRT'Used by  and 0. Make your preferred data type an instance of  to use those functions.#A class for monads which contain a  lift some  into pAn applicative functor and monad for looking up key/value pairs in the QUERY_STRING, Request body, and cookies.~the environment used to lookup query parameters. It consists of the triple: (query string inputs, body inputs, cookie inputs)a list of errors^apply 'RqData a' to a  see also: , , , , , #transform the result of 'RqData a'.This is similar to _* except it also allows you to modify the  not just a.use ` to convert a  to a value of type a )look "key" `checkRq` (unsafeReadRq "key") use with NOTE: This function is marked unsafe because some Read instances are vulnerable to attacks that attempt to create an out of memory condition. For example: "read "1e10000000000000" :: Integer see also: use e to convert a  to a value of type a #look "key" `checkRq` (readRq "key") use with convert or validate a valueThis is similar to _u except that the function can fail by returning Left and an error message. The error will be propagated by calling .9This function is useful for a number of things including:  Parsing a  into another type]Checking that a value meets some requirements (for example, that is an Int between 1 and 10).Example usage at: ?http://happstack.com/docs/crashcourse/RqData.html#rqdatacheckrqlike & but the check function can be monadica similar to '(+ but returns all matches not just the first-Gets the first matching named input parameter7Searches the QUERY_STRING followed by the Request body. see also: .Gets all matches for the named input parameter7Searches the QUERY_STRING followed by the Request body. see also: 8Gets the first matching named input parameter as a lazy  ByteString7Searches the QUERY_STRING followed by the Request body. see also: 7Gets all matches for the named input parameter as lazy  ByteStrings7Searches the QUERY_STRING followed by the Request body. see also: 3Gets the first matching named input parameter as a 7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded.Example: lhandler :: ServerPart Response handler = do foo <- look "foo" ok $ toResponse $ "foo = " ++ foo see also: , , and 2Gets all matches for the named input parameter as s7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also:  and 8Gets the first matching named input parameter as a lazy b7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also: , , , , and :Gets the first matching named input parameter as a strict b7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also: , , , , and 7Gets all matches for the named input parameter as lazy bs7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also: ,  and 9Gets all matches for the named input parameter as strict bs7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also: ,  and :Gets the named cookie the cookie name is case insensitive!gets the named cookie as a string0gets the named cookie as the requested Read typeCGets the first matching named input parameter and decodes it using c7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also:   FGets all matches for the named input parameter and decodes them using c7Searches the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also:   "Gets the first matching named filejFiles can only appear in the request body. Additionally, the form must set enctype="multipart/form-data".,This function returns a tuple consisting of: +The temporary location of the uploaded file*The local filename supplied by the browser(The content-type supplied by the browserIf the user does not supply a file in the html form input field, the behaviour will depend upon the browser. Most browsers will send a 0-length file with an empty file name, so checking that (2) is not empty is usually sufficient to ensure the field has been filled.ENOTE: You must move the file from the temporary location before the wC is sent. The temporary files are automatically removed after the w is sent. 6gets all the input parameters, and converts them to a HThe results will contain the QUERY_STRING followed by the Request body.>This function assumes the underlying octets are UTF-8 encoded. see also:   gets all the input parametersHThe results will contain the QUERY_STRING followed by the Request body. see also:   The body of a i= is not received or decoded unless this function is invoked.7It is an error to try to use the look functions for a i& with out first calling this function.It is ok to call  # at the beginning of every request: umain = simpleHTTP nullConf $ do decodeBody (defaultBodyPolicy "/tmp/" 4096 4096 4096) handlers4You can achieve finer granularity quotas by calling  . with different values in different handlers.Only the first call to  e will have any effect. Calling it a second time, even with different quota values, will do nothing.run  in a E.Example: a simple GET or POSTD variable based authentication guard. It handles the request with  errorHandler if authentication fails. J data AuthCredentials = AuthCredentials { username :: String, password :: String } isValid :: AuthCredentials -> Bool isValid = const True myRqData :: RqData AuthCredentials myRqData = do username <- look "username" password <- look "password" return (AuthCredentials username password) checkAuth :: (String -> ServerPart Response) -> ServerPart Response checkAuth errorHandler = do d <- getDataFn myRqData case d of (Left e) -> errorHandler (unlines e) (Right a) | isValid a -> mzero (Right a) | otherwise -> errorHandler "invalid"NOTE: you must call  P prior to calling this function if the request method is POST, PUT, PATCH, etc. similar to /, except it calls a sub-handler on success or * on failure.NOTE: you must call  P prior to calling this function if the request method is POST, PUT, PATCH, etc. A variant of  that uses  to chose your  for you. The example from  becomes:  data AuthCredentials = AuthCredentials { username :: String, password :: String } isValid :: AuthCredentials -> Bool isValid = const True myRqData :: RqData AuthCredentials myRqData = do username <- look "username" password <- look "password" return (AuthCredentials username password) instance FromData AuthCredentials where fromData = myRqData checkAuth :: (String -> ServerPart Response) -> ServerPart Response checkAuth errorHandler = do d <- getData case d of (Left e) -> errorHandler (unlines e) (Right a) | isValid a -> mzero (Right a) | otherwise -> errorHandler "invalid"NOTE: you must call  P prior to calling this function if the request method is POST, PUT, PATCH, etc. similar to , except it calls a subhandler on success or * on failure.NOTE: you must call  P prior to calling this function if the request method is POST, PUT, PATCH, etc.#limit the scope to the Request body qhandler :: ServerPart Response handler = do foo <- body $ look "foo" ok $ toResponse $ "foo = " ++ foo#limit the scope to the QUERY_STRING xhandler :: ServerPart Response handler = do foo <- queryString $ look "foo" ok $ toResponse $ "foo = " ++ foolimit the scope to s which produce a  ByteString (aka, not a file)Hdefghij^+name of key (only used for error reporting) to `0 on error, 1 on success+name of key (only used for error reporting) to `0 on error, 1 on successak  !name of input field to search for;(temporary file location, uploaded file name, content-type)    monad to evaluatereturn 0 errors or 1 a !"#$%&'(1#$&'(%*     1     #$%&'(*>defghij^ak      !"#$%&'(None09:;<=DRT7CA class alias for all the classes a standard server monad (such as Hs) is expected to have instances for. This allows you to keep your type signatures shorter and easier to understand.8 Get a header out of the request.9uAdd headers into the response. This method does not overwrite any existing header of the same name, hence the name 9'. If you want to replace a header use :.:^Set a header into the response. This will replace an existing header of the same name. Use 9; if you want to add more than one header of the same name.;Set a far-future Expires header. Useful for static resources. If the browser has the resource cached, no extra request is spent.<Run an 4 action and, if it returns +", pass it to the second argument.=9A variant of require that can run in any monad, not just 4.789:;<=>?@ABCDEFG456:<;=EFGHKPQVWXYe789:;<=HK7EFGPQ6V:;<=W98:;45XY<=e789:;<=>?@ABCDEFGNone09:;<=DRTHFlatten H (5 e m) a into a H m a so that it can be use with  simpleHTTP. Used with mapServerPartT', e.g., fsimpleHTTP conf $ mapServerPartT' (spUnWrapErrorT simpleErrorHandler) $ myPart `catchError` errorPartNote that in this example, simpleErrorHandler will only be run if  errorPart" throws an error. You can replace simpleErrorHandler$ with your own custom error handler. see also: II.A simple error handler which can be used with H.It returns the error message as a plain text message to the browser. More sophisticated behaviour can be achieved by calling your own custom error handler instead. see also: HJThis  ServerPart modifier enables the use of  throwError and  catchError inside the 7 actions, by adding the 5! monad transformer to the stack.-You can wrap the complete second argument to  simpleHTTP in this function.DEPRECATED: use H instead.HIJHIJHIJHIJNone09:;<=DORT Ksee qRa l& from file extensions to content-typesexample: QmyMimeMap :: MimeMap myMimeMap = Map.fromList [("gz","application/x-gzip"), ... ] see also: sS>try to guess the content-type of a file based on its extension see also: TT>try to guess the content-type of a file based on its extension=defaults to "application/octet-stream" if no match was found.Useful as an argument to a see also: S, aU9returns a specific content type, completely ignoring the m argument.Use this with a5 if you want to explicitly specify the content-type. see also: T, aV,a list of common index files. Specifically:  index.html,  index.xml,  index.gif!Typically used as an argument to  serveDiretory.W*return a simple "File not found 404 page."n Similar to o2 but does not include the extension separator charXPrevents files of the form '.foo' or  'bar/.foo' from being servedYReturns 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.Z-Use sendFile to send the contents of a Handle[&Send the contents of a Lazy ByteString\&Send the contents of a Lazy ByteString]ESend the specified file with the specified mime-type using sendFile()=NOTE: assumes file exists and is readable by the server. See `.*WARNING: No security checks are performed.^KSend the specified file with the specified mime-type using lazy ByteStrings=NOTE: assumes file exists and is readable by the server. See `.*WARNING: No security checks are performed._MSend the specified file with the specified mime-type using strict ByteStrings=NOTE: assumes file exists and is readable by the server. See `.*WARNING: No security checks are performed.`Serve a single, specified file. The name of the file being served is specified explicity. It is not derived automatically from the i url. example 1:5Serve using sendfile() and the specified content-type RserveFileUsing filePathSendFile (asContentType "image/jpeg") "/srv/data/image.jpg" example 2:OServe using a lazy ByteString and the guess the content-type from the extension OserveFileUsing filePathLazy (guessContentTypeM mimeTypes) "/srv/data/image.jpg"*WARNING: No security checks are performed.aServe a single, specified file. The name of the file being served is specified explicity. It is not derived automatically from the i url. example 1:!Serve as a specific content-type: <serveFile (asContentType "image/jpeg") "/srv/data/image.jpg" example 2:3Serve guessing the content-type from the extension: =serveFile (guessContentTypeM mimeTypes) "/srv/data/image.jpg"QIf the specified path does not exist or is not a file, this function will return *.*WARNING: No security checks are performed.NOTE: alias for ` ]bLike a , but uses d[ to prevent directory traversal attacks when the path to the file is supplied by the user.cMServe files from a directory and its subdirectories (parameterizable version)5Parameterize this function to create functions like, f, g, and h You supply: 4a low-level function which takes a content-type and m and generates a Response6a function which determines the content-type from the m%a list of all the default index filesANOTE: unlike fileServe, there are no index files by default. See V.d Combine two mFs, ensuring that the resulting path leads to a file within the first m.(combineSafe "/var/uploads/" "etc/passwd"Just "/var/uploads/etc/passwd")combineSafe "/var/uploads/" "/etc/passwd"Nothing.combineSafe "/var/uploads/" "../../etc/passwd"Nothing;combineSafe "/var/uploads/" "../uploads/home/../etc/passwd"Just "/var/uploads/etc/passwd"f:Serve files from a directory and its subdirectories using sendFile.Usage: 0fileServe ["index.html"] "path/to/files/on/disk"f* does not support directory browsing. See qDEPRECATED: use q instead.Note:The list of index files ["index.html"] is only used to determine what file to show if the user requests a directory. You *do not* need to explicitly list all the files you want to serve.gNServe files from a directory and its subdirectories (lazy ByteString version).8WARNING: May leak file handles. You should probably use f instead.hPServe files from a directory and its subdirectories (strict ByteString version).\WARNING: the entire file will be read into RAM before being served. You should probably use f instead.iattempt to serve index filesm1try to find an index file, calls mzero on failureoSa function to generate an HTML page showing the contents of a directory on the disk see also: n, ppTa function to generate an HTML table showing the contents of a directory on the disk4This function generates most of the content of the o page. If you want to style the page differently, or add google analytics code, etc, you can just create a new page template to wrap around this HTML. see also: p, op,look up the meta data associated with a fileqJServe files and directories from a directory and its subdirectories using sendFile.Usage: DserveDirectory EnableBrowsing ["index.html"] "path/to/files/on/disk"LIf the requested path does not match a file or directory on the disk, then q calls *.AIf the requested path is a file then the file is served normally.sIf the requested path is a directory, then the result depends on what the first two arguments to the function are.CThe first argument controls whether directory browsing is enabled.CThe second argument is a list of index files (such as index.html).When a directory is requested, q will first try to find one of the index files (in the order they are listed). If that fails, it will show a directory listing if L# is set, otherwise it will return %forbidden "Directory index forbidden".`Here is an explicit list of all the possible outcomes when the argument is a (valid) directory: M, empty index file list>This will always return, forbidden "Directory index forbidden" M, non-empty index file list +If an index file is found it will be shown.8Otherwise returns, forbidden "Directory index forbidden" L, empty index file listAlways shows a directory index. L, non-empty index file list *If an index file is found it will be shown!Otherwise shows a directory index see also: V, arlike q but with custom mimeTypessReady collection of common mime types. Except for the first two entries, the mappings come from an Ubuntu 8.04 /etc/mime.types file.,KLMNOPQRSTUthe content-type to returnVWnXYZcontent-type stringfile path for content to sendmod-time for the handle (MUST NOT be later than server's time of message origination), incoming request (used to check for if-modified-since header)offset into Handlenumber of bytes to send[content-type string (e.g. "text/plain; charset=utf-8")lazy bytestring content to sendZmod-time for the bytestring, incoming request (used to check for if-modified-since header)offset into the bytestringcnumber of bytes to send (offset + count must be less than or equal to the length of the bytestring)\content-type string (e.g. "text/plain; charset=utf-8")lazy bytestring content to sendZmod-time for the bytestring, incoming request (used to check for if-modified-since header)offset into the bytestringcnumber of bytes to send (offset + count must be less than or equal to the length of the bytestring)]content-type stringpath to file on disk^content-type stringpath to file on disk_content-type stringpath to file on disk` typically ], ^, or _9function for determining content-type of file. Typically U or Tpath to the file to servea9function for determining content-type of file. Typically U or Tpath to the file to serveb0directory wherein served files must be contained9function for determining content-type of file. Typically U or Tpath to the file to servecUfunction which takes a content-type and filepath and generates a response (typically ], ^, or _)function which returns the mime-type for FilePath -> [FilePath] -- ^ index file names, in case the requested path is a directoryfile/directory to servedeqf;index file names, in case the requested path is a directoryfile/directory to serveg;index file names, in case the requested path is a directoryfile/directory to serveh:index file names, in case the next argument is a directoryfile/directory to servei$list of possible index files (e.g.,  index.html) see also s+directory on disk to search for index filesjklmusually ])function to calculate mime type, usually Tlist of index files. See also Vdirectory to search innopath to directory on disklist of entries in that pathplist of files+meta data, see pp.path to directory on disk containing the entryentry in that directoryqallow directory browsing;index file names, in case the requested path is a directoryfile/directory to serverallow directory browsing;index file names, in case the requested path is a directory1function which returns the mime-type for FilePathfile/directory to serves)KLMNPOQRSTUVWXYZ[\]^_`abcdefghijklmnopqrs)fcghKLMqrab`Z[\]^_RsUSTNOPQnopXVdemiljkWY'KLMNOPQRSTUVWnXYZ[\]^_`abcdeqfghijklmnoppqrs)None09:;<=DRT KLMRTUVabfqs KLMqabRsUTVfNone09:;<=DRTBinstances of this class provide a variety of ways to match on the i method. Examples: >method GET -- match GET or HEAD method [GET, POST] -- match GET, HEAD or POST method HEAD -- match HEAD /but not/ GET method (== GET) -- match GET or HEAD method (not . (==) DELETE) -- match any method except DELETE method () -- match any methodAs you can see, GET implies that HEAD should match as well. This is to make it harder to write an application that uses HTTP incorrectly. Happstack handles HEAD requests automatically, but we still need to make sure our handlers don't mismatch or a HEAD will result in a 404.MIf you must, you can still do something like this to match GET without HEAD: guardRq ((== GET) . rqMethod))Guard using an arbitrary function on the i.Cguard which checks that an insecure connection was made via http://Example: ?handler :: ServerPart Response handler = do http ...Aguard which checks that a secure connection was made via https://Example: @handler :: ServerPart Response handler = do https ...-Guard against the method only (as opposed to ).Example: Qhandler :: ServerPart Response handler = do methodOnly [GET, HEAD] ...`Guard against the method. This function also guards against *any remaining path segments*. See - for the version that guards only by method.Example: Nhandler :: ServerPart Response handler = do methodM [GET, HEAD] ...eNOTE: This function is largely retained for backwards compatibility. The fact that implicitly calls P is often forgotten and leads to confusion. It is probably better to just use  and call  explicitly.6This function will likely be deprecated in the future.-Guard against the method only (as opposed to ).Example: Qhandler :: ServerPart Response handler = do methodOnly [GET, HEAD] ...kGuard against the method. Note, this function also guards against any remaining path segments. Similar to % but with a different type signature.Example: Jhandler :: ServerPart Response handler = methodSP [GET, HEAD] $ subHandlerbNOTE: This style of combinator is going to be deprecated in the future. It is better to just use . Thandler :: ServerPart Response handler = method [GET, HEAD] >> nullDir >> subHandlerAguard which only succeeds if there are no remaining path segments8Often used if you want to explicitly assign a route for rPPop a path element and run the supplied handler if it matches the given string. Khandler :: ServerPart Response handler = dir "foo" $ dir "bar" $ subHandler/The path element can not contain '/'. See also .Guard against a m . Unlike  the mh may contain '/'. If the guard succeeds, the matched elements will be popped from the directory stack. dirs "foo/bar" $ ... See also: .Guard against the host.This matches against the host" header specified in the incoming i.(Can be used to support virtual hosting, ,http://en.wikipedia.org/wiki/Virtual_hosting0Note that this matches against the value of the Host* header which may include the port number. ?http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23 see also:  Lookup the host; header in the incoming request and pass it to the handler. see also: *Pop a path element and parse it using the e in the d class.GGrab the rest of the URL (dirs + query) and passes it to your handler.)Pop any path element and run the handler.OSucceeds if a path component was popped. Fails is the remaining path was empty.0Guard which checks that the Request URI ends in '/'&. Useful for distinguishing between foo and foo/The opposite of .None09:;<=DRTmSends the serialized request to the host defined in the request and attempts to parse response upon arrival.None09:;<=DRTB is for creating a part that acts as a proxy. The sole argument [] is a list of allowed domains for proxying. This matches the domain part of the request and the wildcard * can be used. E.g."*" to match anything.3"*.example.com" to match anything under example.com'"example.com" to match just example.com6TODO: annoyingly enough, this method eventually calls escapeQ, so any headers you set won't be used, and the computation immediately ends. Take a proxy i and create a w*. Your basic proxy building block. See .2TODO: this would be more useful if it didn't call escapeN (e.g. it let you modify the response afterwards, or set additional headers)-This is a reverse proxy implementation. See .2TODO: this would be more useful if it didn't call escape , just like . defaultHost8map to look up hostname mappings. For the reverse proxythe result is a  ServerPartT! that will reverse proxy for you.None09:;<=DRT)A simple HTTP basic authentication guard.-If authentication fails, this part will call *.example: main = simpleHTTP nullConf $ msum [ basicAuth "127.0.0.1" (fromList [("happstack","rocks")]) $ ok "You are in the secret club" , ok "You are not in the secret club." ]the realm namethe username password mapthe part to guard*(c) Happstack.com 2010; (c) HAppS Inc 2007BSD-like'Happstack team <happs@googlegroups.com> provisional requires mtlNone09:;<=?DIRT s An array of t6, useful for processing command line options into an  for ."Parse command line options into a .:start the server, and handle requests using the supplied K.@This function will not return, though it may throw an exception.LNOTE: The server will only listen on IPv4 due to portability issues in the Network module. For IPv6 support, use  with custom socket.A combination of  and P. See P: for a discussion of the first argument of this function.vNOTE: This function always binds to IPv4 ports until Network module is fixed to support IPv6 in a portable way. Use 5 with custom socket if you want different behaviour.Generate a result from a H and a i6. This is mainly used by CGI (and fast-cgi) wrappers.Run r 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 implKNote: It's important to use the same conf (or at least the same port) for  and . see also: , Like  with a socket.-Bind port and return the socket for use with m. This function always binds to IPv4 ports until Network module is fixed to support IPv6 in a portable way.7Bind to ip and port and return the socket for use with .  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)u Takes your 7 , if it is v it returns " else it converts the value to a w and applies your filter to it.MWait for a signal. On unix, a signal is sigINT or sigTERM (aka Control-C).&On windows, the signal is entering: e return sAIP address to bind to (must be an IP address and not a host name)port number to bind touw <=>?@CDEFGHINJKLMOPRdefghijmntvsklopqruwxy|z}{~#$&'(%*456:<;=EFGHKPQVWXYe     789:;<=HIJ  suwNone09:;<=DRT  reads the Accept-EncodingJ header. Then, if possible will compress the response body with methods gzip or deflate.This function uses [. If you want to provide alternative handers (perhaps to change compression levels), see  main = simpleHTTP nullConf $ do str <- compressedResponseFilter return $ toResponse ("This response compressed using: " ++ str) reads the Accept-Encoding_ header. Then, if possible will compress the response body using one of the supplied filters.6A filter function takes two arguments. The first is a # with the value to be used as the 'Content-Encoding' header. The second is xF which indicates if the compression filter is allowed to fallback to identity.wThis is important if the resource being sent using sendfile, since sendfile does not provide a compression option. If identityM is allowed, then the file can be sent uncompressed using sendfile. But if identity@ is not allowed, then the filter will need to return error 406.'You should probably always include the identity and * encodings as acceptable. pmyFilters :: (FilterMonad Response m) => [(String, String -> Bool -> m ()] myFilters = [ ("gzip" , gzipFilter) , ("identity", identityFilter) , ("*" , starFilter) ] main = simpleHTTP nullConf $ do let filters = str <- compressedResponseFilter' return $ toResponse ("This response compressed using: " ++ str) Ignore the Accept-Encoding header in the i7 and attempt to compress the body of the response with gzip.calls  using y. see also:  Ignore the Accept-Encoding header in the i< and attempt compress the body of the response with zlib's deflate methodcalls  using z. see also: >compression filter for the identity encoding (aka, do nothing) see also: %compression filter for the * encodingThis filter always fails. Ignore the Accept-Encoding header in the iP and attempt to compress the body of the response using the supplied compressor.1We can not compress files being transfered using y. If identity. is an allowed encoding, then just return the w" unmodified. Otherwise we return 406 Not Acceptable. see also: , , , , {0based on the rules describe in rfc2616 sec. 14.3Jan assoc list of encodings and their corresponding compression functions.e.g. F[("gzip", gzipFilter), ("identity", identityFilter), ("*",starFilter)]'a parser for the Accept-Encoding header name of the encoding chosencompression filter assoc listname of the encoding chosen+encoding to use for Content-Encoding header!fallback to identity for SendFile+encoding to use for Content-Encoding header!fallback to identity for SendFile+encoding to use for Content-Encoding header>fallback to identity for SendFile (irrelavant for this filter)+encoding to use for Content-Encoding header>fallback to identity for SendFile (irrelavant for this filter)function to compress the body+encoding to use for Content-Encoding header!fallback to identity for SendFile{|}   {|}*None09:;<=DRTNone09:;<=DRT parse the 'Accept-Language' header, or [] if not found.deconstruct the P results a return a list of languages sorted by preference in descending order.5Note: this implementation does not conform to RFC4647wAmong other things, it does not handle wildcards. A proper implementation needs to take a list of available languages.+*(c) Happstack.com 2010; (c) HAppS Inc 2007BSD3'Happstack team <happs@googlegroups.com> provisional'GHC-only, Windows, Linux, FreeBSD, OS XNone09:;<=DRT<=>?@CDEFGHINJKLMOPRdefghijmntvsklopqruwxy|z}{~#$&'(%*456:<;=EFGHKPQVWXYe     789:;<=HIJKLMRTUVabfqs~,-./00123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTTUVWXYZ[\]^_`abcdeffghijklmnopqqrstuvwxyz{|}~             ! " # # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B B C D E F G H I J K L M N O P Q R S T U U V W X Y Z [ [ \ ] ^ _ ` a b c d d e f g h i j k l m n o p q r s t u v w x y z { | } ~                                                                                                                                   !"#$%&L'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`#abcdefghijklmnopqrstuvwxyz{|}~2IJ              !!"!"!#!$!%!&!'!(!)!*!+,-./0./123./456789:;<=>?@ABCDEFGHIHJKFLFMNOPQRS./TQUVNWXNWYZ[\% ]^_`abcdefghijklmn9o8pqrstuvwxyz{|}~ ./-happstack-server-7.5.0-4GCp4adJ6jC4toPwU5OFTSHappstack.Server.SURI(Happstack.Server.Internal.TimeoutManager#Happstack.Server.Internal.TimeoutIO'Happstack.Server.Internal.TimeoutSocket Happstack.Server.Internal.SocketHappstack.Server.Internal.Types#Happstack.Server.Internal.LogFormat Happstack.Server.Internal.Cookie#Happstack.Server.Internal.Multipart%Happstack.Server.Internal.MessageWrap Happstack.Server.Internal.MonadsHappstack.Server.ResponseHappstack.Server.Validation!Happstack.Server.Internal.Handler Happstack.Server.Internal.ListenHappstack.Server.CookieHappstack.Server.RqDataHappstack.Server.MonadsHappstack.Server.Error)Happstack.Server.FileServe.BuildingBlocksHappstack.Server.RoutingHappstack.Server.ClientHappstack.Server.ProxyHappstack.Server.AuthHappstack.Server.SimpleHTTP%Happstack.Server.Internal.CompressionHappstack.Server.I18NPaths_happstack_serverHappstack.Server.SURI.ParseURI"Happstack.Server.Internal.SocketTH'Happstack.Server.Internal.RFC822Headers#Happstack.Server.Internal.LazyLinerHappstack.Server.Internal.ClockHappstack.Server.TypesspUnwrapErrorTCpack"Happstack.Server.Internal.LowLevel Data.ListlookupHappstack.Server.FileServeHappstack.Server.CompressionHappstack.ServerFromPathfromPathToSURItoSURISURIsuripathqueryschemeu_schemeu_patha_schemea_path percentDecode unEscapeQSunEscapeisAbsrenderparse $fToSURIText $fToSURIText0 $fToSURI[] $fToSURIURI $fToSURISURI $fOrdSURI $fReadSURI $fShowSURI$fEqSURI $fDataSURIHandleManager initializeregisterregisterKillThreadticklepauseresumecancel forceTimeoutforceTimeoutAll TimeoutIOtoHandle toPutLazytoPuttoGet toGetContents toSendFile toShutdowntoSecuresPutLazyTickle sPutTicklesGet sGetContentssendFileTickle iterTickletimeoutSocketIO acceptLitesockAddrToPeer ContentTypectType ctSubtype ctParametersformatTimeCombinedformatRequestCombined CookieLifeSessionMaxAgeExpiresExpiredCookie cookieVersion cookiePath cookieDomain cookieName cookieValuesecurehttpOnlycalcLifemkCookiemkCookieHeader parseCookies cookiesParser getCookies getCookie getCookies' getCookie' $fShowCookie $fEqCookie $fReadCookie $fDataCookie$fEqCookieLife$fOrdCookieLife$fReadCookieLife$fShowCookieLife EscapeHTTP FromReqURI fromReqURIRqBodyBodyunBodyRequestrqSecurerqMethodrqPathsrqUrirqQuery rqInputsQuery rqInputsBody rqCookies rqVersion rqHeadersrqBodyrqPeerResponseSendFilersCode rsHeadersrsFlagsrsBody rsValidator sfFilePathsfOffsetsfCountHostInput inputValue inputFilenameinputContentTypeRsFlags rsfLengthLength ContentLengthTransferEncodingChunkedNoContentLengthHeaders HeaderPairhNamehValueMethodGETHEADPOSTPUTDELETETRACEOPTIONSCONNECTPATCH EXTENSIONConfport validator logAccesstimeout threadGroup LogAccess HttpVersion isHTTP1_1 isHTTP1_0 continueHTTPnullConf logMAccess canHaveBody nullRsFlagsnoContentLengthchunked contentLengthshowRsValidatortakeRequestBodyreadInputsBodyrqURL setRsCode mkHeaders getHeader getHeaderBSgetHeaderUnsafe hasHeader hasHeaderBShasHeaderUnsafe setHeader setHeaderBSsetHeaderUnsafe addHeader addHeaderBSaddHeaderUnsaferesultresultBSredirectreadDec'readM fromReadS$fShowEscapeHTTP$fExceptionEscapeHTTP$fFromReqURIBool$fFromReqURIDouble$fFromReqURIFloat$fFromReqURIWord64$fFromReqURIWord32$fFromReqURIWord16$fFromReqURIWord8$fFromReqURIWord$fFromReqURIInteger$fFromReqURIInt64$fFromReqURIInt32$fFromReqURIInt16$fFromReqURIInt8$fFromReqURIInt$fFromReqURIChar$fFromReqURIText$fFromReqURIText0$fFromReqURI[]$fHasHeadersMap$fHasHeadersRequest$fHasHeadersResponse $fShowRequest$fErrorResponse$fShowResponse$fShowHttpVersion$fReadHttpVersion$fEqHttpVersion $fShowMethod $fReadMethod $fEqMethod $fOrdMethod $fDataMethod$fReadHeaderPair$fShowHeaderPair $fEqLength $fOrdLength $fReadLength $fShowLength $fEnumLength $fShowRsFlags $fReadRsFlags $fShowInput $fReadInput $fReadRqBody $fShowRqBody FileSaver InputIterFailed BodyResult HeaderResult InputWorkerWorkBodyWork HeaderWorkBodyPartspanS takeWhileScrlfcrlfcrlf blankLine dropWhileSdefaultFileSaverdefaultInputIter hPutLimit hPutLimit'bodyPartToInputbodyPartsToInputs multipartBody simpleInputdefaultInputTypeparseMultipartBody dropPreambledropLine isBoundarystartsWithDashes splitParts splitPart splitBlank splitBoundarysplitAtEmptyLine splitAtCRLF $fEqBodyPart $fOrdBodyPart$fReadBodyPart$fShowBodyPart BodyPolicy inputWorkermaxDiskmaxRAM maxHeader queryInputdefaultBodyPolicy bodyInput formDecode formDecodeBS decodeBodymultipartDecodepathEls splitList splitListBysplitWebMonad finishWithUnWebTWebTunWebT FilterMonad setFilter composeFilter getFilterFilterT unFilterT FilterFun SetAppendSetAppend ServerMonadaskRqlocalRq ServerPartT unServerPartT ServerPartWebrunServerPartT withRequest anyRequestmapServerPartTmapServerPartT' smAskRqEnv smLocalRqEnvextract unFilterFun filterFun ignoreFiltersescapeescape'ununWebTmkWebTmapWebT localContextmulti debugFilteroutputTraceMessage mkFailMessage failResponsefailHtml escapeString escapeHTTP$fWebMonadaExceptT$fFilterMonadaExceptT$fServerMonadExceptT$fWebMonadaErrorT$fFilterMonadaErrorT$fServerMonadErrorT$fWebMonadaRWST$fWebMonadaRWST0$fFilterMonadresRWST$fFilterMonadresRWST0$fServerMonadRWST$fServerMonadRWST0$fWebMonadaWriterT$fWebMonadaWriterT0$fFilterMonadresWriterT$fFilterMonadresWriterT0$fServerMonadWriterT$fServerMonadWriterT0$fWebMonadaStateT$fWebMonadaStateT0$fFilterMonadresStateT$fFilterMonadresStateT0$fServerMonadStateT$fServerMonadStateT0$fWebMonadaReaderT$fFilterMonadresReaderT$fServerMonadReaderT$fMonadWriterwWebT$fMonadErroreWebT$fMonadStatestWebT$fMonadReaderrWebT$fAlternativeWebT$fApplicativeWebT $fMonoidWebT$fFilterMonadResponseWebT$fMonadPlusWebT$fMonadTransWebT$fWebMonadResponseWebT $fMonadWebT$fMonadBaseControlbWebT$fMonadTransControlWebT $fMonadIOWebT$fMonadBasebWebT$fMonadThrowWebT$fMonadCatchWebT$fFilterMonadaFilterT$fMonadBaseControlbFilterT$fMonadTransControlFilterT$fMonadIOFilterT$fMonadBasebFilterT$fMonadThrowFilterT$fMonadCatchFilterT$fFunctorSetAppend$fMonoidSetAppend$fServerMonadServerPartT$fWebMonadResponseServerPartT $fFilterMonadResponseServerPartT$fMonadStatesServerPartT$fMonadReaderrServerPartT$fMonadErroreServerPartT$fMonadWriterwServerPartT$fAlternativeServerPartT$fApplicativeServerPartT$fMonoidServerPartT$fMonadTransServerPartT$fMonadBaseControlbServerPartT$fMonadTransControlServerPartT$fMonadIOServerPartT$fMonadBasebServerPartT$fMonadThrowServerPartT$fMonadCatchServerPartT $fEqSetAppend$fShowSetAppend$fFunctorFilterT$fApplicativeFilterT$fMonadFilterT$fMonadTransFilterT $fFunctorWebT$fMonadServerPartT$fMonadPlusServerPartT$fFunctorServerPartT ToMessage toContentType toMessage toResponse toResponseBSflattenifModifiedSincesetResponseCoderespok noContentmovedPermanentlyfoundseeOther tempRedirect badRequest unauthorized forbiddennotFoundrequestEntityTooLargeinternalServerError badGatewayprettyResponse$fToMessageByteString$fToMessageByteString0$fToMessageResponse$fToMessageMarkupM$fToMessageHtml$fToMessageHtml0$fToMessageMaybe$fToMessageInteger$fToMessageText$fToMessageText0 $fToMessage[] $fToMessage() setValidatorsetValidatorSP validateConf runValidatorwdgHTMLValidator noopValidatorlazyProcValidatorrequest parseResponse putRequestlistenOn listenOnIPv4listenlisten' addCookie addCookies expireCookieFromDatafromData HasRqDataaskRqEnv localRqEnv rqDataErrorRqDataRqEnvErrorsunErrors mapRqData unsafeReadRqreadRqcheckRqcheckRqM lookInput lookInputslookBSlookBSslooklookslookText lookText' lookTexts lookTexts' lookCookielookCookieValuereadCookieValuelookRead lookReadslookFile lookPairs lookPairsBS getDataFn withDataFngetDatawithDatabody queryString bytestring$fFromDataMaybe$fFromData(,,,)$fFromData(,,) $fFromData(,)$fHasRqDataExceptT$fHasRqDataErrorT$fHasRqDataRWST$fHasRqDataRWST0$fHasRqDataWriterT$fHasRqDataWriterT0$fHasRqDataStateT$fHasRqDataStateT0$fHasRqDataReaderT$fHasRqDataServerPartT$fHasRqDataRqData $fErrorErrors$fMonoidErrors$fAlternativeReaderError$fApplicativeReaderError$fMonadReaderrReaderError$fFunctorReaderError$fMonadReaderError$fMonadPlusReaderError $fEqErrors $fOrdErrors $fShowErrors $fReadErrors $fDataErrors$fFunctorRqData $fMonadRqData$fMonadPlusRqData$fApplicativeRqData$fAlternativeRqData$fMonadReaderRqData Happstack getHeaderM addHeaderM setHeaderM neverExpiresrequirerequireM$fHappstackExceptT$fHappstackErrorT$fHappstackRWST$fHappstackRWST0$fHappstackWriterT$fHappstackWriterT0$fHappstackReaderT$fHappstackStateT$fHappstackStateT0$fHappstackServerPartTsimpleErrorHandlererrorHandlerSPBrowsingEnableBrowsingDisableBrowsing EntryKindFile Directory UnknownKindMimeMapguessContentTypeguessContentTypeM asContentTypedefaultIxFiles fileNotFound blockDotFilesisDotsendFileResponselazyByteStringResponsestrictByteStringResponsefilePathSendFile filePathLazyfilePathStrictserveFileUsing serveFile serveFileFrom fileServe' combineSafe isSafePath fileServe fileServeLazyfileServeStrictdoIndex doIndexLazy doIndexStrictdoIndex'tryIndex browseIndexrenderDirectoryContentsrenderDirectoryContentsTableserveDirectoryserveDirectory' mimeTypes $fEqEntryKind$fOrdEntryKind$fReadEntryKind$fShowEntryKind$fDataEntryKind$fEnumEntryKind $fEqBrowsing$fEnumBrowsing $fOrdBrowsing$fReadBrowsing$fShowBrowsing$fDataBrowsing MatchMethod matchMethodguardRqhttphttpsmethodmethodM methodOnlymethodSPnullDirdirdirshostwithHosturiRestanyPath trailingSlashnoTrailingSlash$fMatchMethod()$fMatchMethod(->)$fMatchMethod[]$fMatchMethodMethod getResponse proxyServe proxyServe' rproxyServe unproxify unrproxify basicAuth parseConfig simpleHTTP simpleHTTP' simpleHTTP''simpleHTTPWithSocketsimpleHTTPWithSocket'bindPortbindIPv4waitForTerminationcompressedResponseFiltercompressedResponseFilter' gzipFilter deflateFilteridentityFilter starFiltercompressWithFilterstandardEncodingHandlers encodingsacceptLanguage bestLanguagecatchIOversionbindirlibdirdatadir libexecdir sysconfdir getBinDir getLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName breakChar breakCharEnd parseURIRefpabsuri pauthority pauthinner pauthportpurirefpquery pfragment unsafeTail unsafeHead unsafeIndexStateActiveInactivePausedCanceled ignoreAll supportsIPv6showHostAddressshowHostAddress6 HostAddress6 HostAddressbaseGHC.ShowShowshowContentTypeparseContentTypeGHC.Basefailws1crLf lineStringContentDispositionContentTransferEncodingHeaderpHeaders parseHeaderspHeaderextraFieldLineshowParameters p_parameter pContentTypegetContentTypepContentTransferEncodingparseContentTransferEncodinggetContentTransferEncodingpContentDispositionparseContentDispositiongetContentDispositionparseMlookupMlexeme literalStringbuggyLiteralStringheaderNameChar tspecials tokencharp_token text_charsp_text quoted_pairGHC.Num+-LazynewLinerHandle headerLinesgetBytesStrictgetBytesgetResttoStrictbytestring-0.10.8.1Data.ByteString.LazytoChunks DateCachecachedPOSIXTimecachedHttpDateformatHttpDatemkTimeclockupdatergetApproximateTimegetApproximatePOSIXTimegetApproximateUTCTimefctllowghc-prim GHC.TypesIntFloatString HasHeadersTrueNothinggetHeaderUnsafe' locationCcloseC connectionC keepaliveC updateHeadersheaders checkHeaderBScheckHeaderUnsafeGHC.ListspanidMonadMaybemzeroJust Data.EitherEither Data.MonoidEndoDualMonoidLeftRight mtl-2.2.1-BLKBelFsPB3BoFeSWSOYj6Control.Monad.Reader.Class MonadReadertransformers-0.5.2.0Control.Monad.Trans.ReaderReaderTIOControl.Monad.Trans.ErrorErrorTControl.Monad.Error.Class throwError catchError Data.FoldablemsumData.ByteString.Lazy.Char8modifyResponserequiredrloopescapeHttpHandlercleanupTempFiles consumeChunksconsumeChunksImplcrlfLC lazylines requestLine responseLine staticHeadersputAugmentedResultaugmentHeaderspversionhttp09http10http11connectionCLower keepAliveCcrlfCfsepCcontentLengthCcontentlengthCdateC dateCLowerserverC happstackCtransferEncodingCchunkedCresponseMessagelog' runRqDatafmap Text.Readreadlookups#text-1.2.2.2-KC7dWoG09dA1F6jKj5GSqhData.Text.InternalTextGHC.ReadReadunRqData ReaderError unReaderErrorapEitherrunReaderError fromMaybeBodycontainers-0.5.7.1 Data.Map.BaseMapGHC.IOFilePathgetExtfilepath-1.4.1.1System.FilePath.Posix takeExtension getMetaDataisParentGHC.Real/hoSystem.Console.GetOptOptDescrrunWebTmempty notFoundHtmlBool#zlib-0.6.1.2-BfeUVhBVvrx1Nvtzv6OD9cCodec.Compression.GZipcompressCodec.Compression.Zlib bestEncodingstandardEncodingshandlers