Skip to content

Commit

Permalink
Add lint (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
ringsaturn authored Feb 26, 2024
1 parent e45e488 commit a7798c5
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 77 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: golangci-lint
on:
push:
branches:
- master
- main
pull_request:

permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
pull-requests: read

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: "1.19"
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Require: The version of golangci-lint to use.
# When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
# When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
version: v1.53

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
#
# Note: By default, the `.golangci.yml` file should be at the root of the repository.
# The location of the configuration file can be changed by using `--config=`
# args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0

# Optional: show only new issues if it's a pull request. The default value is `false`.
only-new-issues: true

# Optional: if set to true, then all caching functionality will be completely disabled,
# takes precedence over all other caching options.
# skip-cache: true

# Optional: if set to true, then the action won't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true, then the action won't cache or restore ~/.cache/go-build.
# skip-build-cache: true

# Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'.
# install-mode: "goinstall"
39 changes: 8 additions & 31 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ import (
"crypto/tls"
"encoding/json"
"io"
"net"
"net/http"
"strconv"
"time"

"github.com/ringsaturn/apns2/token"
"golang.org/x/net/http2"
)

// Apple HTTP/2 Development & Production urls
Expand Down Expand Up @@ -48,16 +46,6 @@ var (
TLSDialTimeout = 20 * time.Second
)

// DialTLS is the default dial function for creating TLS connections for
// non-proxied HTTPS requests.
var DialTLS = func(network, addr string, cfg *tls.Config) (net.Conn, error) {
dialer := &net.Dialer{
Timeout: TLSDialTimeout,
KeepAlive: TCPKeepAlive,
}
return tls.DialWithDialer(dialer, network, addr, cfg)
}

// Client represents a connection with the APNs
type Client struct {
Host string
Expand All @@ -82,25 +70,19 @@ type connectionCloser interface {
// If your use case involves multiple long-lived connections, consider using
// the ClientManager, which manages clients for you.
func NewClient(certificate tls.Certificate) *Client {
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{certificate},
}
if len(certificate.Certificate) > 0 {
tlsConfig.BuildNameToCertificate()
}
transport := &http2.Transport{
TLSClientConfig: tlsConfig,
DialTLS: DialTLS,
ReadIdleTimeout: ReadIdleTimeout,
}
return &Client{
client := &Client{
HTTPClient: &http.Client{
Transport: transport,
Timeout: HTTPClientTimeout,
Transport: &http.Transport{},
},
Certificate: certificate,
Host: DefaultHost,
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{certificate},
}
client.HTTPClient.Transport.(*http.Transport).TLSClientConfig = tlsConfig
return client
}

// NewTokenClient returns a new Client with an underlying http.Client configured
Expand All @@ -112,15 +94,10 @@ func NewClient(certificate tls.Certificate) *Client {
// notifications; don’t repeatedly open and close connections. APNs treats rapid
// connection and disconnection as a denial-of-service attack.
func NewTokenClient(token *token.Token) *Client {
transport := &http2.Transport{
DialTLS: DialTLS,
ReadIdleTimeout: ReadIdleTimeout,
}
return &Client{
Token: token,
HTTPClient: &http.Client{
Transport: transport,
Timeout: HTTPClientTimeout,
Timeout: HTTPClientTimeout,
},
Host: DefaultHost,
}
Expand Down
45 changes: 4 additions & 41 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

"golang.org/x/net/http2"

apns "github.com/ringsaturn/apns2"
"github.com/ringsaturn/apns2/certificate"
"github.com/ringsaturn/apns2/token"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -113,40 +109,6 @@ func TestClientBadDeviceToken(t *testing.T) {
assert.Nil(t, res)
}

func TestClientNameToCertificate(t *testing.T) {
crt, _ := certificate.FromP12File("certificate/_fixtures/certificate-valid.p12", "")
client := apns.NewClient(crt)
name := client.HTTPClient.Transport.(*http2.Transport).TLSClientConfig.NameToCertificate
assert.Len(t, name, 1)

certificate2 := tls.Certificate{}
client2 := apns.NewClient(certificate2)
name2 := client2.HTTPClient.Transport.(*http2.Transport).TLSClientConfig.NameToCertificate
assert.Len(t, name2, 0)
}

func TestDialTLSTimeout(t *testing.T) {
apns.TLSDialTimeout = 10 * time.Millisecond
crt, _ := certificate.FromP12File("certificate/_fixtures/certificate-valid.p12", "")
client := apns.NewClient(crt)
dialTLS := client.HTTPClient.Transport.(*http2.Transport).DialTLS
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
address := listener.Addr().String()
defer listener.Close()
var e error
if _, e = dialTLS("tcp", address, nil); e == nil {
t.Fatal("Dial completed successfully")
}
// Go 1.7.x and later will return a context deadline exceeded error
// Previous versions will return a time out
if !strings.Contains(e.Error(), "timed out") && !errors.Is(e, context.DeadlineExceeded) {
t.Errorf("Unexpected error: %s", e)
}
}

// Functional Tests

func TestURL(t *testing.T) {
Expand Down Expand Up @@ -221,6 +183,7 @@ func TestClientPushWithNilContext(t *testing.T) {
}))
defer server.Close()

//lint:ignore SA1012 we need use nil context for test
res, err := mockClient(server.URL).PushWithContext(nil, n)

Check failure on line 187 in client_test.go

View workflow job for this annotation

GitHub Actions / lint

SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use (staticcheck)
assert.EqualError(t, err, "net/http: nil Context")
assert.Nil(t, res)
Expand Down Expand Up @@ -390,7 +353,7 @@ func Test400BadRequestPayloadEmptyResponse(t *testing.T) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("apns-id", apnsID)
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("{\"reason\":\"PayloadEmpty\"}"))
_, _ = w.Write([]byte("{\"reason\":\"PayloadEmpty\"}"))
}))
defer server.Close()
res, err := mockClient(server.URL).Push(n)
Expand All @@ -408,7 +371,7 @@ func Test410UnregisteredResponse(t *testing.T) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("apns-id", apnsID)
w.WriteHeader(http.StatusGone)
w.Write([]byte("{\"reason\":\"Unregistered\", \"timestamp\": 1458114061260 }"))
_, _ = w.Write([]byte("{\"reason\":\"Unregistered\", \"timestamp\": 1458114061260 }"))
}))
defer server.Close()
res, err := mockClient(server.URL).Push(n)
Expand All @@ -424,7 +387,7 @@ func TestMalformedJSONResponse(t *testing.T) {
n := mockNotification()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Write([]byte("{{MalformedJSON}}"))
_, _ = w.Write([]byte("{{MalformedJSON}}"))
}))
defer server.Close()
res, err := mockClient(server.URL).Push(n)
Expand Down
6 changes: 3 additions & 3 deletions payload/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func (p *Payload) URLArgs(urlArgs []string) *Payload {
// This function makes the notification a critical alert, which should be pre-approved by Apple.
// See: https://developer.apple.com/contact/request/notifications-critical-alerts-entitlement/
//
// {"aps":{"sound":{"critical":1,"name":name,"volume":1.0}}}
// {"aps":{"sound":{"critical":1,"name":name,"volume":1.0}}}
func (p *Payload) SoundName(name string) *Payload {
p.aps().sound().Name = name
return p
Expand All @@ -400,7 +400,7 @@ func (p *Payload) SoundName(name string) *Payload {
// This function makes the notification a critical alert, which should be pre-approved by Apple.
// See: https://developer.apple.com/contact/request/notifications-critical-alerts-entitlement/
//
// {"aps":{"sound":{"critical":1,"name":"default","volume":volume}}}
// {"aps":{"sound":{"critical":1,"name":"default","volume":volume}}}
func (p *Payload) SoundVolume(volume float32) *Payload {
p.aps().sound().Volume = volume
return p
Expand All @@ -411,7 +411,7 @@ func (p *Payload) SoundVolume(volume float32) *Payload {
// (Using InterruptionLevelCritical requires an approved entitlement from Apple.)
// See: https://developer.apple.com/documentation/usernotifications/unnotificationinterruptionlevel/
//
// {"aps":{"interruption-level":passive}}
// {"aps":{"interruption-level":passive}}
func (p *Payload) InterruptionLevel(interruptionLevel EInterruptionLevel) *Payload {
p.aps().InterruptionLevel = interruptionLevel
return p
Expand Down
5 changes: 4 additions & 1 deletion response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ func TestResponseSent(t *testing.T) {
func TestIntTimestampParse(t *testing.T) {
response := &apns.Response{}
payload := "{\"reason\":\"Unregistered\", \"timestamp\":1458114061260}"
json.Unmarshal([]byte(payload), &response)
err := json.Unmarshal([]byte(payload), &response)
if err != nil {
t.Error(err)
}
assert.Equal(t, int64(1458114061260)/1000, response.Timestamp.Unix())
}

Expand Down
2 changes: 1 addition & 1 deletion token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (t *Token) GenerateIfExpired() (bearer string) {
t.Lock()
defer t.Unlock()
if t.Expired() {
t.Generate()
_, _ = t.Generate()
}
return t.Bearer
}
Expand Down

0 comments on commit a7798c5

Please sign in to comment.