148 lines · 5.4 KB · Go
RawDownload
package executor import (	"context"	"net/http"	"net/url"	"testing" 	"github.com/router-for-me/CLIProxyAPI/v6/internal/config"	cliproxyauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"	sdkconfig "github.com/router-for-me/CLIProxyAPI/v6/sdk/config") func TestNewProxyAwareHTTPClientDirectBypassesGlobalProxy(t *testing.T) {	t.Parallel() 	client := newProxyAwareHTTPClient(		context.Background(),		&config.Config{SDKConfig: sdkconfig.SDKConfig{ProxyURL: "http://global-proxy.example.com:8080"}},		&cliproxyauth.Auth{ProxyURL: "direct"},		0,	) 	transport, ok := client.Transport.(*http.Transport)	if !ok {		t.Fatalf("transport type = %T, want *http.Transport", client.Transport)	}	if transport.Proxy != nil {		t.Fatal("expected direct transport to disable proxy function")	}} func TestNewProxyAwareHTTPClientNoProxyReusesSharedClient(t *testing.T) {	t.Parallel() 	first := newProxyAwareHTTPClient(context.Background(), nil, nil, 0)	second := newProxyAwareHTTPClient(context.Background(), nil, nil, 0) 	if first == second {		t.Fatal("expected distinct client wrappers for direct no-proxy path")	}	if first.Transport != nil {		t.Fatalf("expected direct client to use default transport, got %T", first.Transport)	}	if second.Transport != nil {		t.Fatalf("expected second direct client to use default transport, got %T", second.Transport)	}} func TestNewProxyAwareHTTPClientProxyReusesCachedClientWithoutTimeout(t *testing.T) {	t.Parallel() 	cfg := &config.Config{SDKConfig: sdkconfig.SDKConfig{ProxyURL: "http://proxy.example.com:8080"}}	first := newProxyAwareHTTPClient(context.Background(), cfg, nil, 0)	second := newProxyAwareHTTPClient(context.Background(), cfg, nil, 0) 	if first == second {		t.Fatal("expected proxy calls to receive distinct client wrappers")	}	transport, ok := first.Transport.(*http.Transport)	if !ok {		t.Fatalf("transport type = %T, want *http.Transport", first.Transport)	}	if second.Transport != transport {		t.Fatal("expected proxy transport to be reused across client wrappers")	}	proxyFunc := transport.Proxy	if proxyFunc == nil {		t.Fatal("expected proxy transport to configure proxy function")	}	targetURL, errParse := url.Parse("https://example.com")	if errParse != nil {		t.Fatalf("url.Parse() error = %v", errParse)	}	gotProxy, errProxy := proxyFunc(&http.Request{URL: targetURL})	if errProxy != nil {		t.Fatalf("proxy function error = %v", errProxy)	}	if gotProxy == nil || gotProxy.String() != "http://proxy.example.com:8080" {		t.Fatalf("proxy = %v, want http://proxy.example.com:8080", gotProxy)	}} func TestNewProxyAwareHTTPClientNoProxyDoesNotLeakAntigravityTransportMutation(t *testing.T) {	client := newAntigravityHTTPClient(context.Background(), nil, nil, 0)	transport, ok := client.Transport.(*http.Transport)	if !ok {		t.Fatalf("antigravity transport type = %T, want *http.Transport", client.Transport)	}	if transport.ForceAttemptHTTP2 {		t.Fatal("expected antigravity transport to disable HTTP/2")	} 	regular := newProxyAwareHTTPClient(context.Background(), nil, nil, 0)	if regular.Transport != nil {		t.Fatalf("regular client transport = %T, want nil default transport", regular.Transport)	}} func TestNewProxyAwareHTTPClientProxyDoesNotLeakAntigravityTransportMutation(t *testing.T) {	cfg := &config.Config{SDKConfig: sdkconfig.SDKConfig{ProxyURL: "http://proxy.example.com:8080"}} 	antigravityClient := newAntigravityHTTPClient(context.Background(), cfg, nil, 0)	antigravityTransport, ok := antigravityClient.Transport.(*http.Transport)	if !ok {		t.Fatalf("antigravity transport type = %T, want *http.Transport", antigravityClient.Transport)	}	if antigravityTransport.TLSClientConfig == nil || len(antigravityTransport.TLSClientConfig.NextProtos) != 1 || antigravityTransport.TLSClientConfig.NextProtos[0] != "http/1.1" {		t.Fatalf("expected antigravity transport to force HTTP/1.1 ALPN, got %#v", antigravityTransport.TLSClientConfig)	} 	regular := newProxyAwareHTTPClient(context.Background(), cfg, nil, 0)	regularTransport, ok := regular.Transport.(*http.Transport)	if !ok {		t.Fatalf("regular transport type = %T, want *http.Transport", regular.Transport)	}	if regularTransport == antigravityTransport {		t.Fatal("expected regular proxy client to keep cached transport instead of antigravity clone")	}	if regularTransport.TLSClientConfig != nil && len(regularTransport.TLSClientConfig.NextProtos) == 1 && regularTransport.TLSClientConfig.NextProtos[0] == "http/1.1" {		t.Fatalf("regular transport unexpectedly inherited antigravity HTTP/1.1-only ALPN override: %#v", regularTransport.TLSClientConfig.NextProtos)	}} type roundTripperFunc func(*http.Request) (*http.Response, error) func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {	return f(req)} func TestNewProxyAwareHTTPClientInvalidProxyFallsBackToContextTransport(t *testing.T) {	t.Parallel() 	ctx := context.WithValue(context.Background(), "cliproxy.roundtripper", roundTripperFunc(func(req *http.Request) (*http.Response, error) {		return &http.Response{StatusCode: http.StatusNoContent, Request: req}, nil	})) 	client := newProxyAwareHTTPClient(ctx, &config.Config{		SDKConfig: sdkconfig.SDKConfig{ProxyURL: "://bad-proxy"},	}, nil, 0) 	if client.Transport == nil {		t.Fatal("expected context transport fallback when proxy build fails")	}	if _, ok := client.Transport.(roundTripperFunc); !ok {		t.Fatalf("transport type = %T, want context roundTripperFunc fallback", client.Transport)	}}