gemini-router 0.1.0.0 → 0.1.1.0
raw patch · 3 files changed
+37/−8 lines, 3 filesdep +HsOpenSSLdep ~basedep ~gemini-serverPVP ok
version bump matches the API change (PVP)
Dependencies added: HsOpenSSL
Dependency ranges changed: base, gemini-server
API changes (from Hackage documentation)
+ Network.Gemini.Router: cert :: Applicative m => String -> (X509 -> RouteT m Response) -> RouteT m Response
+ Network.Gemini.Router: optionalCert :: Applicative m => (Maybe X509 -> RouteT m Response) -> RouteT m Response
Files
- CHANGELOG.md +5/−1
- Network/Gemini/Router.hs +27/−4
- gemini-router.cabal +5/−3
CHANGELOG.md view
@@ -1,6 +1,10 @@ # Revision history for gemini-router +## 0.1.1.0 -- 2021-02-22++* SSL/TLS support+ - Add functions for obtaining a client certificate+ ## 0.1.0.0 -- 2020-07-24 * First version. Released on an unsuspecting world.-
Network/Gemini/Router.hs view
@@ -14,6 +14,8 @@ , capture , input , optionalInput+, cert+, optionalCert , custom -- * Getters , getRequest@@ -30,6 +32,7 @@ import Control.Monad.IO.Class (MonadIO(..)) import Network.URI (uriQuery, pathSegments, unEscapeString)+import OpenSSL.X509 (X509) #if __GLASGOW_HASKELL__ < 808 import Control.Monad.Fail (MonadFail(..))@@ -91,7 +94,7 @@ runRouteT' runM r req = fromMaybe notFound <$> runM (runRouteT r req path) where notFound = Response 51 "Not found" mempty- path = unEscapeString <$> pathSegments req+ path = unEscapeString <$> pathSegments (requestURI req) -- Building Routes -------------------------------@@ -132,7 +135,7 @@ -- and returns the route to run on the -- rest of the path -> RouteT f Response-input q f = RouteT $ \req path -> case uriQuery req of+input q f = RouteT $ \req path -> case uriQuery $ requestURI req of '?':query -> runRouteT (f $ unEscapeString query) req path _ -> pure $ pure $ Response 10 q mempty @@ -143,10 +146,31 @@ -- returns the route to run on -- the rest of the path -> RouteT f a-optionalInput f = RouteT $ \req path -> case uriQuery req of+optionalInput f = RouteT $ \req path -> case uriQuery $ requestURI req of '?':query -> runRouteT (f $ Just $ unEscapeString query) req path _ -> runRouteT (f Nothing) req path +-- | Require a client certificate, returning an error (code 60) if absent+cert :: Applicative m+ => String -- ^ String to return to the client if there is no+ -- client certificate in the request+ -> (X509 -> RouteT m Response) -- ^ Function that takes the client+ -- certificate and returns the route to run+ -- on the rest of the request+ -> RouteT m Response+cert msg f = RouteT $ \req path -> case requestCert req of+ Just c -> runRouteT (f c) req path+ Nothing -> pure $ pure $ Response 60 msg mempty++-- | Obtain, if present, the client certificate+optionalCert :: Applicative m+ => (Maybe X509 -> RouteT m Response)+ -- ^ Function that takes the client certificate (if present)+ -- and returns the route to run on the rest of the request+ -> RouteT m Response+optionalCert f = RouteT $ \req path ->+ runRouteT (f $ requestCert req) req path+ -- | Build custom routes. Takes a function that takes the request and the -- remaining path segments and returns the result. A 'Nothing' makes the -- request fall through to the next route@@ -161,4 +185,3 @@ getPath :: Applicative m => RouteT m [String] getPath = RouteT $ \_ path -> pure $ Just path-
gemini-router.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: gemini-router-version: 0.1.0.0+version: 0.1.1.0 synopsis: A simple Happstack-style Gemini router description: This package contains a 'Router' monad transformer that works on top of the@@ -26,10 +26,12 @@ exposed-modules: Network.Gemini.Router -- other-modules: other-extensions: FlexibleInstances, CPP- build-depends: base ^>=4.13.0.0 || ^>=4.14.0.0- , gemini-server ^>=0.1.0.0+ build-depends: base ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0+ , gemini-server ^>=0.2.0.0 , transformers ^>=0.5.6.2 , network-uri ^>=2.6.3.0 || ^>=2.7.0.0+ , HsOpenSSL ^>=0.11.5.1 -- hs-source-dirs:+ ghc-options: -Wall default-language: Haskell2010