push-notifications 0.2 → 0.2.1
raw patch · 4 files changed
+41/−25 lines, 4 files
Files
- ChangeLog.md +6/−1
- README.md +3/−3
- push-notifications.cabal +4/−4
- src/Network/PushNotification/IOS.hs +28/−17
ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for push-notifications -## 0.1.0.0+## 0.2.1.0 +* APNS: Close socket upon exception++## 0.2.0.0+ * Remove deprecated `pushMess` function+* Rename project and change module names to begin with `Network.PushNotification`
README.md view
@@ -17,9 +17,9 @@ Sending push notifications requires an "Apple Push Services" certificate and an Apple-provided device token. ### Getting an APS Certificate-The APS certificate is produced in the iOS Provisioning Portal. Once you've generated the certificate, you can download it from the Provisioning Portal. It is usually named @aps_production.cer@ or @aps_development.cer@.+The APS certificate is produced in the iOS Provisioning Portal. Once you've generated the certificate, you can download it from the Provisioning Portal. It is usually named `aps_production.cer` or `aps_development.cer`. -The private key for the certificate can be extracted from Apple's Keychain utility as a @.p12@ file.+The private key for the certificate can be extracted from Apple's Keychain utility as a `.p12` file. Once you have both the certificate and private key, the following commands can be used to convert the certificate and private key files into the format required by this library. @@ -32,7 +32,7 @@ Device tokens are retrieved on the device itself by calling the @registerForRemoteNotifications@ method of the @UIApplication@ object. -For more information, please see [Apple's documentation](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html#//apple_ref/doc/uid/TP40008194-CH6-SW1 here).+For more information, please see [Apple's documentation](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html#//apple_ref/doc/uid/TP40008194-CH6-SW1). ## Credits
push-notifications.cabal view
@@ -1,12 +1,12 @@ name: push-notifications-version: 0.2-copyright: (c) 2019 Obsidian Systems and David Fendrich+version: 0.2.1+copyright: (c) 2019 Obsidian Systems, Teemu Ikonen, David Fendrich license: BSD3 license-file: LICENSE maintainer: maintainer@obsidian.systems build-type: Simple cabal-version: >= 1.14-homepage: https://github.com/obsidiansystems/haskell-phone-push+homepage: https://github.com/obsidiansystems/push-notifications category: Network APIs stability: experimental synopsis: Push notifications for Android and iOS@@ -20,7 +20,7 @@ source-repository head type: git- location: http://github.com/obsidiansystems/haskell-phone-push.git+ location: http://github.com/obsidiansystems/push-notifications.git Library Exposed-modules:
src/Network/PushNotification/IOS.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} -- | -- Module: Network.PushNotification.IOS@@ -35,6 +36,7 @@ module Network.PushNotification.IOS where +import Control.Exception (bracket, catch, IOException) import Data.Binary.Put import Data.Convertible (convert) import GHC.Word (Word32, Word16)@@ -80,6 +82,15 @@ checkFailTest :: FilePath -> FilePath -> IO [B.ByteString] checkFailTest = checkFail feedbackTest +withSocketSafe :: ProtocolNumber -> (Socket -> IO a) -> IO a+withSocketSafe proto =+ bracket (socket AF_INET Stream proto) $ \sock ->+ catch (close sock) $ \(e :: IOException) ->+ putStrLn . unwords $ [ "Caught exception trying to close"+ , "Apple push notifications socket:"+ , show e+ ]+ checkFail :: String -> FilePath -> FilePath -> IO [B.ByteString] checkFail server keyfile certfile = withOpenSSL $ do ssl <- context@@ -90,16 +101,16 @@ proto <- getProtocolNumber "tcp" he <- getHostByName server- sock <- socket AF_INET Stream proto- Network.Socket.connect sock (SockAddrInet 2196 (hostAddress he))+ withSocketSafe proto $ \sock -> do+ Network.Socket.connect sock (SockAddrInet 2196 (hostAddress he)) - sslsocket <- connection ssl sock- SSL.connect sslsocket -- Handshake- bs <- SSL.read sslsocket 7600000- print $ B.length bs- SSL.shutdown sslsocket Unidirectional+ sslsocket <- connection ssl sock+ SSL.connect sslsocket -- Handshake+ bs <- SSL.read sslsocket 7600000+ print $ B.length bs+ SSL.shutdown sslsocket Unidirectional - return $ splitBS bs+ return $ splitBS bs -- | Opens an APNS connection, runs the supplied action with the SSL socket, and closes the connection. --@@ -120,15 +131,15 @@ -- Open socket proto <- (getProtocolNumber "tcp") he <- getHostByName server- sock <- socket AF_INET Stream proto- Network.Socket.connect sock (SockAddrInet 2195 (hostAddress he))- -- Promote socket to SSL stream- sslsocket <- connection ssl sock- SSL.connect sslsocket -- Handshake- -- Use socket- f sslsocket- -- Close gracefully- SSL.shutdown sslsocket Unidirectional+ withSocketSafe proto $ \sock -> do+ Network.Socket.connect sock (SockAddrInet 2195 (hostAddress he))+ -- Promote socket to SSL stream+ sslsocket <- connection ssl sock+ SSL.connect sslsocket -- Handshake+ -- Use socket+ f sslsocket+ -- Close gracefully+ SSL.shutdown sslsocket Unidirectional -- | Send a message through the SSL socket sendApplePushMessage :: SSL -> ApplePushMessage -> IO ()