mirror of
https://github.com/minio/minio.git
synced 2025-01-11 15:03:22 -05:00
Limit Response Recorder memory (#20399)
Disable body recording for... * admin inspect * admin metrics * profiling download Also, if the recorded body is > 10MB, drop it.
This commit is contained in:
parent
84e122c5c3
commit
9d5cdaa2e3
@ -159,14 +159,14 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
|
||||
|
||||
// Info operations
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/info").HandlerFunc(adminMiddleware(adminAPI.ServerInfoHandler, traceAllFlag, noObjLayerFlag))
|
||||
adminRouter.Methods(http.MethodGet, http.MethodPost).Path(adminVersion + "/inspect-data").HandlerFunc(adminMiddleware(adminAPI.InspectDataHandler, noGZFlag, traceAllFlag))
|
||||
adminRouter.Methods(http.MethodGet, http.MethodPost).Path(adminVersion + "/inspect-data").HandlerFunc(adminMiddleware(adminAPI.InspectDataHandler, noGZFlag, traceHdrsS3HFlag))
|
||||
|
||||
// StorageInfo operations
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/storageinfo").HandlerFunc(adminMiddleware(adminAPI.StorageInfoHandler, traceAllFlag))
|
||||
// DataUsageInfo operations
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/datausageinfo").HandlerFunc(adminMiddleware(adminAPI.DataUsageInfoHandler, traceAllFlag))
|
||||
// Metrics operation
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/metrics").HandlerFunc(adminMiddleware(adminAPI.MetricsHandler, traceAllFlag))
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/metrics").HandlerFunc(adminMiddleware(adminAPI.MetricsHandler, traceHdrsS3HFlag))
|
||||
|
||||
if globalIsDistErasure || globalIsErasure {
|
||||
// Heal operations
|
||||
@ -193,9 +193,9 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
|
||||
// Profiling operations - deprecated API
|
||||
adminRouter.Methods(http.MethodPost).Path(adminVersion+"/profiling/start").HandlerFunc(adminMiddleware(adminAPI.StartProfilingHandler, traceAllFlag, noObjLayerFlag)).
|
||||
Queries("profilerType", "{profilerType:.*}")
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/profiling/download").HandlerFunc(adminMiddleware(adminAPI.DownloadProfilingHandler, traceAllFlag, noObjLayerFlag))
|
||||
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/profiling/download").HandlerFunc(adminMiddleware(adminAPI.DownloadProfilingHandler, traceHdrsS3HFlag, noObjLayerFlag))
|
||||
// Profiling operations
|
||||
adminRouter.Methods(http.MethodPost).Path(adminVersion + "/profile").HandlerFunc(adminMiddleware(adminAPI.ProfileHandler, traceAllFlag, noObjLayerFlag))
|
||||
adminRouter.Methods(http.MethodPost).Path(adminVersion + "/profile").HandlerFunc(adminMiddleware(adminAPI.ProfileHandler, traceHdrsS3HFlag, noObjLayerFlag))
|
||||
|
||||
// Config KV operations.
|
||||
if enableConfigOps {
|
||||
|
@ -26,6 +26,8 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/klauspost/compress/gzip"
|
||||
)
|
||||
|
||||
// ResponseRecorder - is a wrapper to trap the http response
|
||||
@ -98,10 +100,16 @@ func (lrw *ResponseRecorder) Write(p []byte) (int, error) {
|
||||
if lrw.TimeToFirstByte == 0 {
|
||||
lrw.TimeToFirstByte = time.Now().UTC().Sub(lrw.StartTime)
|
||||
}
|
||||
gzipped := lrw.Header().Get("Content-Encoding") == "gzip"
|
||||
if !gzipped && ((lrw.LogErrBody && lrw.StatusCode >= http.StatusBadRequest) || lrw.LogAllBody) {
|
||||
// Always logging error responses.
|
||||
lrw.body.Write(p)
|
||||
|
||||
if (lrw.LogErrBody && lrw.StatusCode >= http.StatusBadRequest) || lrw.LogAllBody {
|
||||
// If body is > 10MB, drop it.
|
||||
if lrw.bytesWritten+len(p) > 10<<20 {
|
||||
lrw.LogAllBody = false
|
||||
lrw.body = bytes.Buffer{}
|
||||
} else {
|
||||
// Always logging error responses.
|
||||
lrw.body.Write(p)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return n, err
|
||||
@ -128,8 +136,16 @@ var gzippedBody = []byte("<GZIP>")
|
||||
// Body - Return response body.
|
||||
func (lrw *ResponseRecorder) Body() []byte {
|
||||
if lrw.Header().Get("Content-Encoding") == "gzip" {
|
||||
// ... otherwise we return the <GZIP> place holder
|
||||
return gzippedBody
|
||||
if lrw.body.Len() > 1<<20 {
|
||||
return gzippedBody
|
||||
}
|
||||
r, err := gzip.NewReader(&lrw.body)
|
||||
if err != nil {
|
||||
return gzippedBody
|
||||
}
|
||||
defer r.Close()
|
||||
b, _ := io.ReadAll(io.LimitReader(r, 10<<20))
|
||||
return b
|
||||
}
|
||||
// If there was an error response or body logging is enabled
|
||||
// then we return the body contents
|
||||
@ -152,7 +168,9 @@ func (lrw *ResponseRecorder) WriteHeader(code int) {
|
||||
|
||||
// Flush - Calls the underlying Flush.
|
||||
func (lrw *ResponseRecorder) Flush() {
|
||||
lrw.ResponseWriter.(http.Flusher).Flush()
|
||||
if flusher, ok := lrw.ResponseWriter.(http.Flusher); ok {
|
||||
flusher.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
// Size - returns the number of bytes written
|
||||
|
Loading…
Reference in New Issue
Block a user