Built-in Handlers
Azu provides a comprehensive set of built-in middleware handlers for common HTTP concerns, including error handling, logging, CORS, static file serving, and more.
Overview
Built-in middleware enables:
Error handling: Automatic exception catching and error page rendering
Logging: Request/response logging with structured data
Security: CORS, CSRF protection, and request validation
Performance: Static file serving and caching
Monitoring: Request throttling, rate limiting, and metrics
Reliability: Request ID injection and IP spoofing protection
Middleware Stack
Handler Reference
Rescuer Handler
Handles exceptions and renders error pages.
# Basic usage
Azu::Handler::Rescuer.new
# With custom configuration
Azu::Handler::Rescuer.new(
show_details: false, # Hide error details in production
log_errors: true, # Log errors to console
custom_templates: { # Custom error templates
404 => "errors/not_found.html",
500 => "errors/server_error.html"
}
)
Features:
Automatic exception catching
Custom error page templates
Environment-aware error details
Structured error logging
Logger Handler
Logs request and response information.
# Basic usage
Azu::Handler::Logger.new
# With custom configuration
Azu::Handler::Logger.new(
level: :info, # Log level
format: :json, # Log format (json, text)
include_headers: false, # Include request headers
include_body: false, # Include request body
sensitive_fields: ["password"], # Fields to redact
custom_logger: MyLogger.new # Custom logger instance
)
Features:
Request/response logging
Performance timing
Sensitive data redaction
Custom log formats
Structured logging
CORS Handler
Handles Cross-Origin Resource Sharing.
# Basic usage
Azu::Handler::CORS.new
# With custom configuration
Azu::Handler::CORS.new(
origins: ["https://example.com", "https://api.example.com"],
methods: ["GET", "POST", "PUT", "DELETE"],
headers: ["Content-Type", "Authorization"],
credentials: true,
max_age: 86400
)
Features:
Configurable origins
Method and header whitelisting
Credential support
Preflight request handling
CSRF Handler
Protects against Cross-Site Request Forgery attacks.
# Basic usage
Azu::Handler::CSRF.new
# With custom configuration
Azu::Handler::CSRF.new(
secret: "your-secret-key",
token_length: 32,
cookie_name: "_csrf_token",
header_name: "X-CSRF-Token",
excluded_paths: ["/api/webhook"]
)
Features:
Automatic token generation
Token validation
Cookie and header support
Path exclusions
Static Handler
Serves static files efficiently.
# Basic usage
Azu::Handler::Static.new
# With custom configuration
Azu::Handler::Static.new(
root: "public", # Static files directory
index: "index.html", # Default index file
cache_control: "public, max-age=31536000", # Cache headers
gzip: true, # Enable gzip compression
etag: true, # Enable ETag headers
mime_types: { # Custom MIME types
".md" => "text/markdown",
".cson" => "application/cson"
}
)
Features:
Efficient file serving
Automatic MIME type detection
Caching headers
Gzip compression
ETag support
Throttle Handler
Implements rate limiting and request throttling.
# Basic usage
Azu::Handler::Throttle.new
# With custom configuration
Azu::Handler::Throttle.new(
limit: 100, # Requests per window
window: 60, # Time window in seconds
key_by: :ip, # Throttle by IP address
store: RedisStore.new, # Storage backend
headers: { # Custom headers
"X-RateLimit-Limit" => "100",
"X-RateLimit-Remaining" => "remaining",
"X-RateLimit-Reset" => "reset_time"
}
)
Features:
Configurable rate limits
Multiple storage backends
Custom throttling keys
Rate limit headers
Sliding window algorithm
Request ID Handler
Injects unique request IDs for tracing.
# Basic usage
Azu::Handler::RequestID.new
# With custom configuration
Azu::Handler::RequestID.new(
header_name: "X-Request-ID",
generator: ->{ SecureRandom.uuid },
include_in_response: true
)
Features:
Unique request identification
Request tracing
Custom ID generation
Response header injection
IP Spoofing Handler
Protects against IP address spoofing.
# Basic usage
Azu::Handler::IPSpoofing.new
# With custom configuration
Azu::Handler::IPSpoofing.new(
trusted_proxies: ["10.0.0.0/8", "172.16.0.0/12"],
header_names: ["X-Forwarded-For", "X-Real-IP"],
fallback_to_direct: true
)
Features:
IP spoofing detection
Trusted proxy configuration
Multiple header support
Fallback mechanisms
Configuration Examples
Development Configuration
# config/development.cr
ExampleApp.start [
Azu::Handler::Rescuer.new(show_details: true),
Azu::Handler::Logger.new(level: :debug),
Azu::Handler::CORS.new(origins: ["http://localhost:3000"]),
Azu::Handler::Static.new(root: "public"),
Azu::Handler::RequestID.new
]
Production Configuration
# config/production.cr
ExampleApp.start [
Azu::Handler::Rescuer.new(show_details: false),
Azu::Handler::Logger.new(
level: :info,
format: :json,
include_headers: false
),
Azu::Handler::CORS.new(
origins: ["https://yourdomain.com"],
credentials: true
),
Azu::Handler::CSRF.new(secret: ENV["CSRF_SECRET"]),
Azu::Handler::Throttle.new(
limit: 1000,
window: 60,
store: RedisStore.new(ENV["REDIS_URL"])
),
Azu::Handler::Static.new(
root: "public",
cache_control: "public, max-age=31536000"
),
Azu::Handler::RequestID.new,
Azu::Handler::IPSpoofing.new(
trusted_proxies: ["10.0.0.0/8"]
)
]
API-Only Configuration
# config/api.cr
ExampleApp.start [
Azu::Handler::Rescuer.new,
Azu::Handler::Logger.new(format: :json),
Azu::Handler::CORS.new(
origins: ["*"],
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
),
Azu::Handler::Throttle.new(limit: 100, window: 60),
Azu::Handler::RequestID.new
]
Performance Considerations
Handler Order
The order of handlers affects performance:
# Optimal order for performance
ExampleApp.start [
# 1. Error handling (always first)
Azu::Handler::Rescuer.new,
# 2. Logging (early for timing)
Azu::Handler::Logger.new,
# 3. Security (before processing)
Azu::Handler::CORS.new,
Azu::Handler::CSRF.new,
# 4. Static files (fast path)
Azu::Handler::Static.new,
# 5. Rate limiting (before expensive operations)
Azu::Handler::Throttle.new,
# 6. Request processing
Azu::Handler::RequestID.new,
Azu::Handler::IPSpoofing.new
]
Caching Strategies
# Aggressive caching for static assets
Azu::Handler::Static.new(
cache_control: "public, max-age=31536000, immutable",
etag: true,
gzip: true
)
# No caching for API responses
Azu::Handler::Cache.new(
cache_control: "no-cache, no-store, must-revalidate",
etag: false
)
Security Best Practices
CORS Configuration
# Restrictive CORS for security
Azu::Handler::CORS.new(
origins: ["https://yourdomain.com"], # Specific origins only
methods: ["GET", "POST"], # Minimal methods
headers: ["Content-Type"], # Minimal headers
credentials: false, # Disable credentials
max_age: 3600 # Short preflight cache
)
CSRF Protection
# Secure CSRF configuration
Azu::Handler::CSRF.new(
secret: SecureRandom.hex(32), # Strong secret
token_length: 32, # Long tokens
cookie_name: "__Host-csrf", # Secure cookie
header_name: "X-CSRF-Token", # Custom header
excluded_paths: ["/api/webhook"] # Exclude webhooks
)
Rate Limiting
# Defensive rate limiting
Azu::Handler::Throttle.new(
limit: 100, # Conservative limits
window: 60, # 1-minute windows
key_by: :ip, # IP-based limiting
store: RedisStore.new, # Persistent storage
retry_after: true # Include Retry-After header
)
Monitoring and Debugging
Logging Configuration
# Comprehensive logging
Azu::Handler::Logger.new(
level: :info,
format: :json,
include_headers: true,
include_body: false,
sensitive_fields: ["password", "token", "secret"],
custom_logger: StructuredLogger.new
)
Error Tracking
# Error tracking integration
class ErrorTrackingHandler
include Azu::Handler
def call(request : HttpRequest, response : Response) : Response
@next.call(request, response)
rescue ex : Exception
# Send to error tracking service
ErrorTracker.capture_exception(ex, {
request_id: request.headers["X-Request-ID"]?,
user_id: request.current_user?.id,
path: request.path,
method: request.method
})
# Re-raise for Rescuer to handle
raise ex
end
end
Customization Examples
Custom Error Pages
# Custom error page templates
Azu::Handler::Rescuer.new(
custom_templates: {
404 => "errors/not_found.html",
500 => "errors/server_error.html",
422 => "errors/validation_error.html"
}
)
Custom Rate Limiting
# User-based rate limiting
class UserRateLimitHandler
include Azu::Handler
def call(request : HttpRequest, response : Response) : Response
user_id = request.current_user?.id
if user_id && rate_limit_exceeded?(user_id)
return Response.new(
status: 429,
body: {error: "Rate limit exceeded"}.to_json,
headers: {"Content-Type" => "application/json"}
)
end
@next.call(request, response)
end
private def rate_limit_exceeded?(user_id : String) : Bool
# Custom rate limiting logic
false
end
end
Next Steps
Custom Middleware - Creating your own middleware handlers
Error Handling - Advanced error handling strategies
API Reference: Handlers - Complete handler API documentation
Performance Tuning - Optimizing middleware performance
Built-in middleware provides a solid foundation for common web application concerns while maintaining flexibility for customization.
Last updated
Was this helpful?