From 5a2b739b95818ad41b0ffadfa8a46f0b201df716 Mon Sep 17 00:00:00 2001 From: Agung Candra Date: Mon, 18 Sep 2023 15:43:43 +0700 Subject: [PATCH 1/2] feat: change path params with pattern --- boot/gw_server_options.go | 14 ++++++++++---- middleware/common.go | 11 ++++++----- middleware/common_test.go | 7 ++++--- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/boot/gw_server_options.go b/boot/gw_server_options.go index b5ccd2a..fc79362 100644 --- a/boot/gw_server_options.go +++ b/boot/gw_server_options.go @@ -9,15 +9,16 @@ import ( "context" "encoding/json" "fmt" + "net/http" + "net/textproto" + "strings" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" rkmid "github.com/rookie-ninja/rk-entry/v2/middleware" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" - "net/http" - "net/textproto" - "strings" ) // Gateway options for marshaller and unmarshaler. @@ -173,12 +174,17 @@ func NewRkGwServerMuxOptions(mOptIn *protojson.MarshalOptions, uOptIn *protojson scheme = "https" } - return metadata.Pairs( + md := metadata.Pairs( "x-forwarded-method", req.Method, "x-forwarded-path", req.URL.Path, "x-forwarded-scheme", scheme, "x-forwarded-remote-addr", req.RemoteAddr, "x-forwarded-user-agent", req.UserAgent()) + if pattern, ok := runtime.HTTPPathPattern(c); ok { + md["x-forwarded-pattern"] = []string{pattern} + } + + return md }), runtime.WithOutgoingHeaderMatcher(OutgoingHeaderMatcher), diff --git a/middleware/common.go b/middleware/common.go index 7454e8f..8867b55 100644 --- a/middleware/common.go +++ b/middleware/common.go @@ -8,13 +8,14 @@ package rkgrpcmid import ( "context" - "github.com/rookie-ninja/rk-entry/v2/middleware" - "go.uber.org/zap" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/peer" "net" "path" "strings" + + rkmid "github.com/rookie-ninja/rk-entry/v2/middleware" + "go.uber.org/zap" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" ) var ( @@ -42,7 +43,7 @@ func GetGwInfo(md metadata.MD) (gwMethod, gwPath, gwScheme, gwUserAgent string) gwMethod = tokens[0] } - if tokens := md["x-forwarded-path"]; len(tokens) > 0 { + if tokens := md["x-forwarded-pattern"]; len(tokens) > 0 { gwPath = tokens[0] } diff --git a/middleware/common_test.go b/middleware/common_test.go index ffd2a02..2d554da 100644 --- a/middleware/common_test.go +++ b/middleware/common_test.go @@ -7,10 +7,11 @@ package rkgrpcmid import ( "context" + "testing" + "github.com/stretchr/testify/assert" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" - "testing" ) type FakeAddr struct{} @@ -26,14 +27,14 @@ func (f FakeAddr) String() string { func TestGetGwInfo(t *testing.T) { md := metadata.New(map[string]string{ "x-forwarded-method": "ut-method", - "x-forwarded-path": "ut-path", "x-forwarded-scheme": "ut-scheme", "x-forwarded-user-agent": "ut-agent", + "x-forwarded-pattern": "ut-path/{id}", }) method, path, scheme, agent := GetGwInfo(md) assert.Equal(t, "ut-method", method) - assert.Equal(t, "ut-path", path) + assert.Equal(t, "ut-path/{id}", path) assert.Equal(t, "ut-scheme", scheme) assert.Equal(t, "ut-agent", agent) } From d3aef8c594958783586f34ac892f99cec132c566 Mon Sep 17 00:00:00 2001 From: Agung Candra Date: Mon, 18 Sep 2023 16:01:32 +0700 Subject: [PATCH 2/2] add test on metadata builder --- boot/gw_server_options.go | 42 ++++++++++++++++++---------------- boot/gw_server_options_test.go | 23 ++++++++++++++++--- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/boot/gw_server_options.go b/boot/gw_server_options.go index fc79362..fe241a2 100644 --- a/boot/gw_server_options.go +++ b/boot/gw_server_options.go @@ -166,32 +166,34 @@ func NewRkGwServerMuxOptions(mOptIn *protojson.MarshalOptions, uOptIn *protojson MarshalOptions: *mOpt, UnmarshalOptions: *uOpt, }), - runtime.WithMetadata(func(c context.Context, req *http.Request) metadata.MD { - // we are unable to get scheme with req.URL.Scheme. - // Let's check with TLS. - scheme := "http" - if req.TLS != nil { - scheme = "https" - } - - md := metadata.Pairs( - "x-forwarded-method", req.Method, - "x-forwarded-path", req.URL.Path, - "x-forwarded-scheme", scheme, - "x-forwarded-remote-addr", req.RemoteAddr, - "x-forwarded-user-agent", req.UserAgent()) - if pattern, ok := runtime.HTTPPathPattern(c); ok { - md["x-forwarded-pattern"] = []string{pattern} - } - - return md - }), + runtime.WithMetadata(rkGwMetadataBuilder), runtime.WithOutgoingHeaderMatcher(OutgoingHeaderMatcher), runtime.WithIncomingHeaderMatcher(IncomingHeaderMatcher), } } +func rkGwMetadataBuilder(c context.Context, req *http.Request) metadata.MD { + // we are unable to get scheme with req.URL.Scheme. + // Let's check with TLS. + scheme := "http" + if req.TLS != nil { + scheme = "https" + } + + md := metadata.Pairs( + "x-forwarded-method", req.Method, + "x-forwarded-path", req.URL.Path, + "x-forwarded-scheme", scheme, + "x-forwarded-remote-addr", req.RemoteAddr, + "x-forwarded-user-agent", req.UserAgent()) + if pattern, ok := runtime.HTTPPathPattern(c); ok { + md["x-forwarded-pattern"] = []string{pattern} + } + + return md +} + // HttpErrorHandler Mainly copies from runtime.DefaultHTTPErrorHandler. // We reformat error response with rkerror.ErrorResp. func HttpErrorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) { diff --git a/boot/gw_server_options_test.go b/boot/gw_server_options_test.go index 8a371df..821b50b 100644 --- a/boot/gw_server_options_test.go +++ b/boot/gw_server_options_test.go @@ -8,15 +8,17 @@ package rkgrpc import ( "context" "errors" + "io" + "net/http" + "net/http/httptest" + "testing" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/stretchr/testify/assert" testhttp "github.com/stretchr/testify/http" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/encoding/protojson" "gopkg.in/yaml.v3" - "io" - "net/http" - "testing" ) type FakeEncoder struct{} @@ -280,6 +282,21 @@ func TestNewRkGwServerMuxOptions(t *testing.T) { assert.Len(t, opts, 5) } +func TestRkGwMetadataBuilder(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/uc-path", nil) + ctxAnnotator := runtime.WithHTTPPathPattern("/uc/path/{id}") + ctx := ctxAnnotator(context.Background()) + + md := rkGwMetadataBuilder(ctx, req) + assert.Equal(t, metadata.Pairs( + "x-forwarded-method", req.Method, + "x-forwarded-path", req.URL.Path, + "x-forwarded-scheme", "http", + "x-forwarded-remote-addr", req.RemoteAddr, + "x-forwarded-user-agent", req.UserAgent(), + "x-forwarded-pattern", "/uc/path/{id}"), md) +} + // ************ Test utility ************ func assertNotPanic(t *testing.T) {