feat: rename HttpCustomizer to HttpTransportCustomizer and make it return http.Transport that is later used (#30)

* feat: rename HttpCustomizer to HttpTransportCustomizer and make it return http.Transport that is later used

* linting
This commit is contained in:
Mateusz Filipowicz
2025-02-19 01:03:21 +01:00
committed by GitHub
parent e25b426a84
commit 7c7ef98c03
6 changed files with 39 additions and 58 deletions

View File

@@ -15,6 +15,9 @@ ij_smart_tabs = false
ij_wrap_on_typing = false
ij_any_block_comment_add_space = true
[*.go]
indent_style = tab
[*.conf]
ij_continuation_indent_size = 2

View File

@@ -84,14 +84,14 @@ List of available client configuration options is available [here](https://pkg.g
### Customizing HTTP Client
You can customize underlying HTTP client by using `HttpCustomizer` interface:
You can customize underlying HTTP client by using `HttpTransportCustomizer` interface:
```go
c, err := unifi.NewClient(&unifi.ClientConfig{
...
HttpCustomizer: func(transport *http.Transport) error {
HttpTransportCustomizer: func(transport *http.Transport) (*http.Transport, error) {
transport.MaxIdleConns = 10
return nil
return transport, nil
},
})
```

View File

@@ -57,29 +57,6 @@ if err != nil {
These helper methods abstract away the boilerplate of manually constructing HTTP requests and processing responses, allowing you to focus on your application's logic while leveraging built-in
validation and error handling provided by the SDK.
## Customizing the HTTP Client
While the basic configuration allows simple modifications, you can fully customize the underlying HTTP client for more
control over connection settings, proxy configuration, TLS settings, and connection pooling.
Example:
```go
c, err := unifi.NewClient(&unifi.ClientConfig{
BaseURL: "https://unifi.localdomain",
APIKey: "your-api-key",
HttpCustomizer: func (transport *http.Transport) error {
transport.MaxIdleConns = 20
transport.IdleConnTimeout = 90 * time.Second
// Customize TLS settings or add a proxy configuration
return nil
},
})
if err != nil {
log.Fatalf("Error creating client: %v", err)
}
```
## Interceptors and Middleware
Interceptors provide hooks into the request/response cycle and can be used for logging, metrics collection, or modifying

View File

@@ -58,16 +58,17 @@ if err != nil {
## Customizing the HTTP Client
You can provide your own HTTP client configuration using the `HttpCustomizer` callback. This is useful if you need to tweak connection settings like timeouts, idle connection settings, or TLS configurations:
You can provide your own HTTP client configuration using the `HttpTransportCustomizer` callback. This is useful if you need to tweak connection settings like timeouts, idle connection settings, or TLS configurations:
```go
c, err := unifi.NewClient(&unifi.ClientConfig{
BaseURL: "https://unifi.localdomain",
APIKey: "your-api-key",
HttpCustomizer: func(transport *http.Transport) error {
HttpTransportCustomizer: func(transport *http.Transport) (*http.Transport, error) {
transport.MaxIdleConns = 10
// Customize TLS settings, proxy, etc. as needed
return nil
// You can also create new instance of transport and return it, instead of customizing pre-configured
return transport, nil
},
})
if err != nil {
@@ -132,14 +133,14 @@ import (
)
// customTransportCustomizer customizes the HTTP transport, e.g., setting idle connection limits and TLS options.
func customTransportCustomizer(transport *http.Transport) error {
func customTransportCustomizer(transport *http.Transport) (*http.Transport, error) {
transport.MaxIdleConns = 50
transport.IdleConnTimeout = 120 * time.Second
// Set a custom TLS configuration
transport.TLSClientConfig = &tls.Config{
MinVersion: tls.VersionTLS12,
}
return nil
return transport, nil
}
// myErrorHandler implements a custom error handler for HTTP responses.
@@ -175,7 +176,7 @@ func main() {
Timeout: 30 * time.Second, // Maximum duration to wait for a response
VerifySSL: true, // Enable SSL certificate verification
Interceptors: []unifi.ClientInterceptor{&customInterceptor{}}, // Custom interceptors for request/response manipulation
HttpCustomizer: customTransportCustomizer, // Function to customize the underlying HTTP transport
HttpTransportCustomizer: customTransportCustomizer, // Function to customize the underlying HTTP transport
UserAgent: "MyCustomAgent/1.0", // Custom User-Agent string
ErrorHandler: &myErrorHandler{}, // Custom error handler for processing HTTP response errors
UseLocking: true, // Enable internal locking for safe concurrent request processing

View File

@@ -30,9 +30,9 @@ const (
DefaultValidation validationMode = SoftValidation // TODO: change to hard in next major version
)
// HttpCustomizer is a function type for customizing the HTTP transport.
// HttpTransportCustomizer is a function type for customizing the HTTP transport.
// It receives a pointer to an http.Transport and returns an error if customization fails.
type HttpCustomizer func(transport *http.Transport) error
type HttpTransportCustomizer func(transport *http.Transport) (*http.Transport, error)
// ResponseErrorHandler defines a method for handling HTTP response errors.
// HandleError processes the HTTP response and returns an error if the response indicates failure.
@@ -53,7 +53,7 @@ Fields:
Timeout: The maximum duration to wait for responses; default is no timeout.
VerifySSL: When false, disables SSL certificate verification.
Interceptors: A slice of ClientInterceptor implementations that can modify requests and responses.
HttpCustomizer:An optional function to customize the HTTP transport (e.g., for custom TLS settings).
HttpTransportCustomizer:An optional function to customize the HTTP transport (e.g., for custom TLS settings).
UserAgent: The User-Agent header string for outgoing HTTP requests.
ErrorHandler: A custom handler for processing HTTP response errors.
UseLocking: If true, enables internal locking for concurrent request processing.
@@ -67,7 +67,7 @@ type ClientConfig struct {
Timeout time.Duration // How long to wait for replies, default: forever.
VerifySSL bool
Interceptors []ClientInterceptor
HttpCustomizer HttpCustomizer
HttpTransportCustomizer HttpTransportCustomizer
UserAgent string
ErrorHandler ResponseErrorHandler
UseLocking bool
@@ -158,8 +158,8 @@ func newClientFromConfig(config *ClientConfig, v *validator) (*client, error) {
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{InsecureSkipVerify: !config.VerifySSL},
}
if config.HttpCustomizer != nil {
if err = config.HttpCustomizer(transport); err != nil {
if config.HttpTransportCustomizer != nil {
if transport, err = config.HttpTransportCustomizer(transport); err != nil {
return nil, fmt.Errorf("failed customizing HTTP transport: %w", err)
}
}

View File

@@ -90,9 +90,9 @@ func TestCustomizeHttpClient(t *testing.T) {
_, err := NewClient(&ClientConfig{
URL: localUrl,
APIKey: "test-key",
HttpCustomizer: func(transport *http.Transport) error {
HttpTransportCustomizer: func(transport *http.Transport) (*http.Transport, error) {
called = true
return nil
return transport, nil
},
})
@@ -850,16 +850,16 @@ func TestLoginWithAPIKeyDirect(t *testing.T) {
assert.NoError(t, err)
}
func TestHttpCustomizerError(t *testing.T) {
func TestHttpTransportCustomizerError(t *testing.T) {
t.Parallel()
customizer := func(transport *http.Transport) error {
return errors.New("customization failed")
customizer := func(transport *http.Transport) (*http.Transport, error) {
return nil, errors.New("customization failed")
}
_, err := NewClient(&ClientConfig{
URL: testUrl,
APIKey: "test-key",
VerifySSL: false,
HttpCustomizer: customizer,
HttpTransportCustomizer: customizer,
})
require.Error(t, err)
assert.Contains(t, err.Error(), "failed customizing HTTP transport")