, getHeader
, getAccept
, getAcceptEncoding
+ , isEncodingAcceptable
, getContentType
-- ** Finding an entity
import Data.Bits
import qualified Data.ByteString.Lazy.Char8 as B
import Data.ByteString.Lazy.Char8 (ByteString)
-import Data.Char
import Data.List
import Data.Maybe
import Network.HTTP.Lucu.Abortion
import Network.HTTP.Lucu.Config
+import Network.HTTP.Lucu.ContentCoding
import Network.HTTP.Lucu.DefaultPage
import Network.HTTP.Lucu.ETag
import qualified Network.HTTP.Lucu.Headers as H
import Network.HTTP.Lucu.HttpVersion
import Network.HTTP.Lucu.Interaction
import Network.HTTP.Lucu.Parser
-import Network.HTTP.Lucu.Parser.Http
import Network.HTTP.Lucu.Postprocess
import Network.HTTP.Lucu.RFC1123DateTime
import Network.HTTP.Lucu.Request
(Just $ "Unparsable Accept: " ++ accept)
-- |Get a list of @(contentCoding, qvalue)@ enumerated on header
--- \"Accept-Encoding\".
+-- \"Accept-Encoding\". The list is sorted in descending order by
+-- qvalue.
getAcceptEncoding :: Resource [(String, Maybe Double)]
getAcceptEncoding
= do accEncM <- getHeader "Accept-Encoding"
-- identity のみが許される。
-> return [("identity", Nothing)]
Just accEnc
- -> case parseStr accEncListP accEnc of
- (Success x, _) -> return x
+ -> case parseStr acceptEncodingListP accEnc of
+ (Success x, _) -> return $ reverse $ sortBy orderAcceptEncodings x
_ -> abort BadRequest []
(Just $ "Unparsable Accept-Encoding: " ++ accEnc)
- where
- accEncListP :: Parser [(String, Maybe Double)]
- accEncListP = allowEOF $! listOf accEncP
-
- accEncP :: Parser (String, Maybe Double)
- accEncP = do coding <- token
- qVal <- option Nothing
- $ do string ";q="
- q <- qvalue
- return $ Just q
- return (normalizeCoding coding, qVal)
-
- normalizeCoding :: String -> String
- normalizeCoding coding
- = case map toLower coding of
- "x-gzip" -> "gzip"
- "x-compress" -> "compress"
- other -> other
+
+-- |Check whether a given content-coding is acceptable.
+isEncodingAcceptable :: String -> Resource Bool
+isEncodingAcceptable coding
+ = do accList <- getAcceptEncoding
+ return (flip any accList $ \ (c, q) ->
+ (c == "*" || c `noCaseEq` coding) && q /= Just 0)
+
-- |Get the header \"Content-Type\" as
-- 'Network.HTTP.Lucu.MIMEType.MIMEType'.
-- header \"Content-Encoding\" to @codings@.
setContentEncoding :: [String] -> Resource ()
setContentEncoding codings
- = setHeader "Content-Encoding" $ joinWith ", " codings
+ = do ver <- getRequestVersion
+ let tr = case ver of
+ HttpVersion 1 0 -> unnormalizeCoding
+ HttpVersion 1 1 -> id
+ setHeader "Content-Encoding" $ joinWith ", " $ map tr codings
{- DecidingBody 時に使用するアクション群 -}