Skip to content

Commit

Permalink
warn on duplicate URI
Browse files Browse the repository at this point in the history
  • Loading branch information
technicallyty committed Jan 10, 2025
1 parent 0f20fcb commit 8336880
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
15 changes: 13 additions & 2 deletions server/v2/api/grpcgateway/interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ func newGatewayInterceptor[T transaction.Tx](logger log.Logger, gateway *runtime
if err != nil {
return nil, err
}
regexQueryMD := createRegexMapping(getMapping)
regexQueryMD := createRegexMapping(logger, getMapping)
if err != nil {
return nil, err
}
return &gatewayInterceptor[T]{
logger: logger,
gateway: gateway,
Expand Down Expand Up @@ -159,11 +162,19 @@ func getHTTPGetAnnotationMapping() (map[string]string, error) {

// createRegexMapping converts the annotationMapping (HTTP annotation -> query input type name) to a
// map of regular expressions for that HTTP annotation pattern, to queryMetadata.
func createRegexMapping(annotationMapping map[string]string) map[*regexp.Regexp]queryMetadata {
func createRegexMapping(logger log.Logger, annotationMapping map[string]string) map[*regexp.Regexp]queryMetadata {
regexQueryMD := make(map[*regexp.Regexp]queryMetadata)
seenPatterns := make(map[string]string)
for annotation, queryInputName := range annotationMapping {
pattern, wildcardNames := patternToRegex(annotation)
reg := regexp.MustCompile(pattern)
if otherAnnotation, ok := seenPatterns[pattern]; !ok {
seenPatterns[pattern] = annotation
} else {
// TODO: eventually we want this to error, but there is currently a duplicate in the protobuf.
// see: https://github.com/cosmos/cosmos-sdk/issues/23281
logger.Warn("duplicate HTTP annotation found %q and %q. query will resolve to %q", annotation, otherAnnotation, queryInputName)
}
regexQueryMD[reg] = queryMetadata{
queryInputProtoName: queryInputName,
wildcardKeyNames: wildcardNames,
Expand Down
49 changes: 49 additions & 0 deletions server/v2/api/grpcgateway/interceptor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package grpcgateway

import (
"bytes"
"testing"

"github.com/stretchr/testify/require"

"cosmossdk.io/log"
)

func Test_createRegexMapping(t *testing.T) {
tests := []struct {
name string
annotations map[string]string
wantWarn bool
}{
{
name: "no annotations should not warn",
},
{
name: "different annotations should not warn",
annotations: map[string]string{
"/foo/bar/{baz}": "",
"/crypto/{currency}": "",
},
},
{
name: "duplicate annotations should warn",
annotations: map[string]string{
"/hello/{world}": "",
"/hello/{developers}": "",
},
wantWarn: true,
},
}
buf := bytes.NewBuffer(nil)
logger := log.NewLogger(buf)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
createRegexMapping(logger, tt.annotations)
if tt.wantWarn {
require.NotEmpty(t, buf.String())
} else {
require.Empty(t, buf.String())
}
})
}
}
7 changes: 6 additions & 1 deletion server/v2/api/grpcgateway/uri_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import (
"io"
"net/http"
"net/url"
"os"
"regexp"
"testing"

gogoproto "github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"

"cosmossdk.io/log"
)

func TestMatchURI(t *testing.T) {
Expand Down Expand Up @@ -91,11 +94,13 @@ func TestMatchURI(t *testing.T) {
},
}

logger := log.NewLogger(os.Stdout)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
u, err := url.Parse(tc.uri)
require.NoError(t, err)
regexpMapping := createRegexMapping(tc.mapping)
regexpMapping := createRegexMapping(logger, tc.mapping)
require.NoError(t, err)
actual := matchURL(u, regexpMapping)
require.Equal(t, tc.expected, actual)
})
Expand Down

0 comments on commit 8336880

Please sign in to comment.