12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- // Generic HTTP transport for imgproxy
- package generichttp
- import (
- "crypto/tls"
- "fmt"
- "net"
- "net/http"
- "syscall"
- "time"
- "golang.org/x/net/http2"
- )
- func New(verifyNetworks bool, config *Config) (*http.Transport, error) {
- if err := config.Validate(); err != nil {
- return nil, err
- }
- dialer := &net.Dialer{
- Timeout: 30 * time.Second,
- KeepAlive: 30 * time.Second,
- DualStack: true,
- }
- if verifyNetworks {
- dialer.Control = func(network, address string, c syscall.RawConn) error {
- return verifySourceNetwork(address, config)
- }
- }
- transport := &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- DialContext: dialer.DialContext,
- MaxIdleConns: 100,
- MaxIdleConnsPerHost: 100,
- IdleConnTimeout: time.Duration(config.ClientKeepAliveTimeout) * time.Second,
- TLSHandshakeTimeout: 10 * time.Second,
- ExpectContinueTimeout: 1 * time.Second,
- ForceAttemptHTTP2: false,
- DisableCompression: true,
- HTTP2: &http.HTTP2Config{
- MaxReceiveBufferPerStream: 128 * 1024,
- },
- }
- if config.ClientKeepAliveTimeout <= 0 {
- transport.MaxIdleConnsPerHost = -1
- transport.DisableKeepAlives = true
- }
- if config.IgnoreSslVerification {
- transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
- }
- transport2, err := http2.ConfigureTransports(transport)
- if err != nil {
- return nil, err
- }
- // TODO: Move this to transport.HTTP2 when https://go.dev/issue/67813 is closed
- transport2.MaxReadFrameSize = 16 * 1024
- transport2.PingTimeout = 5 * time.Second
- transport2.ReadIdleTimeout = time.Second
- return transport, nil
- }
- func verifySourceNetwork(addr string, config *Config) error {
- host, _, err := net.SplitHostPort(addr)
- if err != nil {
- host = addr
- }
- ip := net.ParseIP(host)
- if ip == nil {
- return newSourceAddressError(fmt.Sprintf("Invalid source address: %s", addr))
- }
- if !config.AllowLoopbackSourceAddresses && (ip.IsLoopback() || ip.IsUnspecified()) {
- return newSourceAddressError(fmt.Sprintf("Loopback source address is not allowed: %s", addr))
- }
- if !config.AllowLinkLocalSourceAddresses && (ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast()) {
- return newSourceAddressError(fmt.Sprintf("Link-local source address is not allowed: %s", addr))
- }
- if !config.AllowPrivateSourceAddresses && ip.IsPrivate() {
- return newSourceAddressError(fmt.Sprintf("Private source address is not allowed: %s", addr))
- }
- return nil
- }
|