From 5116526fbc3420c22742e3fe063420ed2ab10ab5 Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 15:01:25 +0800 Subject: [PATCH 1/9] add timeout --- client.go | 10 +++++++--- client_test.go | 6 +++--- conn.go | 21 ++++++++++++++++++--- conn_test.go | 6 +++--- feedback_test.go | 6 +++--- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/client.go b/client.go index de7ab1a..f70ac95 100644 --- a/client.go +++ b/client.go @@ -48,12 +48,15 @@ func newClientWithConn(gw string, conn Conn) Client { return c } -func NewClientWithCert(gw string, cert tls.Certificate) Client { - conn := NewConnWithCert(gw, cert) - +func NewClietWithCertTimeout(gw string, cert tls.Certificate, timeout int) Client { + conn := NewConnWithCertTimeout(gw, cert, timeout) return newClientWithConn(gw, conn) } +func NewClientWithCert(gw string, cert tls.Certificate) Client { + return NewClietWithCertTimeout(gw, cert, 0) +} + func NewClient(gw string, cert string, key string) (Client, error) { conn, err := NewConn(gw, cert, key) if err != nil { @@ -132,6 +135,7 @@ func (c *Client) runLoop() { if err != nil { // TODO Probably want to exponentially backoff... time.Sleep(1 * time.Second) + log.Println("err connecting to apns ", err.Error()) continue } diff --git a/client_test.go b/client_test.go index c9dfd47..65c5a39 100644 --- a/client_test.go +++ b/client_test.go @@ -3,12 +3,12 @@ package apns_test import ( "bytes" "encoding/binary" - "io/ioutil" - "os" - "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/timehop/apns" + "io/ioutil" + "os" + "time" ) var _ = Describe("Client", func() { diff --git a/conn.go b/conn.go index d3aa712..6c231c6 100644 --- a/conn.go +++ b/conn.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "net" "strings" + "time" ) const ( @@ -18,19 +19,24 @@ const ( type Conn struct { NetConn net.Conn Conf *tls.Config + timeout time.Duration gateway string connected bool } -func NewConnWithCert(gw string, cert tls.Certificate) Conn { +func NewConnWithCertTimeout(gw string, cert tls.Certificate, timeout int) Conn { gatewayParts := strings.Split(gw, ":") conf := tls.Config{ Certificates: []tls.Certificate{cert}, ServerName: gatewayParts[0], } - return Conn{gateway: gw, Conf: &conf} + return Conn{gateway: gw, Conf: &conf, timeout: time.Duration(timeout) * time.Second} +} + +func NewConnWithCert(gw string, cert tls.Certificate) Conn { + return NewConnWithCertTimeout(gw, cert, 0) } // NewConnWithFiles creates a new Conn from certificate and key in the specified files @@ -60,12 +66,15 @@ func (c *Conn) Connect() error { c.NetConn.Close() } - conn, err := net.Dial("tcp", c.gateway) + conn, err := net.DialTimeout("tcp", c.gateway, c.timeout) if err != nil { return err } tlsConn := tls.Client(conn, c.Conf) + if c.timeout > 0 { + tlsConn.SetDeadline(time.Now().Add(c.timeout * 3)) + } err = tlsConn.Handshake() if err != nil { return err @@ -85,11 +94,17 @@ func (c *Conn) Close() error { // Read reads data from the connection func (c *Conn) Read(p []byte) (int, error) { + if c.timeout > 0 { + c.NetConn.SetReadDeadline(time.Now().Add(c.timeout)) + } i, err := c.NetConn.Read(p) return i, err } // Write writes data from the connection func (c *Conn) Write(p []byte) (int, error) { + if c.timeout > 0 { + c.NetConn.SetWriteDeadline(time.Now().Add(c.timeout)) + } return c.NetConn.Write(p) } diff --git a/conn_test.go b/conn_test.go index e910e6c..1ca4f79 100644 --- a/conn_test.go +++ b/conn_test.go @@ -4,6 +4,9 @@ import ( "bytes" "crypto/tls" "fmt" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/timehop/apns" "io" "io/ioutil" "log" @@ -11,9 +14,6 @@ import ( "os" "strings" "time" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/timehop/apns" ) var DummyCert = `-----BEGIN CERTIFICATE----- diff --git a/feedback_test.go b/feedback_test.go index 29978b4..dcfe620 100644 --- a/feedback_test.go +++ b/feedback_test.go @@ -4,12 +4,12 @@ import ( "bytes" "encoding/binary" "encoding/hex" - "io/ioutil" - "os" - "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/timehop/apns" + "io/ioutil" + "os" + "time" ) var _ = Describe("Feedback", func() { From 7fcb9c84ac1ad7cf9d6465acc41addd4a4492715 Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 15:24:43 +0800 Subject: [PATCH 2/9] fix ut error --- conn.go | 1 + 1 file changed, 1 insertion(+) diff --git a/conn.go b/conn.go index 6c231c6..ba702cb 100644 --- a/conn.go +++ b/conn.go @@ -79,6 +79,7 @@ func (c *Conn) Connect() error { if err != nil { return err } + tlsConn.SetDeadline(time.Time{}) c.NetConn = tlsConn return nil From d7acc6e26a6de856f6aca79d516fc59ea8d1b0d1 Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 15:55:06 +0800 Subject: [PATCH 3/9] fix ut timeout issue --- conn.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/conn.go b/conn.go index ba702cb..e00ec63 100644 --- a/conn.go +++ b/conn.go @@ -66,7 +66,13 @@ func (c *Conn) Connect() error { c.NetConn.Close() } - conn, err := net.DialTimeout("tcp", c.gateway, c.timeout) + var conn net.Conn + var err error + if c.timeout > 0 { + conn, err = net.DialTimeout("tcp", c.gateway, c.timeout) + } else { + conn, err = net.Dial("tcp", c.gateway) + } if err != nil { return err } @@ -79,7 +85,6 @@ func (c *Conn) Connect() error { if err != nil { return err } - tlsConn.SetDeadline(time.Time{}) c.NetConn = tlsConn return nil From 461ddf8363e6e36fe0a50ec19830df5f5985fe48 Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 16:10:27 +0800 Subject: [PATCH 4/9] add timeout for NewConnWithFilesTimeout --- conn.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/conn.go b/conn.go index e00ec63..c3983f4 100644 --- a/conn.go +++ b/conn.go @@ -50,13 +50,18 @@ func NewConn(gw string, crt string, key string) (Conn, error) { } // NewConnWithFiles creates a new Conn from certificate and key in the specified files -func NewConnWithFiles(gw string, certFile string, keyFile string) (Conn, error) { +func NewConnWithFilesTimeout(gw string, certFile string, keyFile string, timeout int) (Conn, error) { cert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { return Conn{}, err } - return NewConnWithCert(gw, cert), nil + return NewConnWithCertTimeout(gw, cert, timeout), nil +} + +// NewConnWithFiles creates a new Conn from certificate and key in the specified files +func NewConnWithFiles(gw string, certFile string, keyFile string) (Conn, error) { + return NewConnWithFilesTimeout(gw, certFile, keyFile, 0) } // Connect actually creates the TLS connection From 4d50428b9ad330d24f390c30905008330c2cc277 Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 17:14:14 +0800 Subject: [PATCH 5/9] add timeout for NewClientWithFilesTimeout --- client.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client.go b/client.go index f70ac95..bbc03b0 100644 --- a/client.go +++ b/client.go @@ -66,8 +66,8 @@ func NewClient(gw string, cert string, key string) (Client, error) { return newClientWithConn(gw, conn), nil } -func NewClientWithFiles(gw string, certFile string, keyFile string) (Client, error) { - conn, err := NewConnWithFiles(gw, certFile, keyFile) +func NewClientWithFilesTimeout(gw string, certFile string, keyFile string, timeout int) (Client, error) { + conn, err := NewConnWithFilesTimeout(gw, certFile, keyFile, timeout) if err != nil { return Client{}, err } @@ -75,6 +75,10 @@ func NewClientWithFiles(gw string, certFile string, keyFile string) (Client, err return newClientWithConn(gw, conn), nil } +func NewClientWithFiles(gw string, certFile string, keyFile string) (Client, error) { + return NewClientWithFilesTimeout(gw, certFile, keyFile, 0) +} + func (c *Client) Send(n Notification) error { c.notifs <- n return nil From cc3af8d94e979f5d997f4ebe32778174a32c22bc Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 17:52:23 +0800 Subject: [PATCH 6/9] add read error log --- client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/client.go b/client.go index bbc03b0..c53e8d0 100644 --- a/client.go +++ b/client.go @@ -216,6 +216,7 @@ func readErrs(c *Conn) chan error { _, err := c.Read(p) if err != nil { errs <- err + log.Printf("read err", err.Error()) return } From 13d95abb9a4b972e8a51d6dc86654e782cf842bf Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 17:55:56 +0800 Subject: [PATCH 7/9] do not timeout on read --- conn.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/conn.go b/conn.go index c3983f4..a23113f 100644 --- a/conn.go +++ b/conn.go @@ -105,9 +105,6 @@ func (c *Conn) Close() error { // Read reads data from the connection func (c *Conn) Read(p []byte) (int, error) { - if c.timeout > 0 { - c.NetConn.SetReadDeadline(time.Now().Add(c.timeout)) - } i, err := c.NetConn.Read(p) return i, err } From 6e1ce686500080215ed4b2f1712c3f09a3a84a58 Mon Sep 17 00:00:00 2001 From: hexihui Date: Sun, 10 Jan 2016 18:01:34 +0800 Subject: [PATCH 8/9] no read timeout --- client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/client.go b/client.go index c53e8d0..f1ecb09 100644 --- a/client.go +++ b/client.go @@ -213,6 +213,7 @@ func readErrs(c *Conn) chan error { go func() { p := make([]byte, 6, 6) + c.NetConn.SetReadDeadline(time.Time{}) _, err := c.Read(p) if err != nil { errs <- err From db300fa984c1cf382e6c78f8336637e4c981b304 Mon Sep 17 00:00:00 2001 From: hexihui Date: Mon, 11 Jan 2016 15:08:49 +0800 Subject: [PATCH 9/9] fix read error log --- client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.go b/client.go index f1ecb09..5d9eeb4 100644 --- a/client.go +++ b/client.go @@ -217,7 +217,7 @@ func readErrs(c *Conn) chan error { _, err := c.Read(p) if err != nil { errs <- err - log.Printf("read err", err.Error()) + log.Println("read err", err.Error()) return }