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 → [Ascii] → AsciiBuilder
36 {-# INLINEABLE joinWith #-}
37 joinWith sep = flip go (∅)
39 go ∷ [Ascii] → A.AsciiBuilder → A.AsciiBuilder
42 go (x:[]) ab = ab ⊕ A.toAsciiBuilder x
43 go (x:xs) ab = go xs ( ab ⊕
44 A.toAsciiBuilder sep ⊕
51 -- > ==> "\"ab\\\"c\""
52 quoteStr ∷ Ascii → AsciiBuilder
53 quoteStr str = A.toAsciiBuilder "\"" ⊕
54 go (A.toByteString str) (∅) ⊕
57 go ∷ BS.ByteString → AsciiBuilder → AsciiBuilder
59 = case BS.break (≡ '"') bs of
61 | BS.null y → ab ⊕ b2ab x
62 | otherwise → go (BS.tail y) (ab ⊕ b2ab x
63 ⊕ A.toAsciiBuilder "\\\"")
65 b2ab ∷ BS.ByteString → AsciiBuilder
66 b2ab = A.toAsciiBuilder ∘ A.unsafeFromByteString
68 -- |> parseWWWFormURLEncoded "aaa=bbb&ccc=ddd"
69 -- > ==> [("aaa", "bbb"), ("ccc", "ddd")]
70 parseWWWFormURLEncoded ∷ String → [(String, String)]
71 parseWWWFormURLEncoded src
73 | otherwise = do pairStr <- splitBy (\ c → c == ';' || c == '&') src
74 let (key, value) = break (== '=') pairStr
75 return ( unEscapeString key
76 , unEscapeString $ case value of