commit
ec1cfdd566
3
Makefile
3
Makefile
|
@ -34,5 +34,8 @@ endif
|
|||
docker tag -f $(PRODUCTION_IMAGE):latest $(DEPLOY_ACCOUNT)/$(PRODUCTION_IMAGE):$(tag)
|
||||
docker push $(DEPLOY_ACCOUNT)/$(PRODUCTION_IMAGE):$(tag)
|
||||
|
||||
lint:
|
||||
golint gopush
|
||||
|
||||
clean:
|
||||
-rm -rf build.tar.gz gopush.tar.gz bin/*
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// A push notification server using Gin framework written in Go (Golang).
|
||||
//
|
||||
// Details about the gopush project are found in github page:
|
||||
//
|
||||
// https://github.com/appleboy/gopush
|
||||
//
|
||||
// Support Google Cloud Message using go-gcm library for Android.
|
||||
// Support HTTP/2 Apple Push Notification Service using apns2 library.
|
||||
// Support YAML configuration.
|
||||
// Support command line to send single Android or iOS notification.
|
||||
// Support Web API to send push notification.
|
||||
// Support zero downtime restarts for go servers using endless.
|
||||
// Support HTTP/2 or HTTP/1.1 protocol.
|
||||
//
|
||||
// The pre-compiled binaries can be downloaded from release page.
|
||||
//
|
||||
// Send Android notification
|
||||
//
|
||||
// $ gopush -android -m="your message" -k="API Key" -t="Device token"
|
||||
//
|
||||
// Send iOS notification
|
||||
//
|
||||
// $ gopush -ios -m="your message" -i="API Key" -t="Device token"
|
||||
//
|
||||
// The default endpoint is APNs development. Please add -production flag for APNs production push endpoint.
|
||||
//
|
||||
// $ gopush -ios -m="your message" -i="API Key" -t="Device token" -production
|
||||
//
|
||||
// For more details, see the documentation and example.
|
||||
//
|
32
gorush.go
32
gorush.go
|
@ -1,33 +1,3 @@
|
|||
// A push notification server using Gin framework written in Go (Golang).
|
||||
//
|
||||
// Details about the gopush project are found in github page:
|
||||
//
|
||||
// https://github.com/appleboy/gopush
|
||||
//
|
||||
// Support Google Cloud Message using go-gcm library for Android.
|
||||
// Support HTTP/2 Apple Push Notification Service using apns2 library.
|
||||
// Support YAML configuration.
|
||||
// Support command line to send single Android or iOS notification.
|
||||
// Support Web API to send push notification.
|
||||
// Support zero downtime restarts for go servers using endless.
|
||||
// Support HTTP/2 or HTTP/1.1 protocol.
|
||||
//
|
||||
// The pre-compiled binaries can be downloaded from release page.
|
||||
//
|
||||
// Send Android notification
|
||||
//
|
||||
// $ gopush -android -m="your message" -k="API Key" -t="Device token"
|
||||
//
|
||||
// Send iOS notification
|
||||
//
|
||||
// $ gopush -ios -m="your message" -i="API Key" -t="Device token"
|
||||
//
|
||||
// The default endpoint is APNs development. Please add -production flag for APNs production push endpoint.
|
||||
//
|
||||
// $ gopush -ios -m="your message" -i="API Key" -t="Device token" -production
|
||||
//
|
||||
// For more details, see the documentation and example.
|
||||
//
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -76,7 +46,7 @@ func main() {
|
|||
}
|
||||
|
||||
if *apiKey != "" {
|
||||
gopush.PushConf.Android.ApiKey = *apiKey
|
||||
gopush.PushConf.Android.APIKey = *apiKey
|
||||
}
|
||||
|
||||
// overwrite server port
|
||||
|
|
|
@ -5,14 +5,16 @@ import (
|
|||
"io/ioutil"
|
||||
)
|
||||
|
||||
// ConfYaml is config structure.
|
||||
type ConfYaml struct {
|
||||
Core SectionCore `yaml:"core"`
|
||||
Api SectionApi `yaml:"api"`
|
||||
API SectionAPI `yaml:"api"`
|
||||
Android SectionAndroid `yaml:"android"`
|
||||
Ios SectionIos `yaml:"ios"`
|
||||
Log SectionLog `yaml:"log"`
|
||||
}
|
||||
|
||||
// SectionCore is sub seciont of config.
|
||||
type SectionCore struct {
|
||||
Port string `yaml:"port"`
|
||||
MaxNotification int `yaml:"max_notification"`
|
||||
|
@ -22,16 +24,19 @@ type SectionCore struct {
|
|||
KeyPath string `yaml:"key_path"`
|
||||
}
|
||||
|
||||
type SectionApi struct {
|
||||
PushUri string `yaml:"push_uri"`
|
||||
StatGoUri string `yaml:"stat_go_uri"`
|
||||
// SectionAPI is sub seciont of config.
|
||||
type SectionAPI struct {
|
||||
PushURI string `yaml:"push_uri"`
|
||||
StatGoURI string `yaml:"stat_go_uri"`
|
||||
}
|
||||
|
||||
// SectionAndroid is sub seciont of config.
|
||||
type SectionAndroid struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
ApiKey string `yaml:"apikey"`
|
||||
APIKey string `yaml:"apikey"`
|
||||
}
|
||||
|
||||
// SectionIos is sub seciont of config.
|
||||
type SectionIos struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
PemCertPath string `yaml:"pem_cert_path"`
|
||||
|
@ -39,6 +44,7 @@ type SectionIos struct {
|
|||
Production bool `yaml:"production"`
|
||||
}
|
||||
|
||||
// SectionLog is sub seciont of config.
|
||||
type SectionLog struct {
|
||||
Format string `yaml:"format"`
|
||||
AccessLog string `yaml:"access_log"`
|
||||
|
@ -47,6 +53,7 @@ type SectionLog struct {
|
|||
ErrorLevel string `yaml:"error_level"`
|
||||
}
|
||||
|
||||
// BuildDefaultPushConf is default config setting.
|
||||
func BuildDefaultPushConf() ConfYaml {
|
||||
var conf ConfYaml
|
||||
|
||||
|
@ -59,12 +66,12 @@ func BuildDefaultPushConf() ConfYaml {
|
|||
conf.Core.MaxNotification = 100
|
||||
|
||||
// Api
|
||||
conf.Api.PushUri = "/api/push"
|
||||
conf.Api.StatGoUri = "/api/status"
|
||||
conf.API.PushURI = "/api/push"
|
||||
conf.API.StatGoURI = "/api/status"
|
||||
|
||||
// Android
|
||||
conf.Android.Enabled = false
|
||||
conf.Android.ApiKey = ""
|
||||
conf.Android.APIKey = ""
|
||||
|
||||
// iOS
|
||||
conf.Ios.Enabled = false
|
||||
|
@ -82,6 +89,7 @@ func BuildDefaultPushConf() ConfYaml {
|
|||
return conf
|
||||
}
|
||||
|
||||
// LoadConfYaml provide load yml config.
|
||||
func LoadConfYaml(confPath string) (ConfYaml, error) {
|
||||
var config ConfYaml
|
||||
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
package gopush
|
||||
|
||||
const (
|
||||
// Version is gorush server version.
|
||||
Version = "1.0.0"
|
||||
)
|
||||
|
||||
const (
|
||||
// PlatFormIos constant is 1 for iOS
|
||||
PlatFormIos = iota + 1
|
||||
// PlatFormAndroid constant is 2 for Android
|
||||
PlatFormAndroid
|
||||
)
|
||||
|
||||
const (
|
||||
StatusSucceededPush = "succeeded-push"
|
||||
StatusFailedPush = "failed-push"
|
||||
// SucceededPush is log block
|
||||
SucceededPush = "succeeded-push"
|
||||
// FailedPush is log block
|
||||
FailedPush = "failed-push"
|
||||
)
|
||||
|
|
|
@ -7,9 +7,14 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
PushConf ConfYaml
|
||||
// PushConf is gorush config
|
||||
PushConf ConfYaml
|
||||
// CertificatePemIos is ios certificate file
|
||||
CertificatePemIos tls.Certificate
|
||||
ApnsClient *apns.Client
|
||||
LogAccess *logrus.Logger
|
||||
LogError *logrus.Logger
|
||||
// ApnsClient is apns client
|
||||
ApnsClient *apns.Client
|
||||
// LogAccess is log server request log
|
||||
LogAccess *logrus.Logger
|
||||
// LogError is log server error log
|
||||
LogError *logrus.Logger
|
||||
)
|
||||
|
|
|
@ -21,6 +21,7 @@ var (
|
|||
reset = string([]byte{27, 91, 48, 109})
|
||||
)
|
||||
|
||||
// LogReq is http request log
|
||||
type LogReq struct {
|
||||
URI string `json:"uri"`
|
||||
Method string `json:"method"`
|
||||
|
@ -29,6 +30,7 @@ type LogReq struct {
|
|||
Agent string `json:"agent"`
|
||||
}
|
||||
|
||||
// LogPushEntry is push response log
|
||||
type LogPushEntry struct {
|
||||
Type string `json:"type"`
|
||||
Platform string `json:"platform"`
|
||||
|
@ -52,6 +54,7 @@ type LogPushEntry struct {
|
|||
Category string `json:"category,omitempty"`
|
||||
}
|
||||
|
||||
// InitLog use for initial log module
|
||||
func InitLog() error {
|
||||
|
||||
var err error
|
||||
|
@ -92,6 +95,7 @@ func InitLog() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SetLogOut provide log stdout and stderr output
|
||||
func SetLogOut(log *logrus.Logger, outString string) error {
|
||||
switch outString {
|
||||
case "stdout":
|
||||
|
@ -111,6 +115,8 @@ func SetLogOut(log *logrus.Logger, outString string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SetLogLevel is define log level what you want
|
||||
// log level: panic, fatal, error, warn, info and debug
|
||||
func SetLogLevel(log *logrus.Logger, levelString string) error {
|
||||
level, err := logrus.ParseLevel(levelString)
|
||||
|
||||
|
@ -123,6 +129,7 @@ func SetLogLevel(log *logrus.Logger, levelString string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// LogRequest record http request
|
||||
func LogRequest(uri string, method string, ip string, contentType string, agent string) {
|
||||
var output string
|
||||
log := &LogReq{
|
||||
|
@ -134,9 +141,9 @@ func LogRequest(uri string, method string, ip string, contentType string, agent
|
|||
}
|
||||
|
||||
if PushConf.Log.Format == "json" {
|
||||
logJson, _ := json.Marshal(log)
|
||||
logJSON, _ := json.Marshal(log)
|
||||
|
||||
output = string(logJson)
|
||||
output = string(logJSON)
|
||||
} else {
|
||||
// format is string
|
||||
output = fmt.Sprintf("|%s header %s| %s %s %s %s %s",
|
||||
|
@ -174,6 +181,7 @@ func typeForPlatForm(platform int) string {
|
|||
}
|
||||
}
|
||||
|
||||
// LogPush record user push request and server response.
|
||||
func LogPush(status, token string, req PushNotification, errPush error) {
|
||||
var plat, platColor, output string
|
||||
|
||||
|
@ -194,19 +202,19 @@ func LogPush(status, token string, req PushNotification, errPush error) {
|
|||
}
|
||||
|
||||
if PushConf.Log.Format == "json" {
|
||||
logJson, _ := json.Marshal(log)
|
||||
logJSON, _ := json.Marshal(log)
|
||||
|
||||
output = string(logJson)
|
||||
output = string(logJSON)
|
||||
} else {
|
||||
switch status {
|
||||
case StatusSucceededPush:
|
||||
case SucceededPush:
|
||||
output = fmt.Sprintf("|%s %s %s| %s%s%s [%s] %s",
|
||||
green, log.Type, reset,
|
||||
platColor, log.Platform, reset,
|
||||
log.Token,
|
||||
log.Message,
|
||||
)
|
||||
case StatusFailedPush:
|
||||
case FailedPush:
|
||||
output = fmt.Sprintf("|%s %s %s| %s%s%s [%s] | %s | Error Message: %s",
|
||||
red, log.Type, reset,
|
||||
platColor, log.Platform, reset,
|
||||
|
@ -218,13 +226,14 @@ func LogPush(status, token string, req PushNotification, errPush error) {
|
|||
}
|
||||
|
||||
switch status {
|
||||
case StatusSucceededPush:
|
||||
case SucceededPush:
|
||||
LogAccess.Info(string(output))
|
||||
case StatusFailedPush:
|
||||
case FailedPush:
|
||||
LogError.Error(string(output))
|
||||
}
|
||||
}
|
||||
|
||||
// LogMiddleware provide gin router handler.
|
||||
func LogMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
LogRequest(c.Request.URL.Path, c.Request.Method, c.ClientIP(), c.ContentType(), c.Request.Header.Get("User-Agent"))
|
||||
|
|
|
@ -10,22 +10,24 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// D provide string array
|
||||
type D map[string]interface{}
|
||||
|
||||
const (
|
||||
// PriorityLow will tell APNs to send the push message at a time that takes
|
||||
// ApnsPriorityLow will tell APNs to send the push message at a time that takes
|
||||
// into account power considerations for the device. Notifications with this
|
||||
// priority might be grouped and delivered in bursts. They are throttled, and
|
||||
// in some cases are not delivered.
|
||||
ApnsPriorityLow = 5
|
||||
|
||||
// PriorityHigh will tell APNs to send the push message immediately.
|
||||
// ApnsPriorityHigh will tell APNs to send the push message immediately.
|
||||
// Notifications with this priority must trigger an alert, sound, or badge on
|
||||
// the target device. It is an error to use this priority for a push
|
||||
// notification that contains only the content-available key.
|
||||
ApnsPriorityHigh = 10
|
||||
)
|
||||
|
||||
// Alert is APNs payload
|
||||
type Alert struct {
|
||||
Action string `json:"action,omitempty"`
|
||||
ActionLocKey string `json:"action-loc-key,omitempty"`
|
||||
|
@ -38,10 +40,12 @@ type Alert struct {
|
|||
TitleLocKey string `json:"title-loc-key,omitempty"`
|
||||
}
|
||||
|
||||
// RequestPush support multiple notification request.
|
||||
type RequestPush struct {
|
||||
Notifications []PushNotification `json:"notifications" binding:"required"`
|
||||
}
|
||||
|
||||
// PushNotification is single notification request
|
||||
type PushNotification struct {
|
||||
// Common
|
||||
Tokens []string `json:"tokens" binding:"required"`
|
||||
|
@ -54,7 +58,7 @@ type PushNotification struct {
|
|||
Data D `json:"data,omitempty"`
|
||||
|
||||
// Android
|
||||
ApiKey string `json:"api_key,omitempty"`
|
||||
APIKey string `json:"api_key,omitempty"`
|
||||
To string `json:"to,omitempty"`
|
||||
CollapseKey string `json:"collapse_key,omitempty"`
|
||||
DelayWhileIdle bool `json:"delay_while_idle,omitempty"`
|
||||
|
@ -73,9 +77,10 @@ type PushNotification struct {
|
|||
Alert Alert `json:"alert,omitempty"`
|
||||
}
|
||||
|
||||
// CheckPushConf provide check your yml config.
|
||||
func CheckPushConf() error {
|
||||
if !PushConf.Ios.Enabled && !PushConf.Android.Enabled {
|
||||
return errors.New("Please enable iOS or Android config in yaml config")
|
||||
return errors.New("Please enable iOS or Android config in yml config")
|
||||
}
|
||||
|
||||
if PushConf.Ios.Enabled {
|
||||
|
@ -85,7 +90,7 @@ func CheckPushConf() error {
|
|||
}
|
||||
|
||||
if PushConf.Android.Enabled {
|
||||
if PushConf.Android.ApiKey == "" {
|
||||
if PushConf.Android.APIKey == "" {
|
||||
return errors.New("Missing Android API Key")
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +98,7 @@ func CheckPushConf() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// InitAPNSClient use for initialize APNs Client.
|
||||
func InitAPNSClient() error {
|
||||
if PushConf.Ios.Enabled {
|
||||
var err error
|
||||
|
@ -115,6 +121,7 @@ func InitAPNSClient() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SendNotification provide send all push request.
|
||||
func SendNotification(req RequestPush) int {
|
||||
var count int
|
||||
for _, notification := range req.Notifications {
|
||||
|
@ -124,14 +131,14 @@ func SendNotification(req RequestPush) int {
|
|||
continue
|
||||
}
|
||||
|
||||
count += 1
|
||||
count++
|
||||
go PushToIOS(notification)
|
||||
case PlatFormAndroid:
|
||||
if !PushConf.Android.Enabled {
|
||||
continue
|
||||
}
|
||||
|
||||
count += 1
|
||||
count++
|
||||
go PushToAndroid(notification)
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +146,7 @@ func SendNotification(req RequestPush) int {
|
|||
return count
|
||||
}
|
||||
|
||||
// GetIOSNotification use for define iOS notificaiton.
|
||||
// The iOS Notification Payload
|
||||
// ref: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html
|
||||
func GetIOSNotification(req PushNotification) *apns.Notification {
|
||||
|
@ -233,6 +241,7 @@ func GetIOSNotification(req PushNotification) *apns.Notification {
|
|||
return notification
|
||||
}
|
||||
|
||||
// PushToIOS provide send notification to APNs server.
|
||||
func PushToIOS(req PushNotification) bool {
|
||||
|
||||
notification := GetIOSNotification(req)
|
||||
|
@ -245,7 +254,7 @@ func PushToIOS(req PushNotification) bool {
|
|||
|
||||
if err != nil {
|
||||
// apns server error
|
||||
LogPush(StatusFailedPush, token, req, err)
|
||||
LogPush(FailedPush, token, req, err)
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -253,19 +262,20 @@ func PushToIOS(req PushNotification) bool {
|
|||
if res.StatusCode != 200 {
|
||||
// error message:
|
||||
// ref: https://github.com/sideshow/apns2/blob/master/response.go#L14-L65
|
||||
LogPush(StatusFailedPush, token, req, errors.New(res.Reason))
|
||||
LogPush(FailedPush, token, req, errors.New(res.Reason))
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if res.Sent() {
|
||||
LogPush(StatusSucceededPush, token, req, nil)
|
||||
LogPush(SucceededPush, token, req, nil)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// GetAndroidNotification use for define Android notificaiton.
|
||||
// HTTP Connection Server Reference for Android
|
||||
// https://developers.google.com/cloud-messaging/http-server-ref
|
||||
func GetAndroidNotification(req PushNotification) gcm.HttpMessage {
|
||||
|
@ -331,16 +341,17 @@ func GetAndroidNotification(req PushNotification) gcm.HttpMessage {
|
|||
return notification
|
||||
}
|
||||
|
||||
// PushToAndroid provide send notification to Android server.
|
||||
func PushToAndroid(req PushNotification) bool {
|
||||
var apiKey string
|
||||
var APIKey string
|
||||
|
||||
notification := GetAndroidNotification(req)
|
||||
|
||||
if apiKey = PushConf.Android.ApiKey; req.ApiKey != "" {
|
||||
apiKey = req.ApiKey
|
||||
if APIKey = PushConf.Android.APIKey; req.APIKey != "" {
|
||||
APIKey = req.APIKey
|
||||
}
|
||||
|
||||
res, err := gcm.SendHttp(apiKey, notification)
|
||||
res, err := gcm.SendHttp(APIKey, notification)
|
||||
|
||||
if err != nil {
|
||||
// GCM server error
|
||||
|
@ -353,11 +364,11 @@ func PushToAndroid(req PushNotification) bool {
|
|||
|
||||
for k, result := range res.Results {
|
||||
if result.Error != "" {
|
||||
LogPush(StatusFailedPush, req.Tokens[k], req, errors.New(result.Error))
|
||||
LogPush(FailedPush, req.Tokens[k], req, errors.New(result.Error))
|
||||
continue
|
||||
}
|
||||
|
||||
LogPush(StatusSucceededPush, req.Tokens[k], req, nil)
|
||||
LogPush(SucceededPush, req.Tokens[k], req, nil)
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
|
@ -18,7 +18,7 @@ func TestDisabledAndroidIosConf(t *testing.T) {
|
|||
err := CheckPushConf()
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, "Please enable iOS or Android config in yaml config", err.Error())
|
||||
assert.Equal(t, "Please enable iOS or Android config in yml config", err.Error())
|
||||
}
|
||||
|
||||
func TestMissingIOSCertificate(t *testing.T) {
|
||||
|
@ -37,7 +37,7 @@ func TestMissingAndroidAPIKey(t *testing.T) {
|
|||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = ""
|
||||
PushConf.Android.APIKey = ""
|
||||
|
||||
err := CheckPushConf()
|
||||
|
||||
|
@ -49,7 +49,7 @@ func TestCorrectConf(t *testing.T) {
|
|||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = "xxxxx"
|
||||
PushConf.Android.APIKey = "xxxxx"
|
||||
|
||||
PushConf.Ios.Enabled = true
|
||||
PushConf.Ios.PemKeyPath = "xxxxx"
|
||||
|
@ -237,7 +237,7 @@ func TestPushToAndroidWrongAPIKey(t *testing.T) {
|
|||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + "a"
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY") + "a"
|
||||
|
||||
req := PushNotification{
|
||||
Tokens: []string{"aaaaaa", "bbbbb"},
|
||||
|
@ -253,7 +253,7 @@ func TestPushToAndroidWrongToken(t *testing.T) {
|
|||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
req := PushNotification{
|
||||
Tokens: []string{"aaaaaa", "bbbbb"},
|
||||
|
@ -269,14 +269,14 @@ func TestPushToAndroidRightTokenForJSONLog(t *testing.T) {
|
|||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
// log for json
|
||||
PushConf.Log.Format = "json"
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
}
|
||||
|
@ -289,12 +289,12 @@ func TestPushToAndroidRightTokenForStringLog(t *testing.T) {
|
|||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
}
|
||||
|
@ -303,20 +303,20 @@ func TestPushToAndroidRightTokenForStringLog(t *testing.T) {
|
|||
assert.True(t, success)
|
||||
}
|
||||
|
||||
func TestOverwriteAndroidApiKey(t *testing.T) {
|
||||
func TestOverwriteAndroidAPIKey(t *testing.T) {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
// overwrite android api key
|
||||
ApiKey: "1234",
|
||||
APIKey: "1234",
|
||||
}
|
||||
|
||||
success := PushToAndroid(req)
|
||||
|
@ -331,9 +331,9 @@ func TestSenMultipleNotifications(t *testing.T) {
|
|||
InitAPNSClient()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPush{
|
||||
Notifications: []PushNotification{
|
||||
|
@ -345,7 +345,7 @@ func TestSenMultipleNotifications(t *testing.T) {
|
|||
},
|
||||
// android
|
||||
PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
},
|
||||
|
@ -364,9 +364,9 @@ func TestDisabledAndroidNotifications(t *testing.T) {
|
|||
InitAPNSClient()
|
||||
|
||||
PushConf.Android.Enabled = false
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPush{
|
||||
Notifications: []PushNotification{
|
||||
|
@ -378,7 +378,7 @@ func TestDisabledAndroidNotifications(t *testing.T) {
|
|||
},
|
||||
// android
|
||||
PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
},
|
||||
|
@ -397,9 +397,9 @@ func TestDisabledIosNotifications(t *testing.T) {
|
|||
InitAPNSClient()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
req := RequestPush{
|
||||
Notifications: []PushNotification{
|
||||
|
@ -411,7 +411,7 @@ func TestDisabledIosNotifications(t *testing.T) {
|
|||
},
|
||||
// android
|
||||
PushNotification{
|
||||
Tokens: []string{android_token, "bbbbb"},
|
||||
Tokens: []string{androidToken, "bbbbb"},
|
||||
Platform: 2,
|
||||
Message: "Welcome",
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
func AbortWithError(c *gin.Context, code int, message string) {
|
||||
func abortWithError(c *gin.Context, code int, message string) {
|
||||
c.JSON(code, gin.H{
|
||||
"code": code,
|
||||
"message": message,
|
||||
|
@ -29,21 +29,21 @@ func pushHandler(c *gin.Context) {
|
|||
if err := c.BindJSON(&form); err != nil {
|
||||
msg = "Missing notifications field."
|
||||
LogAccess.Debug(msg)
|
||||
AbortWithError(c, http.StatusBadRequest, msg)
|
||||
abortWithError(c, http.StatusBadRequest, msg)
|
||||
return
|
||||
}
|
||||
|
||||
if len(form.Notifications) == 0 {
|
||||
msg = "Notifications field is empty."
|
||||
LogAccess.Debug(msg)
|
||||
AbortWithError(c, http.StatusBadRequest, msg)
|
||||
abortWithError(c, http.StatusBadRequest, msg)
|
||||
return
|
||||
}
|
||||
|
||||
if len(form.Notifications) > PushConf.Core.MaxNotification {
|
||||
msg = fmt.Sprintf("Number of notifications(%d) over limit(%d)", len(form.Notifications), PushConf.Core.MaxNotification)
|
||||
LogAccess.Debug(msg)
|
||||
AbortWithError(c, http.StatusBadRequest, msg)
|
||||
abortWithError(c, http.StatusBadRequest, msg)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ func pushHandler(c *gin.Context) {
|
|||
})
|
||||
}
|
||||
|
||||
func GetMainEngine() *gin.Engine {
|
||||
func routerEngine() *gin.Engine {
|
||||
// set server mode
|
||||
gin.SetMode(PushConf.Core.Mode)
|
||||
|
||||
|
@ -67,19 +67,20 @@ func GetMainEngine() *gin.Engine {
|
|||
r.Use(VersionMiddleware())
|
||||
r.Use(LogMiddleware())
|
||||
|
||||
r.GET(PushConf.Api.StatGoUri, api.StatusHandler)
|
||||
r.POST(PushConf.Api.PushUri, pushHandler)
|
||||
r.GET(PushConf.API.StatGoURI, api.StatusHandler)
|
||||
r.POST(PushConf.API.PushURI, pushHandler)
|
||||
r.GET("/", rootHandler)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// RunHTTPServer provide run http or https protocol.
|
||||
func RunHTTPServer() error {
|
||||
var err error
|
||||
if PushConf.Core.SSL && PushConf.Core.CertPath != "" && PushConf.Core.KeyPath != "" {
|
||||
err = endless.ListenAndServeTLS(":"+PushConf.Core.Port, PushConf.Core.CertPath, PushConf.Core.KeyPath, GetMainEngine())
|
||||
err = endless.ListenAndServeTLS(":"+PushConf.Core.Port, PushConf.Core.CertPath, PushConf.Core.KeyPath, routerEngine())
|
||||
} else {
|
||||
err = endless.ListenAndServe(":"+PushConf.Core.Port, GetMainEngine())
|
||||
err = endless.ListenAndServe(":"+PushConf.Core.Port, routerEngine())
|
||||
}
|
||||
|
||||
return err
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var go_version = runtime.Version()
|
||||
var goVersion = runtime.Version()
|
||||
|
||||
func initTest() {
|
||||
PushConf = BuildDefaultPushConf()
|
||||
|
@ -66,7 +66,7 @@ func TestRootHandler(t *testing.T) {
|
|||
PushConf.Log.Format = "json"
|
||||
|
||||
r.GET("/").
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
data := []byte(r.Body.String())
|
||||
|
||||
value, _ := jsonparser.GetString(data, "text")
|
||||
|
@ -82,12 +82,12 @@ func TestAPIStatusHandler(t *testing.T) {
|
|||
r := gofight.New()
|
||||
|
||||
r.GET("/api/status").
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
data := []byte(r.Body.String())
|
||||
|
||||
value, _ := jsonparser.GetString(data, "go_version")
|
||||
value, _ := jsonparser.GetString(data, "goVersion")
|
||||
|
||||
assert.Equal(t, go_version, value)
|
||||
assert.Equal(t, goVersion, value)
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ func TestMissingNotificationsParameter(t *testing.T) {
|
|||
|
||||
// missing notifications parameter.
|
||||
r.POST("/api/push").
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
|
@ -115,7 +115,7 @@ func TestEmptyNotifications(t *testing.T) {
|
|||
SetJSON(gofight.D{
|
||||
"notifications": []PushNotification{},
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
|
@ -144,7 +144,7 @@ func TestOutOfRangeMaxNotifications(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
|
@ -154,9 +154,9 @@ func TestSuccessPushHandler(t *testing.T) {
|
|||
initTest()
|
||||
|
||||
PushConf.Android.Enabled = true
|
||||
PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY")
|
||||
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
|
||||
|
||||
android_token := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
|
||||
|
||||
r := gofight.New()
|
||||
|
||||
|
@ -164,13 +164,13 @@ func TestSuccessPushHandler(t *testing.T) {
|
|||
SetJSON(gofight.D{
|
||||
"notifications": []gofight.D{
|
||||
gofight.D{
|
||||
"tokens": []string{android_token, "bbbbb"},
|
||||
"tokens": []string{androidToken, "bbbbb"},
|
||||
"platform": 2,
|
||||
"message": "Welcome",
|
||||
},
|
||||
},
|
||||
}).
|
||||
Run(GetMainEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
Run(routerEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
|
||||
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
})
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"runtime"
|
||||
)
|
||||
|
||||
// PrintGoPushVersion provide print server engine
|
||||
func PrintGoPushVersion() {
|
||||
fmt.Printf(`GoPush %s, Compiler: %s %s, Copyright (C) 2016 Bo-Yi Wu, Inc.`,
|
||||
Version,
|
||||
|
@ -13,6 +14,7 @@ func PrintGoPushVersion() {
|
|||
runtime.Version())
|
||||
}
|
||||
|
||||
// VersionMiddleware : add version on header.
|
||||
func VersionMiddleware() gin.HandlerFunc {
|
||||
// Set out header value for each response
|
||||
return func(c *gin.Context) {
|
||||
|
|
Loading…
Reference in New Issue