diff --git a/dev/Caddyfile b/dev/Caddyfile index 7d97c917830..bdf6458eed5 100644 --- a/dev/Caddyfile +++ b/dev/Caddyfile @@ -18,3 +18,9 @@ :3081 { reverse_proxy 127.0.0.1:3082 } + +# Caddy (:3083) -> Cody Gateway (:9992) +{$SOURCEGRAPH_HTTPS_DOMAIN}:3083 { + tls internal + reverse_proxy 127.0.0.1:9992 +} diff --git a/internal/completions/client/client.go b/internal/completions/client/client.go index ad392e7ad26..1f32da18438 100644 --- a/internal/completions/client/client.go +++ b/internal/completions/client/client.go @@ -39,7 +39,7 @@ func getBasic(endpoint string, provider conftypes.CompletionsProviderName, acces case conftypes.CompletionsProviderNameAzureOpenAI: return azureopenai.NewClient(azureopenai.GetAPIClient, endpoint, accessToken) case conftypes.CompletionsProviderNameSourcegraph: - return codygateway.NewClient(httpcli.UncachedExternalDoer, endpoint, accessToken) + return codygateway.NewClient(httpcli.CodyGatewayDoer, endpoint, accessToken) case conftypes.CompletionsProviderNameFireworks: return fireworks.NewClient(httpcli.UncachedExternalDoer, endpoint, accessToken), nil case conftypes.CompletionsProviderNameAWSBedrock: diff --git a/internal/httpcli/client.go b/internal/httpcli/client.go index b4b3a91edc1..435a9dd2b5a 100644 --- a/internal/httpcli/client.go +++ b/internal/httpcli/client.go @@ -111,6 +111,7 @@ var ( externalRetryDelayMax, _ = time.ParseDuration(env.Get("SRC_HTTP_CLI_EXTERNAL_RETRY_DELAY_MAX", "3s", "Max retry delay duration for external HTTP requests")) externalRetryMaxAttempts, _ = strconv.Atoi(env.Get("SRC_HTTP_CLI_EXTERNAL_RETRY_MAX_ATTEMPTS", "20", "Max retry attempts for external HTTP requests")) externalRetryAfterMaxDuration, _ = time.ParseDuration(env.Get("SRC_HTTP_CLI_EXTERNAL_RETRY_AFTER_MAX_DURATION", "3s", "Max duration to wait in retry-after header before we won't auto-retry")) + codyGatewayDisableHTTP2 = env.MustGetBool("SRC_HTTP_CLI_DISABLE_CODY_GATEWAY_HTTP2", false, "Whether we should disable HTTP2 for Cody Gateway communication") ) // NewExternalClientFactory returns a httpcli.Factory with common options @@ -178,6 +179,10 @@ var ExternalDoer, _ = ExternalClientFactory.Doer() // This client does not cache responses. To cache responses see ExternalDoer instead. var UncachedExternalDoer, _ = UncachedExternalClientFactory.Doer() +// CodyGatewayDoer is a client for communication with Cody Gateway. +// This client does not cache responses. +var CodyGatewayDoer, _ = UncachedExternalClientFactory.Doer(NewDisableHTTP2Opt(codyGatewayDisableHTTP2)) + // TestExternalClientFactory is a httpcli.Factory with common options // and is created for tests where you'd normally use an ExternalClientFactory. // Must be used in tests only as it doesn't apply any IP restrictions. @@ -827,6 +832,22 @@ func NewMaxIdleConnsPerHostOpt(max int) Opt { } } +// NewDisableHTTP2Opt returns an Opt that makes the http.Client use HTTP/1.1 (instead of defaulting to HTTP/2). +func NewDisableHTTP2Opt(disable bool) Opt { + return func(cli *http.Client) error { + tr, err := getTransportForMutation(cli) + if err != nil { + return errors.Wrap(err, "httpcli.NewDisableHTTP2Opt") + } + if disable { + tr.ForceAttemptHTTP2 = false + tr.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper) + tr.TLSClientConfig = &tls.Config{} + } + return nil + } +} + // NewTimeoutOpt returns a Opt that sets the Timeout field of an http.Client. func NewTimeoutOpt(timeout time.Duration) Opt { return func(cli *http.Client) error {