push-notify-apn 0.3.0.2 → 0.4.0.0
raw patch · 3 files changed
+54/−19 lines, 3 filesdep +crypton-x509dep +crypton-x509-storedep +crypton-x509-systemdep −x509dep −x509-storedep −x509-systemdep ~http2-clientnew-uploader
Dependencies added: crypton-x509, crypton-x509-store, crypton-x509-system
Dependencies removed: x509, x509-store, x509-system
Dependency ranges changed: http2-client
Files
- changelog.md +7/−0
- push-notify-apn.cabal +9/−9
- src/Network/PushNotify/APN.hs +38/−10
changelog.md view
@@ -1,3 +1,10 @@+0.4.0.0+=======++- Support http2-v4 and http2-v5+- Check if connection is open in withConnection+- Use crypton packages+ 0.3.0.2 =======
push-notify-apn.cabal view
@@ -1,5 +1,5 @@ name: push-notify-apn-version: 0.3.0.2+version: 0.4.0.0 synopsis: Send push notifications to mobile iOS devices description: push-notify-apn is a library and command line utility that can be used to send@@ -7,11 +7,11 @@ messages that can be sent to apps on smart phones and tablets without the need to keep open a long lived TCP connection per app, dramatically reducing the power consumption in standby mode.-homepage: https://github.com/memrange/apn#readme+homepage: https://github.com/digitallyinduced/push-notify-apn#readme license: BSD3 license-file: LICENSE-author: Hans-Christian Esperer-maintainer: hc@hcesperer.org+author: Marc Scholten+maintainer: marc@digitallyinduced.com copyright: 2017-2020 Memrange UG category: Network, Cloud, Mobile build-type: Simple@@ -30,7 +30,7 @@ , containers , data-default , http2 >= 3.0- , http2-client+ , http2-client >= 0.10.0.1 , lifted-base , mtl , random@@ -39,9 +39,9 @@ , text , time , tls- , x509- , x509-store- , x509-system+ , crypton-x509+ , crypton-x509-store+ , crypton-x509-system ghc-options: -Wall -W -fwarn-unused-imports -fwarn-unused-binds -fwarn-orphans@@ -77,4 +77,4 @@ source-repository head type: git- location: https://github.com/memrange/push-notify-apn+ location: https://github.com/digitallyinduced/push-notify-apn
src/Network/PushNotify/APN.hs view
@@ -7,6 +7,7 @@ -- Portability: portable -- -- Send push notifications using Apple's HTTP2 APN API+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE OverloadedStrings #-}@@ -39,6 +40,8 @@ , clearSound , addSupplementalField , closeSession+ , isConnectionOpen+ , isSessionOpen , isOpen , ApnSession , JsonAps@@ -69,8 +72,7 @@ import Data.Typeable (Typeable) import Data.X509.CertificateStore import GHC.Generics-import Network.HTTP2.Frame (ErrorCodeId,- toErrorCodeId)+import Network.HTTP2.Frame (ErrorCode) import "http2-client" Network.HTTP2.Client import "http2-client" Network.HTTP2.Client.Helpers import Network.TLS hiding (sendData)@@ -134,10 +136,12 @@ hexEncodedToken = ApnToken . B16.encode . B16.decodeLenient . TE.encodeUtf8 -- | Exceptional responses to a send request-data ApnException = ApnExceptionHTTP ErrorCodeId+data ApnException = ApnExceptionHTTP ErrorCode | ApnExceptionJSON String | ApnExceptionMissingHeader HTTP2.HeaderName | ApnExceptionUnexpectedResponse+ | ApnExceptionConnectionClosed+ | ApnExceptionSessionClosed deriving (Show, Typeable) instance Exception ApnException@@ -433,17 +437,28 @@ -- | Check whether a session is open or has been closed -- by a call to closeSession+isSessionOpen :: ApnSession -> IO Bool+isSessionOpen = readIORef . apnSessionOpen++-- | Check whether a session is open or has been closed+-- by a call to closeSession+{-# DEPRECATED isOpen "Use isSessionOpen instead." #-} isOpen :: ApnSession -> IO Bool-isOpen = readIORef . apnSessionOpen+isOpen = isSessionOpen +-- | Check whether the connection is open or has been closed.+isConnectionOpen :: ApnConnection -> IO Bool+isConnectionOpen = readIORef . apnConnectionOpen+ timeoutSeconds :: Int timeoutSeconds = 300 * 1_000_000 -- 300 seconds to microseconds withConnection :: ApnSession -> (ApnConnection -> ClientIO a) -> ClientIO a withConnection s action = do- lift $ ensureOpen s+ lift $ ensureSessionOpen s ExceptT . try $ withResource (apnSessionPool s) $ \conn -> do+ ensureConnectionOpen conn mRes <- timeout timeoutSeconds (runClientIO (action conn)) case mRes of Nothing -> do@@ -478,7 +493,11 @@ let maxConcurrentStreams = aciMaxConcurrentStreams aci conf = [ (HTTP2.SettingsMaxFrameSize, 16384) , (HTTP2.SettingsMaxConcurrentStreams, maxConcurrentStreams)+#if MIN_VERSION_http2(5,0,0)+ , (HTTP2.SettingsMaxHeaderListSize, 4096)+#else , (HTTP2.SettingsMaxHeaderBlockSize, 4096)+#endif , (HTTP2.SettingsInitialWindowSize, 65536) , (HTTP2.SettingsEnablePush, 1) ]@@ -604,11 +623,16 @@ sendApnRaw c token mJwt message where message = "{\"aps\":{\"content-available\":1}}" -ensureOpen :: ApnSession -> IO ()-ensureOpen s = do- open <- isOpen s- unless open $ error "Session is closed"+ensureSessionOpen :: ApnSession -> IO ()+ensureSessionOpen s = do+ open <- isSessionOpen s+ unless open $ throwIO ApnExceptionConnectionClosed +ensureConnectionOpen :: ApnConnection -> IO ()+ensureConnectionOpen c = do+ open <- isConnectionOpen c+ unless open $ throwIO ApnExceptionConnectionClosed+ -- | Send a push notification message. sendApnRaw :: ApnConnection@@ -639,10 +663,14 @@ upload message (HTTP2.setEndHeader . HTTP2.setEndStream) client (_outgoingFlowControl client) stream osfc let pph _hStreamId _hStream hHeaders _hIfc _hOfc = lift $ print hHeaders+#if MIN_VERSION_http2_client(0, 10, 0)+ response <- waitStream client stream isfc pph+#else response <- waitStream stream isfc pph+#endif let (errOrHeaders, frameResponses, _) = response case errOrHeaders of- Left err -> throwIO (ApnExceptionHTTP $ toErrorCodeId err)+ Left err -> throwIO (ApnExceptionHTTP err) Right hdrs1 -> do let status = getHeaderEx ":status" hdrs1 -- apns-id = getHeaderEx "apns-id" hdrs1