Merge remote-tracking branch 'main/v3' into issue_179_v3
# Conflicts: # http.go
This commit is contained in:
		| @@ -115,14 +115,14 @@ func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) | ||||
| 		md["Method"] = r.Method | ||||
| 		md["URL"] = r.URL.String() | ||||
| 		md["Proto"] = r.Proto | ||||
| 		md["ContentLength"] = fmt.Sprintf("%d", r.ContentLength) | ||||
| 		md["TransferEncoding"] = strings.Join(r.TransferEncoding, ",") | ||||
| 		md["Content-Length"] = fmt.Sprintf("%d", r.ContentLength) | ||||
| 		md["Transfer-Encoding"] = strings.Join(r.TransferEncoding, ",") | ||||
| 		md["Host"] = r.Host | ||||
| 		md["RequestURI"] = r.RequestURI | ||||
| 		if r.TLS != nil { | ||||
| 			md["TLS"] = "true" | ||||
| 			md["TLS_ALPN"] = r.TLS.NegotiatedProtocol | ||||
| 			md["TLS_ServerName"] = r.TLS.ServerName | ||||
| 			md["TLS-ALPN"] = r.TLS.NegotiatedProtocol | ||||
| 			md["TLS-ServerName"] = r.TLS.ServerName | ||||
| 		} | ||||
|  | ||||
| 		ctx = metadata.NewIncomingContext(ctx, md) | ||||
|   | ||||
| @@ -2,13 +2,35 @@ package meter // import "go.unistack.org/micro-server-http/v3/handler/meter" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"compress/gzip" | ||||
| 	"context" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
|  | ||||
| 	codecpb "go.unistack.org/micro-proto/v3/codec" | ||||
| 	"go.unistack.org/micro/v3/errors" | ||||
| 	"go.unistack.org/micro/v3/logger" | ||||
| 	"go.unistack.org/micro/v3/metadata" | ||||
| 	"go.unistack.org/micro/v3/meter" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	contentEncodingHeader = "Content-Encoding" | ||||
| 	acceptEncodingHeader  = "Accept-Encoding" | ||||
| ) | ||||
|  | ||||
| var gzipPool = sync.Pool{ | ||||
| 	New: func() interface{} { | ||||
| 		return gzip.NewWriter(nil) | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| var bufPool = sync.Pool{ | ||||
| 	New: func() interface{} { | ||||
| 		return bytes.NewBuffer(nil) | ||||
| 	}, | ||||
| } | ||||
|  | ||||
| // guard to fail early | ||||
| var _ MeterServiceServer = &Handler{} | ||||
|  | ||||
| @@ -56,12 +78,46 @@ func NewHandler(opts ...Option) *Handler { | ||||
| } | ||||
|  | ||||
| func (h *Handler) Metrics(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error { | ||||
| 	buf := bytes.NewBuffer(nil) | ||||
| 	if err := h.opts.Meter.Write(buf, h.opts.MeterOptions...); err != nil { | ||||
| 		return errors.InternalServerError(h.opts.Name, "%v", err) | ||||
| 	log, ok := logger.FromContext(ctx) | ||||
| 	if !ok { | ||||
| 		log = logger.DefaultLogger | ||||
| 	} | ||||
|  | ||||
| 	buf := bufPool.Get().(*bytes.Buffer) | ||||
| 	defer bufPool.Put(buf) | ||||
| 	buf.Reset() | ||||
|  | ||||
| 	w := io.Writer(buf) | ||||
|  | ||||
| 	if md, ok := metadata.FromIncomingContext(ctx); gzipAccepted(md) && ok { | ||||
| 		md.Set(contentEncodingHeader, "gzip") | ||||
| 		gz := gzipPool.Get().(*gzip.Writer) | ||||
| 		defer gzipPool.Put(gz) | ||||
|  | ||||
| 		gz.Reset(w) | ||||
| 		defer gz.Close() | ||||
|  | ||||
| 		w = gz | ||||
| 	} | ||||
|  | ||||
| 	if err := h.opts.Meter.Write(w, h.opts.MeterOptions...); err != nil { | ||||
| 		log.Error(ctx, "http/meter write failed", err) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	rsp.Data = buf.Bytes() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // gzipAccepted returns whether the client will accept gzip-encoded content. | ||||
| func gzipAccepted(md metadata.Metadata) bool { | ||||
| 	a, ok := md.Get(acceptEncodingHeader) | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	if strings.Contains(a, "gzip") { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user