summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/anachronistic/apns/client.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/anachronistic/apns/client.go')
-rw-r--r--Godeps/_workspace/src/github.com/anachronistic/apns/client.go167
1 files changed, 0 insertions, 167 deletions
diff --git a/Godeps/_workspace/src/github.com/anachronistic/apns/client.go b/Godeps/_workspace/src/github.com/anachronistic/apns/client.go
deleted file mode 100644
index 3fc079a87..000000000
--- a/Godeps/_workspace/src/github.com/anachronistic/apns/client.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package apns
-
-import (
- "crypto/tls"
- "errors"
- "net"
- "strings"
- "time"
-)
-
-var _ APNSClient = &Client{}
-
-// APNSClient is an APNS client.
-type APNSClient interface {
- ConnectAndWrite(resp *PushNotificationResponse, payload []byte) (err error)
- Send(pn *PushNotification) (resp *PushNotificationResponse)
-}
-
-// Client contains the fields necessary to communicate
-// with Apple, such as the gateway to use and your
-// certificate contents.
-//
-// You'll need to provide your own CertificateFile
-// and KeyFile to send notifications. Ideally, you'll
-// just set the CertificateFile and KeyFile fields to
-// a location on drive where the certs can be loaded,
-// but if you prefer you can use the CertificateBase64
-// and KeyBase64 fields to store the actual contents.
-type Client struct {
- Gateway string
- CertificateFile string
- CertificateBase64 string
- KeyFile string
- KeyBase64 string
-}
-
-// BareClient can be used to set the contents of your
-// certificate and key blocks manually.
-func BareClient(gateway, certificateBase64, keyBase64 string) (c *Client) {
- c = new(Client)
- c.Gateway = gateway
- c.CertificateBase64 = certificateBase64
- c.KeyBase64 = keyBase64
- return
-}
-
-// NewClient assumes you'll be passing in paths that
-// point to your certificate and key.
-func NewClient(gateway, certificateFile, keyFile string) (c *Client) {
- c = new(Client)
- c.Gateway = gateway
- c.CertificateFile = certificateFile
- c.KeyFile = keyFile
- return
-}
-
-// Send connects to the APN service and sends your push notification.
-// Remember that if the submission is successful, Apple won't reply.
-func (client *Client) Send(pn *PushNotification) (resp *PushNotificationResponse) {
- resp = new(PushNotificationResponse)
-
- payload, err := pn.ToBytes()
- if err != nil {
- resp.Success = false
- resp.Error = err
- return
- }
-
- err = client.ConnectAndWrite(resp, payload)
- if err != nil {
- resp.Success = false
- resp.Error = err
- return
- }
-
- resp.Success = true
- resp.Error = nil
-
- return
-}
-
-// ConnectAndWrite establishes the connection to Apple and handles the
-// transmission of your push notification, as well as waiting for a reply.
-//
-// In lieu of a timeout (which would be available in Go 1.1)
-// we use a timeout channel pattern instead. We start two goroutines,
-// one of which just sleeps for TimeoutSeconds seconds, while the other
-// waits for a response from the Apple servers.
-//
-// Whichever channel puts data on first is the "winner". As such, it's
-// possible to get a false positive if Apple takes a long time to respond.
-// It's probably not a deal-breaker, but something to be aware of.
-func (client *Client) ConnectAndWrite(resp *PushNotificationResponse, payload []byte) (err error) {
- var cert tls.Certificate
-
- if len(client.CertificateBase64) == 0 && len(client.KeyBase64) == 0 {
- // The user did not specify raw block contents, so check the filesystem.
- cert, err = tls.LoadX509KeyPair(client.CertificateFile, client.KeyFile)
- } else {
- // The user provided the raw block contents, so use that.
- cert, err = tls.X509KeyPair([]byte(client.CertificateBase64), []byte(client.KeyBase64))
- }
-
- if err != nil {
- return err
- }
-
- gatewayParts := strings.Split(client.Gateway, ":")
- conf := &tls.Config{
- Certificates: []tls.Certificate{cert},
- ServerName: gatewayParts[0],
- }
-
- conn, err := net.Dial("tcp", client.Gateway)
- if err != nil {
- return err
- }
- defer conn.Close()
-
- tlsConn := tls.Client(conn, conf)
- err = tlsConn.Handshake()
- if err != nil {
- return err
- }
- defer tlsConn.Close()
-
- _, err = tlsConn.Write(payload)
- if err != nil {
- return err
- }
-
- // Create one channel that will serve to handle
- // timeouts when the notification succeeds.
- timeoutChannel := make(chan bool, 1)
- go func() {
- time.Sleep(time.Second * TimeoutSeconds)
- timeoutChannel <- true
- }()
-
- // This channel will contain the binary response
- // from Apple in the event of a failure.
- responseChannel := make(chan []byte, 1)
- go func() {
- buffer := make([]byte, 6, 6)
- tlsConn.Read(buffer)
- responseChannel <- buffer
- }()
-
- // First one back wins!
- // The data structure for an APN response is as follows:
- //
- // command -> 1 byte
- // status -> 1 byte
- // identifier -> 4 bytes
- //
- // The first byte will always be set to 8.
- select {
- case r := <-responseChannel:
- resp.Success = false
- resp.AppleResponse = ApplePushResponses[r[1]]
- err = errors.New(resp.AppleResponse)
- case <-timeoutChannel:
- resp.Success = true
- }
-
- return err
-}