{-| Module : Network.GemServ Description : Gemini Server Stuff Copyright : (C) Jonathan Lamothe License : AGPL-3.0-or-later Maintainer : jonathan@jlamothe.net Stability : experimental Portability : POSIX This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . -} module Network.GemServ ( encodeRequest, escapeString ) where import Data.Char (ord) import Data.List (intercalate) import Network.GemServ.Types -- | Encodes a 'Request' into a 'String' encodeRequest :: Request -> String encodeRequest req = "gemini://" ++ authority ++ "/" ++ path ++ query where authority = reqHost req ++ case reqPort req of Just port -> ':' : show port Nothing -> "" path = intercalate "/" $ map escapeString $ reqPath req query = case reqQuery req of "" -> "" q -> '?' : escapeString q -- | add required escape sequences to a string escapeString :: String -> String escapeString = concatMap $ \ch -> if ch `elem` unescaped then [ch] else '%' : toHex ch where unescaped = ['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z'] ++ "~-_." toHex ch = let n = ord ch high = n `div` 16 low = n `mod` 16 in [hexDigits !! high, hexDigits !! low] hexDigits :: String hexDigits = ['0'..'9'] ++ ['a'..'f'] --jl