diff --git a/client.go b/client.go index 03b3afc4..c1ea8e68 100644 --- a/client.go +++ b/client.go @@ -41,6 +41,13 @@ func NewClient(opts ...ClientOpt) *GraphQLClient { return c } +// WithHTTPClient sets a custom HTTP client to be used when making downstream queries. +func WithHTTPClient(client *http.Client) ClientOpt { + return func(s *GraphQLClient) { + s.HTTPClient = client + } +} + // WithMaxResponseSize sets the max allowed response size. The client will only // read up to maxResponseSize and that size is exceeded an an error will be // returned. diff --git a/client_test.go b/client_test.go index e6143c1a..5bd99137 100644 --- a/client_test.go +++ b/client_test.go @@ -3,7 +3,9 @@ package bramble import ( "context" "net/http" + "net/http/cookiejar" "net/http/httptest" + "net/url" "testing" "github.com/stretchr/testify/assert" @@ -34,6 +36,33 @@ func TestGraphqlClient(t *testing.T) { assert.Equal(t, "value", res.Root.Test) }) + t.Run("with http client", func(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + cookie, err := r.Cookie("test_cookie") + require.NoError(t, err) + assert.Equal(t, "test_value", cookie.Value) + })) + + jar, err := cookiejar.New(nil) + require.NoError(t, err) + + serverURL, err := url.Parse(srv.URL) + require.NoError(t, err) + + jar.SetCookies(serverURL, []*http.Cookie{ + { + + Name: "test_cookie", + Value: "test_value", + }, + }) + + httpClient := &http.Client{Jar: jar} + c := NewClient(WithHTTPClient(httpClient)) + var res interface{} + _ = c.Request(context.Background(), srv.URL, &Request{}, &res) + }) + t.Run("with user agent", func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "My User Agent", r.Header.Get("User-Agent")) diff --git a/config.go b/config.go index bff55bea..5b0b7459 100644 --- a/config.go +++ b/config.go @@ -3,6 +3,7 @@ package bramble import ( "encoding/json" "fmt" + "net/http" "os" "path/filepath" "strings" @@ -38,6 +39,8 @@ type Config struct { Plugins []PluginConfig // Config extensions that can be shared among plugins Extensions map[string]json.RawMessage + // HTTP client to customize for downstream services query + QueryHTTPClient *http.Client plugins []Plugin executableSchema *ExecutableSchema @@ -264,7 +267,11 @@ func (c *Config) Init() error { services = append(services, NewService(s)) } - queryClient := NewClient(WithMaxResponseSize(c.MaxServiceResponseSize), WithUserAgent(GenerateUserAgent("query"))) + queryClientOptions := []ClientOpt{WithMaxResponseSize(c.MaxServiceResponseSize), WithUserAgent(GenerateUserAgent("query"))} + if c.QueryHTTPClient != nil { + queryClientOptions = append(queryClientOptions, WithHTTPClient(c.QueryHTTPClient)) + } + queryClient := NewClient(queryClientOptions...) es := newExecutableSchema(c.plugins, c.MaxRequestsPerQuery, queryClient, services...) err = es.UpdateSchema(true) if err != nil {