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.Eq.Indirect
37 import Data.Monoid.Unicode
38 import Network.HTTP.Lucu.Headers
39 import Network.HTTP.Lucu.HttpVersion
40 import Network.HTTP.Lucu.StatusCode
41 import Network.HTTP.Lucu.StatusCode.Internal
42 import Prelude.Unicode
44 -- |This is the definition of an HTTP response.
45 data Response = Response {
46 resVersion ∷ !HttpVersion
47 , resStatus ∷ !SomeStatusCode
48 , resHeaders ∷ !Headers
51 instance HasHeaders Response where
52 getHeaders = resHeaders
53 setHeaders res hdr = res { resHeaders = hdr }
55 instance ConvertSuccess Response Ascii where
56 {-# INLINE convertSuccess #-}
57 convertSuccess = convertSuccessVia ((⊥) ∷ AsciiBuilder)
59 instance ConvertSuccess Response AsciiBuilder where
60 {-# INLINE convertSuccess #-}
61 convertSuccess (Response {..})
65 cs ("\x0D\x0A" ∷ Ascii) ⊕
68 deriveAttempts [ ([t| Response |], [t| Ascii |])
69 , ([t| Response |], [t| AsciiBuilder |])
72 -- |Returns an HTTP\/1.1 'Response' with no header fields.
73 emptyResponse ∷ StatusCode sc ⇒ sc → Response
76 resVersion = HttpVersion 1 1
77 , resStatus = fromStatusCode sc
81 -- |@'setStatusCode' sc res@ sets the status code of @res@ to @sc@.
82 setStatusCode ∷ StatusCode sc ⇒ sc → Response → Response
85 resStatus = fromStatusCode sc
88 -- |Returns 'True' iff a given 'Response' allows the existence of
89 -- response entity body.
90 resCanHaveBody ∷ Response → Bool
91 {-# INLINEABLE resCanHaveBody #-}
92 resCanHaveBody (Response {..})
93 | isInformational resStatus = False
94 | resStatus ≡: NoContent = False
95 | resStatus ≡: ResetContent = False
96 | resStatus ≡: NotModified = False
99 -- |@'isInformational' sc@ returns 'True' iff @sc '<' 200@.
100 isInformational ∷ StatusCode sc ⇒ sc → Bool
101 {-# INLINE isInformational #-}
102 isInformational = satisfy (< 200)
104 -- |@'isSuccessful' sc@ returns 'True' iff @200 '<=' sc '<' 300@.
105 isSuccessful ∷ StatusCode sc ⇒ sc → Bool
106 {-# INLINE isSuccessful #-}
107 isSuccessful = satisfy (\ n → n ≥ 200 ∧ n < 300)
109 -- |@'isRedirection' sc@ returns 'True' iff @300 '<=' sc '<' 400@.
110 isRedirection ∷ StatusCode sc ⇒ sc → Bool
111 {-# INLINE isRedirection #-}
112 isRedirection = satisfy (\ n → n ≥ 300 ∧ n < 400)
114 -- |@'isError' sc@ returns 'True' iff @400 '<=' sc@
115 isError ∷ StatusCode sc ⇒ sc → Bool
116 {-# INLINE isError #-}
117 isError = satisfy (≥ 400)
119 -- |@'isClientError' sc@ returns 'True' iff @400 '<=' sc '<' 500@.
120 isClientError ∷ StatusCode sc ⇒ sc → Bool
121 {-# INLINE isClientError #-}
122 isClientError = satisfy (\ n → n ≥ 400 ∧ n < 500)
124 -- |@'isServerError' sc@ returns 'True' iff @500 '<=' sc@.
125 isServerError ∷ StatusCode sc ⇒ sc → Bool
126 {-# INLINE isServerError #-}
127 isServerError = satisfy (≥ 500)
129 satisfy ∷ StatusCode sc ⇒ (Int → Bool) → sc → Bool
130 {-# INLINE satisfy #-}
131 satisfy p (numericCode → num) = p num