diff --git a/src/include/grpc_transcoding/path_matcher.h b/src/include/grpc_transcoding/path_matcher.h index 9ac6ebc..dcb737e 100644 --- a/src/include/grpc_transcoding/path_matcher.h +++ b/src/include/grpc_transcoding/path_matcher.h @@ -374,6 +374,9 @@ void ExtractBindingsFromQueryParameters( // Make sure the query parameter is not a system parameter (e.g. // `api_key`) before adding the binding. if (system_params.find(name) == std::end(system_params)) { + name = UrlUnescapeString(name, + UrlUnescapeSpec::kAllCharacters, + /*query_param_unescape_plus=*/false); // The name of the parameter is a field path, which is a dot-delimited // sequence of field names that identify the (potentially deep) field // in the request, e.g. `book.author.name`. diff --git a/test/path_matcher_test.cc b/test/path_matcher_test.cc index 011d828..9de287e 100644 --- a/test/path_matcher_test.cc +++ b/test/path_matcher_test.cc @@ -868,6 +868,12 @@ TEST_F(PathMatcherTest, VariableBindingsWithQueryParamsEncoding) { Binding{FieldPath{"x"}, "$%/ \n"}, }), bindings); + + EXPECT_EQ(LookupWithParams("GET", "/a", "shelf.search%5Bfield%5D=Hello%20world", &bindings), a); + EXPECT_EQ(Bindings({ + Binding{FieldPath{"shelf","search[field]"}, "Hello world"}, + }), + bindings); } TEST_F(PathMatcherTest, QueryParameterNotUnescapePlus) {