7 -- |Definition of things related on HTTP response.
8 module Network.HTTP.Lucu.Response
14 , module Network.HTTP.Lucu.StatusCode
32 import Data.Ascii (AsciiBuilder)
33 import qualified Data.Ascii as A
34 import Data.Monoid.Unicode
35 import Network.HTTP.Lucu.Headers
36 import Network.HTTP.Lucu.HttpVersion
37 import Network.HTTP.Lucu.StatusCode
38 import Network.HTTP.Lucu.StatusCode.Internal
39 import Prelude.Unicode
41 -- |Convert a 'StatusCode' to an 'AsciiBuilder'.
42 printStatusCode ∷ StatusCode sc ⇒ sc → AsciiBuilder
43 {-# INLINEABLE printStatusCode #-}
44 printStatusCode = A.toAsciiBuilder ∘ textualStatus
46 -- |This is the definition of an HTTP response.
47 data Response = Response {
48 resVersion ∷ !HttpVersion
49 , resStatus ∷ !SomeStatusCode
50 , resHeaders ∷ !Headers
53 instance HasHeaders Response where
54 getHeaders = resHeaders
55 setHeaders res hdr = res { resHeaders = hdr }
57 -- |Returns an HTTP\/1.1 'Response' with no header fields.
58 emptyResponse ∷ StatusCode sc ⇒ sc → Response
61 resVersion = HttpVersion 1 1
62 , resStatus = fromStatusCode sc
66 -- |Returns 'True' iff a given 'Response' allows the existence of
67 -- response entity body.
68 resCanHaveBody ∷ Response → Bool
69 {-# INLINEABLE resCanHaveBody #-}
70 resCanHaveBody (Response {..})
71 | isInformational resStatus = False
72 | resStatus ≈ NoContent = False
73 | resStatus ≈ ResetContent = False
74 | resStatus ≈ NotModified = False
77 -- |Convert a 'Response' to 'AsciiBuilder'.
78 printResponse ∷ Response → AsciiBuilder
79 {-# INLINEABLE printResponse #-}
80 printResponse (Response {..})
81 = printHttpVersion resVersion ⊕
82 A.toAsciiBuilder " " ⊕
83 printStatusCode resStatus ⊕
84 A.toAsciiBuilder "\x0D\x0A" ⊕
85 printHeaders resHeaders
87 -- |@'isInformational' sc@ returns 'True' iff @sc < 200@.
88 isInformational ∷ StatusCode sc ⇒ sc → Bool
89 {-# INLINE isInformational #-}
90 isInformational = satisfy (< 200)
92 -- |@'isSuccessful' sc@ returns 'True' iff @200 <= sc < 300@.
93 isSuccessful ∷ StatusCode sc ⇒ sc → Bool
94 {-# INLINE isSuccessful #-}
95 isSuccessful = satisfy (\ n → n ≥ 200 ∧ n < 300)
97 -- |@'isRedirection' sc@ returns 'True' iff @300 <= sc < 400@.
98 isRedirection ∷ StatusCode sc ⇒ sc → Bool
99 {-# INLINE isRedirection #-}
100 isRedirection = satisfy (\ n → n ≥ 300 ∧ n < 400)
102 -- |@'isError' sc@ returns 'True' iff @400 <= sc@
103 isError ∷ StatusCode sc ⇒ sc → Bool
104 {-# INLINE isError #-}
105 isError = satisfy (≥ 400)
107 -- |@'isClientError' sc@ returns 'True' iff @400 <= sc < 500@.
108 isClientError ∷ StatusCode sc ⇒ sc → Bool
109 {-# INLINE isClientError #-}
110 isClientError = satisfy (\ n → n ≥ 400 ∧ n < 500)
112 -- |@'isServerError' sc@ returns 'True' iff @500 <= sc@.
113 isServerError ∷ StatusCode sc ⇒ sc → Bool
114 {-# INLINE isServerError #-}
115 isServerError = satisfy (≥ 500)
117 satisfy ∷ StatusCode sc ⇒ (Int → Bool) → sc → Bool
118 {-# INLINE satisfy #-}
119 satisfy p (numericCode → num) = p num