6 -- |Utility functions used internally in the Lucu httpd. These
7 -- functions may be useful too for something else.
8 module Network.HTTP.Lucu.Utils
12 , parseWWWFormURLEncoded
16 import Data.Ascii (Ascii, AsciiBuilder)
17 import qualified Data.Ascii as A
18 import qualified Data.ByteString.Char8 as BS
19 import Data.List hiding (last)
20 import Data.Monoid.Unicode
22 import Prelude hiding (last)
23 import Prelude.Unicode
25 -- |> splitBy (== ':') "ab:c:def"
26 -- > ==> ["ab", "c", "def"]
27 splitBy ∷ (a → Bool) → [a] → [[a]]
29 = case break isSep src
30 of (last , [] ) → [last]
31 (first, _sep:rest) → first : splitBy isSep rest
33 -- |> joinWith ":" ["ab", "c", "def"]
35 joinWith ∷ Ascii → [AsciiBuilder] → AsciiBuilder
36 {-# INLINEABLE joinWith #-}
37 joinWith sep = flip go (∅)
39 go ∷ [AsciiBuilder] → AsciiBuilder → AsciiBuilder
43 go (x:xs) ab = go xs (ab ⊕ A.toAsciiBuilder sep ⊕ x)
49 -- > ==> "\"ab\\\"c\""
50 quoteStr ∷ Ascii → AsciiBuilder
51 quoteStr str = A.toAsciiBuilder "\"" ⊕
52 go (A.toByteString str) (∅) ⊕
55 go ∷ BS.ByteString → AsciiBuilder → AsciiBuilder
57 = case BS.break (≡ '"') bs of
59 | BS.null y → ab ⊕ b2ab x
60 | otherwise → go (BS.tail y) (ab ⊕ b2ab x
61 ⊕ A.toAsciiBuilder "\\\"")
63 b2ab ∷ BS.ByteString → AsciiBuilder
64 b2ab = A.toAsciiBuilder ∘ A.unsafeFromByteString
66 -- |> parseWWWFormURLEncoded "aaa=bbb&ccc=ddd"
67 -- > ==> [("aaa", "bbb"), ("ccc", "ddd")]
68 parseWWWFormURLEncoded ∷ String → [(String, String)]
69 parseWWWFormURLEncoded src
71 | otherwise = do pairStr <- splitBy (\ c → c == ';' || c == '&') src
72 let (key, value) = break (== '=') pairStr
73 return ( unEscapeString key
74 , unEscapeString $ case value of