<p>Friendly Automation <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/12751">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve
Kevin Harwell: Looks good to me, but someone else must approve
George Joseph: Looks good to me, approved
Friendly Automation: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_ari.c: Prefer exact handler match over wildcard<br><br>Given the following request path and 2 handler paths...<br>Request: /channels/externalMedia<br>Handler: /channels/{channelId} "wildcard"<br>Handler: /channels/externalmedia "non-wildcard"<br><br>...if /channels/externalMedia was registered as a handler after<br>/channels/{channelId} as shown above, the request would automatically<br>match the wildcard handler and attempt to parse "externalMedia" into<br>the channelId variable which isn't what was intended. It'd work<br>if the non-wildard entry was defined in rest-api/api-docs/channels.json<br>before the wildcard entry but that makes the json files<br>order-dependent which isn't a good thing.<br><br>To combat this issue, the search loop saves any wildcard match but<br>continues looking for exact matches at the same level. If it finds<br>one, it's used. If it hasn't found an exact match at the end of<br>the current level, the wildcard is used. Regardless, after<br>searching the current level, the wildcard is cleared so it won't<br>accidentally match for a different object or a higher level.<br><br>BTW, it's currently not possible for more than 1 wildcard entry<br>to be defined for a level. For instance, there couldn't be:<br>Handler: /channels/{channelId}<br>Handler: /channels/{channelName}<br>We wouldn't know which one to match.<br><br>Change-Id: I574aa3cbe4249c92c30f74b9b40e750e9002f925<br>---<br>M res/res_ari.c<br>1 file changed, 18 insertions(+), 5 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_ari.c b/res/res_ari.c</span><br><span>index 0554587..2664800 100644</span><br><span>--- a/res/res_ari.c</span><br><span>+++ b/res/res_ari.c</span><br><span>@@ -496,6 +496,7 @@</span><br><span> {</span><br><span> RAII_VAR(struct stasis_rest_handlers *, root, NULL, ao2_cleanup);</span><br><span> struct stasis_rest_handlers *handler;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct stasis_rest_handlers *wildcard_handler = NULL;</span><br><span> RAII_VAR(struct ast_variable *, path_vars, NULL, ast_variables_destroy);</span><br><span> char *path = ast_strdupa(uri);</span><br><span> char *path_segment;</span><br><span>@@ -504,37 +505,49 @@</span><br><span> root = handler = get_root_handler();</span><br><span> ast_assert(root != NULL);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, "Finding handler for %s\n", path);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> while ((path_segment = strsep(&path, "/")) && (strlen(path_segment) > 0)) {</span><br><span> struct stasis_rest_handlers *found_handler = NULL;</span><br><span> int i;</span><br><span> </span><br><span> ast_uri_decode(path_segment, ast_uri_http_legacy);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(3, "Finding handler for %s\n", path_segment);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, " Finding handler for %s\n", path_segment);</span><br><span> </span><br><span> for (i = 0; found_handler == NULL && i < handler->num_children; ++i) {</span><br><span> struct stasis_rest_handlers *child = handler->children[i];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(3, " Checking %s\n", child->path_segment);</span><br><span> if (child->is_wildcard) {</span><br><span> /* Record the path variable */</span><br><span> struct ast_variable *path_var = ast_variable_new(child->path_segment, path_segment, __FILE__);</span><br><span> path_var->next = path_vars;</span><br><span> path_vars = path_var;</span><br><span style="color: hsl(0, 100%, 40%);">- found_handler = child;</span><br><span style="color: hsl(120, 100%, 40%);">+ wildcard_handler = child;</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, " Checking %s %s: Matched wildcard.\n", handler->path_segment, child->path_segment);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> } else if (strcmp(child->path_segment, path_segment) == 0) {</span><br><span> found_handler = child;</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, " Checking %s %s: Explicit match with %s\n", handler->path_segment, child->path_segment, path_segment);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, " Checking %s %s: Didn't match %s\n", handler->path_segment, child->path_segment, path_segment);</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (!found_handler && wildcard_handler) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, " No explicit handler found for %s. Using wildcard %s.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ path_segment, wildcard_handler->path_segment);</span><br><span style="color: hsl(120, 100%, 40%);">+ found_handler = wildcard_handler;</span><br><span style="color: hsl(120, 100%, 40%);">+ wildcard_handler = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (found_handler == NULL) {</span><br><span> /* resource not found */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(3, " Handler not found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, " Handler not found for %s\n", path_segment);</span><br><span> ast_ari_response_error(</span><br><span> response, 404, "Not Found",</span><br><span> "Resource not found");</span><br><span> return;</span><br><span> } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(3, " Got it!\n");</span><br><span> handler = found_handler;</span><br><span> }</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/12751">change 12751</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/12751"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-Change-Id: I574aa3cbe4249c92c30f74b9b40e750e9002f925 </div>
<div style="display:none"> Gerrit-Change-Number: 12751 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>