3 , MultiParamTypeClasses
10 -- |Definition of things related on HTTP response.
11 module Network.HTTP.Lucu.Response
12 ( -- * Class and Types
17 , module Network.HTTP.Lucu.StatusCode
32 import Data.Ascii (Ascii, AsciiBuilder)
33 import Data.Convertible.Base
34 import Data.Convertible.Instances.Ascii ()
35 import Data.Convertible.Utils
36 import Data.Monoid.Unicode
37 import Network.HTTP.Lucu.Headers
38 import Network.HTTP.Lucu.HttpVersion
39 import Network.HTTP.Lucu.StatusCode
40 import Network.HTTP.Lucu.StatusCode.Internal
41 import Prelude.Unicode
43 -- |This is the definition of an HTTP response.
44 data Response = Response {
45 resVersion ∷ !HttpVersion
46 , resStatus ∷ !SomeStatusCode
47 , resHeaders ∷ !Headers
50 instance HasHeaders Response where
51 getHeaders = resHeaders
52 setHeaders res hdr = res { resHeaders = hdr }
54 instance ConvertSuccess Response Ascii where
55 {-# INLINE convertSuccess #-}
56 convertSuccess = convertSuccessVia ((⊥) ∷ AsciiBuilder)
58 instance ConvertSuccess Response AsciiBuilder where
59 {-# INLINE convertSuccess #-}
60 convertSuccess (Response {..})
64 cs ("\x0D\x0A" ∷ Ascii) ⊕
67 deriveAttempts [ ([t| Response |], [t| Ascii |])
68 , ([t| Response |], [t| AsciiBuilder |])
71 -- |Returns an HTTP\/1.1 'Response' with no header fields.
72 emptyResponse ∷ StatusCode sc ⇒ sc → Response
75 resVersion = HttpVersion 1 1
76 , resStatus = fromStatusCode sc
80 -- |@'setStatusCode' sc res@ sets the status code of @res@ to @sc@.
81 setStatusCode ∷ StatusCode sc ⇒ sc → Response → Response
84 resStatus = fromStatusCode sc
87 -- |Returns 'True' iff a given 'Response' allows the existence of
88 -- response entity body.
89 resCanHaveBody ∷ Response → Bool
90 {-# INLINEABLE resCanHaveBody #-}
91 resCanHaveBody (Response {..})
92 | isInformational resStatus = False
93 | resStatus ≡ cs NoContent = False
94 | resStatus ≡ cs ResetContent = False
95 | resStatus ≡ cs NotModified = False
98 -- |@'isInformational' sc@ returns 'True' iff @sc '<' 200@.
99 isInformational ∷ StatusCode sc ⇒ sc → Bool
100 {-# INLINE isInformational #-}
101 isInformational = satisfy (< 200)
103 -- |@'isSuccessful' sc@ returns 'True' iff @200 '<=' sc '<' 300@.
104 isSuccessful ∷ StatusCode sc ⇒ sc → Bool
105 {-# INLINE isSuccessful #-}
106 isSuccessful = satisfy (\ n → n ≥ 200 ∧ n < 300)
108 -- |@'isRedirection' sc@ returns 'True' iff @300 '<=' sc '<' 400@.
109 isRedirection ∷ StatusCode sc ⇒ sc → Bool
110 {-# INLINE isRedirection #-}
111 isRedirection = satisfy (\ n → n ≥ 300 ∧ n < 400)
113 -- |@'isError' sc@ returns 'True' iff @400 '<=' sc@
114 isError ∷ StatusCode sc ⇒ sc → Bool
115 {-# INLINE isError #-}
116 isError = satisfy (≥ 400)
118 -- |@'isClientError' sc@ returns 'True' iff @400 '<=' sc '<' 500@.
119 isClientError ∷ StatusCode sc ⇒ sc → Bool
120 {-# INLINE isClientError #-}
121 isClientError = satisfy (\ n → n ≥ 400 ∧ n < 500)
123 -- |@'isServerError' sc@ returns 'True' iff @500 '<=' sc@.
124 isServerError ∷ StatusCode sc ⇒ sc → Bool
125 {-# INLINE isServerError #-}
126 isServerError = satisfy (≥ 500)
128 satisfy ∷ StatusCode sc ⇒ (Int → Bool) → sc → Bool
129 {-# INLINE satisfy #-}
130 satisfy p (numericCode → num) = p num