@@ -26,40 +26,8 @@ would kill the performance of a CGI application.
28module Network.Wai
28module Network.Wai
33− -- ** HTTP protocol versions
38− -- ** Case-insensitive byte strings
41− -- ** Request header names
44− -- ** Response header names
47− -- ** Response status code
49− , status200, statusOK
50− , status201, statusCreated
51− , status206, statusPartialContent
52− , status301, statusMovedPermanently
53− , status302, statusFound
54− , status303, statusSeeOther
55− , status400, statusBadRequest
56− , status401, statusUnauthorized
57− , status403, statusForbidden
58− , status404, statusNotFound
59− , status405, statusNotAllowed
60− , status500, statusServerError
61− -- * WAI interface
29+ ( -- * WAI interface
62− , Request (..)
30+ Request (..)
63 , Response (..)
31 , Response (..)
64 , ResponseEnumerator
32 , ResponseEnumerator
65 , responseEnumerator
33 , responseEnumerator
@@ -70,152 +38,20 @@ module Network.Wai
72import qualified Data.ByteString as B
40import qualified Data.ByteString as B
73−import qualified Data.ByteString.Char8 as B8
74import qualified Data.ByteString.Lazy as L
41import qualified Data.ByteString.Lazy as L
75−import Data.Char (toLower)
76−import Data.String (IsString (..))
77import Data.Typeable (Typeable)
42import Data.Typeable (Typeable)
78import Data.Enumerator (Iteratee, ($$), joinI, run_)
43import Data.Enumerator (Iteratee, ($$), joinI, run_)
79import qualified Data.Enumerator as E
44import qualified Data.Enumerator as E
80−import Data.Enumerator.IO (enumFile)
45+import Data.Enumerator.Binary (enumFile)
81import Blaze.ByteString.Builder (Builder, fromByteString, fromLazyByteString)
46import Blaze.ByteString.Builder (Builder, fromByteString, fromLazyByteString)
82−import Data.Data (Data)
83import Network.Socket (SockAddr)
47import Network.Socket (SockAddr)
84−
48+import qualified Network.HTTP.Types as H
85−-- | HTTP request method. Since the HTTP protocol allows arbitrary request
86−-- methods, we leave this open as a 'B.ByteString'. Please note the request
87−-- methods are case-sensitive.
88−type Method = B.ByteString
90−-- | Version of HTTP protocol used in current request. The value given here
91−-- should be everything following the \"HTTP/\" line in a request. In other
92−-- words, HTTP\/1.1 -> \"1.1\", HTTP\/1.0 -> \"1.0\".
93−type HttpVersion = B.ByteString
97−http09 = B8.pack "0.9"
100−http10 :: HttpVersion
101−http10 = B8.pack "1.0"
104−http11 :: HttpVersion
105−http11 = B8.pack "1.1"
107−-- | A case insensitive bytestring, where the 'Eq' and 'Ord' instances do
108−-- comparisons based on the lower-cased version of this string. For efficiency,
109−-- this datatype contains both the original and lower-case version of the
110−-- string; this means there is no need to lower-case the bytestring for every
113−-- Please note that this datatype has an 'IsString' instance, which can allow
114−-- for very concise code when using the OverloadedStrings language extension.
115−data CIByteString = CIByteString
116− { ciOriginal :: !B.ByteString
117− , ciLowerCase :: !B.ByteString
119− deriving (Data, Typeable)
121−-- | Convert a regular bytestring to a case-insensitive bytestring.
122−mkCIByteString :: B.ByteString -> CIByteString
123−mkCIByteString bs = CIByteString bs $ B8.map toLower bs
125−instance Show CIByteString where
126− show = show . ciOriginal
127−instance Read CIByteString where
128− readsPrec i = map (\(x, y) -> (mkCIByteString x, y)) . readsPrec i
129−instance Eq CIByteString where
130− x == y = ciLowerCase x == ciLowerCase y
131−instance Ord CIByteString where
132− x <= y = ciLowerCase x <= ciLowerCase y
133−instance IsString CIByteString where
134− fromString = mkCIByteString . fromString
136−-- | Headers sent from the client to the server. Note that this is a
137−-- case-insensitive string, as the HTTP spec specifies.
138−type RequestHeader = CIByteString
139−type RequestHeaders = [(RequestHeader, B.ByteString)]
141−-- | Headers sent from the server to the client. Note that this is a
142−-- case-insensitive string, as the HTTP spec specifies.
143−type ResponseHeader = CIByteString
144−type ResponseHeaders = [(ResponseHeader, B.ByteString)]
146−-- | HTTP status code; a combination of the integral code and a status message.
147−-- Equality is determined solely on the basis of the integral code.
148−data Status = Status { statusCode :: Int, statusMessage :: B.ByteString }
151−instance Eq Status where
152− x == y = statusCode x == statusCode y
155−status200, statusOK :: Status
156−status200 = Status 200 $ B8.pack "OK"
160−status201, statusCreated :: Status
161−status201 = Status 201 $ B8.pack "Created"
162−statusCreated = status201
165−status206, statusPartialContent :: Status
166−status206 = Status 206 $ B8.pack "Partial Content"
167−statusPartialContent = status206
169−-- | Moved Permanently
170−status301, statusMovedPermanently :: Status
171−status301 = Status 301 $ B8.pack "Moved Permanently"
172−statusMovedPermanently = status301
175−status302, statusFound :: Status
176−status302 = Status 302 $ B8.pack "Found"
177−statusFound = status302
180−status303, statusSeeOther :: Status
181−status303 = Status 303 $ B8.pack "See Other"
182−statusSeeOther = status303
185−status400, statusBadRequest :: Status
186−status400 = Status 400 $ B8.pack "Bad Request"
187−statusBadRequest = status400
190−status401, statusUnauthorized :: Status
191−status401 = Status 401 $ B8.pack "Unauthorized"
192−statusUnauthorized = status401
195−status403, statusForbidden :: Status
196−status403 = Status 403 $ B8.pack "Forbidden"
197−statusForbidden = status403
200−status404, statusNotFound :: Status
201−status404 = Status 404 $ B8.pack "Not Found"
202−statusNotFound = status404
204−-- | Method Not Allowed
205−status405, statusNotAllowed :: Status
206−status405 = Status 405 $ B8.pack "Method Not Allowed"
207−statusNotAllowed = status405
209−-- | Internal Server Error
210−status500, statusServerError :: Status
211−status500 = Status 500 $ B8.pack "Internal Server Error"
212−statusServerError = status500
214-- | Information on the request sent by the client. This abstracts away the
50-- | Information on the request sent by the client. This abstracts away the
215-- details of the underlying implementation.
51-- details of the underlying implementation.
216data Request = Request
52data Request = Request
217− { requestMethod :: Method
53+ { requestMethod :: H.Method
218− , httpVersion :: HttpVersion
54+ , httpVersion :: H.HttpVersion
219 -- | Extra path information sent by the client. The meaning varies slightly
55 -- | Extra path information sent by the client. The meaning varies slightly
220 -- depending on backend; in a standalone server setting, this is most likely
56 -- depending on backend; in a standalone server setting, this is most likely
221 -- all information after the domain name. In a CGI application, this would be
57 -- all information after the domain name. In a CGI application, this would be
@@ -225,7 +61,7 @@ data Request = Request
225 , queryString :: B.ByteString
61 , queryString :: B.ByteString
226 , serverName :: B.ByteString
62 , serverName :: B.ByteString
227 , serverPort :: Int
63 , serverPort :: Int
228− , requestHeaders :: [(RequestHeader, B.ByteString)]
64+ , requestHeaders :: H.RequestHeaders
229 -- ^ Was this request made over an SSL connection?
65 -- ^ Was this request made over an SSL connection?
230 , isSecure :: Bool
66 , isSecure :: Bool
231 -- ^ Log the given line in some method; how this is accomplished is
67 -- ^ Log the given line in some method; how this is accomplished is
@@ -237,13 +73,13 @@ data Request = Request
237 deriving Typeable
73 deriving Typeable
239data Response
75data Response
240− = ResponseFile Status ResponseHeaders FilePath
76+ = ResponseFile H.Status H.ResponseHeaders FilePath
241− | ResponseBuilder Status ResponseHeaders Builder
77+ | ResponseBuilder H.Status H.ResponseHeaders Builder
242 | ResponseEnumerator (forall a. ResponseEnumerator a)
78 | ResponseEnumerator (forall a. ResponseEnumerator a)
243 deriving Typeable
79 deriving Typeable
245type ResponseEnumerator a =
81type ResponseEnumerator a =
246− (Status -> ResponseHeaders -> Iteratee Builder IO a) -> IO a
82+ (H.Status -> H.ResponseHeaders -> Iteratee Builder IO a) -> IO a
248responseEnumerator :: Response -> ResponseEnumerator a
84responseEnumerator :: Response -> ResponseEnumerator a
249responseEnumerator (ResponseEnumerator e) f = e f
85responseEnumerator (ResponseEnumerator e) f = e f
@@ -253,7 +89,7 @@ responseEnumerator (ResponseBuilder s h b) f = run_ $ do
253 E.yield () $ E.Chunks [b]
89 E.yield () $ E.Chunks [b]
256−responseLBS :: Status -> ResponseHeaders -> L.ByteString -> Response
92+responseLBS :: H.Status -> H.ResponseHeaders -> L.ByteString -> Response
257responseLBS s h = ResponseBuilder s h . fromLazyByteString
93responseLBS s h = ResponseBuilder s h . fromLazyByteString
259type Application = Request -> Iteratee B.ByteString IO Response
95type Application = Request -> Iteratee B.ByteString IO Response