chore(gorush): add timeout for http client (#473)

* chore(gorush): add timeout for http client

dispatch feedback url

See: https://github.com/appleboy/gorush/issues/449

* docs: update readme
This commit is contained in:
Bo-Yi Wu 2020-02-24 22:18:50 +08:00 committed by GitHub
parent e85252b4ae
commit 52622558bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 32 additions and 12 deletions

View File

@ -99,6 +99,7 @@ core:
max_notification: 100 max_notification: 100
sync: false # set true if you need get error message from fail push notification in API response. sync: false # set true if you need get error message from fail push notification in API response.
feedback_hook_url: "" # set a hook url if you need get error message asynchronously from fail push notification in API response. feedback_hook_url: "" # set a hook url if you need get error message asynchronously from fail push notification in API response.
feedback_timeout: 10 # default is 10 second
mode: "release" mode: "release"
ssl: false ssl: false
cert_path: "cert.pem" cert_path: "cert.pem"

View File

@ -21,6 +21,7 @@ core:
max_notification: 100 max_notification: 100
sync: false # set true if you need get error message from fail push notification in API response. sync: false # set true if you need get error message from fail push notification in API response.
feedback_hook_url: "" # set webhook url if you need get error message asynchronously from fail push notification in API response. feedback_hook_url: "" # set webhook url if you need get error message asynchronously from fail push notification in API response.
feedback_timeout: 10 # default is 10 second
mode: "release" mode: "release"
ssl: false ssl: false
cert_path: "cert.pem" cert_path: "cert.pem"
@ -118,6 +119,7 @@ type SectionCore struct {
KeyBase64 string `yaml:"key_base64"` KeyBase64 string `yaml:"key_base64"`
HTTPProxy string `yaml:"http_proxy"` HTTPProxy string `yaml:"http_proxy"`
FeedbackURL string `yaml:"feedback_hook_url"` FeedbackURL string `yaml:"feedback_hook_url"`
FeedbackTimeout int64 `yaml:"feedback_timeout"`
PID SectionPID `yaml:"pid"` PID SectionPID `yaml:"pid"`
AutoTLS SectionAutoTLS `yaml:"auto_tls"` AutoTLS SectionAutoTLS `yaml:"auto_tls"`
} }
@ -262,6 +264,7 @@ func LoadConf(confPath string) (ConfYaml, error) {
conf.Core.Mode = viper.GetString("core.mode") conf.Core.Mode = viper.GetString("core.mode")
conf.Core.Sync = viper.GetBool("core.sync") conf.Core.Sync = viper.GetBool("core.sync")
conf.Core.FeedbackURL = viper.GetString("core.feedback_hook_url") conf.Core.FeedbackURL = viper.GetString("core.feedback_hook_url")
conf.Core.FeedbackTimeout = int64(viper.GetInt("core.feedback_timeout"))
conf.Core.SSL = viper.GetBool("core.ssl") conf.Core.SSL = viper.GetBool("core.ssl")
conf.Core.CertPath = viper.GetString("core.cert_path") conf.Core.CertPath = viper.GetString("core.cert_path")
conf.Core.KeyPath = viper.GetString("core.key_path") conf.Core.KeyPath = viper.GetString("core.key_path")

View File

@ -46,6 +46,7 @@ func (suite *ConfigTestSuite) TestValidateConfDefault() {
assert.Equal(suite.T(), "release", suite.ConfGorushDefault.Core.Mode) assert.Equal(suite.T(), "release", suite.ConfGorushDefault.Core.Mode)
assert.Equal(suite.T(), false, suite.ConfGorushDefault.Core.Sync) assert.Equal(suite.T(), false, suite.ConfGorushDefault.Core.Sync)
assert.Equal(suite.T(), "", suite.ConfGorushDefault.Core.FeedbackURL) assert.Equal(suite.T(), "", suite.ConfGorushDefault.Core.FeedbackURL)
assert.Equal(suite.T(), int64(10), suite.ConfGorushDefault.Core.FeedbackTimeout)
assert.Equal(suite.T(), false, suite.ConfGorushDefault.Core.SSL) assert.Equal(suite.T(), false, suite.ConfGorushDefault.Core.SSL)
assert.Equal(suite.T(), "cert.pem", suite.ConfGorushDefault.Core.CertPath) assert.Equal(suite.T(), "cert.pem", suite.ConfGorushDefault.Core.CertPath)
assert.Equal(suite.T(), "key.pem", suite.ConfGorushDefault.Core.KeyPath) assert.Equal(suite.T(), "key.pem", suite.ConfGorushDefault.Core.KeyPath)
@ -120,6 +121,7 @@ func (suite *ConfigTestSuite) TestValidateConf() {
assert.Equal(suite.T(), "release", suite.ConfGorush.Core.Mode) assert.Equal(suite.T(), "release", suite.ConfGorush.Core.Mode)
assert.Equal(suite.T(), false, suite.ConfGorush.Core.Sync) assert.Equal(suite.T(), false, suite.ConfGorush.Core.Sync)
assert.Equal(suite.T(), "", suite.ConfGorush.Core.FeedbackURL) assert.Equal(suite.T(), "", suite.ConfGorush.Core.FeedbackURL)
assert.Equal(suite.T(), int64(10), suite.ConfGorush.Core.FeedbackTimeout)
assert.Equal(suite.T(), false, suite.ConfGorush.Core.SSL) assert.Equal(suite.T(), false, suite.ConfGorush.Core.SSL)
assert.Equal(suite.T(), "cert.pem", suite.ConfGorush.Core.CertPath) assert.Equal(suite.T(), "cert.pem", suite.ConfGorush.Core.CertPath)
assert.Equal(suite.T(), "key.pem", suite.ConfGorush.Core.KeyPath) assert.Equal(suite.T(), "key.pem", suite.ConfGorush.Core.KeyPath)

View File

@ -8,6 +8,7 @@ core:
max_notification: 100 max_notification: 100
sync: false # set true if you need get error message from fail push notification in API response. sync: false # set true if you need get error message from fail push notification in API response.
feedback_hook_url: "" # set a hook url if you need get error message asynchronously from fail push notification in API response. feedback_hook_url: "" # set a hook url if you need get error message asynchronously from fail push notification in API response.
feedback_timeout: 10 # default is 10 second
mode: "release" mode: "release"
ssl: false ssl: false
cert_path: "cert.pem" cert_path: "cert.pem"

View File

@ -4,11 +4,13 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"net"
"net/http" "net/http"
"time"
) )
// DispatchFeedback sends a feedback to the configured gateway. // DispatchFeedback sends a feedback to the configured gateway.
func DispatchFeedback(log LogPushEntry, url string) error { func DispatchFeedback(log LogPushEntry, url string, timeout int64) error {
if url == "" { if url == "" {
return errors.New("The url can't be empty") return errors.New("The url can't be empty")
@ -23,8 +25,18 @@ func DispatchFeedback(log LogPushEntry, url string) error {
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload)) req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))
req.Header.Set("Content-Type", "application/json; charset=utf-8") req.Header.Set("Content-Type", "application/json; charset=utf-8")
HTTPClient := &http.Client{} var transport = &http.Transport{
resp, err := HTTPClient.Do(req) Dial: (&net.Dialer{
Timeout: 5 * time.Second,
}).Dial,
TLSHandshakeTimeout: 5 * time.Second,
}
var client = &http.Client{
Timeout: time.Duration(timeout) * time.Second,
Transport: transport,
}
resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() defer resp.Body.Close()

View File

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/appleboy/gorush/config" "github.com/appleboy/gorush/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -21,7 +22,7 @@ func TestEmptyFeedbackURL(t *testing.T) {
Error: "", Error: "",
} }
err := DispatchFeedback(logEntry, PushConf.Core.FeedbackURL) err := DispatchFeedback(logEntry, PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
assert.NotNil(t, err) assert.NotNil(t, err)
} }
@ -37,7 +38,7 @@ func TestHTTPErrorInFeedbackCall(t *testing.T) {
Error: "", Error: "",
} }
err := DispatchFeedback(logEntry, config.Core.FeedbackURL) err := DispatchFeedback(logEntry, config.Core.FeedbackURL, config.Core.FeedbackTimeout)
assert.NotNil(t, err) assert.NotNil(t, err)
} }
@ -70,6 +71,6 @@ func TestSuccessfulFeedbackCall(t *testing.T) {
Error: "", Error: "",
} }
err := DispatchFeedback(logEntry, config.Core.FeedbackURL) err := DispatchFeedback(logEntry, config.Core.FeedbackURL, config.Core.FeedbackTimeout)
assert.Nil(t, err) assert.Nil(t, err)
} }

