packages feed

wuss 1.1.19 → 2.0.2.7

raw patch · 8 files changed

Files

+ CHANGELOG.md view
@@ -0,0 +1,4 @@+# Change log++Wuss follows the [Package Versioning Policy](https://pvp.haskell.org).+You can find release notes [on GitHub](https://github.com/tfausak/wuss/releases).
− LICENSE.markdown
@@ -1,21 +0,0 @@-MIT License--Copyright (c) 2021 Taylor Fausak--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.
+ LICENSE.txt view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2026 Taylor Fausak++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.
− README.markdown
@@ -1,75 +0,0 @@-# Wuss--[![CI](https://github.com/tfausak/wuss/workflows/CI/badge.svg)](https://github.com/tfausak/wuss/actions/new)-[![Hackage](https://img.shields.io/hackage/v/wuss)](https://hackage.haskell.org/package/wuss)-[![Stackage](https://www.stackage.org/package/wuss/badge/nightly?label=stackage)](https://www.stackage.org/package/wuss)--Secure WebSocket (WSS) clients in Haskell.-------Wuss is a library that lets you easily create secure WebSocket clients over the-WSS protocol. It is a small addition to [the `websockets` package][] and is-adapted from existing solutions by [@jaspervdj][], [@mpickering][], and-[@elfenlaid][].---   [Installation](#installation)--   [Usage](#usage)--## Installation--To add Wuss as a dependency to your package, add it to your Cabal file.--```-build-depends: wuss-```--For other use cases, install it with Cabal.--``` sh-$ cabal install wuss-```--Wuss uses [Semantic Versioning][]. See [the change log][] for a detailed list-of changes.--## Usage--``` hs-import Wuss--import Control.Concurrent (forkIO)-import Control.Monad (forever, unless, void)-import Data.Text (Text, pack)-import Network.WebSockets (ClientApp, receiveData, sendClose, sendTextData)--main :: IO ()-main = runSecureClient "echo.websocket.org" 443 "/" ws--ws :: ClientApp ()-ws connection = do-    putStrLn "Connected!"--    void . forkIO . forever $ do-        message <- receiveData connection-        print (message :: Text)--    let loop = do-            line <- getLine-            unless (null line) $ do-                sendTextData connection (pack line)-                loop-    loop--    sendClose connection (pack "Bye!")-```--For more information about Wuss, please read [the Haddock documentation][].--[the `websockets` package]: https://hackage.haskell.org/package/websockets-[@jaspervdj]: https://gist.github.com/jaspervdj/7198388-[@mpickering]: https://gist.github.com/mpickering/f1b7ba3190a4bb5884f3-[@elfenlaid]: https://gist.github.com/elfenlaid/7b5c28065e67e4cf0767-[semantic versioning]: http://semver.org/spec/v2.0.0.html-[the change log]: CHANGELOG.md-[the haddock documentation]: https://hackage.haskell.org/package/wuss
+ README.md view
@@ -0,0 +1,71 @@+# Wuss++[![CI](https://github.com/tfausak/wuss/actions/workflows/ci.yml/badge.svg)](https://github.com/tfausak/wuss/actions/workflows/ci.yml)+[![Hackage](https://badgen.net/hackage/v/wuss)](https://hackage.haskell.org/package/wuss)++Secure WebSocket (WSS) clients in Haskell.++---++Wuss is a library that lets you easily create secure WebSocket clients over the+WSS protocol. It is a small addition to [the `websockets` package][] and is+adapted from existing solutions by [@jaspervdj][], [@mpickering][], and+[@elfenlaid][].++-   [Installation](#installation)+-   [Usage](#usage)++## Installation++To add Wuss as a dependency to your package, add it to your Cabal file.++```+build-depends: wuss+```++For other use cases, install it with Cabal.++``` sh+$ cabal install wuss+```++## Usage++``` hs+import Wuss++import Control.Concurrent (forkIO)+import Control.Monad (forever, unless, void)+import Data.Text (Text, pack)+import Network.WebSockets (ClientApp, receiveData, sendClose, sendTextData)++main :: IO ()+main = runSecureClient "echo.websocket.org" 443 "/" ws++ws :: ClientApp ()+ws connection = do+    putStrLn "Connected!"++    void . forkIO . forever $ do+        message <- receiveData connection+        print (message :: Text)++    let loop = do+            line <- getLine+            unless (null line) $ do+                sendTextData connection (pack line)+                loop+    loop++    sendClose connection (pack "Bye!")+```++For more information about Wuss, please read [the Haddock documentation][].++[the `websockets` package]: https://hackage.haskell.org/package/websockets+[@jaspervdj]: https://gist.github.com/jaspervdj/7198388+[@mpickering]: https://gist.github.com/mpickering/f1b7ba3190a4bb5884f3+[@elfenlaid]: https://gist.github.com/elfenlaid/7b5c28065e67e4cf0767+[semantic versioning]: http://semver.org/spec/v2.0.0.html+[the change log]: CHANGELOG.md+[the haddock documentation]: https://hackage.haskell.org/package/wuss
+ source/library/Wuss.hs view
@@ -0,0 +1,305 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- |+--    Wuss is a library that lets you easily create secure WebSocket clients over+--    the WSS protocol. It is a small addition to+--    <https://hackage.haskell.org/package/websockets the websockets package>+--    and is adapted from existing solutions by+--    <https://gist.github.com/jaspervdj/7198388 @jaspervdj>,+--    <https://gist.github.com/mpickering/f1b7ba3190a4bb5884f3 @mpickering>, and+--    <https://gist.github.com/elfenlaid/7b5c28065e67e4cf0767 @elfenlaid>.+--+--    == Example+--+--    > import Wuss+--    >+--    > import Control.Concurrent (forkIO)+--    > import Control.Monad (forever, unless, void)+--    > import Data.Text (Text, pack)+--    > import Network.WebSockets (ClientApp, receiveData, sendClose, sendTextData)+--    >+--    > main :: IO ()+--    > main = runSecureClient "echo.websocket.org" 443 "/" ws+--    >+--    > ws :: ClientApp ()+--    > ws connection = do+--    >     putStrLn "Connected!"+--    >+--    >     void . forkIO . forever $ do+--    >         message <- receiveData connection+--    >         print (message :: Text)+--    >+--    >     let loop = do+--    >             line <- getLine+--    >             unless (null line) $ do+--    >                 sendTextData connection (pack line)+--    >                 loop+--    >     loop+--    >+--    >     sendClose connection (pack "Bye!")+--+--    == Retry+--+--    Note that it is possible for the connection itself or any message to fail and need to be retried.+--    Fortunately this can be handled by something like <https://hackage.haskell.org/package/retry the retry package>.+--    See <https://github.com/tfausak/wuss/issues/18#issuecomment-990921703 this comment> for an example.+module Wuss+  ( runSecureClient,+    newSecureClientConnection,+    runSecureClientWith,+    newSecureClientConnectionWith,+    Config (..),+    defaultConfig,+    runSecureClientWithConfig,+    newSecureClientConnectionWithConfig,+  )+where++import qualified Control.Applicative as Applicative+import qualified Control.Exception as Exception+import qualified Control.Monad.Catch as Catch+import qualified Control.Monad.IO.Class as MonadIO+import qualified Data.ByteString as StrictBytes+import qualified Data.ByteString.Lazy as LazyBytes+import qualified Data.Default as Default+import qualified Data.Maybe as Maybe+import qualified Data.String as String+import qualified Network.Connection as Connection+import qualified Network.Socket as Socket+import qualified Network.WebSockets as WebSockets+import qualified Network.WebSockets.Stream as Stream+import qualified System.IO as IO+import qualified System.IO.Error as IO.Error+import Prelude (($), (.))++-- |+--    A secure replacement for 'Network.WebSockets.runClient'.+--+--    >>> let app _connection = return ()+--    >>> runSecureClient "echo.websocket.org" 443 "/" app+runSecureClient ::+  (MonadIO.MonadIO m) =>+  (Catch.MonadMask m) =>+  -- | Host+  Socket.HostName ->+  -- | Port+  Socket.PortNumber ->+  -- | Path+  String.String ->+  -- | Application+  WebSockets.ClientApp a ->+  m a+runSecureClient host port path app = do+  let options = WebSockets.defaultConnectionOptions+  runSecureClientWith host port path options [] app++-- | Build a new `Connection` from the client's point of view.+--+-- /WARNING/: Be sure to run the returned `IO ()` action after you are done+-- using the `Connection` in order to properly close the communication channel.+-- `runSecureClient` handles this for you, prefer to use it when possible.+newSecureClientConnection ::+  (MonadIO.MonadIO m) =>+  (Catch.MonadMask m) =>+  -- | Host+  Socket.HostName ->+  -- | PortNumber+  Socket.PortNumber ->+  -- | Path+  String.String ->+  m (WebSockets.Connection, IO.IO ())+newSecureClientConnection host port path = do+  let options = WebSockets.defaultConnectionOptions+  newSecureClientConnectionWith host port path options []++-- |+--    A secure replacement for 'Network.WebSockets.runClientWith'.+--+--    >>> let options = defaultConnectionOptions+--    >>> let headers = []+--    >>> let app _connection = return ()+--    >>> runSecureClientWith "echo.websocket.org" 443 "/" options headers app+--+--    If you want to run a secure client without certificate validation, use+--    'Network.WebSockets.runClientWithStream'. For example:+--+--    > let host = "echo.websocket.org"+--    > let port = 443+--    > let path = "/"+--    > let options = defaultConnectionOptions+--    > let headers = []+--    > let tlsSettings = TLSSettingsSimple+--    >     -- This is the important setting.+--    >     { settingDisableCertificateValidation = True+--    >     , settingDisableSession = False+--    >     , settingUseServerName = False+--    >     }+--    > let connectionParams = ConnectionParams+--    >     { connectionHostname = host+--    >     , connectionPort = port+--    >     , connectionUseSecure = Just tlsSettings+--    >     , connectionUseSocks = Nothing+--    >     }+--    >+--    > context <- initConnectionContext+--    > connection <- connectTo context connectionParams+--    > stream <- makeStream+--    >     (fmap Just (connectionGetChunk connection))+--    >     (maybe (return ()) (connectionPut connection . toStrict))+--    > runClientWithStream stream host path options headers $ \ connection -> do+--    >     -- Do something with the connection.+--    >     return ()+runSecureClientWith ::+  (MonadIO.MonadIO m) =>+  (Catch.MonadMask m) =>+  -- | Host+  Socket.HostName ->+  -- | Port+  Socket.PortNumber ->+  -- | Path+  String.String ->+  -- | Options+  WebSockets.ConnectionOptions ->+  -- | Headers+  WebSockets.Headers ->+  -- | Application+  WebSockets.ClientApp a ->+  m a+runSecureClientWith host port path options headers app = do+  let config = defaultConfig+  runSecureClientWithConfig host port path config options headers app++-- | Build a new `Connection` from the client's point of view.+--+-- /WARNING/: Be sure to run the returned `IO ()` action after you are done+-- using the `Connection` in order to properly close the communication channel.+-- `runSecureClientWith` handles this for you, prefer to use it when possible.+newSecureClientConnectionWith ::+  (MonadIO.MonadIO m) =>+  (Catch.MonadMask m) =>+  -- | Host+  Socket.HostName ->+  -- | PortNumber+  Socket.PortNumber ->+  -- | Path+  String.String ->+  -- | Options+  WebSockets.ConnectionOptions ->+  -- | Headers+  WebSockets.Headers ->+  m (WebSockets.Connection, IO.IO ())+newSecureClientConnectionWith host port path options headers = do+  let config = defaultConfig+  newSecureClientConnectionWithConfig host port path config options headers++-- | Configures a secure WebSocket connection.+newtype Config = Config+  { -- | How to get bytes from the connection. Typically+    -- 'Connection.connectionGetChunk', but could be something else like+    -- 'Connection.connectionGetLine'.+    connectionGet :: Connection.Connection -> IO.IO StrictBytes.ByteString+  }++-- | The default 'Config' value used by 'runSecureClientWith'.+defaultConfig :: Config+defaultConfig = do+  Config {connectionGet = Connection.connectionGetChunk}++-- | Runs a secure WebSockets client with the given 'Config'.+runSecureClientWithConfig ::+  (MonadIO.MonadIO m) =>+  (Catch.MonadMask m) =>+  -- | Host+  Socket.HostName ->+  -- | Port+  Socket.PortNumber ->+  -- | Path+  String.String ->+  -- | Config+  Config ->+  -- | Options+  WebSockets.ConnectionOptions ->+  -- | Headers+  WebSockets.Headers ->+  -- | Application+  WebSockets.ClientApp a ->+  m a+runSecureClientWithConfig host port path config options headers app =+  Catch.bracket+    (newSecureClientConnectionWithConfig host port path config options headers)+    (\(_, close) -> MonadIO.liftIO close)+    (\(conn, _) -> MonadIO.liftIO (app conn))++-- | Build a new `Connection` from the client's point of view.+--+-- /WARNING/: Be sure to run the returned `IO ()` action after you are done+-- using the `Connection` in order to properly close the communication channel.+-- `runSecureClientWithConfig` handles this for you, prefer to use it when+-- possible.+newSecureClientConnectionWithConfig ::+  (MonadIO.MonadIO m) =>+  (Catch.MonadMask m) =>+  -- | Host+  Socket.HostName ->+  -- | PortNumber+  Socket.PortNumber ->+  -- | Path+  String.String ->+  -- | Config+  Config ->+  -- | Options+  WebSockets.ConnectionOptions ->+  -- | Headers+  WebSockets.Headers ->+  m (WebSockets.Connection, IO.IO ())+newSecureClientConnectionWithConfig host port path config options headers = do+  context <- MonadIO.liftIO Connection.initConnectionContext+  Catch.bracketOnError+    (MonadIO.liftIO $ Connection.connectTo context (connectionParams host port))+    (MonadIO.liftIO . Connection.connectionClose)+    ( \connection -> MonadIO.liftIO $ do+        stream <-+          Stream.makeStream+            (reader config connection)+            (writer connection)+        conn <- WebSockets.newClientConnection stream host path options headers+        Applicative.pure (conn, Connection.connectionClose connection)+    )++connectionParams ::+  Socket.HostName -> Socket.PortNumber -> Connection.ConnectionParams+connectionParams host port = do+  Connection.ConnectionParams+    { Connection.connectionHostname = host,+      Connection.connectionPort = port,+      Connection.connectionUseSecure = Maybe.Just tlsSettings,+      Connection.connectionUseSocks = Maybe.Nothing+    }++tlsSettings :: Connection.TLSSettings+tlsSettings = Default.def++reader ::+  Config ->+  Connection.Connection ->+  IO.IO (Maybe.Maybe StrictBytes.ByteString)+reader config connection =+  IO.Error.catchIOError+    ( do+        chunk <- connectionGet config connection+        Applicative.pure (Maybe.Just chunk)+    )+    ( \e ->+        if IO.Error.isEOFError e+          then Applicative.pure Maybe.Nothing+          else Exception.throwIO e+    )++writer ::+  Connection.Connection -> Maybe.Maybe LazyBytes.ByteString -> IO.IO ()+writer connection maybeBytes = do+  case maybeBytes of+    Maybe.Nothing -> do+      Applicative.pure ()+    Maybe.Just bytes -> do+      Connection.connectionPut connection (LazyBytes.toStrict bytes)
− src/lib/Wuss.hs
@@ -1,217 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--{- |-    Wuss is a library that lets you easily create secure WebSocket clients over-    the WSS protocol. It is a small addition to-    <https://hackage.haskell.org/package/websockets the websockets package>-    and is adapted from existing solutions by-    <https://gist.github.com/jaspervdj/7198388 @jaspervdj>,-    <https://gist.github.com/mpickering/f1b7ba3190a4bb5884f3 @mpickering>, and-    <https://gist.github.com/elfenlaid/7b5c28065e67e4cf0767 @elfenlaid>.--    == Example--    > import Wuss-    >-    > import Control.Concurrent (forkIO)-    > import Control.Monad (forever, unless, void)-    > import Data.Text (Text, pack)-    > import Network.WebSockets (ClientApp, receiveData, sendClose, sendTextData)-    >-    > main :: IO ()-    > main = runSecureClient "echo.websocket.org" 443 "/" ws-    >-    > ws :: ClientApp ()-    > ws connection = do-    >     putStrLn "Connected!"-    >-    >     void . forkIO . forever $ do-    >         message <- receiveData connection-    >         print (message :: Text)-    >-    >     let loop = do-    >             line <- getLine-    >             unless (null line) $ do-    >                 sendTextData connection (pack line)-    >                 loop-    >     loop-    >-    >     sendClose connection (pack "Bye!")--}-module Wuss-    ( runSecureClient-    , runSecureClientWith-    , Config(..)-    , defaultConfig-    , runSecureClientWithConfig-    ) where--import qualified Control.Applicative as Applicative-import qualified Control.Exception as Exception-import qualified Data.Bool as Bool-import qualified Data.ByteString as StrictBytes-import qualified Data.ByteString.Lazy as LazyBytes-import qualified Data.Maybe as Maybe-import qualified Data.String as String-import qualified Network.Connection as Connection-import qualified Network.Socket as Socket-import qualified Network.WebSockets as WebSockets-import qualified Network.WebSockets.Stream as Stream-import qualified System.IO as IO-import qualified System.IO.Error as IO.Error---{- |-    A secure replacement for 'Network.WebSockets.runClient'.--    >>> let app _connection = return ()-    >>> runSecureClient "echo.websocket.org" 443 "/" app--}-runSecureClient-    :: Socket.HostName -- ^ Host-    -> Socket.PortNumber -- ^ Port-    -> String.String -- ^ Path-    -> WebSockets.ClientApp a -- ^ Application-    -> IO.IO a-runSecureClient host port path app = do-    let options = WebSockets.defaultConnectionOptions-    runSecureClientWith host port path options [] app---{- |-    A secure replacement for 'Network.WebSockets.runClientWith'.--    >>> let options = defaultConnectionOptions-    >>> let headers = []-    >>> let app _connection = return ()-    >>> runSecureClientWith "echo.websocket.org" 443 "/" options headers app--    If you want to run a secure client without certificate validation, use-    'Network.WebSockets.runClientWithStream'. For example:--    > let host = "echo.websocket.org"-    > let port = 443-    > let path = "/"-    > let options = defaultConnectionOptions-    > let headers = []-    > let tlsSettings = TLSSettingsSimple-    >     -- This is the important setting.-    >     { settingDisableCertificateValidation = True-    >     , settingDisableSession = False-    >     , settingUseServerName = False-    >     }-    > let connectionParams = ConnectionParams-    >     { connectionHostname = host-    >     , connectionPort = port-    >     , connectionUseSecure = Just tlsSettings-    >     , connectionUseSocks = Nothing-    >     }-    >-    > context <- initConnectionContext-    > connection <- connectTo context connectionParams-    > stream <- makeStream-    >     (fmap Just (connectionGetChunk connection))-    >     (maybe (return ()) (connectionPut connection . toStrict))-    > runClientWithStream stream host path options headers $ \ connection -> do-    >     -- Do something with the connection.-    >     return ()--}-runSecureClientWith-    :: Socket.HostName -- ^ Host-    -> Socket.PortNumber -- ^ Port-    -> String.String -- ^ Path-    -> WebSockets.ConnectionOptions -- ^ Options-    -> WebSockets.Headers -- ^ Headers-    -> WebSockets.ClientApp a -- ^ Application-    -> IO.IO a-runSecureClientWith host port path options headers app = do-    let config = defaultConfig-    runSecureClientWithConfig host port path config options headers app----- | Configures a secure WebSocket connection.-data Config = Config-    { connectionGet :: Connection.Connection -> IO.IO StrictBytes.ByteString-    -- ^ How to get bytes from the connection. Typically-    -- 'Connection.connectionGetChunk', but could be something else like-    -- 'Connection.connectionGetLine'.-    }----- | The default 'Config' value used by 'runSecureClientWith'.-defaultConfig-    :: Config-defaultConfig = do-    Config-        { connectionGet = Connection.connectionGetChunk-        }----- | Runs a secure WebSockets client with the given 'Config'.-runSecureClientWithConfig-    :: Socket.HostName -- ^ Host-    -> Socket.PortNumber -- ^ Port-    -> String.String -- ^ Path-    -> Config -- ^ Config-    -> WebSockets.ConnectionOptions -- ^ Options-    -> WebSockets.Headers -- ^ Headers-    -> WebSockets.ClientApp a -- ^ Application-    -> IO.IO a-runSecureClientWithConfig host port path config options headers app = do-    context <- Connection.initConnectionContext-    Exception.bracket-        (Connection.connectTo context (connectionParams host port))-        Connection.connectionClose-        (\connection -> do-            stream <--                Stream.makeStream (reader config connection) (writer connection)-            WebSockets.runClientWithStream stream host path options headers app)---connectionParams-    :: Socket.HostName-    -> Socket.PortNumber-    -> Connection.ConnectionParams-connectionParams host port = do-    Connection.ConnectionParams-        { Connection.connectionHostname = host-        , Connection.connectionPort = port-        , Connection.connectionUseSecure = Maybe.Just tlsSettings-        , Connection.connectionUseSocks = Maybe.Nothing-        }---tlsSettings-    :: Connection.TLSSettings-tlsSettings = do-    Connection.TLSSettingsSimple-        { Connection.settingDisableCertificateValidation = Bool.False-        , Connection.settingDisableSession = Bool.False-        , Connection.settingUseServerName = Bool.False-        }---reader-    :: Config-    -> Connection.Connection-    -> IO.IO (Maybe.Maybe StrictBytes.ByteString)-reader config connection =-    IO.Error.catchIOError (do-        chunk <- (connectionGet config) connection-        Applicative.pure (Maybe.Just chunk))-    (\e ->-        if IO.Error.isEOFError e-            then Applicative.pure Maybe.Nothing-            else Exception.throwIO e)---writer-    :: Connection.Connection-    -> Maybe.Maybe LazyBytes.ByteString-    -> IO.IO ()-writer connection maybeBytes = do-    case maybeBytes of-        Maybe.Nothing -> do-            Applicative.pure ()-        Maybe.Just bytes -> do-            Connection.connectionPut connection (LazyBytes.toStrict bytes)
wuss.cabal view
@@ -1,8 +1,6 @@-cabal-version: >= 1.10-+cabal-version: 2.2 name: wuss-version: 1.1.19-+version: 2.0.2.7 synopsis: Secure WebSocket (WSS) clients description:   Wuss is a library that lets you easily create secure WebSocket clients over@@ -15,8 +13,11 @@  build-type: Simple category: Network-extra-source-files: README.markdown-license-file: LICENSE.markdown+extra-doc-files:+  CHANGELOG.md+  README.md++license-file: LICENSE.txt license: MIT maintainer: Taylor Fausak @@ -24,22 +25,35 @@   location: https://github.com/tfausak/wuss   type: git -library+flag pedantic+  default: False+  manual: True++common library+  build-depends: base ^>=4.20.0.0 || ^>=4.21.0.0 || ^>=4.22.0.0   build-depends:-    base >= 4.13.0 && < 4.17-    , bytestring >= 0.10.10 && < 0.12-    , connection >= 0.3.1 && < 0.4-    , network >= 3.1.1 && < 3.2-    , websockets >= 0.12.7 && < 0.13+    bytestring ^>=0.12.0.2,+    crypton-connection ^>=0.3.2 || ^>=0.4.0,+    data-default ^>=0.7.0 || ^>=0.8.0.0,+    exceptions ^>=0.10.7,+    network ^>=3.1.4.0 || ^>=3.2.0.0,+    websockets ^>=0.12.7.3 || ^>=0.13.0.0,+   default-language: Haskell2010-  exposed-modules: Wuss   ghc-options:     -Weverything+    -Wno-all-missed-specialisations     -Wno-missing-exported-signatures+    -Wno-missing-kind-signatures+    -Wno-missing-safe-haskell-mode+    -Wno-prepositive-qualified-module     -Wno-unsafe-  hs-source-dirs: src/lib -  if impl(ghc >= 8.10)-    ghc-options:-      -Wno-missing-safe-haskell-mode-      -Wno-prepositive-qualified-module+  if flag(pedantic)+    ghc-options: -Werror++library+  import: library+  -- cabal-gild: discover source/library+  exposed-modules: Wuss+  hs-source-dirs: source/library