Use responsewriter.UserProvidedDecorator instead of auto flush response (#6171)

Signed-off-by: hongming <coder.scala@gmail.com>
This commit is contained in:
hongming
2024-09-13 16:40:36 +08:00
committed by GitHub
parent 499e10d913
commit bbc476d47c
3 changed files with 21 additions and 9 deletions

View File

@@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/apis/audit"
"k8s.io/apiserver/pkg/endpoints/responsewriter"
"k8s.io/klog/v2" "k8s.io/klog/v2"
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1" clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
"kubesphere.io/api/iam/v1beta1" "kubesphere.io/api/iam/v1beta1"
@@ -398,6 +399,9 @@ func (a *auditing) eventToBytes(events []*Event) [][]byte {
return res return res
} }
var _ http.ResponseWriter = &ResponseCapture{}
var _ responsewriter.UserProvidedDecorator = &ResponseCapture{}
type ResponseCapture struct { type ResponseCapture struct {
http.ResponseWriter http.ResponseWriter
wroteHeader bool wroteHeader bool
@@ -413,6 +417,10 @@ func NewResponseCapture(w http.ResponseWriter) *ResponseCapture {
} }
} }
func (c *ResponseCapture) Unwrap() http.ResponseWriter {
return c.ResponseWriter
}
func (c *ResponseCapture) Header() http.Header { func (c *ResponseCapture) Header() http.Header {
return c.ResponseWriter.Header() return c.ResponseWriter.Header()
} }
@@ -425,9 +433,6 @@ func (c *ResponseCapture) Write(data []byte) (int, error) {
if err != nil { if err != nil {
return n, err return n, err
} }
if flusher, ok := c.ResponseWriter.(http.Flusher); ok {
flusher.Flush()
}
return n, nil return n, nil
} }

View File

@@ -8,6 +8,7 @@ package filters
import ( import (
"net/http" "net/http"
"k8s.io/apiserver/pkg/endpoints/responsewriter"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"kubesphere.io/kubesphere/pkg/apiserver/auditing" "kubesphere.io/kubesphere/pkg/apiserver/auditing"
@@ -44,7 +45,7 @@ func (a *auditingFilter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if event := a.LogRequestObject(req, info); event != nil { if event := a.LogRequestObject(req, info); event != nil {
resp := auditing.NewResponseCapture(w) resp := auditing.NewResponseCapture(w)
a.next.ServeHTTP(resp, req) a.next.ServeHTTP(responsewriter.WrapForHTTP1Or2(resp), req)
go a.LogResponseObject(event, resp) go a.LogResponseObject(event, resp)
} else { } else {
a.next.ServeHTTP(w, req) a.next.ServeHTTP(w, req)

View File

@@ -13,6 +13,7 @@ import (
"strconv" "strconv"
"time" "time"
"k8s.io/apiserver/pkg/endpoints/responsewriter"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"kubesphere.io/kubesphere/pkg/apiserver/metrics" "kubesphere.io/kubesphere/pkg/apiserver/metrics"
@@ -20,12 +21,19 @@ import (
"kubesphere.io/kubesphere/pkg/utils/iputil" "kubesphere.io/kubesphere/pkg/utils/iputil"
) )
var _ http.ResponseWriter = &metaResponseWriter{}
var _ responsewriter.UserProvidedDecorator = &metaResponseWriter{}
type metaResponseWriter struct { type metaResponseWriter struct {
http.ResponseWriter http.ResponseWriter
statusCode int statusCode int
size int size int
} }
func (r *metaResponseWriter) Unwrap() http.ResponseWriter {
return r.ResponseWriter
}
func newMetaResponseWriter(w http.ResponseWriter) *metaResponseWriter { func newMetaResponseWriter(w http.ResponseWriter) *metaResponseWriter {
return &metaResponseWriter{ return &metaResponseWriter{
ResponseWriter: w, ResponseWriter: w,
@@ -48,9 +56,6 @@ func (r *metaResponseWriter) Write(b []byte) (int, error) {
if err != nil { if err != nil {
return size, err return size, err
} }
if flusher, ok := r.ResponseWriter.(http.Flusher); ok {
flusher.Flush()
}
return size, nil return size, nil
} }
@@ -66,7 +71,8 @@ func WithGlobalFilter(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
wrapper := newMetaResponseWriter(w) wrapper := newMetaResponseWriter(w)
start := time.Now() start := time.Now()
handler.ServeHTTP(wrapper, req)
handler.ServeHTTP(responsewriter.WrapForHTTP1Or2(wrapper), req)
elapsedTime := time.Since(start) elapsedTime := time.Since(start)
// Record metrics for each request // Record metrics for each request
@@ -94,7 +100,7 @@ func WithGlobalFilter(handler http.Handler) http.Handler {
req.Proto, req.Proto,
wrapper.statusCode, wrapper.statusCode,
wrapper.size, wrapper.size,
elapsedTime.Microseconds(), elapsedTime.Milliseconds(),
) )
}) })
} }