Skip to content
Merged
Show file tree
Hide file tree
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
170 changes: 170 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ A comprehensive Go package for building and executing HTTP requests with advance
- 🎯 **Type-Safe Generic Client** - Go generics for type-safe HTTP responses
- ✅ **Input Validation** - Comprehensive validation with error accumulation
- 🔐 **Authentication Support** - Built-in Basic and Bearer token authentication
- 🌐 **Proxy Support** - HTTP/HTTPS proxy configuration with authentication (supports corporate proxies, authenticated proxies, and custom ports)
- 📝 **Optional Logging** - slog integration for observability (disabled by default)
- 📦 **Zero External Dependencies** - Only Go standard library, no third-party packages

Expand All @@ -31,6 +32,7 @@ A comprehensive Go package for building and executing HTTP requests with advance
- [Generic HTTP Client](#generic-http-client)
- [Retry Logic](#retry-logic)
- [Client Builder](#client-builder)
- [Proxy Configuration](#proxy-configuration)
- [Logging](#logging)
- [Examples](#examples)
- [API Reference](#api-reference)
Expand Down Expand Up @@ -446,6 +448,174 @@ client := httpx.NewClientBuilder().

The builder validates all settings and uses defaults for out-of-range values.

### Proxy Configuration

The httpx package provides comprehensive HTTP/HTTPS proxy support across all client types. Configure proxies to route your requests through corporate firewalls, load balancers, or testing proxies.

#### Key Features

- ✅ HTTP and HTTPS proxy support
- 🔐 Proxy authentication (username/password)
- 🔄 Works with retry logic
- 🎯 Compatible with all client types
- 🌐 Full URL or host:port formats
- 📝 Graceful fallback on invalid URLs

#### Basic Usage

##### With ClientBuilder

```go
// HTTP proxy
client := httpx.NewClientBuilder().
WithProxy("http://proxy.example.com:8080").
WithTimeout(10 * time.Second).
Build()

// HTTPS proxy
client := httpx.NewClientBuilder().
WithProxy("https://secure-proxy.example.com:3128").
Build()
```

##### With GenericClient

```go
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}

client := httpx.NewGenericClient[User](
httpx.WithProxy[User]("http://proxy.example.com:8080"),
httpx.WithTimeout[User](10*time.Second),
httpx.WithMaxRetries[User](3),
)

response, err := client.Get("https://api.example.com/users/1")
```

##### With Retry Client

```go
client := httpx.NewHTTPRetryClient(
httpx.WithProxyRetry("http://proxy.example.com:8080"),
httpx.WithMaxRetriesRetry(5),
httpx.WithRetryStrategyRetry(
httpx.ExponentialBackoff(500*time.Millisecond, 30*time.Second),
),
)
```

#### Proxy Authentication

Include credentials directly in the proxy URL:

```go
client := httpx.NewClientBuilder().
WithProxy("http://username:password@proxy.example.com:8080").
Build()
```

**Security Note:** For production, consider using environment variables or secret management:

```go
proxyURL := fmt.Sprintf("http://%s:%s@%s:%s",
os.Getenv("PROXY_USER"),
os.Getenv("PROXY_PASS"),
os.Getenv("PROXY_HOST"),
os.Getenv("PROXY_PORT"),
)

client := httpx.NewClientBuilder().
WithProxy(proxyURL).
Build()
```

#### Common Proxy Ports

- **HTTP Proxy**: 8080, 3128, 8888
- **HTTPS Proxy**: 3128, 8443
- **Squid**: 3128 (most common)
- **Corporate Proxies**: 8080, 80

#### Disable Proxy

Override environment proxy settings by passing an empty string:

```go
// Disable proxy (ignore HTTP_PROXY environment variable)
client := httpx.NewClientBuilder().
WithProxy("").
Build()
```

#### Complete Example

```go
package main

import (
"fmt"
"log"
"time"

"github.com/slashdevops/httpx"
)

type APIResponse struct {
Message string `json:"message"`
Status string `json:"status"`
}

func main() {
// Configure client with proxy and full options
client := httpx.NewGenericClient[APIResponse](
httpx.WithProxy[APIResponse]("http://proxy.example.com:8080"),
httpx.WithTimeout[APIResponse](15*time.Second),
httpx.WithMaxRetries[APIResponse](5),
httpx.WithRetryStrategy[APIResponse](httpx.JitterBackoffStrategy),
httpx.WithRetryBaseDelay[APIResponse](500*time.Millisecond),
httpx.WithRetryMaxDelay[APIResponse](30*time.Second),
)

// Build request with authentication
req, err := httpx.NewRequestBuilder("https://api.example.com").
WithMethodGET().
WithPath("/data").
WithBearerAuth("your-token-here").
WithHeader("Accept", "application/json").
Build()

if err != nil {
log.Fatal(err)
}

// Execute through proxy
response, err := client.Do(req)
if err != nil {
log.Fatal(err)
}

fmt.Printf("Response: %s\n", response.Data.Message)
}
```

#### Error Handling

The library gracefully handles proxy configuration errors:

```go
client := httpx.NewClientBuilder().
WithProxy("://invalid-url"). // Invalid URL
WithLogger(logger). // Optional: log warnings
Build()

// Client builds successfully, but proxy is not configured
// Warning logged if logger is provided
```

### Logging

The httpx package supports optional logging using Go's standard `log/slog` package. **Logging is disabled by default** to maintain clean, silent HTTP operations. Enable it when you need observability into retries, errors, and other HTTP client operations.
Expand Down
63 changes: 63 additions & 0 deletions docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
// - WithExpectContinueTimeout: Set expect continue timeout
// - WithMaxIdleConnsPerHost: Set maximum idle connections per host
// - WithDisableKeepAlive: Disable HTTP keep-alive
// - WithProxy: Configure HTTP/HTTPS proxy server
// - WithHTTPClient: Use a pre-configured HTTP client (takes precedence)
//
// Integration with RequestBuilder:
Expand Down Expand Up @@ -257,6 +258,9 @@
// WithRetryBaseDelay(500 * time.Millisecond).
// WithRetryMaxDelay(10 * time.Second).
//
// // Proxy configuration
// WithProxy("http://proxy.example.com:8080").
//
// Build()
//
// Combine with GenericClient:
Expand Down Expand Up @@ -360,6 +364,65 @@
// // Handle specific status codes
// }
//
// # Proxy Configuration
//
// The package provides comprehensive proxy support for all HTTP clients.
// Proxy configuration works transparently across all client types and
// supports both HTTP and HTTPS proxies with optional authentication.
//
// Basic proxy configuration with ClientBuilder:
//
// client := httpx.NewClientBuilder().
// WithProxy("http://proxy.example.com:8080").
// Build()
//
// HTTPS proxy:
//
// client := httpx.NewClientBuilder().
// WithProxy("https://secure-proxy.example.com:3128").
// Build()
//
// Proxy with authentication:
//
// client := httpx.NewClientBuilder().
// WithProxy("http://username:password@proxy.example.com:8080").
// Build()
//
// Proxy with GenericClient:
//
// client := httpx.NewGenericClient[User](
// httpx.WithProxy[User]("http://proxy.example.com:8080"),
// httpx.WithTimeout[User](10*time.Second),
// httpx.WithMaxRetries[User](3),
// )
//
// Proxy with retry client:
//
// client := httpx.NewHTTPRetryClient(
// httpx.WithProxyRetry("http://proxy.example.com:8080"),
// httpx.WithMaxRetriesRetry(5),
// )
//
// Disable proxy (override environment variables):
//
// client := httpx.NewClientBuilder().
// WithProxy(""). // Empty string disables proxy
// Build()
//
// Common proxy ports:
// - HTTP proxy: 8080, 3128, 8888
// - HTTPS proxy: 3128, 8443
// - SOCKS proxy: 1080 (not directly supported, use custom transport)
//
// The proxy configuration:
// - Works transparently with all request types
// - Preserves all headers and authentication
// - Compatible with retry logic
// - Supports connection pooling
// - Respects timeout settings
// - Validates proxy URL format
// - Falls back gracefully on invalid URLs
//
// # Thread Safety
//
// All utilities in this package are safe for concurrent use across multiple goroutines:
Expand Down
Loading
Loading