F      !"#$%&'()*+,-./0123456789:;<=>?@ABCDE8KMiddleware is a component that sits between the server and application. It M can do such tasks as GZIP encoding or response caching. What follows is the J general definition of middleware, though a middleware author should feel  free to modify this. GAs an example of an alternate type for middleware, suppose you write a N function to load up session information. The session information is simply a  string map [(String, String)]0. A logical type signatures for this middleware  might be:  " loadSession :: ([(String, String)] -> Application) -> Application#Here, instead of taking a standard  as its first argument, the M middleware takes a function which consumes the session information as well. FA common optimization is to use the sendfile system call when sending F files from the disk. This datatype facilitates this optimization; if  F= is returned, the server will send the file from the disk by  whatever means it wishes. If G, it will call the . JThe response body returned to the server from the application. We provide / three separate constructors as optimizations:   4 is the most general type, allowing constant-memory @ production of a response, even in the presence of interleaved I/ O actions.   < serves a static file from the filesystem. Many servers use M a sendfile system call to optimize this type of serving, making this a huge  performance gain.  =. Often times, we wish to return a response that includes no  interleaved I/#O. In this case, we can use Haskell's natural laziness to our = advantage, and represent the response as a lazy bytestring.  GInformation on the request sent by the client. This abstracts away the + details of the underlying implementation. GExtra path information sent by the client. The meaning varies slightly K depending on backend; in a standalone server setting, this is most likely L all information after the domain name. In a CGI application, this would be B the information following the path to the CGI executable itself. 8If no query string was specified, this should be empty. .Was this request made over an SSL connection? ?Log the given line in some method; how this is accomplished is  server-dependant.  The client's host information. HAn enumerator is a data producer. It takes two arguments: a function to E enumerate over (the iteratee) and an accumulating parameter. As the N enumerator produces output, it calls the iteratee, thereby avoiding the need K to allocate large amounts of memory for storing the entire piece of data. HNormally in Haskell, we can achieve the same results with laziness. For J example, an inifinite list does not require inifinite memory storage; we M simply get away with thunks. However, when operating in the IO monad, we do A not have this luxury. There are other approaches, such as lazy I/ O. If you 2 would like to program in this manner, please see  Network.Wai.Enumerator, in particular toLBS. That said, let'4s address the details of this particular enumerator  implementation. You'9ll notice that the iteratee is a function that takes two  arguments and returns an H* value. The second argument is simply the 0 piece of data generated by the enumerator. The H value at the end is K a means to alert the enumerator whether to continue or not. If it returns  F3, then the enumeration should cease. If it returns G , it should  continue. EThe accumulating parameter (a) has meaning only to the iteratee; the K enumerator simply passes it around. The enumerator itself also returns an  H value; a G1 means the enumerator ran to completion, while a  F< indicates early termination was requested by the iteratee. 8s are not required to be resumable. That is to say, the  A may only be called once. While this requirement puts a bit of a E strain on the caller in some situations, it saves a large amount of 6 complication- and thus performance- on the producer. FIn WAI, an Enumerator is used to represent the response body. We have M specifically chosen one of the simplest representations of an enumerator to 5 avoid coding complication and performance overhead. This is a source for I"s. It is a function (wrapped in a M newtype) that will return Nothing if the data has been completely consumed,  or return the next I" from the source along with a new   to continue reading from. Be certain not to reuse a ! It might work fine with some  implementations of ", while causing bugs with others. IThis datatype is used by WAI to represent a request body. We choose this N over an enumerator in that it gives the application power over control flow. J This not only makes it easier to use in many situations, but also allows J implementation of some features such as a backtracking parser which doesn't # read the entire body into memory. KHTTP status code; a combination of the integral code and a status message. B Equality is determined solely on the basis of the integral code.  !"@Headers sent from the server to the client. Note that this is a 6 case-insensitive string, as the HTTP spec specifies. #@Headers sent from the client to the server. Note that this is a 6 case-insensitive string, as the HTTP spec specifies. $)A case insensitive bytestring, where the J and K instances do N comparisons based on the lower-cased version of this string. For efficiency, H this datatype contains both the original and lower-case version of the L string; this means there is no need to lower-case the bytestring for every  comparison. &Please note that this datatype has an L instance, which can allow L for very concise code when using the OverloadedStrings language extension. %&'(GVersion of HTTP protocol used in current request. The value given here $ should be everything following the "HTTP/" line in a request. In other  words, HTTP/1.1 -> "1.1", HTTP/1.0 -> "1.0". )FHTTP request method. Since the HTTP protocol allows arbitrary request " methods, we leave this open as a I. Please note the request  methods are case-sensitive. *HTTP/0.9 +HTTP/1.0 ,HTTP/1.1 -?Convert a regular bytestring to a case-insensitive bytestring. .OK /Moved Permanently 0Found 1 See Other 2 Bad Request 3 Unauthorized 4 Forbidden 5 Not Found 6Method Not Allowed 7Internal Server Error 8  !"#$%&'()*+,-./012345678)(*+,$%&'-#" !./01234567  8    ! !"#$%&'%&'()*+,-./012345678 This function safely converts a  (where you pull data) to an  @ (which pushes the data to you). There should be no significant C performance impact from its use, and it uses no unsafe functions. 9 Uses lazy I/O (via M!) to provide a lazy interface to  the given . Normal lazy I/O warnings apply. :Convert a lazy bytestring to a (. This operation does not request lazy I/O. 89:89:89: ;(Performs a specified conversion on each I output by an  enumerator. < This uses unsafeInterleaveIO( to lazily read from an enumerator. All  normal lazy I/4O warnings apply. In addition, since it is based on  ?4, please observe all precautions for that function. =DThis function safely converts a lazy bytestring into an enumerator. >Same as =:, but the lazy bytestring is in the IO monad. This allows M you to lazily read a file into memory, perform some mapping on the data and  convert it into an enumerator. ?0This function uses another thread to convert an  to a  2. In essence, this allows you to write code which "pulls" instead H of code which is pushed to. While this can be a useful technique, some  caveats apply: / It will be more resource heavy than using the  directly. L You *must* consume all input. If you do not, then the other thread will be  deadlocked. @$Read a chunk of data from the given N at a time. We use  O6 from the bytestring package to determine the largest  chunk to take. AJWrapper around fromHandle to perform an action after EOF or an exception. BA little wrapper around @' which first opens a file for reading. CGWrapper around fromFile to perform an action after the file is closed. D5Enumerator to read and remove a file. Being based on C, it B ensures the file is removed, even in the presence of exceptions. E(Since the response body is defined as a , this function M simply reduces the whole value to an enumerator. This can be convenient for 5 server implementations not optimizing file sending. ;<=>?@ABCDE ;<=>?@ABCDE ;<=>?@ABCDEP      !"##$%&'()*+,-./012345678978:;<=>?@ABCDBCEBCFGHIBJKBJLBMNBOPBQRGSTU wai-0.2.2 Network.WaiNetwork.Wai.SourceNetwork.Wai.Enumerator Middleware ApplicationResponsestatusresponseHeaders responseBody ResponseBody ResponseLBSResponseEnumerator ResponseFileRequest requestMethod httpVersionpathInfo queryString serverName serverPortrequestHeadersisSecure requestBody errorHandler remoteHost Enumerator runEnumeratorSource runSourceStatus statusCode statusMessageResponseHeader RequestHeader CIByteString ciOriginal ciLowerCase HttpVersionMethodhttp09http10http11mkCIByteString status200 status301 status302 status303 status400 status401 status403 status404 status405 status500 toEnumeratortoLBSfromLBSmapEfromLBS'toSource fromHandlefromHandleFinallyfromFilefromFileFinally fromTempFilefromResponseBodybase Data.EitherLeftRightEitherbytestring-0.9.1.7Data.ByteString.Internal ByteString GHC.ClassesEqOrd Data.StringIsStringGHC.IOunsafeInterleaveIOGHC.IO.Handle.TypesHandleData.ByteString.Lazy.InternaldefaultChunkSize