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
34 import Data.Ascii (Ascii, AsciiBuilder)
35 import Data.Convertible.Base
36 import Data.Convertible.Instances.Ascii ()
37 import Data.Convertible.Utils
38 import Data.Monoid.Unicode
39 import Network.HTTP.Lucu.Headers
40 import Network.HTTP.Lucu.HttpVersion
41 import Network.HTTP.Lucu.StatusCode
42 import Network.HTTP.Lucu.StatusCode.Internal
43 import Prelude.Unicode
45 -- |This is the definition of an HTTP response.
46 data Response = Response {
47 resVersion ∷ !HttpVersion
48 , resStatus ∷ !SomeStatusCode
49 , resHeaders ∷ !Headers
52 instance HasHeaders Response where
53 getHeaders = resHeaders
54 setHeaders res hdr = res { resHeaders = hdr }
56 instance ConvertSuccess Response Ascii where
57 {-# INLINE convertSuccess #-}
58 convertSuccess = convertSuccessVia ((⊥) ∷ AsciiBuilder)
60 instance ConvertSuccess Response AsciiBuilder where
61 {-# INLINE convertSuccess #-}
62 convertSuccess (Response {..})
66 cs ("\x0D\x0A" ∷ Ascii) ⊕
69 deriveAttempts [ ([t| Response |], [t| Ascii |])
70 , ([t| Response |], [t| AsciiBuilder |])
73 -- |Returns an HTTP\/1.1 'Response' with no header fields.
74 emptyResponse ∷ StatusCode sc ⇒ sc → Response
77 resVersion = HttpVersion 1 1
78 , resStatus = fromStatusCode sc
82 -- |@'setStatusCode' sc res@ sets the status code of @res@ to @sc@.
83 setStatusCode ∷ StatusCode sc ⇒ sc → Response → Response
86 resStatus = fromStatusCode sc
89 -- |Returns 'True' iff a given 'Response' allows the existence of
90 -- response entity body.
91 resCanHaveBody ∷ Response → Bool
92 {-# INLINEABLE resCanHaveBody #-}
93 resCanHaveBody (Response {..})
94 | isInformational resStatus = False
95 | resStatus ≈ NoContent = False
96 | resStatus ≈ ResetContent = False
97 | resStatus ≈ NotModified = False
100 -- |@'isInformational' sc@ returns 'True' iff @sc '<' 200@.
101 isInformational ∷ StatusCode sc ⇒ sc → Bool
102 {-# INLINE isInformational #-}
103 isInformational = satisfy (< 200)
105 -- |@'isSuccessful' sc@ returns 'True' iff @200 '<=' sc '<' 300@.
106 isSuccessful ∷ StatusCode sc ⇒ sc → Bool
107 {-# INLINE isSuccessful #-}
108 isSuccessful = satisfy (\ n → n ≥ 200 ∧ n < 300)
110 -- |@'isRedirection' sc@ returns 'True' iff @300 '<=' sc '<' 400@.
111 isRedirection ∷ StatusCode sc ⇒ sc → Bool
112 {-# INLINE isRedirection #-}
113 isRedirection = satisfy (\ n → n ≥ 300 ∧ n < 400)
115 -- |@'isError' sc@ returns 'True' iff @400 '<=' sc@
116 isError ∷ StatusCode sc ⇒ sc → Bool
117 {-# INLINE isError #-}
118 isError = satisfy (≥ 400)
120 -- |@'isClientError' sc@ returns 'True' iff @400 '<=' sc '<' 500@.
121 isClientError ∷ StatusCode sc ⇒ sc → Bool
122 {-# INLINE isClientError #-}
123 isClientError = satisfy (\ n → n ≥ 400 ∧ n < 500)
125 -- |@'isServerError' sc@ returns 'True' iff @500 '<=' sc@.
126 isServerError ∷ StatusCode sc ⇒ sc → Bool
127 {-# INLINE isServerError #-}
128 isServerError = satisfy (≥ 500)
130 satisfy ∷ StatusCode sc ⇒ (Int → Bool) → sc → Bool
131 {-# INLINE satisfy #-}
132 satisfy p (numericCode → num) = p num