-getHeader :: String -> Resource (Maybe String)
-getHeader name = name `seq`
- do req <- getRequest
- return $! H.getHeader name req
-
--- |Get a list of 'Network.HTTP.Lucu.MIMEType.MIMEType' enumerated on
--- header \"Accept\".
-getAccept :: Resource [MIMEType]
-getAccept = do accept <- getHeader "Accept"
- if accept == Nothing then
- return []
- else
- case parseStr mimeTypeListP $ fromJust accept of
- (Success xs, _) -> return xs
- _ -> return []
-
--- |Get the header \"Content-Type\" as
--- 'Network.HTTP.Lucu.MIMEType.MIMEType'.
-getContentType :: Resource (Maybe MIMEType)
-getContentType = do cType <- getHeader "Content-Type"
- if cType == Nothing then
- return Nothing
- else
- case parseStr mimeTypeP $ fromJust cType of
- (Success t, _) -> return $ Just t
- _ -> return Nothing
+getHeader ∷ CIAscii → Resource (Maybe Ascii)
+getHeader name
+ = H.getHeader name <$> getRequest
+
+-- |Get a list of 'MIMEType' enumerated on header \"Accept\".
+getAccept ∷ Resource [MIMEType]
+getAccept
+ = do acceptM ← getHeader "Accept"
+ case acceptM of
+ Nothing
+ → return []
+ Just accept
+ → case P.parseOnly p (A.toByteString accept) of
+ Right xs → return xs
+ Left _ → abort BadRequest []
+ (Just $ "Unparsable Accept: " ⊕ A.toText accept)
+ where
+ p = do xs ← mimeTypeListP
+ P.endOfInput
+ return xs
+
+-- |Get a list of @(contentCoding, qvalue)@ enumerated on header
+-- \"Accept-Encoding\". The list is sorted in descending order by
+-- qvalue.
+getAcceptEncoding ∷ Resource [(CIAscii, Maybe Double)]
+getAcceptEncoding
+ = do accEncM ← getHeader "Accept-Encoding"
+ case accEncM of
+ Nothing
+ -- HTTP/1.0 には Accept-Encoding が無い場合の規定が無い
+ -- ので安全の爲 identity が指定された事にする。HTTP/1.1
+ -- の場合は何でも受け入れて良い事になってゐるので "*" が
+ -- 指定された事にする。
+ → do ver ← getRequestVersion
+ case ver of
+ HttpVersion 1 0 → return [("identity", Nothing)]
+ HttpVersion 1 1 → return [("*" , Nothing)]
+ _ → abort InternalServerError []
+ (Just "getAcceptEncoding: unknown HTTP version")
+ Just ae
+ → if ae ≡ "" then
+ -- identity のみが許される。
+ return [("identity", Nothing)]
+ else
+ case P.parseOnly p (A.toByteString ae) of
+ Right xs → return $ map toTuple $ reverse $ sort xs
+ Left _ → abort BadRequest []
+ (Just $ "Unparsable Accept-Encoding: " ⊕ A.toText ae)
+ where
+ p = do xs ← acceptEncodingListP
+ P.endOfInput
+ return xs