mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-11-13 07:25:13 +00:00
feat: Add response body capture to ContentBasedETagMiddleware for accurate content-based ETag generation
- Add ResponseWriterWrapper struct with gin.ResponseWriter and body buffer fields to capture response content - Add Write method to ResponseWriterWrapper that captures response body while writing to original writer - Add Body method to ResponseWriterWrapper that returns captured response bytes - Update ContentBasedETagMiddleware to wrap response writer with ResponseWriterWrapper before calling
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -12,6 +13,23 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ResponseWriterWrapper wraps gin.ResponseWriter to capture response body
|
||||||
|
type ResponseWriterWrapper struct {
|
||||||
|
gin.ResponseWriter
|
||||||
|
body *bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write captures the response body while writing to the original writer
|
||||||
|
func (w *ResponseWriterWrapper) Write(data []byte) (int, error) {
|
||||||
|
w.body.Write(data)
|
||||||
|
return w.ResponseWriter.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body returns the captured response body
|
||||||
|
func (w *ResponseWriterWrapper) Body() []byte {
|
||||||
|
return w.body.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
// PerformanceMetrics tracks performance statistics
|
// PerformanceMetrics tracks performance statistics
|
||||||
type PerformanceMetrics struct {
|
type PerformanceMetrics struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
@@ -445,6 +463,13 @@ func ETagValidationMiddleware() gin.HandlerFunc {
|
|||||||
// ContentBasedETagMiddleware generates ETags based on response content
|
// ContentBasedETagMiddleware generates ETags based on response content
|
||||||
func ContentBasedETagMiddleware() gin.HandlerFunc {
|
func ContentBasedETagMiddleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
// Wrap the response writer to capture the body
|
||||||
|
wrapper := &ResponseWriterWrapper{
|
||||||
|
ResponseWriter: c.Writer,
|
||||||
|
body: bytes.NewBuffer(nil),
|
||||||
|
}
|
||||||
|
c.Writer = wrapper
|
||||||
|
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|
||||||
// Only generate ETags for successful GET requests
|
// Only generate ETags for successful GET requests
|
||||||
@@ -452,10 +477,16 @@ func ContentBasedETagMiddleware() gin.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// For content-based ETags, we would need to capture the response body
|
// Generate ETag based on captured response content
|
||||||
// This is a simplified version that uses weak ETags for dynamic content
|
responseBody := wrapper.Body()
|
||||||
etag := generateWeakETag(c)
|
if len(responseBody) > 0 {
|
||||||
c.Header("ETag", etag)
|
etag := generateContentETag(c, responseBody)
|
||||||
|
c.Header("ETag", etag)
|
||||||
|
} else {
|
||||||
|
// Fallback to weak ETag for empty responses
|
||||||
|
etag := generateWeakETag(c)
|
||||||
|
c.Header("ETag", etag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user