hotfix (#186)
## Pull Request template Please, go through these steps before clicking submit on this PR. 1. Give a descriptive title to your PR. 2. Provide a description of your changes. 3. Make sure you have some relevant tests. 4. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes (if applicable). **PLEASE REMOVE THIS TEMPLATE BEFORE SUBMITTING** Co-authored-by: Gorbunov Kirill Andreevich <kgorbunov@mtsbank.ru> Reviewed-on: #186 Co-authored-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru> Co-committed-by: Кирилл Горбунов <kirya_gorbunov_2015@mail.ru>
This commit was merged in pull request #186.
	This commit is contained in:
		
							
								
								
									
										50
									
								
								handler.go
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								handler.go
									
									
									
									
									
								
							| @@ -109,20 +109,20 @@ func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) | |||||||
| 			md = metadata.New(len(r.Header) + 8) | 			md = metadata.New(len(r.Header) + 8) | ||||||
| 		} | 		} | ||||||
| 		for k, v := range r.Header { | 		for k, v := range r.Header { | ||||||
| 			md[k] = v | 			md[k] = v[0] | ||||||
| 		} | 		} | ||||||
| 		md["RemoteAddr"] = []string{r.RemoteAddr} | 		md["RemoteAddr"] = r.RemoteAddr | ||||||
| 		md["Method"] = []string{r.Method} | 		md["Method"] = r.Method | ||||||
| 		md["URL"] = []string{r.URL.String()} | 		md["URL"] = r.URL.String() | ||||||
| 		md["Proto"] = []string{r.Proto} | 		md["Proto"] = r.Proto | ||||||
| 		md["Content-Length"] = []string{fmt.Sprintf("%d", r.ContentLength)} | 		md["Content-Length"] = fmt.Sprintf("%d", r.ContentLength) | ||||||
| 		md["Transfer-Encoding"] = r.TransferEncoding | 		md["Transfer-Encoding"] = r.TransferEncoding[0] | ||||||
| 		md["Host"] = []string{r.Host} | 		md["Host"] = r.Host | ||||||
| 		md["RequestURI"] = []string{r.RequestURI} | 		md["RequestURI"] = r.RequestURI | ||||||
| 		if r.TLS != nil { | 		if r.TLS != nil { | ||||||
| 			md["TLS"] = []string{"true"} | 			md["TLS"] = "true" | ||||||
| 			md["TLS-ALPN"] = []string{r.TLS.NegotiatedProtocol} | 			md["TLS-ALPN"] = r.TLS.NegotiatedProtocol | ||||||
| 			md["TLS-ServerName"] = []string{r.TLS.ServerName} | 			md["TLS-ServerName"] = r.TLS.ServerName | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		ctx = metadata.NewIncomingContext(ctx, md) | 		ctx = metadata.NewIncomingContext(ctx, md) | ||||||
| @@ -290,7 +290,7 @@ func (h *Server) HTTPHandlerFunc(handler interface{}) (http.HandlerFunc, error) | |||||||
| 		w.Header().Set(metadata.HeaderContentType, ct) | 		w.Header().Set(metadata.HeaderContentType, ct) | ||||||
| 		if md, ok := metadata.FromOutgoingContext(ctx); ok { | 		if md, ok := metadata.FromOutgoingContext(ctx); ok { | ||||||
| 			for k, v := range md { | 			for k, v := range md { | ||||||
| 				w.Header()[k] = v | 				w.Header()[k] = []string{v} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if md := getRspHeader(ctx); md != nil { | 		if md := getRspHeader(ctx); md != nil { | ||||||
| @@ -349,23 +349,23 @@ func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||||
| 		md = metadata.New(len(r.Header) + 8) | 		md = metadata.New(len(r.Header) + 8) | ||||||
| 	} | 	} | ||||||
| 	for k, v := range r.Header { | 	for k, v := range r.Header { | ||||||
| 		md[k] = v | 		md[k] = v[0] | ||||||
| 	} | 	} | ||||||
| 	md["RemoteAddr"] = []string{r.RemoteAddr} | 	md["RemoteAddr"] = r.RemoteAddr | ||||||
| 	if r.TLS != nil { | 	if r.TLS != nil { | ||||||
| 		md["Scheme"] = []string{"https"} | 		md["Scheme"] = "https" | ||||||
| 	} else { | 	} else { | ||||||
| 		md["Scheme"] = []string{"http"} | 		md["Scheme"] = "http" | ||||||
| 	} | 	} | ||||||
| 	md["Method"] = []string{r.Method} | 	md["Method"] = r.Method | ||||||
| 	md["URL"] = []string{r.URL.String()} | 	md["URL"] = r.URL.String() | ||||||
| 	md["Proto"] = []string{r.Proto} | 	md["Proto"] = r.Proto | ||||||
| 	md["Content-Length"] = []string{fmt.Sprintf("%d", r.ContentLength)} | 	md["Content-Length"] = fmt.Sprintf("%d", r.ContentLength) | ||||||
| 	if len(r.TransferEncoding) > 0 { | 	if len(r.TransferEncoding) > 0 { | ||||||
| 		md["Transfer-Encoding"] = r.TransferEncoding | 		md["Transfer-Encoding"] = r.TransferEncoding[0] | ||||||
| 	} | 	} | ||||||
| 	md["Host"] = []string{r.Host} | 	md["Host"] = r.Host | ||||||
| 	md["RequestURI"] = []string{r.RequestURI} | 	md["RequestURI"] = r.RequestURI | ||||||
| 	ctx = metadata.NewIncomingContext(ctx, md) | 	ctx = metadata.NewIncomingContext(ctx, md) | ||||||
|  |  | ||||||
| 	path := r.URL.Path | 	path := r.URL.Path | ||||||
| @@ -550,7 +550,7 @@ func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |||||||
| 	w.Header().Set(metadata.HeaderContentType, ct) | 	w.Header().Set(metadata.HeaderContentType, ct) | ||||||
| 	if md, ok := metadata.FromOutgoingContext(ctx); ok { | 	if md, ok := metadata.FromOutgoingContext(ctx); ok { | ||||||
| 		for k, v := range md { | 		for k, v := range md { | ||||||
| 			w.Header()[k] = v | 			w.Header()[k] = []string{v} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if md := getRspHeader(ctx); md != nil { | 	if md := getRspHeader(ctx); md != nil { | ||||||
|   | |||||||
| @@ -42,9 +42,10 @@ type Handler struct { | |||||||
| type Option func(*Options) | type Option func(*Options) | ||||||
|  |  | ||||||
| type Options struct { | type Options struct { | ||||||
| 	Meter        meter.Meter | 	Meter           meter.Meter | ||||||
| 	Name         string | 	Name            string | ||||||
| 	MeterOptions []options.Option | 	MeterOptions    []options.Option | ||||||
|  | 	DisableCompress bool | ||||||
| } | } | ||||||
|  |  | ||||||
| func Meter(m meter.Meter) Option { | func Meter(m meter.Meter) Option { | ||||||
| @@ -59,6 +60,12 @@ func Name(name string) Option { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func DisableCompress(g bool) Option { | ||||||
|  | 	return func(o *Options) { | ||||||
|  | 		o.DisableCompress = g | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func MeterOptions(opts ...options.Option) Option { | func MeterOptions(opts ...options.Option) Option { | ||||||
| 	return func(o *Options) { | 	return func(o *Options) { | ||||||
| 		o.MeterOptions = append(o.MeterOptions, opts...) | 		o.MeterOptions = append(o.MeterOptions, opts...) | ||||||
| @@ -66,7 +73,7 @@ func MeterOptions(opts ...options.Option) Option { | |||||||
| } | } | ||||||
|  |  | ||||||
| func NewOptions(opts ...Option) Options { | func NewOptions(opts ...Option) Options { | ||||||
| 	options := Options{Meter: meter.DefaultMeter} | 	options := Options{Meter: meter.DefaultMeter, DisableCompress: false} | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| 		o(&options) | 		o(&options) | ||||||
| 	} | 	} | ||||||
| @@ -90,8 +97,9 @@ func (h *Handler) Metrics(ctx context.Context, req *codecpb.Frame, rsp *codecpb. | |||||||
|  |  | ||||||
| 	w := io.Writer(buf) | 	w := io.Writer(buf) | ||||||
|  |  | ||||||
| 	if md, ok := metadata.FromContext(ctx); gzipAccepted(md) && ok { | 	if md, ok := metadata.FromIncomingContext(ctx); gzipAccepted(md) && ok && !h.opts.DisableCompress { | ||||||
| 		md.Set(contentEncodingHeader, "gzip") | 		omd, _ := metadata.FromOutgoingContext(ctx) | ||||||
|  | 		omd.Set(contentEncodingHeader, "gzip") | ||||||
| 		gz := gzipPool.Get().(*gzip.Writer) | 		gz := gzipPool.Get().(*gzip.Writer) | ||||||
| 		defer gzipPool.Put(gz) | 		defer gzipPool.Put(gz) | ||||||
|  |  | ||||||
| @@ -99,6 +107,7 @@ func (h *Handler) Metrics(ctx context.Context, req *codecpb.Frame, rsp *codecpb. | |||||||
| 		defer gz.Close() | 		defer gz.Close() | ||||||
|  |  | ||||||
| 		w = gz | 		w = gz | ||||||
|  | 		gz.Flush() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := h.opts.Meter.Write(w, h.opts.MeterOptions...); err != nil { | 	if err := h.opts.Meter.Write(w, h.opts.MeterOptions...); err != nil { | ||||||
|   | |||||||
							
								
								
									
										49
									
								
								handler/meter/meter_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								handler/meter/meter_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | package meter | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	codecpb "go.unistack.org/micro-proto/v4/codec" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestHandler_Metrics(t *testing.T) { | ||||||
|  | 	type fields struct { | ||||||
|  | 		opts Options | ||||||
|  | 	} | ||||||
|  | 	type args struct { | ||||||
|  | 		ctx context.Context | ||||||
|  | 		req *codecpb.Frame | ||||||
|  | 		rsp *codecpb.Frame | ||||||
|  | 	} | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name    string | ||||||
|  | 		fields  fields | ||||||
|  | 		args    args | ||||||
|  | 		wantErr bool | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			"Test #1", | ||||||
|  | 			fields{ | ||||||
|  | 				opts: NewOptions(), | ||||||
|  | 			}, | ||||||
|  | 			args{ | ||||||
|  | 				context.Background(), | ||||||
|  | 				&codecpb.Frame{Data: []byte("gzip")}, | ||||||
|  | 				&codecpb.Frame{}, | ||||||
|  | 			}, | ||||||
|  | 			true, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||||||
|  | 			h := &Handler{ | ||||||
|  | 				opts: tt.fields.opts, | ||||||
|  | 			} | ||||||
|  | 			if err := h.Metrics(tt.args.ctx, tt.args.req, tt.args.rsp); (err != nil) != tt.wantErr { | ||||||
|  | 				t.Errorf("Metrics() error = %v, wantErr %v", err, tt.wantErr) | ||||||
|  | 			} | ||||||
|  | 			t.Logf("RSP: %v", tt.args.rsp.Data) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								http.go
									
									
									
									
									
								
							| @@ -217,7 +217,7 @@ func (h *Server) newHTTPHandler(handler interface{}, opts ...options.Option) *ht | |||||||
| 		pth := &patHandler{mtype: mtype, name: name, rcvr: rcvr} | 		pth := &patHandler{mtype: mtype, name: name, rcvr: rcvr} | ||||||
| 		hdlr.name = name | 		hdlr.name = name | ||||||
|  |  | ||||||
| 		if err := hdlr.handlers.Insert(md["Method"], md["Path"][0], pth); err != nil { | 		if err := hdlr.handlers.Insert([]string{md["Method"]}, md["Path"], pth); err != nil { | ||||||
| 			h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add handler for %s %s", md["Method"][0], md["Path"][0])) | 			h.opts.Logger.Error(h.opts.Context, fmt.Sprintf("cant add handler for %s %s", md["Method"][0], md["Path"][0])) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -468,7 +468,7 @@ func (h *Server) Start() error { | |||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		if cerr := hs.Serve(ts); cerr != nil && !errors.Is(cerr, net.ErrClosed) { | 		if cerr := hs.Serve(ts); cerr != nil && !errors.Is(cerr, net.ErrClosed) { | ||||||
| 			h.opts.Logger.Error(h.opts.Context, cerr) | 			h.opts.Logger.Error(h.opts.Context, cerr.Error()) | ||||||
| 		} | 		} | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								util.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								util.go
									
									
									
									
									
								
							| @@ -33,13 +33,11 @@ func FillRequest(ctx context.Context, req interface{}, opts ...FillRequestOption | |||||||
|  |  | ||||||
| 	cookies := md["Cookie"] | 	cookies := md["Cookie"] | ||||||
| 	cmd := make(map[string]string, len(cookies)) | 	cmd := make(map[string]string, len(cookies)) | ||||||
| 	for _, cookie := range cookies { | 	kv := strings.Split(cookies, "=") | ||||||
| 		kv := strings.Split(cookie, "=") | 	if len(kv) != 2 { | ||||||
| 		if len(kv) != 2 { | 		return nil | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		cmd[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) |  | ||||||
| 	} | 	} | ||||||
|  | 	cmd[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) | ||||||
| 	for idx := 0; idx < len(options.cookies)/2; idx += 2 { | 	for idx := 0; idx < len(options.cookies)/2; idx += 2 { | ||||||
| 		k := http.CanonicalHeaderKey(options.cookies[idx]) | 		k := http.CanonicalHeaderKey(options.cookies[idx]) | ||||||
| 		v, ok := cmd[k] | 		v, ok := cmd[k] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user