Browse Source

Rewritten util::stripIter(), which now returns pair of iterator.

Tatsuhiro Tsujikawa 14 years ago
parent
commit
6ef91d60b3
10 changed files with 108 additions and 84 deletions
  1. 3 21
      src/HttpHeader.cc
  2. 4 3
      src/HttpResponse.cc
  3. 2 1
      src/NsCookieParser.cc
  4. 5 2
      src/ServerStatMan.cc
  5. 1 1
      src/Sqlite3CookieParser.cc
  6. 39 25
      src/cookie_helper.cc
  7. 7 2
      src/cookie_helper.h
  8. 9 3
      src/util.cc
  9. 20 16
      src/util.h
  10. 18 10
      test/CookieHelperTest.cc

+ 3 - 21
src/HttpHeader.cc

@@ -198,24 +198,6 @@ void HttpHeader::setRequestPath(const std::string& requestPath)
   requestPath_ = requestPath;
 }
 
-namespace {
-template<typename InputIterator>
-std::pair<InputIterator, InputIterator> stripIter2
-(InputIterator first, InputIterator last,
- const std::string& chars = "\r\n \t")
-{
-  for(; first != last &&
-        std::find(chars.begin(), chars.end(), *first) != chars.end(); ++first);
-  if(first == last) {
-    return std::make_pair(first, last);
-  }
-  InputIterator left = last-1;
-  for(; left != first &&
-        std::find(chars.begin(), chars.end(), *left) != chars.end(); --left);
-  return std::make_pair(first, left+1);
-}
-} // namespace
-
 void HttpHeader::fill
 (std::string::const_iterator first,
  std::string::const_iterator last)
@@ -233,7 +215,7 @@ void HttpHeader::fill
         // multiline header?
         if(*first == ' ' || *first == '\t') {
           std::pair<std::string::const_iterator,
-                    std::string::const_iterator> p = stripIter2(first, j);
+                    std::string::const_iterator> p = util::stripIter(first, j);
           if(!name.empty() && p.first != p.second) {
             if(!value.empty()) {
               value += ' ';
@@ -246,9 +228,9 @@ void HttpHeader::fill
           put(name, value);
         }
         std::pair<std::string::const_iterator,
-                  std::string::const_iterator> p = stripIter2(first, sep);
+                  std::string::const_iterator> p = util::stripIter(first, sep);
         name.assign(p.first, p.second);
-        p = stripIter2(sep+1, j);
+        p = util::stripIter(sep+1, j);
         value.assign(p.first, p.second);
       }
     }

+ 4 - 3
src/HttpResponse.cc

@@ -309,11 +309,12 @@ bool parseMetalinkHttpLink(MetalinkHttpEntry& result, const std::string& s)
   if(last == s.end()) {
     return false;
   }
-  std::string uri = util::stripIter(first+1, last);
-  if(uri.empty()) {
+  std::pair<std::string::const_iterator,
+            std::string::const_iterator> p = util::stripIter(first+1, last);
+  if(p.first == p.second) {
     return false;
   } else {
-    result.uri = uri;
+    result.uri.assign(p.first, p.second);
   }
   last = std::find(last, s.end(), ';');
   if(last != s.end()) {

+ 2 - 1
src/NsCookieParser.cc

@@ -66,7 +66,8 @@ bool parseNsCookie
     return false;
   }
   std::string cookieDomain = cookie::removePrecedingDots(vs[0]);
-  if(vs[5].empty() || cookieDomain.empty() || !cookie::goodPath(vs[2])) {
+  if(vs[5].empty() || cookieDomain.empty() ||
+     !cookie::goodPath(vs[2].begin(), vs[2].end())) {
     return false;
   }
   int64_t expiryTime;

+ 5 - 2
src/ServerStatMan.cc

@@ -148,10 +148,13 @@ bool ServerStatMan::load(const std::string& filename)
         return false;
       }
     }
