forked from Silverfish/proton-bridge
feat: MinSpeed -> MinBytesPerSecond, check every 3 seconds
This commit is contained in:
@ -32,6 +32,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
|||||||
### Fixed
|
### Fixed
|
||||||
* Use correct binary name when finding location of addcert.scpt
|
* Use correct binary name when finding location of addcert.scpt
|
||||||
* GODT-267 Correctly detect if a message is a draft even if does not have DraftLabel
|
* GODT-267 Correctly detect if a message is a draft even if does not have DraftLabel
|
||||||
|
* GODT-308 reduce minimum read speed threshold to avoid issues with flaky internet
|
||||||
|
|
||||||
## [v1.2.6] Donghai - beta (2020-03-31)
|
## [v1.2.6] Donghai - beta (2020-03-31)
|
||||||
|
|
||||||
|
|||||||
@ -31,11 +31,11 @@ import (
|
|||||||
|
|
||||||
func (c *Config) GetAPIConfig() *pmapi.ClientConfig {
|
func (c *Config) GetAPIConfig() *pmapi.ClientConfig {
|
||||||
return &pmapi.ClientConfig{
|
return &pmapi.ClientConfig{
|
||||||
AppVersion: strings.Title(c.appName) + "_" + c.version,
|
AppVersion: strings.Title(c.appName) + "_" + c.version,
|
||||||
ClientID: c.appName,
|
ClientID: c.appName,
|
||||||
Timeout: 10 * time.Minute, // Overall request timeout (~25MB / 10 mins => ~40kB/s, should be reasonable).
|
Timeout: 10 * time.Minute, // Overall request timeout (~25MB / 10 mins => ~40kB/s, should be reasonable).
|
||||||
FirstReadTimeout: 30 * time.Second, // 30s to match 30s response header timeout.
|
FirstReadTimeout: 30 * time.Second, // 30s to match 30s response header timeout.
|
||||||
MinSpeed: 1 << 10, // Enforce minimum download speed of 1kB/s.
|
MinBytesPerSecond: 1 << 10, // Enforce minimum download speed of 1kB/s.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -87,13 +87,13 @@ type ClientConfig struct {
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
|
|
||||||
// FirstReadTimeout specifies the timeout from getting response to the first read of body response.
|
// FirstReadTimeout specifies the timeout from getting response to the first read of body response.
|
||||||
// This timeout is applied only when MinSpeed is used.
|
// This timeout is applied only when MinBytesPerSecond is used.
|
||||||
// Default is 5 minutes.
|
// Default is 5 minutes.
|
||||||
FirstReadTimeout time.Duration
|
FirstReadTimeout time.Duration
|
||||||
|
|
||||||
// MinSpeed specifies minimum Bytes per second or the request will be canceled.
|
// MinBytesPerSecond specifies minimum Bytes per second or the request will be canceled.
|
||||||
// Zero means no limitation.
|
// Zero means no limitation.
|
||||||
MinSpeed int64
|
MinBytesPerSecond int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client defines the interface of a PMAPI client.
|
// Client defines the interface of a PMAPI client.
|
||||||
@ -316,7 +316,7 @@ func (c *client) doJSONBuffered(req *http.Request, reqBodyBuffer []byte, data in
|
|||||||
req.Header.Set("Accept", "application/vnd.protonmail.v1+json")
|
req.Header.Set("Accept", "application/vnd.protonmail.v1+json")
|
||||||
|
|
||||||
var cancelRequest context.CancelFunc
|
var cancelRequest context.CancelFunc
|
||||||
if c.cm.config.MinSpeed > 0 {
|
if c.cm.config.MinBytesPerSecond > 0 {
|
||||||
var ctx context.Context
|
var ctx context.Context
|
||||||
ctx, cancelRequest = context.WithCancel(req.Context())
|
ctx, cancelRequest = context.WithCancel(req.Context())
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -332,7 +332,7 @@ func (c *client) doJSONBuffered(req *http.Request, reqBodyBuffer []byte, data in
|
|||||||
defer res.Body.Close() //nolint[errcheck]
|
defer res.Body.Close() //nolint[errcheck]
|
||||||
|
|
||||||
var resBody []byte
|
var resBody []byte
|
||||||
if c.cm.config.MinSpeed == 0 {
|
if c.cm.config.MinBytesPerSecond == 0 {
|
||||||
resBody, err = ioutil.ReadAll(res.Body)
|
resBody, err = ioutil.ReadAll(res.Body)
|
||||||
} else {
|
} else {
|
||||||
resBody, err = c.readAllMinSpeed(res.Body, cancelRequest)
|
resBody, err = c.readAllMinSpeed(res.Body, cancelRequest)
|
||||||
@ -417,17 +417,22 @@ func (c *client) readAllMinSpeed(data io.Reader, cancelRequest context.CancelFun
|
|||||||
timer := time.AfterFunc(firstReadTimeout, func() {
|
timer := time.AfterFunc(firstReadTimeout, func() {
|
||||||
cancelRequest()
|
cancelRequest()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// speedCheckSeconds controls how often we check the transfer speed.
|
||||||
|
const speedCheckSeconds = 3
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
for {
|
for {
|
||||||
_, err := io.CopyN(&buffer, data, c.cm.config.MinSpeed)
|
_, err := io.CopyN(&buffer, data, c.cm.config.MinBytesPerSecond*speedCheckSeconds)
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
timer.Reset(1 * time.Second)
|
timer.Reset(speedCheckSeconds * time.Second)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.ReadAll(&buffer)
|
return ioutil.ReadAll(&buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,10 +30,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var testClientConfig = &ClientConfig{
|
var testClientConfig = &ClientConfig{
|
||||||
AppVersion: "GoPMAPI_1.0.14",
|
AppVersion: "GoPMAPI_1.0.14",
|
||||||
ClientID: "demoapp",
|
ClientID: "demoapp",
|
||||||
FirstReadTimeout: 500 * time.Millisecond,
|
FirstReadTimeout: 500 * time.Millisecond,
|
||||||
MinSpeed: 256,
|
MinBytesPerSecond: 256,
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestClient(cm *ClientManager) *client {
|
func newTestClient(cm *ClientManager) *client {
|
||||||
@ -175,7 +175,7 @@ func TestClient_FirstReadTimeout(t *testing.T) {
|
|||||||
|
|
||||||
func TestClient_MinSpeedTimeout(t *testing.T) {
|
func TestClient_MinSpeedTimeout(t *testing.T) {
|
||||||
finish, c := newTestServerCallbacks(t,
|
finish, c := newTestServerCallbacks(t,
|
||||||
routeSlow(2*time.Second),
|
routeSlow(4*time.Second), // 1 second longer than the minimum transfer speed poll time.
|
||||||
)
|
)
|
||||||
defer finish()
|
defer finish()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user