]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Make API search case insensitive 1334/head
authorChristian Hofstaedtler <christian@hofstaedtler.name>
Mon, 17 Mar 2014 15:39:38 +0000 (16:39 +0100)
committerChristian Hofstaedtler <christian@hofstaedtler.name>
Mon, 17 Mar 2014 15:39:38 +0000 (16:39 +0100)
pdns/misc.hh
pdns/ws-auth.cc
regression-tests.api/test_Zones.py

index 60855138fb11e719bec1d39a7a315a1bace00c3e..917fd36ccff203ee5e0e674ed629c1af00a83e90 100644 (file)
@@ -338,6 +338,15 @@ inline bool pdns_iequals(const std::string& a, const std::string& b)
   return true;
 }
 
+inline bool pdns_iequals_ch(const char a, const char b) __attribute__((pure));
+inline bool pdns_iequals_ch(const char a, const char b)
+{
+  if ((a != b) && (dns_tolower(a) != dns_tolower(b)))
+    return false;
+
+  return true;
+}
+
 // lifted from boost, with thanks
 class AtomicCounter
 {
@@ -438,6 +447,17 @@ struct CIStringPairCompare: public std::binary_function<pair<string, uint16_t>,
   }
 };
 
+inline size_t pdns_ci_find(const string& haystack, const string& needle)
+{
+  string::const_iterator it = std::search(haystack.begin(), haystack.end(),
+    needle.begin(), needle.end(), pdns_iequals_ch);
+  if (it == haystack.end()) {
+    // not found
+    return string::npos;
+  } else {
+    return it - haystack.begin();
+  }
+}
 
 pair<string, string> splitField(const string& inp, char sepa);
 
index 0a86b704bdda5ea5edb5e8e94909af5b6b5ba60f..9569e14ee34b27618d414e0b1379786b8736d76b 100644 (file)
@@ -747,7 +747,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) {
   BOOST_FOREACH(const DomainInfo& di, domains) {
     string zoneId = apiZoneNameToId(di.zone);
 
-    if (di.zone.find(q) != string::npos) {
+    if (pdns_ci_find(di.zone, q) != string::npos) {
       Value object;
       object.SetObject();
       object.AddMember("type", "zone", doc.GetAllocator());
@@ -768,7 +768,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) {
       if (!rr.qtype.getCode())
         continue; // skip empty non-terminals
 
-      if (rr.qname.find(q) == string::npos && rr.content.find(q) == string::npos)
+      if (pdns_ci_find(rr.qname, q) == string::npos && pdns_ci_find(rr.content, q) == string::npos)
         continue;
 
       Value object;
@@ -787,7 +787,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) {
 
     di.backend->listComments(di.id);
     while(di.backend->getComment(comment)) {
-      if (comment.qname.find(q) == string::npos && comment.content.find(q) == string::npos)
+      if (pdns_ci_find(comment.qname, q) == string::npos && pdns_ci_find(comment.content, q) == string::npos)
         continue;
 
       Value object;
index 78e9ed62cff4b1ad3547edc6c73d7b0465ad8cde..7995f0a724f466965fdc5721b701d461705f0cac 100644 (file)
@@ -509,6 +509,15 @@ class AuthZones(ApiTestCase):
         # should return zone, SOA, ns1, ns2
         self.assertEquals(len(r.json()), 4)
 
+    def test_SearchRRCaseInsensitive(self):
+        name = 'search-rr-insenszone.name'
+        self.create_zone(name=name)
+        r = self.session.get(self.url("/servers/localhost/search-data?q=rr-insensZONE"))
+        self.assertSuccessJson(r)
+        print r.json()
+        # should return zone, SOA, ns1, ns2
+        self.assertEquals(len(r.json()), 4)
+
 
 @unittest.skipIf(not isRecursor(), "Not applicable")
 class RecursorZones(ApiTestCase):