noCaseCmp' p1 l1 p2 l2
| p1 `seq` l1 `seq` p2 `seq` l2 `seq` False = undefined
| l1 == 0 && l2 == 0 = return EQ
- | l1 == 0 && l1 /= 0 = return LT
- | l1 /= 0 && l2 == 0 = return GT
+ | l1 == 0 = return LT
+ | l2 == 0 = return GT
| otherwise
= do c1 <- peek p1
c2 <- peek p2
toHeaders :: [(ByteString, ByteString)] -> Headers
-toHeaders xs = M.fromList [(toNCBS a, b) | (a, b) <- xs]
+toHeaders xs = mkHeaders xs M.empty
+
+
+mkHeaders :: [(ByteString, ByteString)] -> Headers -> Headers
+mkHeaders [] m = m
+mkHeaders ((key, val):xs) m = mkHeaders xs $
+ case M.lookup (toNCBS key) m of
+ Nothing -> M.insert (toNCBS key) val m
+ Just old -> M.insert (toNCBS key) (merge old val) m
+ where
+ merge :: ByteString -> ByteString -> ByteString
+ -- カンマ區切りである事を假定する。RFC ではカンマ區切りに出來ない
+ -- ヘッダは複數個あってはならない事になってゐる。
+ merge a b
+ | C8.null a && C8.null b = C8.empty
+ | C8.null a = b
+ | C8.null b = a
+ | otherwise = C8.concat [a, C8.pack ", ", b]
fromHeaders :: Headers -> [(ByteString, ByteString)]
headersP :: Parser Headers
headersP = do xs <- many header
crlf
- return (M.fromList xs)
+ return $! toHeaders xs
where
- header :: Parser (NCBS, ByteString)
+ header :: Parser (ByteString, ByteString)
header = do name <- token
char ':'
-- FIXME: これは多少インチキだが、RFC 2616 のこの部分
crlf
let value = foldr (++) "" contents
norm = normalize value
- return (toNCBS $ C8.pack name, C8.pack norm)
+ return (C8.pack name, C8.pack norm)
normalize :: String -> String
normalize = trimBody . trim isWhiteSpace