packages feed

porpoise (empty) → 0.1.0.0

raw patch · 6 files changed

+294/−0 lines, 6 filesdep +basedep +http-typesdep +mtlsetup-changed

Dependencies added: base, http-types, mtl, network, porpoise, profunctors, unliftio, vault, wai, warp

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for porpoise++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,7 @@+Copyright 2020 Samuel Schlesinger++Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Web/Porpoise.hs view
@@ -0,0 +1,222 @@+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE RankNTypes #-}+{- |+Module: Porpoise+Description: A very minimal web framework wrapping wai+Copyright: (c) Samuel Schlesinger 2020+License: MIT+Maintainer: sgschlesinger@gmail.com+Stability: experimental+Portability: POSIX, Windows++A very minimal HTTP server framework wrapping wai.+-}+module Web.Porpoise+( +  -- ** Server Language+  Server(..)+, toApplication+, liftS+, serverIO+, Profunctor(..)+, Category(..)+, MonadUnliftIO(..)+, ResponseReceived+, Application+  -- ** Observing a 'Request' +, Request+, requestMethod+, httpVersion+, rawPathInfo+, rawQueryString+, requestHeaders+, isSecure+, remoteHost+, pathInfo+, queryString+, getRequestBodyChunk+, vault+, requestBodyLength+, requestHeaderHost+, requestHeaderRange+, requestHeaderReferer+, requestHeaderUserAgent+, strictRequestBody+, lazyRequestBody+, RequestBodyLength(..)+  -- ** Building a 'Response'+, Response+, FilePart(..)+, responseLBS+, responseStream+, responseRaw+, responseBuilder+, responseFile+, StreamingBody+  -- ** Miscellaneous re-exports+, Status+, mkStatus+, Header+, HeaderName+, ResponseHeaders+, RequestHeaders+, hAccept+, hAcceptCharset+, hAcceptEncoding+, hAcceptLanguage+, hAcceptRanges+, hAge+, hAllow+, hAuthorization+, hCacheControl+, hConnection+, hContentEncoding+, hContentLanguage+, hContentLocation+, hContentMD5+, hContentRange+, hContentType+, hDate+, hETag+, hExpect+, hExpires+, hFrom+, hHost+, hIfMatch+, hIfModifiedSince+, hIfNoneMatch+, hIfRange+, hIfUnmodifiedSince+, hLastModified+, hLocation+, hMaxForwards+, hOrigin+, hPragma+, hPrefer+, hPreferenceApplied+, hProxyAuthenticate+, hRange+, hReferer+, hRetryAfter+, hServer+, hTE+, hTrailer+, hTransferEncoding+, hUpgrade+, hUserAgent+, hVary+, hVia+, hWWWAuthenticate+, hWarning+, hContentDisposition+, hMIMEVersion+, hCookie+, hSetCookie+, ByteRange(..)+, renderByteRangeBuilder+, renderByteRange+, ByteRanges+, renderByteRangesBuilder+, parseByteRanges+, HttpVersion(..)+, http09+, http10+, http11+, http20+, Method+, methodGet+, methodPost+, methodHead+, methodPut+, methodDelete+, methodTrace+, methodConnect+, methodOptions+, methodPatch+, StdMethod(..)+, parseMethod+, renderMethod+, renderStdMethod+, QueryItem+, Query+, urlEncode+, urlDecode+, urlEncodeBuilder+, extractPath+, decodePath+, encodePath+, SockAddr+, Vault+) where++import Prelude hiding ((.), id)+import Data.Coerce (coerce)+import Control.Arrow (Kleisli(Kleisli))+import Data.Profunctor (Profunctor(..))+import Control.Monad.Fail (MonadFail)+import Control.Monad.Reader (MonadReader, ReaderT(ReaderT))+import Control.Monad.Cont (MonadCont, ContT(ContT))+import Control.Category (Category((.), id))+import Network.Wai+import Network.Wai.Internal (ResponseReceived(ResponseReceived))+import UnliftIO (MonadIO(liftIO), MonadUnliftIO(withRunInIO))+import Network.HTTP.Types.Header+import Network.HTTP.Types.Version+import Network.HTTP.Types.Method+import Network.HTTP.Types.URI+import Network.HTTP.Types.Status+import Data.Vault.Lazy (Vault)+import Network.Socket (SockAddr)++{- |+A server application which receives a request and responds.+-}+newtype Server m request response = Server+  { unServer :: request -> (response -> m ResponseReceived) -> m ResponseReceived }+  deriving (Functor, Applicative, Monad, MonadIO, MonadFail, MonadCont)+    via ReaderT request (ContT ResponseReceived m)++askRequest :: Monad m => Server m request request+askRequest = id++instance Functor m => Profunctor (Server m) where+  dimap f g (Server h) = Server \request respond -> h (f request) (respond . g)++instance Monad m => Category (Server m) where+  Server a . Server b = coerce $ Kleisli (fmap ContT a) . Kleisli (fmap ContT b)+  id :: forall a. Server m a a+  id = Server \request respond -> respond request++{- |+Compile a 'Server' a runnable wai application.+-}+{-# INLINE toApplication #-}+toApplication :: Server IO Request Response -> Application+toApplication = unServer++{- |+Lift a computation from the base monad into the 'Server' monad. This is+provided because this library prefers to use the second to last type variable+position for the contravariant component in the 'Profunctor' instance,+and so we are able to write a 'Category' instance.+-}+{-# INLINE liftS #-}+liftS :: Monad m => m response -> Server m request response+liftS r = Server $ const (r >>=)++{- |+In any monad that has an instance of 'MonadUnliftIO', we can retrieve a+function allowing our 'Server' to operate in 'IO'. The resulting function is+expected to be used to transform the 'Server' prior to calling 'toApplication'.+-}+{-# INLINE serverIO #-}+serverIO :: MonadUnliftIO m => m (Server m request response -> Server IO request response)+serverIO =+  withRunInIO+    \runner -> pure+      \(Server f) -> Server+        \request respond -> runner (f request (liftIO . respond))
+ example/example.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments #-}+module Main where++import qualified Network.Wai.Handler.Warp as Warp+import Web.Porpoise++main :: IO ()+main = Warp.run 8080 $ toApplication do+  pure $ responseLBS (mkStatus 404 "Thingy not found") [(hContentType, "text/html")] "<p> Ya sorry </p>"
+ porpoise.cabal view
@@ -0,0 +1,48 @@+cabal-version:       2.4+name:                porpoise+version:             0.1.0.0+license:             MIT+license-file:        LICENSE+synopsis:            A minimalist HTTP server framework written on top of wai+description:         A minimalist HTTP server framework written on top of wai.+author:              Samuel Schlesinger+maintainer:          sgschlesinger@gmail.com+copyright:           2020 Samuel Schlesinger+category:            Control+build-type:          Simple+extra-source-files:  CHANGELOG.md+tested-with:         GHC ==8.6.1 ||+                         ==8.6.2 ||+                         ==8.6.3 ||+                         ==8.6.4 ||+                         ==8.6.5 ||+                         ==8.8.1 ||+                         ==8.8.2 ||+                         ==8.8.3 ||+                         ==8.8.4 ||+                         ==8.10.1 ||+                         ==8.10.2++source-repository head+  type: git +  location: https://github.com/samuelschlesinger/porpoise++library+  exposed-modules:     Web.Porpoise+  build-depends:       base >=4.12 && <4.16,+                       wai >=3.2,+                       profunctors >=0.5,+                       mtl >=2.2,+                       unliftio >=0.2,+                       http-types >=0.12,+                       network >=3.1,+                       vault >=0.3+  default-language:    Haskell2010++executable porpoise-example+  main-is:             example.hs+  hs-source-dirs:      example+  build-depends:       base >=4.12 && <4.16,+                       warp >=3.3,+                       porpoise+  default-language:    Haskell2010