Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MIddleware to SDK config #394

Merged
merged 6 commits into from
Apr 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions core/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ type APIKey struct {
Prefix string
}

// Middleware is a function that wraps an http.RoundTripper to provide additional functionality
// such as logging, authentication, etc.
type Middleware func(http.RoundTripper) http.RoundTripper

// Configuration stores the configuration of the API client
type Configuration struct {
Host string `json:"host,omitempty"`
Expand All @@ -90,6 +94,7 @@ type Configuration struct {
Servers ServerConfigurations
OperationServers map[string]ServerConfigurations
HTTPClient *http.Client
Middleware []Middleware

// If != nil, a goroutine will be launched that will refresh the service account's access token when it's close to being expired.
// The goroutine is killed whenever this context is canceled.
Expand Down Expand Up @@ -284,6 +289,18 @@ func WithJar(jar http.CookieJar) ConfigurationOption {
}
}

// WithMiddleware returns a ConfigurationOption that adds a Middleware to the client.
// The Middleware is prepended to the list of Middlewares so that the last added Middleware is the first to be executed.
// Warning: Providing this option may overide the authentication performed by the SDK if the middlewares provided break the chain.
// If changes are made to the authentication header and the chain is preserved, they will be overwritten. If you wish to overwrite authentication, use WithCustomAuth.
func WithMiddleware(m Middleware) ConfigurationOption {
// Prepend m to the list of middlewares
return func(config *Configuration) error {
config.Middleware = append([]Middleware{m}, config.Middleware...)
return nil
}
}

// WithBackgroundTokenRefresh returns a ConfigurationOption that enables access token refreshing in backgound.
//
// If enabled, a goroutine will be launched that will refresh the service account's access token when it's close to being expired.
Expand Down Expand Up @@ -532,3 +549,19 @@ func containsCaseSensitive(haystack []string, needle string) bool {
}
return false
}

// ChainMiddleware chains multiple middlewares to create a single http.RoundTripper
// The middlewares are applied in reverse order, so the last middleware provided in the arguments is the first to be executed
// If the root http.RoundTripper is nil, http.DefaultTransport is used
func ChainMiddleware(rt http.RoundTripper, middlewares ...Middleware) http.RoundTripper {
if rt == nil {
rt = http.DefaultTransport
}

// Apply middlewares in reverse order
for i := len(middlewares) - 1; i >= 0; i-- {
rt = middlewares[i](rt)
}

return rt
}
Loading