View File

@ -374,12 +374,12 @@ Retry:
if PushConf.Core.Sync { if PushConf.Core.Sync {
req.AddLog(getLogPushEntry(FailedPush, token, req, err)) req.AddLog(getLogPushEntry(FailedPush, token, req, err))
} else if PushConf.Core.FeedbackURL != "" { } else if PushConf.Core.FeedbackURL != "" {
go func(logger *logrus.Logger, log LogPushEntry, url string) { go func(logger *logrus.Logger, log LogPushEntry, url string, timeout int64) {
err := DispatchFeedback(log, url) err := DispatchFeedback(log, url, timeout)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
} }
}(LogError, getLogPushEntry(FailedPush, token, req, err), PushConf.Core.FeedbackURL) }(LogError, getLogPushEntry(FailedPush, token, req, err), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
} }
StatStorage.AddIosError(1) StatStorage.AddIosError(1)

View File

@ -160,12 +160,12 @@ Retry:
if PushConf.Core.Sync { if PushConf.Core.Sync {
req.AddLog(getLogPushEntry(FailedPush, to, req, result.Error)) req.AddLog(getLogPushEntry(FailedPush, to, req, result.Error))
} else if PushConf.Core.FeedbackURL != "" { } else if PushConf.Core.FeedbackURL != "" {
go func(logger *logrus.Logger, log LogPushEntry, url string) { go func(logger *logrus.Logger, log LogPushEntry, url string, timeout int64) {
err := DispatchFeedback(log, url) err := DispatchFeedback(log, url, timeout)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
} }
}(LogError, getLogPushEntry(FailedPush, to, req, result.Error), PushConf.Core.FeedbackURL) }(LogError, getLogPushEntry(FailedPush, to, req, result.Error), PushConf.Core.FeedbackURL, PushConf.Core.FeedbackTimeout)
} }
continue continue
} }