wai-middleware-clacks (empty) → 0.1.0.0
raw patch · 7 files changed
+359/−0 lines, 7 filesdep +basedep +base-compat-batteriesdep +bytestringsetup-changed
Dependencies added: base, base-compat-batteries, bytestring, case-insensitive, http-types, tasty, tasty-wai, text, wai, wai-middleware-clacks
Files
- CHANGELOG.md +5/−0
- LICENSE +30/−0
- README.md +83/−0
- Setup.hs +2/−0
- src/Network/Wai/Middleware/Clacks.hs +92/−0
- tests/Spec.hs +46/−0
- wai-middleware-clacks.cabal +101/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# CHANGELOG++## v0.1.0.0++* Initial release
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Pavan Rikhi (c) 2020++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Pavan Rikhi nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,83 @@+# wai-middleware-clacks++[](https://travis-ci.org/prikhi/wai-middleware-clacks)++*"You know they'll never really die while the Trunk is alive."*++`wai-middleware-clacks` is a middleware that inserts an arbitrary+`X-Clacks-Overhead` header into every Wai response. From+[GNU Terry Pratchett](http://gnuterrypratchett.com):++> In Terry Pratchett's Discworld series, the clacks are a series of semaphore+> towers loosely based on the concept of the telegraph. Invented by an+> artificer named Robert Dearheart, the towers could send messages "at the+> speed of light" using standardized codes. Three of these codes are of+> particular import:+>+> * G: send the message on+> * N: do not log the message+> * U: turn the message around at the end of the line and send it back again+>+> When Dearheart's son John died due to an accident while working on a clacks+> tower, Dearheart inserted John's name into the overhead of the clacks with a+> "GNU" in front of it as a way to memorialize his son forever (or for at least+> as long as the clacks are standing.)+>+> Keeping the legacy of Sir Terry Pratchett alive forever. For as long as his+> name is still passed along the Clacks, Death can't have him.+++## Usage++To use this package to keep the legacy of Terry Pratchett alive, simply pass+your wai application to @clacks gnuTerryPratchett@ before passing it to the+@run@ function:++```haskell+import Network.Wai.Handler.Warp (run)+import Network.Wai.Middleware.Clacks (clacks, gnuTerryPratchett)++import MyLib.App (myApp)++main :: IO ()+main = run 8080 $ clacks gnuTerryPratchett myApp+```++You can use the `Clacks` type to build a custom configuration for the `clacks`+function, allowing you to pass anything into the header:++```haskell+import Data.List.NonEmpty (NonEmpty(..))+import Network.Wai (Middleware)+import Network.Wai.Middleware.Clacks (Clacks(..), clacks)++myClacks :: Middleware+myClacks = clacks $ Clacks $ "GNU Ada Lovelace" :| ["GNU Hoban Washburne", "GNU Shephard Book"]+```+++## Build++You can build the project with stack:++```+stack build+```++For development, you can enable fast builds with file-watching,+documentation-building, & test-running:++```+stack test --haddock --fast --file-watch --pedantic+```++To build & open the documentation, run++```+stack haddock --open wai-middleware-clacks+```+++## LICENSE++BSD-3
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Network/Wai/Middleware/Clacks.hs view
@@ -0,0 +1,92 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}+{-|+The @Clacks@ middleware adds a @X-Clacks-Overhead@ header to every response+served by a Wai server.++To use this package to keep the legacy of Terry Pratchett alive, simply+pass your wai application to @clacks gnuTerryPratchett@ before passing it+to the @run@ function:++> import Network.Wai.Handler.Warp (run)+> import Network.Wai.Middleware.Clacks (clacks, gnuTerryPratchett)+>+> import MyLib.App (myApp)+>+> main :: IO ()+> main = run 8080 $ clacks gnuTerryPratchett myApp++You can use the 'Clacks' type to build a custom configuration for the+'clacks' function, allowing you to pass anything into the header:++> import Data.List.NonEmpty (NonEmpty(..))+> import Network.Wai (Middleware)+> import Network.Wai.Middleware.Clacks (Clacks(..), clacks)+>+> myClacks :: Middleware+> myClacks = clacks $ Clacks $ "GNU Ada Lovelace" :| ["GNU Hoban Washburne", "GNU Shephard Book"]++For more information about the Clacks or the @X-Clacks-Overhead@ header,+check out the <http://www.gnuterrypratchett.com GNU Terry Pratchett website>.++-}+module Network.Wai.Middleware.Clacks+ ( clacks+ , Clacks(..)+ , gnuTerryPratchett+ , clacksHeaderName+ )+where++import Prelude.Compat++import Data.List.NonEmpty.Compat ( NonEmpty(..)+ , toList+ )+import Data.Text.Encoding ( encodeUtf8 )+import Network.HTTP.Types.Header ( ResponseHeaders+ , HeaderName+ )+import Network.Wai ( Middleware+ , modifyResponse+ , mapResponseHeaders+ )++import qualified Data.ByteString as BS+import qualified Data.CaseInsensitive as CI+import qualified Data.List as L+import qualified Data.Text as T+++-- | A "Network.Wai" 'Middleware' that adds a @X-Clacks-Overhead@ header+-- containing the messages in the 'Clacks' configuration.+clacks :: Clacks -> Middleware+clacks settings = modifyResponse $ mapResponseHeaders addHeader+ where+ headerContents :: BS.ByteString+ headerContents =+ encodeUtf8 . T.intercalate "," . toList $ clacksMessages settings+ addHeader :: ResponseHeaders -> ResponseHeaders+ addHeader hs = case L.find ((== clacksHeaderName) . fst) hs of+ Nothing -> (clacksHeaderName, headerContents) : hs+ Just (_, "") -> (clacksHeaderName, headerContents) : hs+ Just (name, contents) ->+ (name, contents <> "," <> headerContents)+ : filter ((/= clacksHeaderName) . fst) hs++-- | Configuration for the Clacks WAI Middleware.+newtype Clacks =+ Clacks+ { clacksMessages :: NonEmpty T.Text+ -- ^ The Clacks Messages to Include in the Header.+ } deriving (Show, Read, Eq)+++-- | Sends a Clacks message of @GNU Terry Pratchett@.+gnuTerryPratchett :: Clacks+gnuTerryPratchett = Clacks $ "GNU Terry Pratchett" :| []+++-- | The name of the Clacks header.+clacksHeaderName :: HeaderName+clacksHeaderName = CI.mk "X-Clacks-Overhead"
+ tests/Spec.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE OverloadedStrings #-}+import Data.List.NonEmpty.Compat ( NonEmpty(..) )+import Test.Tasty+import Test.Tasty.Wai+import Network.HTTP.Types ( status200 )+import Network.Wai ( Application+ , responseLBS+ )++import Network.Wai.Middleware.Clacks++main :: IO ()+main = defaultMain tests+++tests :: TestTree+tests = testGroup "Wai Tests" [testSingle, testMultiple, testExisting]+ where+ testSingle :: TestTree+ testSingle = testWai (simpleApp gnuTerryPratchett) "Single Message" $ do+ get "42" >>= assertHeader clacksHeaderName "GNU Terry Pratchett"+ testMultiple :: TestTree+ testMultiple =+ let settings = Clacks $ "GNU Terry Pratchett" :| ["GNU Ada Lovelace"]+ in testWai (simpleApp settings) "Multiple Messages"+ $ get "9001"+ >>= assertHeader clacksHeaderName+ "GNU Terry Pratchett,GNU Ada Lovelace"+ testExisting :: TestTree+ testExisting =+ testWai (existingHeaderApp gnuTerryPratchett) "Existing Clacks Header"+ $ do+ get "neko" >>= assertHeader+ clacksHeaderName+ "GNU Ada Lovelace,GNU Terry Pratchett"+++simpleApp :: Clacks -> Application+simpleApp settings =+ clacks settings $ \_ cb -> cb $ responseLBS status200 [] "Hello World"++existingHeaderApp :: Clacks -> Application+existingHeaderApp settings = clacks settings $ \_ cb -> cb $ responseLBS+ status200+ [(clacksHeaderName, "GNU Ada Lovelace")]+ "Hello World"
+ wai-middleware-clacks.cabal view
@@ -0,0 +1,101 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.33.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 895632c4795b860ff962c56d9e843f228030b41aadc1d8f3806e7fefbccc5229++name: wai-middleware-clacks+version: 0.1.0.0+synopsis: GNU Terry Pratchett - Add the X-Clacks-Overhead Header to Wai Responses.+description: /"You know they'll never really die while the Trunk is alive."/+ .+ @wai-middleware-clacks@ is a middleware that inserts an arbitrary+ @X-Clacks-Overhead@ header into every Wai response. From+ <http://gnuterrypratchett.com GNU Terry Pratchett>:+ .+ > In Terry Pratchett's Discworld series, the clacks are a series of+ > semaphore towers loosely based on the concept of the telegraph. Invented+ > by an artificer named Robert Dearheart, the towers could send messages+ > "at the speed of light" using standardized codes. Three of these codes+ > are of particular import:+ >+ > G: send the message on+ > N: do not log the message+ > U: turn the message around at the end of the line and send it back again+ >+ > When Dearheart's son John died due to an accident while working on a+ > clacks tower, Dearheart inserted John's name into the overhead of the+ > clacks with a "GNU" in front of it as a way to memorialize his son forever+ > (or for at least as long as the clacks are standing.)+ >+ >+ > Keeping the legacy of Sir Terry Pratchett alive forever. For as long as+ > his name is still passed along the Clacks, Death can't have him.+ .+ Please see the+ <https://github.com/prikhi/wai-middleware-clacks/blob/master/README.md README>+ or+ <https://hackage.haskell.org/package/wai-middleware-clacks/docs/Network-Wai-Middleware-Clacks.html module documentation>+ for usage instructions.+category: Web, Wai+homepage: https://github.com/prikhi/wai-middleware-clacks#readme+bug-reports: https://github.com/prikhi/wai-middleware-clacks/issues+author: Pavan Rikhi+maintainer: pavan.rikhi@gmail.com+copyright: 2020 Pavan Rikhi+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ CHANGELOG.md++source-repository head+ type: git+ location: https://github.com/prikhi/wai-middleware-clacks++library+ exposed-modules:+ Network.Wai.Middleware.Clacks+ other-modules:+ Paths_wai_middleware_clacks+ hs-source-dirs:+ src+ ghc-options: -Wall+ build-depends:+ base >=4.3 && <5+ , base-compat-batteries+ , bytestring+ , case-insensitive+ , http-types+ , text+ , wai+ if impl(ghc >= 8.0)+ ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints+ else+ ghc-options: -fwarn-incomplete-record-updates -fwarn-incomplete-uni-patterns+ default-language: Haskell2010++test-suite wai-middleware-clacks-test+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ Paths_wai_middleware_clacks+ hs-source-dirs:+ tests+ ghc-options: -Wall -threaded -rtsopts -with-rtsopts "-N -T"+ build-depends:+ base >=4.3 && <5+ , base-compat-batteries+ , http-types+ , tasty+ , tasty-wai+ , wai+ , wai-middleware-clacks+ if impl(ghc >= 8.0)+ ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints+ else+ ghc-options: -fwarn-incomplete-record-updates -fwarn-incomplete-uni-patterns+ default-language: Haskell2010