Files
cloudpods/pkg/util/httputils/delegate.go
Jian Qiu 325ff3af61 fix: httpclient timeout value cleanup, use notimeout client for oss (#4527)
* fix: httpclient timeout value cleanup, use notimeout client for oss

* Adaptive timeout client

* more test cases

* remove resolve timeout test case

* use adptive timeout only if timeout = 0
2020-01-04 20:51:21 +08:00

105 lines
3.5 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httputils
import (
"net"
"time"
)
type connDelegate struct {
conn net.Conn
socketTimeout time.Duration
finalTimeout time.Duration
}
func getConnDelegate(conn net.Conn, socketTimeout, finalTimeout time.Duration) *connDelegate {
return &connDelegate{
conn: conn,
socketTimeout: socketTimeout,
finalTimeout: finalTimeout,
}
}
func (delegate *connDelegate) Read(b []byte) (n int, err error) {
delegate.SetReadDeadline(time.Now().Add(delegate.socketTimeout))
n, err = delegate.conn.Read(b)
delegate.SetReadDeadline(time.Now().Add(delegate.finalTimeout))
return n, err
}
func (delegate *connDelegate) Write(b []byte) (n int, err error) {
delegate.SetWriteDeadline(time.Now().Add(delegate.socketTimeout))
n, err = delegate.conn.Write(b)
finalTimeout := time.Now().Add(delegate.finalTimeout)
delegate.SetWriteDeadline(finalTimeout)
delegate.SetReadDeadline(finalTimeout)
return n, err
}
func (delegate *connDelegate) Close() error {
return delegate.conn.Close()
}
func (delegate *connDelegate) LocalAddr() net.Addr {
return delegate.conn.LocalAddr()
}
func (delegate *connDelegate) RemoteAddr() net.Addr {
return delegate.conn.RemoteAddr()
}
// SetDeadline sets the read and write deadlines associated
// with the connection. It is equivalent to calling both
// SetReadDeadline and SetWriteDeadline.
//
// A deadline is an absolute time after which I/O operations
// fail with a timeout (see type Error) instead of
// blocking. The deadline applies to all future and pending
// I/O, not just the immediately following call to Read or
// Write. After a deadline has been exceeded, the connection
// can be refreshed by setting a deadline in the future.
//
// An idle timeout can be implemented by repeatedly extending
// the deadline after successful Read or Write calls.
//
// A zero value for t means I/O operations will not time out.
//
// Note that if a TCP connection has keep-alive turned on,
// which is the default unless overridden by Dialer.KeepAlive
// or ListenConfig.KeepAlive, then a keep-alive failure may
// also return a timeout error. On Unix systems a keep-alive
// failure on I/O can be detected using
// errors.Is(err, syscall.ETIMEDOUT).
func (delegate *connDelegate) SetDeadline(t time.Time) error {
return delegate.conn.SetDeadline(t)
}
// SetReadDeadline sets the deadline for future Read calls
// and any currently-blocked Read call.
// A zero value for t means Read will not time out.
func (delegate *connDelegate) SetReadDeadline(t time.Time) error {
return delegate.conn.SetReadDeadline(t)
}
// SetWriteDeadline sets the deadline for future Write calls
// and any currently-blocked Write call.
// Even if write times out, it may return n > 0, indicating that
// some of the data was successfully written.
// A zero value for t means Write will not time out.
func (delegate *connDelegate) SetWriteDeadline(t time.Time) error {
return delegate.conn.SetWriteDeadline(t)
}