{"id":109,"date":"2006-03-29T15:55:57","date_gmt":"2006-03-29T22:55:57","guid":{"rendered":"http:\/\/kennyw.com\/indigo\/109"},"modified":"2006-03-29T15:55:57","modified_gmt":"2006-03-29T22:55:57","slug":"demystifying-hostnamecomparisonmode-wildcards-and-uri-matching","status":"publish","type":"post","link":"https:\/\/kennyw.com\/?p=109","title":{"rendered":"Demystifying HostNameComparisonMode: Wildcards, and URI Matching"},"content":{"rendered":"<p>Today I was asked &#8220;what is StrongWildcard and WeakWildcard, and which one should I use?&#8221;.  The piece of object model that my co-worker is asking about is:<\/p>\n<div class=\"code\">\n<code class=\"keyword\">public enum<\/code> HostNameComparisonMode<br \/>\n{<\/p>\n<div class=\"indent1\">StrongWildcard = 0,<br \/>\nExact = 1,<br \/>\nWeakWildcard = 2,<\/div>\n<p>}<\/p><\/div>\n<p>Most bindings have a HostNameComparisonMode property on them.  This property is used for service-side endpoints (IChannelListener), in conjunction with the ListenUri of that endpoint.  The values are semantics similar to + and * for <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/http\/http\/processing_registrations.asp\">http.sys registrations<\/a>.  &#8220;Wildcard&#8221; vs. &#8220;Exact&#8221; refers to how we match the authority (hostname+port) piece of an incoming Uri. For &#8220;Wildcard&#8221;, anything matches. For &#8220;Exact&#8221;, we perform a case-insensitive string comparison to determine equality.<\/p>\n<p>&#8220;Strong&#8221; vs. &#8220;Weak&#8221; has to do with the relative priorities of endpoints. We use three longest-prefix-match tables, one each for StrongWildcard, Exact, and WeakWildcard.  When a Message comes into the system, we first try to match the Uri against our Strong table (which uses a wildcard comparison on hostname+port). If nothing matches, we try the Exact table (using a case-insensitive exact comparison on hostname+port).  Lastly, if there was no match on Strong or Exact, we check the Weak table (again using a wildcard match for hostname+port).<\/p>\n<p>For example, let&#8217;s say you have the following endpoints registered on your machine:<\/p>\n<ol>\n<li>(http:\/\/foo.com\/a\/b\/c\/, StrongWildcard)<\/li>\n<li>(http:\/\/foo.com\/a\/b\/, Exact)<\/li>\n<li>(http:\/\/bar.com\/, Exact)<\/li>\n<li>(http:\/\/foo.com\/a\/, WeakWildcard)<\/li>\n<\/ol>\n<p>A request coming in for <code class=\"keyword\">http:\/\/foo.com\/a\/b\/c\/d\/<\/code> will match (1).<\/p>\n<p>A request for <code class=\"keyword\">http:\/\/foo.com\/a\/b\/<\/code> will match (2) since the strong comparison fails (\/a\/b\/c\/ is not a prefix of \/a\/b\/).<\/p>\n<p>A request for <code class=\"keyword\">http:\/\/foo.com\/a\/d\/<\/code> will match (4).  Even though &#8220;\/&#8221; is a prefix match of &#8220;\/a\/d\/&#8221; for (3), the hostnames differ and so the Exact match will fail.<\/p>\n<p>Lastly, a request for <code class=\"keyword\">http:\/\/bar.com\/a\/b\/<\/code> will match (3).  (2) is a prefix match but the hostnames differ, and (3) takes precedence over (4) in priority order.<\/p>\n<p>Hopfully this helps demystify our endpoint URI matching process!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today I was asked &#8220;what is StrongWildcard and WeakWildcard, and which one should I use?&#8221;. The piece of object model that my co-worker is asking about is: public enum HostNameComparisonMode { StrongWildcard = 0, Exact = 1, WeakWildcard = 2, } Most bindings have a HostNameComparisonMode property on them. This property is used for service-side [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-109","post","type-post","status-publish","format-standard","hentry","category-indigo"],"_links":{"self":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/109","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=109"}],"version-history":[{"count":0,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/109\/revisions"}],"wp:attachment":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}