summaryrefslogtreecommitdiff
path: root/mini-http-server/Network/HTTP/Server/Mini/URI.hs
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2026-05-08 19:26:10 +0200
committerTom Smeding <tom@tomsmeding.com>2026-05-08 19:26:10 +0200
commit30d4ca02ea147089af994ea7d5f7941a4bbe94a7 (patch)
tree9fd9086c74976f7851a7622756a20dcb6af91e18 /mini-http-server/Network/HTTP/Server/Mini/URI.hs
parentba9d7504080fb4e9adfb2d33290190e06d2f8773 (diff)
Rename mini-http to mini-http-server
And move Parser to Internal.Parser for test suite
Diffstat (limited to 'mini-http-server/Network/HTTP/Server/Mini/URI.hs')
-rw-r--r--mini-http-server/Network/HTTP/Server/Mini/URI.hs44
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)]