From 008367384837b781d9800765edad56079cc8c067 Mon Sep 17 00:00:00 2001 From: Josh Humphries <2035234+jhump@users.noreply.github.com> Date: Wed, 15 Nov 2023 10:18:32 -0500 Subject: [PATCH] type URLs can have any host and even include URI scheme --- error.go | 8 ++++++-- error_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ protocol_connect.go | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/error.go b/error.go index ed4b8a07..7925f3d7 100644 --- a/error.go +++ b/error.go @@ -74,11 +74,11 @@ func (d *ErrorDetail) Type() string { // than plain type names, but there aren't any descriptor registries // deployed. With the current state of the `Any` code, it's not possible to // build a useful type registry either. To hide this from users, we should - // trim the static hostname that `Any` adds to the type name. + // trim the URL prefix is added to the type name. // // If we ever want to support remote registries, we can add an explicit // `TypeURL` method. - return strings.TrimPrefix(d.pb.GetTypeUrl(), defaultAnyResolverPrefix) + return typeNameFromURL(d.pb.GetTypeUrl()) } // Bytes returns a copy of the Protobuf-serialized detail. @@ -409,3 +409,7 @@ func asMaxBytesError(err error, tmpl string, args ...any) *Error { prefix := fmt.Sprintf(tmpl, args...) return errorf(CodeResourceExhausted, "%s: exceeded %d byte http.MaxBytesReader limit", prefix, maxBytesErr.Limit) } + +func typeNameFromURL(url string) string { + return url[strings.LastIndexByte(url, '/')+1:] +} diff --git a/error_test.go b/error_test.go index 02d6456b..5078c2c0 100644 --- a/error_test.go +++ b/error_test.go @@ -107,3 +107,45 @@ func TestErrorIs(t *testing.T) { assert.False(t, errors.Is(connectErr, NewError(CodeUnavailable, err))) assert.True(t, errors.Is(connectErr, connectErr)) } + +func TestTypeNameFromURL(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + url string + typeName string + }{ + { + name: "no-prefix", + url: "foo.bar.Baz", + typeName: "foo.bar.Baz", + }, + { + name: "standard-prefix", + url: defaultAnyResolverPrefix + "foo.bar.Baz", + typeName: "foo.bar.Baz", + }, + { + name: "different-hostname", + url: "abc.com/foo.bar.Baz", + typeName: "foo.bar.Baz", + }, + { + name: "additional-path-elements", + url: defaultAnyResolverPrefix + "abc/def/foo.bar.Baz", + typeName: "foo.bar.Baz", + }, + { + name: "full-url", + url: "https://abc.com/abc/def/foo.bar.Baz", + typeName: "foo.bar.Baz", + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + assert.Equal(t, typeNameFromURL(testCase.url), testCase.typeName) + }) + } +} diff --git a/protocol_connect.go b/protocol_connect.go index 413cbcfb..fe25dcbb 100644 --- a/protocol_connect.go +++ b/protocol_connect.go @@ -1121,7 +1121,7 @@ func (d *connectWireDetail) MarshalJSON() ([]byte, error) { Value string `json:"value"` Debug json.RawMessage `json:"debug,omitempty"` }{ - Type: strings.TrimPrefix(d.pb.GetTypeUrl(), defaultAnyResolverPrefix), + Type: typeNameFromURL(d.pb.GetTypeUrl()), Value: base64.RawStdEncoding.EncodeToString(d.pb.GetValue()), } // Try to produce debug info, but expect failure when we don't have