Description
cache.config accepts url= as a primary destination. A valid rule passes parsing, but UrlMatcher does not add it to the URL hash table. The configuration loads without an error, and the rule never matches a request.
The insertion code is in UrlMatcher<Data, Result>::NewEntry() in src/proxy/ControlMatcher.cc:
cur_d = data_array + num_el;
error = cur_d->Init(line_info);
if (error.failed()) {
url_str[num_el] = ats_strdup(pattern);
url_value[num_el] = num_el;
url_ht.emplace(url_str[num_el], url_value[num_el]);
num_el++;
}
return error;
error.failed() is true when initialization fails. This condition is backwards: a successfully initialized rule skips the insertion into url_ht, while the function still returns success.
Expected behavior
When cur_d->Init(line_info) succeeds, ATS should add the rule to url_ht. The rule's cache action should apply when a request URL exactly matches the configured value.
Cause
The exact URL matcher was added for TS-1280. The original code used a string pointer for errors and inserted the rule only after successful initialization:
errBuf = cur_d->Init(line_info);
if (errBuf == NULL) {
// Insert into url_ht.
}
Commit 70cc2d4ce1762b182dd52f43a6313c61772c3a8a replaced the error string with config_parse_error. That type evaluates to true when an error is present, but the same change made the UrlMatcher condition if (error), reversing the old success check.
Commit 39f8e5c057386bffd51f5ba2284d2e715543e100 later changed the condition to if (error.failed()) without correcting the reversed logic.
Related commits:
Suggested fix
error = cur_d->Init(line_info);
-if (error.failed()) {
+if (!error.failed()) {
url_str[num_el] = ats_strdup(pattern);
url_value[num_el] = num_el;
url_ht.emplace(url_str[num_el], url_value[num_el]);
num_el++;
}
Regression tests should cover:
- A valid
url= rule is inserted and matches the complete URL.
- A different URL does not match the rule.
- A failed
Init() call does not insert a rule and returns a configuration error.
- A duplicate
url= value still returns the duplicate-rule error.
Description
cache.configacceptsurl=as a primary destination. A valid rule passes parsing, butUrlMatcherdoes not add it to the URL hash table. The configuration loads without an error, and the rule never matches a request.The insertion code is in
UrlMatcher<Data, Result>::NewEntry()insrc/proxy/ControlMatcher.cc:error.failed()istruewhen initialization fails. This condition is backwards: a successfully initialized rule skips the insertion intourl_ht, while the function still returns success.Expected behavior
When
cur_d->Init(line_info)succeeds, ATS should add the rule tourl_ht. The rule's cache action should apply when a request URL exactly matches the configured value.Cause
The exact URL matcher was added for TS-1280. The original code used a string pointer for errors and inserted the rule only after successful initialization:
Commit
70cc2d4ce1762b182dd52f43a6313c61772c3a8areplaced the error string withconfig_parse_error. That type evaluates totruewhen an error is present, but the same change made theUrlMatcherconditionif (error), reversing the old success check.Commit
39f8e5c057386bffd51f5ba2284d2e715543e100later changed the condition toif (error.failed())without correcting the reversed logic.Related commits:
ResultSuggested fix
Regression tests should cover:
url=rule is inserted and matches the complete URL.Init()call does not insert a rule and returns a configuration error.url=value still returns the duplicate-rule error.