Skip to content

Commit b88f105

Browse files
author
Ruslan Nigmatullin
committed
Fix verb support
1 parent faf8af1 commit b88f105

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

src/include/grpc_transcoding/path_matcher.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,9 @@ void ExtractBindingsFromQueryParameters(
332332
//
333333
// - Strips off query string: "/a?foo=bar" --> "/a"
334334
// - Collapses extra slashes: "///" --> "/"
335-
std::vector<std::string> ExtractRequestParts(std::string path) {
335+
std::vector<std::string> ExtractRequestParts(
336+
std::string path,
337+
const std::unordered_set<std::string>& custom_verbs) {
336338
// Remove query parameters.
337339
path = path.substr(0, path.find_first_of('?'));
338340

@@ -341,7 +343,12 @@ std::vector<std::string> ExtractRequestParts(std::string path) {
341343
std::size_t last_colon_pos = path.find_last_of(':');
342344
std::size_t last_slash_pos = path.find_last_of('/');
343345
if (last_colon_pos != std::string::npos && last_colon_pos > last_slash_pos) {
344-
path[last_colon_pos] = '/';
346+
std::string verb = path.substr(last_colon_pos + 1);
347+
// only verb in the configured custom verbs, treat it as verb
348+
// replace ":" with / as a separate segment.
349+
if (custom_verbs.find(verb) != custom_verbs.end()) {
350+
path[last_colon_pos] = '/';
351+
}
345352
}
346353

347354
std::vector<std::string> result;
@@ -400,7 +407,7 @@ Method PathMatcher<Method>::Lookup(
400407
const std::string& query_params,
401408
std::vector<VariableBinding>* variable_bindings,
402409
std::string* body_field_path) const {
403-
const std::vector<std::string> parts = ExtractRequestParts(path);
410+
const std::vector<std::string> parts = ExtractRequestParts(path, custom_verbs_);
404411

405412
// If service_name has not been registered to ESP and strict_service_matching_
406413
// is set to false, tries to lookup the method in all registered services.
@@ -432,7 +439,7 @@ Method PathMatcher<Method>::Lookup(
432439
template <class Method>
433440
Method PathMatcher<Method>::Lookup(const std::string& http_method,
434441
const std::string& path) const {
435-
const std::vector<std::string> parts = ExtractRequestParts(path);
442+
const std::vector<std::string> parts = ExtractRequestParts(path, custom_verbs_);
436443

437444
// If service_name has not been registered to ESP and strict_service_matching_
438445
// is set to false, tries to lookup the method in all registered services.
@@ -500,6 +507,9 @@ bool PathMatcherBuilder<Method>::Register(
500507
root_ptr_.get());
501508
// Add the method_data to the methods_ vector for cleanup
502509
methods_.emplace_back(std::move(method_data));
510+
if (!ht->verb().empty()) {
511+
custom_verbs_.insert(ht->verb());
512+
}
503513
return true;
504514
}
505515

test/path_matcher_test.cc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -523,19 +523,24 @@ TEST_F(PathMatcherTest, CustomVerbMatches) {
523523
}
524524

525525
TEST_F(PathMatcherTest, CustomVerbMatch2) {
526-
MethodInfo* verb = AddGetPath("/*/*:verb");
526+
MethodInfo* verb = AddGetPath("/{a=*}/{b=*}:verb");
527527
Build();
528-
EXPECT_EQ(LookupNoBindings("GET", "/some:verb/const:verb"), verb);
528+
Bindings bindings;
529+
EXPECT_EQ(Lookup("GET", "/some:verb/const:verb", &bindings), verb);
530+
EXPECT_EQ(bindings.size(), 2);
531+
EXPECT_EQ(bindings[0].value, "some:verb");
532+
EXPECT_EQ(bindings[1].value, "const");
529533
}
530534

531535
TEST_F(PathMatcherTest, CustomVerbMatch3) {
532-
EXPECT_NE(nullptr, AddGetPath("/foo/*"));
536+
MethodInfo* verb = AddGetPath("/foo/{a=*}");
533537
Build();
534538

535-
// This should match. But due to an implementation bug which
536-
// blinkdly replacing last : with /, it will use /foo/other/verb
537-
// to match /foo/* which will fail.
538-
EXPECT_EQ(LookupNoBindings("GET", "/foo/other:verb"), nullptr);
539+
// This is not custom verb since it was not configured.
540+
Bindings bindings;
541+
EXPECT_EQ(Lookup("GET", "/foo/other:verb", &bindings), verb);
542+
EXPECT_EQ(bindings.size(), 1);
543+
EXPECT_EQ(bindings[0].value, "other:verb");
539544
}
540545

541546
TEST_F(PathMatcherTest, CustomVerbMatch4) {

0 commit comments

Comments
 (0)