diff options
Diffstat (limited to 'mini-http-server/Network/HTTP/Server/Mini/URI.hs')
| -rw-r--r-- | mini-http-server/Network/HTTP/Server/Mini/URI.hs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/mini-http-server/Network/HTTP/Server/Mini/URI.hs b/mini-http-server/Network/HTTP/Server/Mini/URI.hs new file mode 100644 index 0000000..13d7c35 --- /dev/null +++ b/mini-http-server/Network/HTTP/Server/Mini/URI.hs @@ -0,0 +1,44 @@ +{-# LANGUAGE ViewPatterns #-} +module Network.HTTP.Server.Mini.URI where + +import Data.ByteString (ByteString) +import Data.ByteString qualified as BS + +import Network.HTTP.Server.Mini.Util + + +-- | (path components, query string) +-- +-- TODO: percent-decode +parseURI :: ByteString -> ([ByteString], [(ByteString, ByteString)]) +parseURI = \bs -> + case BS.uncons bs of + Just ((== ord8 '/') -> True, bs1) -> goPath id bs1 + _ -> ([], []) + where + goPath f bs + | BS.null bs = (f [], []) + | otherwise = + let (comp, bs1) = BS.span (\c -> c /= ord8 '/' && c /= ord8 '?') bs + in case BS.uncons bs1 of + Just ((== ord8 '/') -> True, bs2) -> + goPath (f . (comp:)) bs2 + Just ((== ord8 '?') -> True, bs2) -> + (f [comp], goQuery bs2) + _ -> (f [comp], []) + + goQuery bs + | BS.null bs = [] + | Just ((== ord8 '&') -> True, bs1) <- BS.uncons bs = goQuery bs1 + | otherwise = + let (key, bs1) = BS.span (\c -> c /= ord8 '=' && c /= ord8 '&') bs + in case BS.uncons bs1 of + Just ((== ord8 '=') -> True, bs2) -> + let (val, bs3) = BS.span (\c -> c /= ord8 '&') bs2 + in case BS.uncons bs3 of + Just (_, bs4) -> (key, val) : goQuery bs4 + Nothing -> [(key, val)] + Just ((== ord8 '&') -> True, bs2) -> + (key, BS.empty) : goQuery bs2 + _ -> + [(key, BS.empty)] |
