Files
go-simple-graphql/http.go
T
2025-11-04 00:32:53 +00:00

83 lines
2.6 KiB
Go

package gql
import (
"crypto/tls"
"net/http"
"strings"
"time"
libpack_logger "github.com/lukaszraczylo/go-simple-graphql/logging"
"golang.org/x/net/http2"
)
func (b *BaseClient) createHttpClient() (http_client *http.Client) {
if strings.HasPrefix(b.endpoint, "http://") {
// Use HTTP/1.1 for http:// endpoints
// Note: h2c (HTTP/2 Cleartext) is rarely supported by servers
httpTransport := &http.Transport{
MaxIdleConns: 100,
MaxConnsPerHost: 50,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 30 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
DisableKeepAlives: false,
DisableCompression: true, // Disable automatic compression to prevent trailing garbage errors
WriteBufferSize: 4096,
ReadBufferSize: 4096,
// Additional settings for connection health
ExpectContinueTimeout: 1 * time.Second, // Timeout for 100-Continue
TLSHandshakeTimeout: 10 * time.Second, // Timeout for TLS handshake
}
http_client = &http.Client{
Timeout: 30 * time.Second,
Transport: httpTransport,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
b.Logger.Debug(&libpack_logger.LogMessage{
Message: "Using HTTP/1.1 for http:// endpoint",
Pairs: nil,
})
} else if strings.HasPrefix(b.endpoint, "https://") {
// Use HTTP/2 for https:// endpoints
tlsClientConfig := &tls.Config{
InsecureSkipVerify: true, // TODO: Make this configurable via environment variable
}
http2Transport := &http2.Transport{
AllowHTTP: true,
TLSClientConfig: tlsClientConfig,
ReadIdleTimeout: 30 * time.Second, // Close idle connections after 30s
PingTimeout: 10 * time.Second, // Detect dead connections with PING
WriteByteTimeout: 10 * time.Second, // Timeout for write operations
DisableCompression: true, // Disable automatic compression to prevent trailing garbage errors
// StrictMaxConcurrentStreams forces the HTTP/2 connection to wait for SETTINGS frame
// This helps with connection health detection
StrictMaxConcurrentStreams: true,
}
http_client = &http.Client{
Timeout: 30 * time.Second,
Transport: http2Transport,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
b.Logger.Debug(&libpack_logger.LogMessage{
Message: "Using HTTP/2 for https:// endpoint",
Pairs: nil,
})
} else {
b.Logger.Critical(&libpack_logger.LogMessage{
Message: "Invalid endpoint - must start with http:// or https://",
})
return nil
}
return http_client
}