diff --git a/README.md b/README.md index b1bbb79..6409309 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ COW 将以下错误认为是墙在作怪: 无论是普通的 HTTP GET 等请求还是 CONNECT 请求,失败后 COW 都会自动重试请求。(如果已经有内容发送回 client 则不会重试而是直接断开连接。) -用连接被重置来判断被墙通常来说比较可靠,超时则不可靠。COW 每隔一分钟会尝试估算合适的超时间隔,避免在网络连接差的情况下把直连网站由于超时也当成被墙。 +用连接被重置来判断被墙通常来说比较可靠,超时则不可靠。COW 每隔半分钟会尝试估算合适的超时间隔,避免在网络连接差的情况下把直连网站由于超时也当成被墙。 COW 默认配置下检测到被墙后,过两分钟再次尝试直连也是为了避免误判。 如果超时自动重试给你造成了问题,请参考[样例配置](doc/sample-config/rc)高级选项中的 `readTimeout`, `dialTimeout` 选项。 diff --git a/estimate_timeout.go b/estimate_timeout.go index 8adc5ca..0eec2b3 100644 --- a/estimate_timeout.go +++ b/estimate_timeout.go @@ -10,7 +10,6 @@ const minDialTimeout = 3 * time.Second const minReadTimeout = 4 * time.Second const defaultDialTimeout = 5 * time.Second const defaultReadTimeout = 5 * time.Second -const maxTimeout = 20 * time.Second var dialTimeout, readTimeout time.Duration // initialized in runEstimateTimeout @@ -30,7 +29,8 @@ var estimateReq = []byte("GET / HTTP/1.1\r\n" + // considering non-blocked sites as blocked when network connection is bad. func estimateTimeout() { debug.Println("estimating timeout") - buf := make([]byte, 4096) + buf := connectBuf.Get() + defer connectBuf.Put(buf) var est time.Duration start := time.Now() @@ -44,9 +44,6 @@ func estimateTimeout() { est = time.Now().Sub(start) * 5 debug.Println("estimated dialTimeout:", est) - if est > maxTimeout { - est = maxTimeout - } if est > config.DialTimeout { dialTimeout = est info.Println("new dial timeout:", dialTimeout) @@ -68,12 +65,10 @@ func estimateTimeout() { if err != io.EOF { errl.Printf("estimateTimeout: error getting %s: %v, network has problem?\n", estimateSite, err) + goto onErr } est = time.Now().Sub(start) * 10 debug.Println("estimated read timeout:", est) - if est > maxTimeout { - est = maxTimeout - } if est > time.Duration(config.ReadTimeout) { readTimeout = est info.Println("new read timeout:", readTimeout) @@ -92,6 +87,12 @@ func runEstimateTimeout() { dialTimeout = config.DialTimeout for { estimateTimeout() - time.Sleep(time.Minute) + time.Sleep(30 * time.Second) } } + +// Guess network status based on doing HTTP request to estimateSite +func networkGood() bool { + return (readTimeout == config.ReadTimeout) && + (dialTimeout == config.DialTimeout) +} diff --git a/sitestat.go b/sitestat.go index 03d8752..4604f19 100644 --- a/sitestat.go +++ b/sitestat.go @@ -143,6 +143,9 @@ func (vc *VisitCnt) visit(inc *vcntint) { } func (vc *VisitCnt) DirectVisit() { + if !networkGood() { + return + } if vc.userSpecified() { return } @@ -153,6 +156,9 @@ func (vc *VisitCnt) DirectVisit() { } func (vc *VisitCnt) BlockedVisit() { + if !networkGood() { + return + } if vc.userSpecified() || vc.AsTempBlocked() { return }