@@ -87,15 +87,26 @@ getsHaveLastModifiedHeader
87-- __References__:
87-- __References__:
89-- * @Allow@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.7>
89-- * @Allow@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.7>
90+-- * Status 405: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html RFC 2616 Section 10.4.6>
90−notAllowedContainsAllowHeader :: ResponsePredicate Text Bool
91+notAllowedContainsAllowHeader :: RequestPredicate Text Bool
91notAllowedContainsAllowHeader
92notAllowedContainsAllowHeader
95+ , reqResps = \req mgr -> mapM (flip httpLbs mgr)
96+ [ req { method = renderStdMethod m }
97+ | m <- [minBound .. maxBound ]
98+ , renderStdMethod m /= method req ]
92− = ResponsePredicate "notAllowedContainsAllowHeader" (\resp ->
102+ name = "notAllowedContainsAllowHeader"
103+ pred' = ResponsePredicate name (\resp ->
93− if responseStatus resp == status405
104+ if responseStatus resp == status405
94− then hasValidHeader "Allow" go resp
105+ then hasValidHeader "Allow" go resp
95− else True)
106+ else True)
97− go x = all (\y -> isRight $ parseMethod $ SBSC.pack y)
108+ go x = all (\y -> isRight $ parseMethod $ SBSC.pack y)
98− $ wordsBy (`elem` (", " :: [Char])) (SBSC.unpack x)
109+ $ wordsBy (`elem` (", " :: [Char])) (SBSC.unpack x)
101-- | When a request contains an @Accept@ header, the server must either return
112-- | When a request contains an @Accept@ header, the server must either return
@@ -104,28 +115,64 @@ notAllowedContainsAllowHeader
105-- This function checks that every *successful* response has a @Content-Type@
116-- This function checks that every *successful* response has a @Content-Type@
106-- header that matches the @Accept@ header.
117-- header that matches the @Accept@ header.
121+-- * @Accept@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.1>
107−honoursAcceptHeader :: Predicate b Bool
122+honoursAcceptHeader :: RequestPredicate b Bool
108honoursAcceptHeader
123honoursAcceptHeader
124+ = RequestPredicate name (ResponsePredicate name $ \req mgr -> do
126+ resp <- httpLbs req mgr
127+ let scode = responseStatus resp
128+ sctype = maybeToList $ lookup "Content-Type" $ responseHeaders resp
129+ sacc = fromMaybe "*/*" $ lookup "Accept" $ requestHeaders req
130+ if 100 < scode && scode < 300
131+ then isJust matchAccept sacc sctype
109− = RequestPredicate "honoursAcceptHeader" _
133+ where name = "honoursAcceptHeader"
136+-- | [__Best Practice__]
111−-- | Whether or not a representation should be cached, it is good practice to
138+-- Whether or not a representation should be cached, it is good practice to
112-- have a @Cache-Control@ header for @GET@ requests. If the representation
139-- have a @Cache-Control@ header for @GET@ requests. If the representation
113-- should not be cached, used @Cache-Control: no-cache@.
140-- should not be cached, used @Cache-Control: no-cache@.
115−-- This function checks that @GET@ responses have a valid @Cache-Control@
142+-- This function checks that @GET@ responses have @Cache-Control@ header.
116−-- header.
143+-- It does NOT currently check that the header is valid.
118−-- References: RFC 7234 Section 5.2
119−-- https://tools.ietf.org/html/rfc7234#section-5.2
147+-- * @Cache-Control@ header: <https://tools.ietf.org/html/rfc7234#section-5.2 RFC 7234 Section 5.2>
120−getsHaveCacheControlHeader :: Predicate b Bool
148+getsHaveCacheControlHeader :: RequestPredicate Text Bool
121getsHaveCacheControlHeader
149getsHaveCacheControlHeader
151+ { reqPredName = name
152+ , reqResps = \req mgr -> if method req == methodGet
153+ then return <$> httpLbs req mgr
155+ , reqPred = ResponsePredicate name $ \resp ->
156+ isJust $ lookup "Cache-Control" $ responseHeaders resp
122− = ResponsePredicate "getsHaveCacheControlHeader" _
158+ where name = "getsHaveCacheControlHeader"
160+-- | [__Best Practice__]
124−-- | Like 'getsHaveCacheControlHeader', but for @HEAD@ requests.
162+-- Like 'getsHaveCacheControlHeader', but for @HEAD@ requests.
125−headsHaveCacheControlHeader :: Predicate b Bool
163+headsHaveCacheControlHeader :: RequestPredicate Text Bool
126headsHaveCacheControlHeader
164headsHaveCacheControlHeader
166+ { reqPredName = name
167+ , reqResps = \req mgr -> if method req == methodHead
168+ then return <$> httpLbs req mgr
170+ , reqPred = ResponsePredicate name $ \resp ->
171+ isJust $ lookup "Cache-Control" $ responseHeaders resp
127− = ResponsePredicate "headsHaveCacheControlHeader" _
173+ where name = "headsHaveCacheControlHeader"
131-- If the original request modifies the resource, this function makes two
178-- If the original request modifies the resource, this function makes two