61 lines
1.3 KiB
Haskell
61 lines
1.3 KiB
Haskell
module Gemini where
|
|
|
|
import Data.ByteString.UTF8
|
|
import Data.Text
|
|
import Network.Mime
|
|
import System.Directory (doesFileExist, doesDirectoryExist)
|
|
import Text.Regex
|
|
import Text.Regex.PCRE
|
|
|
|
|
|
-- check :: FilePath -> IO Bool
|
|
-- check s = do
|
|
-- result <- doesFileExist
|
|
-- if result
|
|
-- then pure True
|
|
-- else pure False
|
|
|
|
-- return components of the url
|
|
-- gemini:// | hostname | uri | ? | query
|
|
parse_url :: String -> [[String]]
|
|
parse_url url =
|
|
(sanitize_uri url) =~ "^(gemini:\\/\\/)([^\\/]*)\\/?([^\\?]*)(\\?)?(.*)?(\\r\\n)$"
|
|
|
|
-- remove any .. in the uri that could escape the location
|
|
sanitize_uri :: String -> String
|
|
sanitize_uri path =
|
|
subRegex (mkRegex "\\.\\.\\/") path ""
|
|
|
|
|
|
-- return a file as a string
|
|
read_file :: String -> IO String
|
|
read_file path = do
|
|
text <- readFile path
|
|
pure text
|
|
|
|
-- read from stdin
|
|
get_request :: IO String
|
|
get_request = do
|
|
stdin <- getContents
|
|
pure stdin
|
|
|
|
data Gemini = MkGemini
|
|
{ domain :: String
|
|
, file :: String
|
|
, query :: String
|
|
, mime :: String
|
|
}
|
|
|
|
parse_to_gemini :: [[String]] -> Gemini
|
|
parse_to_gemini tab =
|
|
MkGemini
|
|
{ domain = tab!!0!!2
|
|
, file = tab!!0!!3
|
|
, query = tab!!0!!5
|
|
, mime = toString (defaultMimeLookup (pack (tab!!0!!3)))
|
|
}
|
|
|
|
get_reply :: String -> Int -> String
|
|
get_reply mime 20 =
|
|
"20 " ++ mime ++ "\n"
|