-    std::string line = util::stripIter(&buf[0], &buf[strlen(buf)]);
-    if(line.empty()) {
+    std::pair<std::string::const_iterator,
+              std::string::const_iterator> p =
+      util::stripIter(&buf[0], &buf[strlen(buf)]);
+    if(p.first == p.second) {
       continue;
     }
+    std::string line(p.first, p.second);
     std::vector<std::string> items;
     util::split(line, std::back_inserter(items), ",");
     std::map<std::string, std::string> m;

+ 1 - 1
src/Sqlite3CookieParser.cc

@@ -108,7 +108,7 @@ int cookieRowMapper(void* data, int columns, char** values, char** names)
   std::string cookieName = toString(values[4]);
   std::string cookiePath = toString(values[1]);
   if(cookieName.empty() || cookieDomain.empty() ||
-     !cookie::goodPath(cookiePath)) {
+     !cookie::goodPath(cookiePath.begin(), cookiePath.end())) {
     return 0;
   }
   int64_t expiryTime;

+ 39 - 25
src/cookie_helper.cc

@@ -65,13 +65,16 @@ std::string::const_iterator getNextDigit
 }
 } // namespace
 
-bool parseDate(time_t& time, const std::string& cookieDate)
+bool parseDate
+(time_t& time,
+ std::string::const_iterator first,
+ std::string::const_iterator last)
 {
   // Following algorithm is described in
   // http://tools.ietf.org/html/rfc6265#section-5.1.1
   std::vector<std::string> dateTokens;
-  for(std::string::const_iterator i = cookieDate.begin(),
-        eoi = cookieDate.end(); i != eoi;) {
+  for(std::string::const_iterator i = first,
+        eoi = last; i != eoi;) {
     unsigned char c = *i;
     if(isDelimiter(c)) {
       ++i;
@@ -210,12 +213,16 @@ bool parse
   if(eq == nvEnd) {
     return false;
   }
-  std::string cookieName = util::stripIter(cookieStr.begin(), eq);
-  if(cookieName.empty()) {
+  std::pair<std::string::const_iterator,
+            std::string::const_iterator> p =
+    util::stripIter(cookieStr.begin(), eq);
+  if(p.first == p.second) {
     return false;
   }
-  std::string cookieValue = util::stripIter(eq+1, nvEnd);
-  cookieValue = util::strip(cookieValue, "\"");
+  std::string cookieName(p.first, p.second);
+  p = util::stripIter(eq+1, nvEnd);
+  p = util::stripIter(p.first, p.second, "\"");
+  std::string cookieValue(p.first, p.second);
   time_t expiryTime = 0;
   bool foundExpires = false;
   bool persistent = false;
@@ -233,36 +240,41 @@ bool parse
   for(std::string::const_iterator i = nvEnd; i != end;) {
     std::string::const_iterator j = std::find(i, end, ';');
     std::string::const_iterator eq = std::find(i, j, '=');
-    std::string attrName = util::stripIter(i, eq);
+    p = util::stripIter(i, eq);
+    std::string attrName(p.first, p.second);
     util::lowercase(attrName);
-    std::string attrValue;
-    if(eq != j) {
-      attrValue = util::stripIter(eq+1, j);
+    std::pair<std::string::const_iterator,
+              std::string::const_iterator> attrp;
+    if(eq == j) {
+      attrp.first = attrp.second = j;
+    } else {
+      attrp = util::stripIter(eq+1, j);
     }
     i = j;
     if(j != end) {
       ++i;
     }
     if(attrName == "expires") {
-      if(parseDate(expiryTime, attrValue)) {
+      if(parseDate(expiryTime, attrp.first, attrp.second)) {
         foundExpires = true;
       } else {
         return false;
       }
     } else if(attrName == "max-age") {
-      if(attrValue.empty() ||
-         (!in(static_cast<unsigned char>(attrValue[0]), 0x30u, 0x39u) &&
-          attrValue[0] != '-')) {
+      if(attrp.first == attrp.second ||
+         (!in(static_cast<unsigned char>(*attrp.first), 0x30u, 0x39u) &&
+          *attrp.first != '-')) {
         return false;
       }
-      for(std::string::const_iterator s = attrValue.begin()+1,
-            eos = attrValue.end(); s != eos; ++s) {
+      for(std::string::const_iterator s = attrp.first+1,
+            eos = attrp.second; s != eos; ++s) {
         if(!in(static_cast<unsigned char>(*s), 0x30u, 0x39u)) {
           return false;
         }
       }
       int64_t delta;
-      if(util::parseLLIntNoThrow(delta, attrValue)) {
+      if(util::parseLLIntNoThrow(delta,
+                                 std::string(attrp.first, attrp.second))) {
         foundMaxAge = true;
         if(delta <= 0) {
           maxAge = 0;
@@ -279,19 +291,19 @@ bool parse
         return false;
       }
     } else if(attrName == "domain") {
-      if(attrValue.empty()) {
+      if(attrp.first == attrp.second) {
         return false;
       }
-      std::string::const_iterator noDot = attrValue.begin();
-      std::string::const_iterator end = attrValue.end();
+      std::string::const_iterator noDot = attrp.first;
+      std::string::const_iterator end = attrp.second;
       for(; noDot != end && *noDot == '.'; ++noDot);
       if(noDot == end) {
         return false;
       }
       cookieDomain = std::string(noDot, end);
     } else if(attrName == "path") {
-      if(goodPath(attrValue)) {
-        cookiePath = attrValue;
+      if(goodPath(attrp.first, attrp.second)) {
+        cookiePath.assign(attrp.first, attrp.second);
       } else {
         cookiePath = defaultPath;
       }
@@ -349,9 +361,11 @@ std::string removePrecedingDots(const std::string& host)
   return std::string(noDot, end);
 }
 
-bool goodPath(const std::string& cookiePath)
+bool goodPath
+(std::string::const_iterator first,
+ std::string::const_iterator last)
 {
-  return !cookiePath.empty() && cookiePath[0] == '/';
+  return first != last && *first == '/';
 }
 
 std::string canonicalizeHost(const std::string& host)

+ 7 - 2
src/cookie_helper.h

@@ -47,7 +47,10 @@ class Cookie;
 
 namespace cookie {
 
-bool parseDate(time_t& time, const std::string& cookieDate);
+bool parseDate
+(time_t& time,
+ std::string::const_iterator first,
+ std::string::const_iterator last);
 
 bool parse
 (Cookie& cookie,
@@ -58,7 +61,9 @@ bool parse
 
 std::string removePrecedingDots(const std::string& host);
 
-bool goodPath(const std::string& cookiePath);
+bool goodPath
+(std::string::const_iterator first,
+ std::string::const_iterator last);
 
 std::string canonicalizeHost(const std::string& host);
 

+ 9 - 3
src/util.cc

@@ -190,7 +190,10 @@ const std::string DEFAULT_STRIP_CHARSET("\r\n\t ");
 
 std::string strip(const std::string& str, const std::string& chars)
 {
-  return stripIter(str.begin(), str.end(), chars);
+  std::pair<std::string::const_iterator,
+            std::string::const_iterator> p =
+    stripIter(str.begin(), str.end(), chars);
+  return std::string(p.first, p.second);
 }
 
 void divide
@@ -203,8 +206,11 @@ void divide
     hp.first = strip(src);
     hp.second = A2STR::NIL;
   } else {
-    hp.first = stripIter(first, dpos);
-    hp.second = stripIter(dpos+1, last);
+    std::pair<std::string::const_iterator,
+              std::string::const_iterator> p = stripIter(first, dpos);
+    hp.first.assign(p.first, p.second);
+    p = stripIter(dpos+1, last);
+    hp.second.assign(p.first, p.second);
   }
 }
 

+ 20 - 16
src/util.h

@@ -142,22 +142,19 @@ int32_t difftvsec(struct timeval tv1, struct timeval tv2);
 extern const std::string DEFAULT_STRIP_CHARSET;
 
 template<typename InputIterator>
-std::string stripIter
+std::pair<InputIterator, InputIterator> stripIter
 (InputIterator first, InputIterator last,
  const std::string& chars = DEFAULT_STRIP_CHARSET)
 {
-  if(std::distance(first, last) == 0) {
-    return A2STR::NIL;
-  }
   for(; first != last &&
         std::find(chars.begin(), chars.end(), *first) != chars.end(); ++first);
   if(first == last) {
-    return A2STR::NIL;
+    return std::make_pair(first, last);
   }
   InputIterator left = last-1;
   for(; left != first &&
         std::find(chars.begin(), chars.end(), *left) != chars.end(); --left);
-  return std::string(first, left+1);
+  return std::make_pair(first, left+1);
 }
 
 std::string strip
@@ -367,9 +364,13 @@ OutputIterator split(const std::string& src, OutputIterator out,
     std::string::const_iterator j = i;
     for(; j != last &&
           std::find(delims.begin(), delims.end(), *j) == delims.end(); ++j);
-    std::string t = doStrip?util::stripIter(i, j):std::string(i, j);
-    if(allowEmpty || !t.empty()) {
-      *out++ = t;
+    std::pair<std::string::const_iterator,
+              std::string::const_iterator> p(i, j);
+    if(doStrip) {
+      p = stripIter(i, j);
+    }
+    if(allowEmpty || p.first != p.second) {
+      *out++ = std::string(p.first, p.second);
     }
     i = j;
     if(j != last) {
@@ -489,24 +490,27 @@ nextParam
         parmnameLast = last;
       }
     }
-    std::string tname, tvalue;
+    std::pair<std::string::const_iterator,
+              std::string::const_iterator> namep;
+    std::pair<std::string::const_iterator,
+              std::string::const_iterator> valuep;
     if(parmnameFirst == parmnameLast) {
       if(!eqFound) {
         parmnameFirst = first;
         parmnameLast = last;
-        tname = util::stripIter(parmnameFirst, parmnameLast);
+        namep = stripIter(parmnameFirst, parmnameLast);
       }
     } else {
       first = parmnameLast+1;
-      tname = util::stripIter(parmnameFirst, parmnameLast);
-      tvalue = util::stripIter(first, last);
+      namep = stripIter(parmnameFirst, parmnameLast);
+      valuep = stripIter(first, last);
     }
     if(last != end) {
       ++last;
     }
-    if(!tname.empty()) {
-      name.swap(tname);
-      value.swap(tvalue);
+    if(namep.first != namep.second) {
+      name.assign(namep.first, namep.second);
+      value.assign(valuep.first, valuep.second);
       return std::make_pair(last, true);
     }
     first = last;

+ 18 - 10
test/CookieHelperTest.cc

@@ -34,25 +34,33 @@ void CookieHelperTest::testParseDate()
 {
   // RFC1123
   time_t time = 0;
-  CPPUNIT_ASSERT(cookie::parseDate(time, "Sat, 06 Sep 2008 15:26:33 GMT"));
+  std::string s = "Sat, 06 Sep 2008 15:26:33 GMT";
+  CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time);
   // RFC850
-  CPPUNIT_ASSERT(cookie::parseDate(time, "Saturday, 06-Sep-08 15:26:33 GMT"));
+  s = "Saturday, 06-Sep-08 15:26:33 GMT";
+  CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time);
   // ANSI C's asctime()
-  CPPUNIT_ASSERT(cookie::parseDate(time, "Sun Sep  6 15:26:33 2008"));
+  s = "Sun Sep  6 15:26:33 2008";
+  CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((time_t)1220714793, time);
-
-  CPPUNIT_ASSERT(cookie::parseDate(time, "Thu Jan 1 0:0:0 1970"));
+  s = "Thu Jan 1 0:0:0 1970";
+  CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end()));
   CPPUNIT_ASSERT_EQUAL((time_t)0, time);
 
-  CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:")); 
-  CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:0")); 
-  CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu Jan 1 1970 0:0:")); 
+  s = "Thu Jan 1 1970 0:";
+  CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end()));
+  s = "Thu Jan 1 1970 0:0";
+  CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end()));
+  s = "Thu Jan 1 1970 0:0:";
+  CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end()));
 
   // Leap year
-  CPPUNIT_ASSERT(cookie::parseDate(time, "Tue, 29 Feb 2000 00:00:00 GMT"));
-  CPPUNIT_ASSERT(!cookie::parseDate(time, "Thu, 29 Feb 2001 00:00:00 GMT"));
+  s = "Tue, 29 Feb 2000 00:00:00 GMT";
+  CPPUNIT_ASSERT(cookie::parseDate(time, s.begin(), s.end()));
+  s = "Thu, 29 Feb 2001 00:00:00 GMT";
+  CPPUNIT_ASSERT(!cookie::parseDate(time, s.begin(), s.end()));
 }
 
 void CookieHelperTest::testDomainMatch()