| 116 | } |
| 117 | |
| 118 | func (g *HTTPGetter) httpClient(opts getterOptions) (*http.Client, error) { |
| 119 | if opts.transport != nil { |
| 120 | return &http.Client{ |
| 121 | Transport: opts.transport, |
| 122 | Timeout: opts.timeout, |
| 123 | }, nil |
| 124 | } |
| 125 | |
| 126 | // Check if we need custom TLS configuration |
| 127 | needsCustomTLS := (opts.certFile != "" && opts.keyFile != "") || opts.caFile != "" || opts.insecureSkipVerifyTLS |
| 128 | |
| 129 | if needsCustomTLS { |
| 130 | // Create a new transport for custom TLS to avoid race conditions |
| 131 | transport := &http.Transport{ |
| 132 | DisableCompression: true, |
| 133 | Proxy: http.ProxyFromEnvironment, |
| 134 | } |
| 135 | |
| 136 | tlsConf, err := tlsutil.NewTLSConfig( |
| 137 | tlsutil.WithInsecureSkipVerify(opts.insecureSkipVerifyTLS), |
| 138 | tlsutil.WithCertKeyPairFiles(opts.certFile, opts.keyFile), |
| 139 | tlsutil.WithCAFile(opts.caFile), |
| 140 | ) |
| 141 | if err != nil { |
| 142 | return nil, fmt.Errorf("can't create TLS config for client: %w", err) |
| 143 | } |
| 144 | |
| 145 | transport.TLSClientConfig = tlsConf |
| 146 | |
| 147 | return &http.Client{ |
| 148 | Transport: transport, |
| 149 | Timeout: opts.timeout, |
| 150 | }, nil |
| 151 | } |
| 152 | |
| 153 | // Use shared transport for default case (no custom TLS) |
| 154 | g.once.Do(func() { |
| 155 | g.transport = &http.Transport{ |
| 156 | DisableCompression: true, |
| 157 | Proxy: http.ProxyFromEnvironment, |
| 158 | TLSClientConfig: &tls.Config{}, |
| 159 | } |
| 160 | }) |
| 161 | |
| 162 | return &http.Client{ |
| 163 | Transport: g.transport, |
| 164 | Timeout: opts.timeout, |
| 165 | }, nil |
| 166 | } |