mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-07 09:00:47 +00:00
63 lines
1.9 KiB
Go
63 lines
1.9 KiB
Go
package download
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
|
|
gitclient "github.com/go-git/go-git/v5/plumbing/transport/client"
|
|
githttp "github.com/go-git/go-git/v5/plumbing/transport/http"
|
|
)
|
|
|
|
func init() {
|
|
// go-git exposes a process-wide protocol registry. Register once during
|
|
// initialization, rather than changing it during concurrent clones. Proxy
|
|
// settings still come from each clone's ProxyOptions.
|
|
transport := githttp.NewClient(newExtensionGitHTTPClient(10*time.Second, 60*time.Second))
|
|
gitclient.InstallProtocol("http", transport)
|
|
gitclient.InstallProtocol("https", transport)
|
|
}
|
|
|
|
func newExtensionGitHTTPClient(connectTimeout, idleTimeout time.Duration) *http.Client {
|
|
dialer := &net.Dialer{Timeout: connectTimeout, KeepAlive: 30 * time.Second}
|
|
// A socket read deadline must apply to one transfer, rather than a shared
|
|
// HTTP/2 connection carrying traffic from other requests.
|
|
protocols := new(http.Protocols)
|
|
protocols.SetHTTP1(true)
|
|
return &http.Client{Transport: &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
conn, err := dialer.DialContext(ctx, network, address)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &gitIdleConn{Conn: conn, timeout: idleTimeout}, nil
|
|
},
|
|
TLSHandshakeTimeout: connectTimeout,
|
|
IdleConnTimeout: idleTimeout,
|
|
Protocols: protocols,
|
|
}}
|
|
}
|
|
|
|
type gitIdleConn struct {
|
|
net.Conn
|
|
timeout time.Duration
|
|
}
|
|
|
|
func (c *gitIdleConn) Read(p []byte) (int, error) {
|
|
if err := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)); err != nil {
|
|
return 0, err
|
|
}
|
|
return c.Conn.Read(p)
|
|
}
|
|
|
|
// Refresh an already-pending read when a pooled HTTP/1 connection starts the
|
|
// next request; time spent idle in the pool must not consume its read allowance.
|
|
func (c *gitIdleConn) Write(p []byte) (int, error) {
|
|
if err := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)); err != nil {
|
|
return 0, err
|
|
}
|
|
return c.Conn.Write(p)
|
|
}
|