@@ -32,6 +32,18 @@ namespace transcoding {
3232template <class Method >
3333class PathMatcherBuilder ; // required for PathMatcher constructor
3434
35+ enum class UrlUnescapeSpec {
36+ // URL path parameters will not decode RFC 6570 reserved characters.
37+ // This is the default behavior.
38+ kAllCharactersExceptReserved = 0 ,
39+ // URL path parameters will be fully URI-decoded except in
40+ // cases of single segment matches in reserved expansion, where "%2F" will be
41+ // left encoded.
42+ kAllCharactersExceptSlash ,
43+ // URL path parameters will be fully URI-decoded.
44+ kAllCharacters ,
45+ };
46+
3547// The immutable, thread safe PathMatcher stores a mapping from a combination of
3648// a service (host) name and a HTTP path to your method (MethodInfo*). It is
3749// constructed with a PathMatcherBuilder and supports one operation: Lookup.
@@ -82,8 +94,7 @@ class PathMatcher {
8294 // The info associated with each method. The path matcher nodes
8395 // will hold pointers to MethodData objects in this vector.
8496 std::vector<std::unique_ptr<MethodData>> methods_;
85- bool fully_decode_reserved_expansion_;
86- bool always_decode_;
97+ UrlUnescapeSpec unescape_spec_;
8798
8899 private:
89100 friend class PathMatcherBuilder <Method>;
@@ -115,20 +126,9 @@ class PathMatcherBuilder {
115126 bool Register (const std::string& http_method, const std::string& path,
116127 const std::string& body_field_path, Method method);
117128
118- // When set to true, URL path parameters will be fully URI-decoded.
119- //
120- // The default behavior is to not decode RFC 6570 reserved characters in multi
121- // segment matches.
122- void SetAlwaysDecode (bool value) { always_decode_ = value; }
123-
124- // When set to true, URL path parameters will be fully URI-decoded except in
125- // cases of single segment matches in reserved expansion, where "%2F" will be
126- // left encoded.
127- //
128- // The default behavior is to not decode RFC 6570 reserved characters in multi
129- // segment matches.
130- void SetFullyDecodeReservedExpansion (bool value) {
131- fully_decode_reserved_expansion_ = value;
129+ // Change unescaping behavior, see UrlUnescapeSpec for available options.
130+ void SetUrlUnescapeSpec (UrlUnescapeSpec unescape_spec) {
131+ unescape_spec_ = unescape_spec;
132132 }
133133
134134 // Returns a unique_ptr to a thread safe PathMatcher that contains all
@@ -151,8 +151,7 @@ class PathMatcherBuilder {
151151 std::unordered_set<std::string> custom_verbs_;
152152 typedef typename PathMatcher<Method>::MethodData MethodData;
153153 std::vector<std::unique_ptr<MethodData>> methods_;
154- bool always_decode_;
155- bool fully_decode_reserved_expansion_;
154+ UrlUnescapeSpec unescape_spec_;
156155
157156 friend class PathMatcher <Method>;
158157};
@@ -421,9 +420,7 @@ PathMatcher<Method>::PathMatcher(PathMatcherBuilder<Method>&& builder)
421420 : root_ptr_(std::move(builder.root_ptr_)),
422421 custom_verbs_ (std::move(builder.custom_verbs_)),
423422 methods_(std::move(builder.methods_)),
424- always_decode_(builder.always_decode_),
425- fully_decode_reserved_expansion_(
426- builder.fully_decode_reserved_expansion_) {}
423+ unescape_spec_(builder.unescape_spec_) {}
427424
428425// Lookup is a wrapper method for the recursive node Lookup. First, the wrapper
429426// splits the request path into slash-separated path parts. Next, the method
@@ -458,9 +455,11 @@ Method PathMatcher<Method>::Lookup(
458455 MethodData* method_data = reinterpret_cast <MethodData*>(lookup_result.data );
459456 if (variable_bindings != nullptr ) {
460457 variable_bindings->clear ();
461- ExtractBindingsFromPath (method_data->variables , parts, variable_bindings,
462- fully_decode_reserved_expansion_ || always_decode_,
463- always_decode_);
458+ ExtractBindingsFromPath (
459+ method_data->variables , parts, variable_bindings,
460+ unescape_spec_ == UrlUnescapeSpec::kAllCharacters ||
461+ unescape_spec_ == UrlUnescapeSpec::kAllCharactersExceptSlash ,
462+ unescape_spec_ == UrlUnescapeSpec::kAllCharacters );
464463 ExtractBindingsFromQueryParameters (
465464 query_params, method_data->system_query_parameter_names ,
466465 variable_bindings);
@@ -498,8 +497,7 @@ Method PathMatcher<Method>::Lookup(const std::string& http_method,
498497template <class Method >
499498PathMatcherBuilder<Method>::PathMatcherBuilder()
500499 : root_ptr_(new PathMatcherNode()),
501- always_decode_ (false ),
502- fully_decode_reserved_expansion_(false ) {}
500+ unescape_spec_ (UrlUnescapeSpec::kAllCharactersExceptReserved ) {}
503501
504502template <class Method >
505503PathMatcherPtr<Method> PathMatcherBuilder<Method>::Build() {
0 commit comments