Overview
Thebodyclose middleware ensures request bodies are properly closed after processing, preventing resource leaks.
Use it when you need:
- Prevent connection leaks
- Ensure proper resource cleanup
- Handle abandoned requests
Installation
Quick Start
Examples
Basic Usage
With Drain
API Reference
Functions
Options
Technical Details
The bodyclose middleware operates by wrapping the request handler with a deferred cleanup function that ensures proper resource management:Implementation Strategy
- Nil Body Check: Immediately passes control to the next handler if the request body is nil, avoiding unnecessary overhead
- Deferred Cleanup: Uses Goβs
deferstatement to guarantee body cleanup regardless of handler outcome (success, error, or panic) - Optional Draining: When
DrainBodyis enabled, reads and discards up toMaxDrainbytes before closing to enable HTTP keep-alive connection reuse - Connection Reuse: By draining the body, the middleware signals to the HTTP client that the connection can be safely reused in connection pools
Resource Management
- Default MaxDrain: 8KB (8192 bytes) to balance connection reuse benefits with performance
- Drain Mechanism: Uses
io.CopyNto limit the amount of data drained, preventing excessive memory consumption on large bodies - Error Handling: Silently ignores drain and close errors to prevent interference with the main request flow
Performance Characteristics
- Minimal Overhead: Only adds a single function call and defer statement per request
- Memory Efficient: Draining is capped by MaxDrain to prevent memory exhaustion
- No Blocking: Draining respects the MaxDrain limit and doesnβt attempt to fully read unbounded bodies
Why It Matters
Without proper body closing:- Connections may not be reused
- Memory leaks can occur
- Connection pool exhaustion
Best Practices
- Place early in middleware chain
- Use with connection pooling
- Consider draining for HTTP keep-alive
Testing
The bodyclose middleware includes comprehensive test coverage to ensure proper functionality:| Test Case | Description | Expected Behavior |
|---|---|---|
TestNew | Basic middleware creation with default options | Request body is properly handled, returns HTTP 200 OK |
TestWithOptions_DrainBody | Middleware with DrainBody enabled | Body is closed after being drained, tracking confirms closure |
TestWithOptions_NoDrain | Middleware with DrainBody disabled | Body is closed without draining, tracking confirms closure |
TestNilBody | Request with nil body (GET request) | Middleware handles nil body gracefully, returns HTTP 200 OK |
TestDrain | Using the Drain() convenience function | Body is drained before closing, request completes successfully |
TestNoDrain | Using the NoDrain() convenience function | Body is closed without draining, request completes successfully |
TestWithOptions_MaxDrain | Custom MaxDrain limit (10 bytes on 1000-byte body) | Only drains up to MaxDrain bytes, prevents excessive memory usage |
Test Coverage
The test suite uses a customtrackingBody type that monitors:
- Whether the body was closed (
closedfield) - Whether the body was fully drained (
drainedfield)