titan
所属分类:自然语言处理
开发工具:Haskell
文件大小:32KB
下载次数:0
上传日期:2021-08-13 06:18:02
上 传 者:
sh-1993
说明: Gemini协议服务器
(A Gemini Protocol Server)
文件列表:
.envrc (8, 2021-08-11)
CHANGELOG.md (108, 2021-08-11)
LICENSE (35106, 2021-08-11)
Setup.hs (46, 2021-08-11)
app (0, 2021-08-11)
app\Main.hs (2907, 2021-08-11)
certs (0, 2021-08-11)
certs\ca.example.com.crt (989, 2021-08-11)
certs\ca.example.com.key (1679, 2021-08-11)
certs\client.example.com.crt (1111, 2021-08-11)
certs\client.example.com.csr (903, 2021-08-11)
certs\client.example.com.key (1675, 2021-08-11)
certs\server.example.com.crt (1111, 2021-08-11)
certs\server.example.com.csr (903, 2021-08-11)
certs\server.example.com.key (1675, 2021-08-11)
default.nix (669, 2021-08-11)
release.nix (91, 2021-08-11)
shell.nix (274, 2021-08-11)
src (0, 2021-08-11)
src\Titan.hs (2046, 2021-08-11)
src\Titan (0, 2021-08-11)
src\Titan\ArgParser.hs (2378, 2021-08-11)
src\Titan\Parser.hs (2527, 2021-08-11)
src\Titan\Router.hs (4155, 2021-08-11)
src\Titan\ToResponse.hs (372, 2021-08-11)
src\Titan\Types.hs (1457, 2021-08-11)
stack.yaml (34, 2021-08-11)
titan.cabal (4185, 2021-08-11)
# Titan
Titan is a [gemini](https://gemini.circumlunar.space/) server whose design is based on [Servant](https://www.servant.dev/).
# How to use
Look at `app/` for an example project.
Titan uses a reduced set of route combinators from Servant:
```
Get a
Capture a
a :> b
:<|>
QueryParam sym a
QueryFlag sym
```
## Example routes
```
type MyAPI =
-- GET /date returns a value of type `Day`
"date" :> Get Day
-- GET /time/:timezone returns a value of type `ZonedTime`
:<|> "time" :> Capture Timezone :> Get ZonedTime
-- GET /add?x={0-9*}&y={0-9*} Returns a value of type `Int`
:<|> "add" :> QueryParam "x" Int :> QueryParam "y" Int :> Get Int
-- GET /books[?published] Returns a value of type `[Text]`
:<|> "books" :> QueryFlag "published" :> Get [Text]
-- Newtype wrapper to prevent an orphan instance
newtype Timezone = Timezone TimeZone
deriving Read
instance FromHttpApiData Timezone where
parseUrlPiece t = Timezone <$> (readTextData t :: Either Text TimeZone)
-- There is one handler per endpoint.
handleDate :: Server (Get Day)
handleDate = do
date <- liftIO $ utctDay <$> getCurrentTime
pure $ Response (Header Two "text/gemini") (Just date)
handleTime :: Server (Capture Timezone :> Get ZonedTime)
handleTime (Timezone tz) = do
time <- liftIO $ utcToZonedTime tz <$> getCurrentTime
pure $ Response (Header Two "text/gemini") (Just time)
handleAdd :: Server (QueryParam "x" Int :> QueryParam "y" Int :> Get Int)
handleAdd (Just x) (Just y) =
pure $ Response (Header Two "text/gemini") (Just (x + y))
handleAdd Nothing Nothing = throwError $ (Five, "Bad values for 'x' and 'y'")
handleAdd Nothing _ = throwError $ (Five, "Bad values for 'x'")
handleAdd _ Nothing = throwError $ (Five, "Bad values for 'y'")
handleBook :: Server (QueryFlag "published" :> Get [Text])
handleBook published =
let books = [ ("One Flew Over the Cuckcoo's Next", True)
, ("The Autobiography of Alice B. Toklas", True)
, ("The Dead Sea Scrolls", False)
, ("The Light House", False)]
in if published
then pure $ Response (Header Two "text/gemini") $
Just $ fmap fst $ filter (\p -> not $ snd p) books
else pure $ Response (Header Two "text/gemini") $
Just $ fmap fst books
-- Handlers run in the `ExceptT (ResponseCode, Text) IO` Monad
handleMyAPI :: Server MyAPI
handleMyAPI = handleDate :<|> handleTime :<|> handleAdd :<|> handleBook
-- Run the server with `runServer`
main :: IO ()
main = Z.withSocketsDo $ do
args <- getArgs >>= parseArgs
runReaderT (runServer (Proxy :: Proxy MyAPI) handleMyAPI) (makeContext args)
```
## Run the server
```
cabal exec titan -- --cert=certs/server.example.com.crt --key=certs/server.example.com.key --cacert=certs/ca.example.com.crt localhost
```
近期下载者:
相关文件:
收藏者: