Advanced Features
CurlDotNet provides powerful advanced features for complex scenarios and enterprise applications.
Table of Contents
- Middleware System
- Protocol Handlers
- Custom Authentication
- Performance Optimization
- Error Recovery
- Extensions
Middleware System
CurlDotNet includes a sophisticated middleware pipeline that allows you to intercept and modify requests and responses.
Built-in Middleware
Retry Middleware
var options = new CurlOptions()
.WithRetry(maxAttempts: 3, delay: TimeSpan.FromSeconds(1));
var result = await Curl.PerformAsync(options);
Logging Middleware
var options = new CurlOptions()
.WithLogging(LogLevel.Debug);
// All requests and responses will be logged
Rate Limiting Middleware
var options = new CurlOptions()
.WithRateLimit(requestsPerSecond: 10);
Custom Middleware
Create your own middleware by implementing ICurlMiddleware:
public class CustomHeaderMiddleware : ICurlMiddleware
{
public async Task<CurlResponse> ExecuteAsync(
CurlOptions options,
Func<CurlOptions, Task<CurlResponse>> next)
{
// Add custom header before request
options.Headers.Add("X-Custom-Header", "Value");
// Execute the request
var response = await next(options);
// Process response
Console.WriteLine($"Response received: {response.StatusCode}");
return response;
}
}
// Register middleware
var options = new CurlOptions()
.UseMiddleware(new CustomHeaderMiddleware());
Protocol Handlers
CurlDotNet supports multiple protocols with specialized handlers:
HTTP/HTTPS Handler
var options = new CurlOptions()
.WithHttp2()
.WithHttp3() // Experimental HTTP/3 support
.WithConnectionReuse();
FTP/FTPS Handler
var options = new CurlOptions("ftp://ftp.example.com/file.txt")
.WithFtpSsl()
.WithCredentials("username", "password")
.WithFtpCreateMissingDirs();
WebSocket Handler
var options = new CurlOptions("ws://example.com/socket")
.WithWebSocket()
.OnMessage((data) => Console.WriteLine($"Received: {data}"));
var connection = await Curl.ConnectWebSocketAsync(options);
await connection.SendAsync("Hello Server");
Custom Protocol Handler
public class CustomProtocolHandler : IProtocolHandler
{
public bool CanHandle(Uri uri) => uri.Scheme == "custom";
public async Task<CurlResponse> ExecuteAsync(CurlOptions options)
{
// Custom protocol implementation
return new CurlResponse();
}
}
CurlOptions.RegisterProtocolHandler(new CustomProtocolHandler());
Custom Authentication
OAuth 2.0
var options = new CurlOptions()
.WithOAuth2(
clientId: "your-client-id",
clientSecret: "your-secret",
tokenEndpoint: "https://auth.example.com/token",
scopes: new[] { "read", "write" }
);
Custom Authentication Provider
public class CustomAuthProvider : IAuthenticationProvider
{
public async Task AuthenticateAsync(CurlOptions options)
{
var token = await GetTokenAsync();
options.Headers["Authorization"] = $"Custom {token}";
}
}
var options = new CurlOptions()
.WithAuthentication(new CustomAuthProvider());
Performance Optimization
Connection Pooling
// Global connection pool configuration
CurlOptions.ConfigureConnectionPool(
maxConnections: 100,
maxConnectionsPerHost: 10,
connectionTimeout: TimeSpan.FromSeconds(30),
idleTimeout: TimeSpan.FromMinutes(5)
);
Request Pipelining
var options = new CurlOptions()
.WithPipelining(maxRequests: 5)
.WithMultiplexing(); // HTTP/2 multiplexing
Compression
var options = new CurlOptions()
.WithCompression(CompressionAlgorithm.Brotli | CompressionAlgorithm.Gzip)
.WithAutoDecompression();
DNS Caching
var options = new CurlOptions()
.WithDnsCache(TimeSpan.FromMinutes(5))
.WithDnsPreResolve(new[] { "api.example.com", "cdn.example.com" });
Error Recovery
Automatic Retry with Backoff
var options = new CurlOptions()
.WithRetryPolicy(new ExponentialBackoffPolicy
{
MaxAttempts = 5,
InitialDelay = TimeSpan.FromSeconds(1),
MaxDelay = TimeSpan.FromSeconds(30),
RetryableStatusCodes = new[] { 429, 503, 504 }
});
Circuit Breaker Pattern
var options = new CurlOptions()
.WithCircuitBreaker(
failureThreshold: 5,
recoveryTimeout: TimeSpan.FromSeconds(30),
onOpen: () => Console.WriteLine("Circuit opened"),
onClose: () => Console.WriteLine("Circuit closed")
);
Fallback Mechanism
var options = new CurlOptions("https://primary.example.com/api")
.WithFallback("https://secondary.example.com/api")
.WithFallback("https://tertiary.example.com/api");
Extensions
Metrics and Telemetry
var options = new CurlOptions()
.WithMetrics(metrics =>
{
Console.WriteLine($"DNS: {metrics.DnsLookupTime}ms");
Console.WriteLine($"Connect: {metrics.ConnectTime}ms");
Console.WriteLine($"TLS: {metrics.TlsHandshakeTime}ms");
Console.WriteLine($"FirstByte: {metrics.TimeToFirstByte}ms");
Console.WriteLine($"Total: {metrics.TotalTime}ms");
});
Request/Response Transformation
var options = new CurlOptions()
.TransformRequest(req =>
{
// Modify request before sending
req.Headers["X-Request-Id"] = Guid.NewGuid().ToString();
return req;
})
.TransformResponse(async resp =>
{
// Process response before returning
if (resp.ContentType == "application/json")
{
resp.ParsedContent = JsonSerializer.Deserialize<dynamic>(resp.Body);
}
return resp;
});
Streaming Support
// Stream large downloads
var options = new CurlOptions()
.WithStreaming()
.OnDataReceived(async (chunk) =>
{
await fileStream.WriteAsync(chunk);
});
// Stream uploads
using var fileStream = File.OpenRead("large-file.zip");
var options = new CurlOptions()
.WithStreamUpload(fileStream)
.OnUploadProgress((sent, total) =>
{
Console.WriteLine($"Uploaded {sent}/{total} bytes");
});
Proxy Configuration
var options = new CurlOptions()
.WithProxy("http://proxy.example.com:8080")
.WithProxyAuth("username", "password")
.WithProxyType(ProxyType.Socks5)
.BypassProxyFor(new[] { "*.internal.com", "192.168.*" });
Best Practices
1. Resource Management
Always dispose of resources properly:
using var curl = new CurlClient();
var response = await curl.ExecuteAsync(options);
2. Error Handling
Implement comprehensive error handling:
try
{
var response = await Curl.PerformAsync(options);
}
catch (CurlTimeoutException ex)
{
// Handle timeout
}
catch (CurlNetworkException ex)
{
// Handle network errors
}
catch (CurlException ex)
{
// Handle general curl errors
}
3. Configuration Management
Centralize configuration:
public static class CurlConfig
{
public static CurlOptions DefaultOptions => new CurlOptions()
.WithTimeout(TimeSpan.FromSeconds(30))
.WithRetry(3)
.WithCompression()
.WithMetrics();
}
4. Testing
Use the mock provider for testing:
// In tests
CurlOptions.UseMockProvider(mock =>
{
mock.Setup("https://api.example.com/users")
.Returns(new CurlResponse
{
StatusCode = 200,
Body = "[{\"id\":1,\"name\":\"Test User\"}]"
});
});
Migration from HttpClient
See the Migration Guide for detailed instructions on migrating from HttpClient to CurlDotNet.