This file is indexed.

/usr/share/doc/libghc-wai-doc/html/src/Network-Wai.html is in libghc-wai-doc 1.1.0.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
<title>Network/Wai.hs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE Rank2Types #-}</span>
<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE ExistentialQuantification #-}</span>
<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
<a name="line-4"></a><span class='hs-comment'>{-|
<a name="line-5"></a>
<a name="line-6"></a>This module defines a generic web application interface. It is a common
<a name="line-7"></a>protocol between web servers and web applications.
<a name="line-8"></a>
<a name="line-9"></a>The overriding design principles here are performance and generality . To
<a name="line-10"></a>address performance, this library is built on top of the enumerator and
<a name="line-11"></a>blaze-builder packages.  The advantages of enumerators over lazy IO have been
<a name="line-12"></a>debated elsewhere and so will not be addressed here.  However, helper functions
<a name="line-13"></a>like 'responseLBS' allow you to continue using lazy IO if you so desire.
<a name="line-14"></a>
<a name="line-15"></a>Generality is achieved by removing many variables commonly found in similar
<a name="line-16"></a>projects that are not universal to all servers. The goal is that the 'Request'
<a name="line-17"></a>object contains only data which is meaningful in all circumstances.
<a name="line-18"></a>
<a name="line-19"></a>Please remember when using this package that, while your application may
<a name="line-20"></a>compile without a hitch against many different servers, there are other
<a name="line-21"></a>considerations to be taken when moving to a new backend. For example, if you
<a name="line-22"></a>transfer from a CGI application to a FastCGI one, you might suddenly find you
<a name="line-23"></a>have a memory leak. Conversely, a FastCGI application would be well served to
<a name="line-24"></a>preload all templates from disk when first starting; this would kill the
<a name="line-25"></a>performance of a CGI application.
<a name="line-26"></a>
<a name="line-27"></a>This package purposely provides very little functionality. You can find various
<a name="line-28"></a>middlewares, backends and utilities on Hackage. Some of the most commonly used
<a name="line-29"></a>include:
<a name="line-30"></a>
<a name="line-31"></a>[warp] &lt;<a href="http://hackage.haskell.org/package/warp">http://hackage.haskell.org/package/warp</a>&gt;
<a name="line-32"></a>
<a name="line-33"></a>[wai-extra] &lt;<a href="http://hackage.haskell.org/package/wai-extra">http://hackage.haskell.org/package/wai-extra</a>&gt;
<a name="line-34"></a>
<a name="line-35"></a>[wai-test] &lt;<a href="http://hackage.haskell.org/package/wai-test">http://hackage.haskell.org/package/wai-test</a>&gt;
<a name="line-36"></a>
<a name="line-37"></a>-}</span>
<a name="line-38"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
<a name="line-39"></a>    <span class='hs-layout'>(</span> <span class='hs-comment'>-- * WAI interface</span>
<a name="line-40"></a>      <span class='hs-conid'>Request</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span>
<a name="line-41"></a>    <span class='hs-layout'>,</span> <span class='hs-conid'>Response</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span>
<a name="line-42"></a>    <span class='hs-layout'>,</span> <span class='hs-varid'>responseSource</span>
<a name="line-43"></a>    <span class='hs-layout'>,</span> <span class='hs-conid'>Application</span>
<a name="line-44"></a>    <span class='hs-layout'>,</span> <span class='hs-conid'>Middleware</span>
<a name="line-45"></a>    <span class='hs-layout'>,</span> <span class='hs-conid'>FilePart</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span>
<a name="line-46"></a>      <span class='hs-comment'>-- * Response body smart constructors</span>
<a name="line-47"></a>    <span class='hs-layout'>,</span> <span class='hs-varid'>responseLBS</span>
<a name="line-48"></a>    <span class='hs-layout'>,</span> <span class='hs-varid'>responseStatus</span>
<a name="line-49"></a>    <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-50"></a>
<a name="line-51"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>B</span>
<a name="line-52"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Lazy</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>L</span>
<a name="line-53"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span> <span class='hs-layout'>(</span><span class='hs-conid'>Typeable</span><span class='hs-layout'>)</span>
<a name="line-54"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Resource</span> <span class='hs-layout'>(</span><span class='hs-conid'>ResourceT</span><span class='hs-layout'>)</span>
<a name="line-55"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Conduit</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>C</span>
<a name="line-56"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Conduit</span><span class='hs-varop'>.</span><span class='hs-conid'>List</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>CL</span>
<a name="line-57"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Conduit</span><span class='hs-varop'>.</span><span class='hs-conid'>Binary</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>CB</span>
<a name="line-58"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span> <span class='hs-layout'>(</span><span class='hs-conid'>Builder</span><span class='hs-layout'>,</span> <span class='hs-varid'>fromLazyByteString</span><span class='hs-layout'>)</span>
<a name="line-59"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Socket</span> <span class='hs-layout'>(</span><span class='hs-conid'>SockAddr</span><span class='hs-layout'>)</span>
<a name="line-60"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>H</span>
<a name="line-61"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span> <span class='hs-layout'>(</span><span class='hs-conid'>Text</span><span class='hs-layout'>)</span>
<a name="line-62"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Lazy</span><span class='hs-varop'>.</span><span class='hs-conid'>Char8</span> <span class='hs-conid'>()</span> <span class='hs-comment'>-- makes it easier to use responseLBS</span>
<a name="line-63"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Blaze</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Builder</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromByteString</span><span class='hs-layout'>)</span>
<a name="line-64"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Vault</span> <span class='hs-layout'>(</span><span class='hs-conid'>Vault</span><span class='hs-layout'>)</span>
<a name="line-65"></a>
<a name="line-66"></a><a name="Request"></a><span class='hs-comment'>-- | Information on the request sent by the client. This abstracts away the</span>
<a name="line-67"></a><a name="Request"></a><span class='hs-comment'>-- details of the underlying implementation.</span>
<a name="line-68"></a><a name="Request"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Request</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Request</span>
<a name="line-69"></a>  <span class='hs-layout'>{</span>  <span class='hs-varid'>requestMethod</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Method</span>
<a name="line-70"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>httpVersion</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>HttpVersion</span>
<a name="line-71"></a>  <span class='hs-comment'>-- | Extra path information sent by the client. The meaning varies slightly</span>
<a name="line-72"></a>  <span class='hs-comment'>-- depending on backend; in a standalone server setting, this is most likely</span>
<a name="line-73"></a>  <span class='hs-comment'>-- all information after the domain name. In a CGI application, this would be</span>
<a name="line-74"></a>  <span class='hs-comment'>-- the information following the path to the CGI executable itself.</span>
<a name="line-75"></a>  <span class='hs-comment'>-- Do not modify this raw value- modify pathInfo instead.</span>
<a name="line-76"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>rawPathInfo</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-77"></a>  <span class='hs-comment'>-- | If no query string was specified, this should be empty. This value</span>
<a name="line-78"></a>  <span class='hs-comment'>-- /will/ include the leading question mark.</span>
<a name="line-79"></a>  <span class='hs-comment'>-- Do not modify this raw value- modify queryString instead.</span>
<a name="line-80"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>rawQueryString</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-81"></a>  <span class='hs-comment'>-- | Generally the host requested by the user via the Host request header.</span>
<a name="line-82"></a>  <span class='hs-comment'>-- Backends are free to provide alternative values as necessary. This value</span>
<a name="line-83"></a>  <span class='hs-comment'>-- should not be used to construct URLs.</span>
<a name="line-84"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>serverName</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-85"></a>  <span class='hs-comment'>-- | The listening port that the server received this request on. It is</span>
<a name="line-86"></a>  <span class='hs-comment'>-- possible for a server to listen on a non-numeric port (i.e., Unix named</span>
<a name="line-87"></a>  <span class='hs-comment'>-- socket), in which case this value will be arbitrary. Like 'serverName',</span>
<a name="line-88"></a>  <span class='hs-comment'>-- this value should not be used in URL construction.</span>
<a name="line-89"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>serverPort</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
<a name="line-90"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>requestHeaders</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>RequestHeaders</span>
<a name="line-91"></a>  <span class='hs-comment'>-- | Was this request made over an SSL connection?</span>
<a name="line-92"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>isSecure</span>       <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span>
<a name="line-93"></a>  <span class='hs-comment'>-- | The client\'s host information.</span>
<a name="line-94"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>remoteHost</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>SockAddr</span>
<a name="line-95"></a>  <span class='hs-comment'>-- | Path info in individual pieces- the url without a hostname/port and without a query string, split on forward slashes,</span>
<a name="line-96"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>pathInfo</span>       <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Text</span><span class='hs-keyglyph'>]</span>
<a name="line-97"></a>  <span class='hs-comment'>-- | Parsed query string information</span>
<a name="line-98"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>queryString</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Query</span>
<a name="line-99"></a>  <span class='hs-layout'>,</span>  <span class='hs-varid'>requestBody</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Source</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-100"></a>  <span class='hs-comment'>-- | A location for arbitrary data to be shared by applications and middleware.</span>
<a name="line-101"></a>  <span class='hs-layout'>,</span> <span class='hs-varid'>vault</span>           <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Vault</span>
<a name="line-102"></a>  <span class='hs-layout'>}</span>
<a name="line-103"></a>  <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Typeable</span><span class='hs-layout'>)</span>
<a name="line-104"></a>
<a name="line-105"></a><a name="Response"></a><span class='hs-comment'>-- |</span>
<a name="line-106"></a><a name="Response"></a><span class='hs-comment'>--</span>
<a name="line-107"></a><a name="Response"></a><span class='hs-comment'>-- Some questions and answers about the usage of 'Builder' here:</span>
<a name="line-108"></a><a name="Response"></a><span class='hs-comment'>--</span>
<a name="line-109"></a><a name="Response"></a><span class='hs-comment'>-- Q1. Shouldn't it be at the user's discretion to use Builders internally and</span>
<a name="line-110"></a><a name="Response"></a><span class='hs-comment'>-- then create a stream of ByteStrings?</span>
<a name="line-111"></a><a name="Response"></a><span class='hs-comment'>--</span>
<a name="line-112"></a><a name="Response"></a><span class='hs-comment'>-- A1. That would be less efficient, as we wouldn't get cheap concatenation</span>
<a name="line-113"></a><a name="Response"></a><span class='hs-comment'>-- with the response headers.</span>
<a name="line-114"></a><a name="Response"></a><span class='hs-comment'>--</span>
<a name="line-115"></a><a name="Response"></a><span class='hs-comment'>-- Q2. Isn't it really inefficient to convert from ByteString to Builder, and</span>
<a name="line-116"></a><a name="Response"></a><span class='hs-comment'>-- then right back to ByteString?</span>
<a name="line-117"></a><a name="Response"></a><span class='hs-comment'>--</span>
<a name="line-118"></a><a name="Response"></a><span class='hs-comment'>-- A2. No. If the ByteStrings are small, then they will be copied into a larger</span>
<a name="line-119"></a><a name="Response"></a><span class='hs-comment'>-- buffer, which should be a performance gain overall (less system calls). If</span>
<a name="line-120"></a><a name="Response"></a><span class='hs-comment'>-- they are already large, then blaze-builder uses an InsertByteString</span>
<a name="line-121"></a><a name="Response"></a><span class='hs-comment'>-- instruction to avoid copying.</span>
<a name="line-122"></a><a name="Response"></a><span class='hs-comment'>--</span>
<a name="line-123"></a><a name="Response"></a><span class='hs-comment'>-- Q3. Doesn't this prevent us from creating comet-style servers, since data</span>
<a name="line-124"></a><a name="Response"></a><span class='hs-comment'>-- will be cached?</span>
<a name="line-125"></a><a name="Response"></a><span class='hs-comment'>--</span>
<a name="line-126"></a><a name="Response"></a><span class='hs-comment'>-- A3. You can force blaze-builder to output a ByteString before it is an</span>
<a name="line-127"></a><a name="Response"></a><span class='hs-comment'>-- optimal size by sending a flush command.</span>
<a name="line-128"></a><a name="Response"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Response</span>
<a name="line-129"></a>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ResponseFile</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Status</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>ResponseHeaders</span> <span class='hs-conid'>FilePath</span> <span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span> <span class='hs-conid'>FilePart</span><span class='hs-layout'>)</span>
<a name="line-130"></a>    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ResponseBuilder</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Status</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>ResponseHeaders</span> <span class='hs-conid'>Builder</span>
<a name="line-131"></a>    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ResponseSource</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Status</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>ResponseHeaders</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Source</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Flush</span> <span class='hs-conid'>Builder</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-132"></a>  <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
<a name="line-133"></a>
<a name="line-134"></a><a name="responseStatus"></a><span class='hs-definition'>responseStatus</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Response</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Status</span>
<a name="line-135"></a><span class='hs-definition'>responseStatus</span> <span class='hs-varid'>rsp</span> <span class='hs-keyglyph'>=</span>
<a name="line-136"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>rsp</span> <span class='hs-keyword'>of</span>
<a name="line-137"></a>      <span class='hs-conid'>ResponseFile</span>    <span class='hs-varid'>s</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span>
<a name="line-138"></a>      <span class='hs-conid'>ResponseBuilder</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span>
<a name="line-139"></a>      <span class='hs-conid'>ResponseSource</span>  <span class='hs-varid'>s</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span>
<a name="line-140"></a>
<a name="line-141"></a><a name="FilePart"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>FilePart</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FilePart</span>
<a name="line-142"></a>    <span class='hs-layout'>{</span> <span class='hs-varid'>filePartOffset</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span>
<a name="line-143"></a>    <span class='hs-layout'>,</span> <span class='hs-varid'>filePartByteCount</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span>
<a name="line-144"></a>    <span class='hs-layout'>}</span> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Show</span>
<a name="line-145"></a>
<a name="line-146"></a><a name="responseSource"></a><span class='hs-definition'>responseSource</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Response</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Status</span><span class='hs-layout'>,</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>ResponseHeaders</span><span class='hs-layout'>,</span> <span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Source</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Flush</span> <span class='hs-conid'>Builder</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-147"></a><span class='hs-definition'>responseSource</span> <span class='hs-layout'>(</span><span class='hs-conid'>ResponseSource</span> <span class='hs-varid'>s</span> <span class='hs-varid'>h</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-varid'>h</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span>
<a name="line-148"></a><span class='hs-definition'>responseSource</span> <span class='hs-layout'>(</span><span class='hs-conid'>ResponseFile</span> <span class='hs-varid'>s</span> <span class='hs-varid'>h</span> <span class='hs-varid'>fp</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>part</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-149"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-varid'>h</span><span class='hs-layout'>,</span> <span class='hs-varid'>sourceFilePart</span> <span class='hs-varid'>part</span> <span class='hs-varid'>fp</span> <span class='hs-conid'>C</span><span class='hs-varop'>.$=</span> <span class='hs-conid'>CL</span><span class='hs-varop'>.</span><span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Chunk</span> <span class='hs-varop'>.</span> <span class='hs-varid'>fromByteString</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-150"></a><span class='hs-definition'>responseSource</span> <span class='hs-layout'>(</span><span class='hs-conid'>ResponseFile</span> <span class='hs-varid'>s</span> <span class='hs-varid'>h</span> <span class='hs-varid'>fp</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-151"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-varid'>h</span><span class='hs-layout'>,</span> <span class='hs-conid'>CB</span><span class='hs-varop'>.</span><span class='hs-varid'>sourceFile</span> <span class='hs-varid'>fp</span> <span class='hs-conid'>C</span><span class='hs-varop'>.$=</span> <span class='hs-conid'>CL</span><span class='hs-varop'>.</span><span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Chunk</span> <span class='hs-varop'>.</span> <span class='hs-varid'>fromByteString</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-152"></a><span class='hs-definition'>responseSource</span> <span class='hs-layout'>(</span><span class='hs-conid'>ResponseBuilder</span> <span class='hs-varid'>s</span> <span class='hs-varid'>h</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-153"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-varid'>h</span><span class='hs-layout'>,</span> <span class='hs-conid'>CL</span><span class='hs-varop'>.</span><span class='hs-varid'>sourceList</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Chunk</span> <span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-154"></a>
<a name="line-155"></a><a name="sourceFilePart"></a><span class='hs-definition'>sourceFilePart</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FilePart</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FilePath</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>C</span><span class='hs-varop'>.</span><span class='hs-conid'>Source</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-156"></a><span class='hs-definition'>sourceFilePart</span> <span class='hs-layout'>(</span><span class='hs-conid'>FilePart</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>count</span><span class='hs-layout'>)</span> <span class='hs-varid'>fp</span> <span class='hs-keyglyph'>=</span>
<a name="line-157"></a>    <span class='hs-conid'>CB</span><span class='hs-varop'>.</span><span class='hs-varid'>sourceFileRange</span> <span class='hs-varid'>fp</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>offset</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>count</span><span class='hs-layout'>)</span>
<a name="line-158"></a>
<a name="line-159"></a><a name="responseLBS"></a><span class='hs-definition'>responseLBS</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>Status</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>H</span><span class='hs-varop'>.</span><span class='hs-conid'>ResponseHeaders</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Response</span>
<a name="line-160"></a><span class='hs-definition'>responseLBS</span> <span class='hs-varid'>s</span> <span class='hs-varid'>h</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ResponseBuilder</span> <span class='hs-varid'>s</span> <span class='hs-varid'>h</span> <span class='hs-varop'>.</span> <span class='hs-varid'>fromLazyByteString</span>
<a name="line-161"></a>
<a name="line-162"></a><a name="Application"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>Application</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Request</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ResourceT</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>Response</span>
<a name="line-163"></a>
<a name="line-164"></a><a name="Middleware"></a><span class='hs-comment'>-- | Middleware is a component that sits between the server and application. It</span>
<a name="line-165"></a><a name="Middleware"></a><span class='hs-comment'>-- can do such tasks as GZIP encoding or response caching. What follows is the</span>
<a name="line-166"></a><a name="Middleware"></a><span class='hs-comment'>-- general definition of middleware, though a middleware author should feel</span>
<a name="line-167"></a><a name="Middleware"></a><span class='hs-comment'>-- free to modify this.</span>
<a name="line-168"></a><a name="Middleware"></a><span class='hs-comment'>--</span>
<a name="line-169"></a><a name="Middleware"></a><span class='hs-comment'>-- As an example of an alternate type for middleware, suppose you write a</span>
<a name="line-170"></a><a name="Middleware"></a><span class='hs-comment'>-- function to load up session information. The session information is simply a</span>
<a name="line-171"></a><a name="Middleware"></a><span class='hs-comment'>-- string map \[(String, String)\]. A logical type signatures for this middleware</span>
<a name="line-172"></a><a name="Middleware"></a><span class='hs-comment'>-- might be:</span>
<a name="line-173"></a><a name="Middleware"></a><span class='hs-comment'>--</span>
<a name="line-174"></a><a name="Middleware"></a><span class='hs-comment'>-- @ loadSession :: ([(String, String)] -&gt; Application) -&gt; Application @</span>
<a name="line-175"></a><a name="Middleware"></a><span class='hs-comment'>--</span>
<a name="line-176"></a><a name="Middleware"></a><span class='hs-comment'>-- Here, instead of taking a standard 'Application' as its first argument, the</span>
<a name="line-177"></a><a name="Middleware"></a><span class='hs-comment'>-- middleware takes a function which consumes the session information as well.</span>
<a name="line-178"></a><a name="Middleware"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>Middleware</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Application</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Application</span>
</pre></body>
</html>