瀏覽代碼

HttpHeader::fill() now stores header name in lowercase.

Find methods in HttpHeader won't lowercase argument, so use lowercase
letters to get HTTP header field.
Tatsuhiro Tsujikawa 14 年之前
父節點
當前提交
d17ea2837b
共有 10 個文件被更改,包括 238 次插入209 次删除
  1. 71 56
      src/HttpHeader.cc
  2. 21 48
      src/HttpHeader.h
  3. 27 18
      src/HttpResponse.cc
  4. 7 6
      src/HttpServer.cc
  5. 4 2
      src/LpdMessageReceiver.cc
  6. 10 0
      src/util.h
  7. 6 5
      test/HttpHeaderProcessorTest.cc
  8. 21 21
      test/HttpHeaderTest.cc
  9. 53 53
      test/HttpResponseTest.cc
  10. 18 0
      test/UtilTest.cc

+ 71 - 56
src/HttpHeader.cc

@@ -39,56 +39,48 @@
 
 
 namespace aria2 {
 namespace aria2 {
 
 
-const std::string HttpHeader::LOCATION("Location");
+const std::string HttpHeader::LOCATION("location");
+const std::string HttpHeader::TRANSFER_ENCODING("transfer-encoding");
+const std::string HttpHeader::CONTENT_ENCODING("content-encoding");
+const std::string HttpHeader::CONTENT_DISPOSITION("content-disposition");
+const std::string HttpHeader::SET_COOKIE("set-cookie");
+const std::string HttpHeader::CONTENT_TYPE("content-type");
+const std::string HttpHeader::RETRY_AFTER("retry-after");
+const std::string HttpHeader::CONNECTION("connection");
+const std::string HttpHeader::CONTENT_LENGTH("content-length");
+const std::string HttpHeader::CONTENT_RANGE("content-range");
+const std::string HttpHeader::LAST_MODIFIED("last-modified");
+const std::string HttpHeader::ACCEPT_ENCODING("accept-encoding");
+const std::string HttpHeader::LINK("link");
+const std::string HttpHeader::DIGEST("digest");
+const std::string HttpHeader::PROXY_CONNECTION("proxy-connection");
+const std::string HttpHeader::AUTHORIZATION("authorization");
 
 
-const std::string HttpHeader::TRANSFER_ENCODING("Transfer-Encoding");
-
-const std::string HttpHeader::CONTENT_ENCODING("Content-Encoding");
-
-const std::string HttpHeader::CONTENT_DISPOSITION("Content-Disposition");
-
-const std::string HttpHeader::SET_COOKIE("Set-Cookie");
-
-const std::string HttpHeader::CONTENT_TYPE("Content-Type");
-
-const std::string HttpHeader::RETRY_AFTER("Retry-After");
-
-const std::string HttpHeader::CONNECTION("Connection");
-
-const std::string HttpHeader::CONTENT_LENGTH("Content-Length");
-
-const std::string HttpHeader::CONTENT_RANGE("Content-Range");
-
-const std::string HttpHeader::LAST_MODIFIED("Last-Modified");
-
-const std::string HttpHeader::ACCEPT_ENCODING("Accept-Encoding");
-
-const std::string HttpHeader::LINK("Link");
-
-const std::string HttpHeader::DIGEST("Digest");
-
-const char HttpHeader::HTTP_1_1[] = "HTTP/1.1";
-const char HttpHeader::CLOSE[] = "close";
-const char HttpHeader::CHUNKED[] = "chunked";
-const char HttpHeader::GZIP[] = "gzip";
-const char HttpHeader::DEFLATE[] = "deflate";
+const std::string HttpHeader::HTTP_1_1 = "HTTP/1.1";
+const std::string HttpHeader::CLOSE = "close";
+const std::string HttpHeader::KEEP_ALIVE = "keep-alive";
+const std::string HttpHeader::CHUNKED = "chunked";
+const std::string HttpHeader::GZIP = "gzip";
+const std::string HttpHeader::DEFLATE = "deflate";
 
 
 HttpHeader::HttpHeader() {}
 HttpHeader::HttpHeader() {}
 HttpHeader::~HttpHeader() {}
 HttpHeader::~HttpHeader() {}
 
 
-void HttpHeader::put(const std::string& name, const std::string& value) {
-  std::multimap<std::string, std::string>::value_type vt
-    (util::toLower(name), value);
+void HttpHeader::put(const std::string& name, const std::string& value)
+{
+  std::multimap<std::string, std::string>::value_type vt(name, value);
   table_.insert(vt);
   table_.insert(vt);
 }
 }
 
 
-bool HttpHeader::defined(const std::string& name) const {
-  return table_.count(util::toLower(name)) >= 1;
+bool HttpHeader::defined(const std::string& name) const
+{
+  return table_.count(name);
 }
 }
 
 
-const std::string& HttpHeader::getFirst(const std::string& name) const {
+const std::string& HttpHeader::find(const std::string& name) const
+{
   std::multimap<std::string, std::string>::const_iterator itr =
   std::multimap<std::string, std::string>::const_iterator itr =
-    table_.find(util::toLower(name));
+    table_.find(name);
   if(itr == table_.end()) {
   if(itr == table_.end()) {
     return A2STR::NIL;
     return A2STR::NIL;
   } else {
   } else {
@@ -96,35 +88,32 @@ const std::string& HttpHeader::getFirst(const std::string& name) const {
   }
   }
 }
 }
 
 
-std::vector<std::string> HttpHeader::get(const std::string& name) const
+std::vector<std::string> HttpHeader::findAll(const std::string& name) const
 {
 {
   std::vector<std::string> v;
   std::vector<std::string> v;
-  std::string n(util::toLower(name));
   std::pair<std::multimap<std::string, std::string>::const_iterator,
   std::pair<std::multimap<std::string, std::string>::const_iterator,
-    std::multimap<std::string, std::string>::const_iterator> itrpair =
-    table_.equal_range(n);
-  std::multimap<std::string, std::string>::const_iterator first = itrpair.first;
-  while(first != itrpair.second) {
-    v.push_back((*first).second);
-    ++first;
+            std::multimap<std::string, std::string>::const_iterator> itrpair =
+    table_.equal_range(name);
+  while(itrpair.first != itrpair.second) {
+    v.push_back((*itrpair.first).second);
+    ++itrpair.first;
   }
   }
   return v;
   return v;
 }
 }
 
 
 std::pair<std::multimap<std::string, std::string>::const_iterator,
 std::pair<std::multimap<std::string, std::string>::const_iterator,
           std::multimap<std::string, std::string>::const_iterator>
           std::multimap<std::string, std::string>::const_iterator>
-HttpHeader::getIterator(const std::string& name) const
+HttpHeader::equalRange(const std::string& name) const
 {
 {
-  std::string n(util::toLower(name));
-  return table_.equal_range(n);
+  return table_.equal_range(name);
 }
 }
 
 
-unsigned int HttpHeader::getFirstAsUInt(const std::string& name) const {
-  return getFirstAsULLInt(name);
+unsigned int HttpHeader::findAsUInt(const std::string& name) const {
+  return findAsULLInt(name);
 }
 }
 
 
-uint64_t HttpHeader::getFirstAsULLInt(const std::string& name) const {
-  const std::string& value = getFirst(name);
+uint64_t HttpHeader::findAsULLInt(const std::string& name) const {
+  const std::string& value = find(name);
   if(value.empty()) {
   if(value.empty()) {
     return 0;
     return 0;
   } else {
   } else {
@@ -134,9 +123,9 @@ uint64_t HttpHeader::getFirstAsULLInt(const std::string& name) const {
 
 
 RangeHandle HttpHeader::getRange() const
 RangeHandle HttpHeader::getRange() const
 {
 {
-  const std::string& rangeStr = getFirst(CONTENT_RANGE);
+  const std::string& rangeStr = find(CONTENT_RANGE);
   if(rangeStr.empty()) {
   if(rangeStr.empty()) {
-    const std::string& clenStr = getFirst(CONTENT_LENGTH);
+    const std::string& clenStr = find(CONTENT_LENGTH);
     if(clenStr.empty()) {
     if(clenStr.empty()) {
       return SharedHandle<Range>(new Range());
       return SharedHandle<Range>(new Range());
     } else {
     } else {
@@ -231,6 +220,7 @@ void HttpHeader::fill
         std::pair<std::string::const_iterator,
         std::pair<std::string::const_iterator,
                   std::string::const_iterator> p = util::stripIter(first, sep);
                   std::string::const_iterator> p = util::stripIter(first, sep);
         name.assign(p.first, p.second);
         name.assign(p.first, p.second);
+        util::lowercase(name);
         p = util::stripIter(sep+1, j);
         p = util::stripIter(sep+1, j);
         value.assign(p.first, p.second);
         value.assign(p.first, p.second);
       }
       }
@@ -250,4 +240,29 @@ void HttpHeader::clearField()
   table_.clear();
   table_.clear();
 }
 }
 
 
+int HttpHeader::getStatusCode() const
+{
+  return statusCode_;
+}
+
+void HttpHeader::setStatusCode(int code)
+{
+  statusCode_ = code;
+}
+
+const std::string& HttpHeader::getVersion() const
+{
+  return version_;
+}
+
+const std::string& HttpHeader::getMethod() const
+{
+  return method_;
+}
+
+const std::string& HttpHeader::getRequestPath() const
+{
+  return requestPath_;
+}
+
 } // namespace aria2
 } // namespace aria2

+ 21 - 48
src/HttpHeader.h

@@ -68,30 +68,21 @@ public:
 
 
   void put(const std::string& name, const std::string& value);
   void put(const std::string& name, const std::string& value);
   bool defined(const std::string& name) const;
   bool defined(const std::string& name) const;
-  const std::string& getFirst(const std::string& name) const;
-  std::vector<std::string> get(const std::string& name) const;
+  const std::string& find(const std::string& name) const;
+  std::vector<std::string> findAll(const std::string& name) const;
   std::pair<std::multimap<std::string, std::string>::const_iterator,
   std::pair<std::multimap<std::string, std::string>::const_iterator,
             std::multimap<std::string, std::string>::const_iterator>
             std::multimap<std::string, std::string>::const_iterator>
-  getIterator(const std::string& name) const;
-  unsigned int getFirstAsUInt(const std::string& name) const;
-  uint64_t getFirstAsULLInt(const std::string& name) const;
+  equalRange(const std::string& name) const;
+  unsigned int findAsUInt(const std::string& name) const;
+  uint64_t findAsULLInt(const std::string& name) const;
 
 
   SharedHandle<Range> getRange() const;
   SharedHandle<Range> getRange() const;
 
 
-  int getStatusCode() const
-  {
-    return statusCode_;
-  }
+  int getStatusCode() const;
 
 
-  void setStatusCode(int code)
-  {
-    statusCode_ = code;
-  }
+  void setStatusCode(int code);
 
 
-  const std::string& getVersion() const
-  {
-    return version_;
-  }
+  const std::string& getVersion() const;
 
 
   void setVersion(const std::string& version);
   void setVersion(const std::string& version);
 
 
@@ -101,10 +92,7 @@ public:
     version_.assign(first, last);
     version_.assign(first, last);
   }
   }
 
 
-  const std::string& getMethod() const
-  {
-    return method_;
-  }
+  const std::string& getMethod() const;
 
 
   void setMethod(const std::string& method);
   void setMethod(const std::string& method);
 
 
@@ -114,10 +102,7 @@ public:
     method_.assign(first, last);
     method_.assign(first, last);
   }
   }
 
 
-  const std::string& getRequestPath() const
-  {
-    return requestPath_;
-  }
+  const std::string& getRequestPath() const;
 
 
   void setRequestPath(const std::string& requestPath);
   void setRequestPath(const std::string& requestPath);
 
 
@@ -127,6 +112,8 @@ public:
     requestPath_.assign(first, last);
     requestPath_.assign(first, last);
   }
   }
 
 
+  // Parses header fields in [first, last). Field name is stored in
+  // lowercase.
   void fill
   void fill
   (std::string::const_iterator first,
   (std::string::const_iterator first,
    std::string::const_iterator last);
    std::string::const_iterator last);
@@ -135,42 +122,28 @@ public:
   void clearField();
   void clearField();
 
 
   static const std::string LOCATION;
   static const std::string LOCATION;
-
   static const std::string TRANSFER_ENCODING;
   static const std::string TRANSFER_ENCODING;
-  
   static const std::string CONTENT_ENCODING;
   static const std::string CONTENT_ENCODING;
-
   static const std::string CONTENT_DISPOSITION;
   static const std::string CONTENT_DISPOSITION;
-  
   static const std::string SET_COOKIE;
   static const std::string SET_COOKIE;
-  
   static const std::string CONTENT_TYPE;
   static const std::string CONTENT_TYPE;
-  
   static const std::string RETRY_AFTER;
   static const std::string RETRY_AFTER;
-  
   static const std::string CONNECTION;
   static const std::string CONNECTION;
-
   static const std::string CONTENT_LENGTH;
   static const std::string CONTENT_LENGTH;
-
   static const std::string CONTENT_RANGE;
   static const std::string CONTENT_RANGE;
-
   static const std::string LAST_MODIFIED;
   static const std::string LAST_MODIFIED;
-
   static const std::string ACCEPT_ENCODING;
   static const std::string ACCEPT_ENCODING;
-
   static const std::string LINK;
   static const std::string LINK;
-
   static const std::string DIGEST;
   static const std::string DIGEST;
-
-  static const char HTTP_1_1[];
-
-  static const char CLOSE[];
-
-  static const char CHUNKED[];
-  
-  static const char GZIP[];
-
-  static const char DEFLATE[];
+  static const std::string AUTHORIZATION;
+  static const std::string PROXY_CONNECTION;
+
+  static const std::string HTTP_1_1;
+  static const std::string CLOSE;
+  static const std::string KEEP_ALIVE;
+  static const std::string CHUNKED;
+  static const std::string GZIP;
+  static const std::string DEFLATE;
 };
 };
 
 
 typedef SharedHandle<HttpHeader> HttpHeaderHandle;
 typedef SharedHandle<HttpHeader> HttpHeaderHandle;

+ 27 - 18
src/HttpResponse.cc

@@ -57,6 +57,7 @@
 #include "uri.h"
 #include "uri.h"
 #include "MetalinkHttpEntry.h"
 #include "MetalinkHttpEntry.h"
 #include "base64.h"
 #include "base64.h"
+#include "array_fun.h"
 #ifdef ENABLE_MESSAGE_DIGEST
 #ifdef ENABLE_MESSAGE_DIGEST
 #include "MessageDigest.h"
 #include "MessageDigest.h"
 #endif // ENABLE_MESSAGE_DIGEST
 #endif // ENABLE_MESSAGE_DIGEST
@@ -118,7 +119,7 @@ std::string HttpResponse::determinFilename() const
 {
 {
   std::string contentDisposition =
   std::string contentDisposition =
     util::getContentDispositionFilename
     util::getContentDispositionFilename
-    (httpHeader_->getFirst(HttpHeader::CONTENT_DISPOSITION));
+    (httpHeader_->find(HttpHeader::CONTENT_DISPOSITION));
   if(contentDisposition.empty()) {
   if(contentDisposition.empty()) {
     std::string file =
     std::string file =
       util::percentDecode(httpRequest_->getFile().begin(),
       util::percentDecode(httpRequest_->getFile().begin(),
@@ -141,7 +142,7 @@ void HttpResponse::retrieveCookie()
   Time now;
   Time now;
   std::pair<std::multimap<std::string, std::string>::const_iterator,
   std::pair<std::multimap<std::string, std::string>::const_iterator,
             std::multimap<std::string, std::string>::const_iterator> r =
             std::multimap<std::string, std::string>::const_iterator> r =
-    httpHeader_->getIterator(HttpHeader::SET_COOKIE);
+    httpHeader_->equalRange(HttpHeader::SET_COOKIE);
   for(; r.first != r.second; ++r.first) {
   for(; r.first != r.second; ++r.first) {
     httpRequest_->getCookieStorage()->parseAndStore
     httpRequest_->getCookieStorage()->parseAndStore
       ((*r.first).second, httpRequest_->getHost(), httpRequest_->getDir(),
       ((*r.first).second, httpRequest_->getHost(), httpRequest_->getDir(),
@@ -177,7 +178,7 @@ void HttpResponse::processRedirect()
 
 
 const std::string& HttpResponse::getRedirectURI() const
 const std::string& HttpResponse::getRedirectURI() const
 {
 {
-  return httpHeader_->getFirst(HttpHeader::LOCATION);
+  return httpHeader_->find(HttpHeader::LOCATION);
 }
 }
 
 
 bool HttpResponse::isTransferEncodingSpecified() const
 bool HttpResponse::isTransferEncodingSpecified() const
@@ -188,7 +189,7 @@ bool HttpResponse::isTransferEncodingSpecified() const
 const std::string& HttpResponse::getTransferEncoding() const
 const std::string& HttpResponse::getTransferEncoding() const
 {
 {
   // TODO See TODO in getTransferEncodingStreamFilter()
   // TODO See TODO in getTransferEncodingStreamFilter()
-  return httpHeader_->getFirst(HttpHeader::TRANSFER_ENCODING);
+  return httpHeader_->find(HttpHeader::TRANSFER_ENCODING);
 }
 }
 
 
 SharedHandle<StreamFilter> HttpResponse::getTransferEncodingStreamFilter() const
 SharedHandle<StreamFilter> HttpResponse::getTransferEncodingStreamFilter() const
@@ -211,7 +212,7 @@ bool HttpResponse::isContentEncodingSpecified() const
 
 
 const std::string& HttpResponse::getContentEncoding() const
 const std::string& HttpResponse::getContentEncoding() const
 {
 {
-  return httpHeader_->getFirst(HttpHeader::CONTENT_ENCODING);
+  return httpHeader_->find(HttpHeader::CONTENT_ENCODING);
 }
 }
 
 
 SharedHandle<StreamFilter> HttpResponse::getContentEncodingStreamFilter() const
 SharedHandle<StreamFilter> HttpResponse::getContentEncodingStreamFilter() const
@@ -249,7 +250,7 @@ std::string HttpResponse::getContentType() const
   if(!httpHeader_) {
   if(!httpHeader_) {
     return A2STR::NIL;
     return A2STR::NIL;
   } else {
   } else {
-    const std::string& ctype = httpHeader_->getFirst(HttpHeader::CONTENT_TYPE);
+    const std::string& ctype = httpHeader_->find(HttpHeader::CONTENT_TYPE);
     std::string::const_iterator i = std::find(ctype.begin(), ctype.end(), ';');
     std::string::const_iterator i = std::find(ctype.begin(), ctype.end(), ';');
     Scip p = util::stripIter(ctype.begin(), i);
     Scip p = util::stripIter(ctype.begin(), i);
     return std::string(p.first, p.second);
     return std::string(p.first, p.second);
@@ -278,27 +279,35 @@ bool HttpResponse::hasRetryAfter() const
 
 
 time_t HttpResponse::getRetryAfter() const
 time_t HttpResponse::getRetryAfter() const
 {
 {
-  return httpHeader_->getFirstAsUInt(HttpHeader::RETRY_AFTER);
+  return httpHeader_->findAsUInt(HttpHeader::RETRY_AFTER);
 }
 }
 
 
 Time HttpResponse::getLastModifiedTime() const
 Time HttpResponse::getLastModifiedTime() const
 {
 {
-  return Time::parseHTTPDate(httpHeader_->getFirst(HttpHeader::LAST_MODIFIED));
+  return Time::parseHTTPDate(httpHeader_->find(HttpHeader::LAST_MODIFIED));
 }
 }
 
 
 bool HttpResponse::supportsPersistentConnection() const
 bool HttpResponse::supportsPersistentConnection() const
 {
 {
-  std::string connection =
-    util::toLower(httpHeader_->getFirst(HttpHeader::CONNECTION));
-  std::string version = httpHeader_->getVersion();
-
+  const std::string& connection = httpHeader_->find(HttpHeader::CONNECTION);
+  const std::string& version = httpHeader_->getVersion();
+  const std::string& proxyConn =
+    httpHeader_->find(HttpHeader::PROXY_CONNECTION);
   return
   return
-    connection.find(HttpHeader::CLOSE) == std::string::npos &&
+    util::strifind(connection.begin(),
+                   connection.end(),
+                   HttpHeader::CLOSE.begin(),
+                   HttpHeader::CLOSE.end()) == connection.end() &&
     (version == HttpHeader::HTTP_1_1 ||
     (version == HttpHeader::HTTP_1_1 ||
-     connection.find("keep-alive") != std::string::npos) &&
+     util::strifind(connection.begin(),
+                    connection.end(),
+                    HttpHeader::KEEP_ALIVE.begin(),
+                    HttpHeader::KEEP_ALIVE.end()) != connection.end()) &&
     (!httpRequest_->isProxyRequestSet() ||
     (!httpRequest_->isProxyRequestSet() ||
-     util::toLower(httpHeader_->getFirst("Proxy-Connection")).find("keep-alive")
-     != std::string::npos);
+     util::strifind(proxyConn.begin(),
+                    proxyConn.end(),
+                    HttpHeader::KEEP_ALIVE.begin(),
+                    HttpHeader::KEEP_ALIVE.end()) != proxyConn.end());
 }
 }
 
 
 namespace {
 namespace {
@@ -368,7 +377,7 @@ void HttpResponse::getMetalinKHttpEntries
 {
 {
   std::pair<std::multimap<std::string, std::string>::const_iterator,
   std::pair<std::multimap<std::string, std::string>::const_iterator,
             std::multimap<std::string, std::string>::const_iterator> p =
             std::multimap<std::string, std::string>::const_iterator> p =
-    httpHeader_->getIterator(HttpHeader::LINK);
+    httpHeader_->equalRange(HttpHeader::LINK);
   for(; p.first != p.second; ++p.first) {
   for(; p.first != p.second; ++p.first) {
     MetalinkHttpEntry e;
     MetalinkHttpEntry e;
     if(parseMetalinkHttpLink(e, (*p.first).second)) {
     if(parseMetalinkHttpLink(e, (*p.first).second)) {
@@ -403,7 +412,7 @@ void HttpResponse::getDigest(std::vector<Checksum>& result) const
   using std::swap;
   using std::swap;
   std::pair<std::multimap<std::string, std::string>::const_iterator,
   std::pair<std::multimap<std::string, std::string>::const_iterator,
             std::multimap<std::string, std::string>::const_iterator> p =
             std::multimap<std::string, std::string>::const_iterator> p =
-    httpHeader_->getIterator(HttpHeader::DIGEST);
+    httpHeader_->equalRange(HttpHeader::DIGEST);
   for(; p.first != p.second; ++p.first) {
   for(; p.first != p.second; ++p.first) {
     const std::string& s = (*p.first).second;
     const std::string& s = (*p.first).second;
     std::string::const_iterator itr = s.begin();
     std::string::const_iterator itr = s.begin();

+ 7 - 6
src/HttpServer.cc

@@ -90,11 +90,11 @@ SharedHandle<HttpHeader> HttpServer::receiveRequest()
     lastBody_.clear();
     lastBody_.clear();
     lastBody_.str("");
     lastBody_.str("");
     lastContentLength_ =
     lastContentLength_ =
-      lastRequestHeader_->getFirstAsUInt(HttpHeader::CONTENT_LENGTH);
+      lastRequestHeader_->findAsUInt(HttpHeader::CONTENT_LENGTH);
     headerProcessor_->clear();
     headerProcessor_->clear();
 
 
     std::string connection =
     std::string connection =
-      util::toLower(lastRequestHeader_->getFirst(HttpHeader::CONNECTION));
+      util::toLower(lastRequestHeader_->find(HttpHeader::CONNECTION));
     acceptsPersistentConnection_ =
     acceptsPersistentConnection_ =
       connection.find(HttpHeader::CLOSE) == std::string::npos &&
       connection.find(HttpHeader::CLOSE) == std::string::npos &&
       (lastRequestHeader_->getVersion() == HttpHeader::HTTP_1_1 ||
       (lastRequestHeader_->getVersion() == HttpHeader::HTTP_1_1 ||
@@ -102,14 +102,14 @@ SharedHandle<HttpHeader> HttpServer::receiveRequest()
 
 
     std::vector<Scip> acceptEncodings;
     std::vector<Scip> acceptEncodings;
     const std::string& acceptEnc =
     const std::string& acceptEnc =
-      lastRequestHeader_->getFirst(HttpHeader::ACCEPT_ENCODING);
+      lastRequestHeader_->find(HttpHeader::ACCEPT_ENCODING);
     util::splitIter(acceptEnc.begin(), acceptEnc.end(),
     util::splitIter(acceptEnc.begin(), acceptEnc.end(),
                     std::back_inserter(acceptEncodings), ',', true);
                     std::back_inserter(acceptEncodings), ',', true);
-    const char A2_GZIP[] = "gzip";
     acceptsGZip_ = false;
     acceptsGZip_ = false;
     for(std::vector<Scip>::const_iterator i = acceptEncodings.begin(),
     for(std::vector<Scip>::const_iterator i = acceptEncodings.begin(),
           eoi = acceptEncodings.end(); i != eoi; ++i) {
           eoi = acceptEncodings.end(); i != eoi; ++i) {
-      if(util::streq((*i).first, (*i).second, A2_GZIP, vend(A2_GZIP)-1)) {
+      if(util::strieq((*i).first, (*i).second,
+                      HttpHeader::GZIP.begin(), HttpHeader::GZIP.end())) {
         acceptsGZip_ = true;
         acceptsGZip_ = true;
         break;
         break;
       }
       }
@@ -214,7 +214,8 @@ bool HttpServer::authenticate()
     return true;
     return true;
   }
   }
 
 
-  const std::string& authHeader = lastRequestHeader_->getFirst("Authorization");
+  const std::string& authHeader =
+    lastRequestHeader_->find(HttpHeader::AUTHORIZATION);
   if(authHeader.empty()) {
   if(authHeader.empty()) {
     return false;
     return false;
   }
   }

+ 4 - 2
src/LpdMessageReceiver.cc

@@ -94,8 +94,10 @@ SharedHandle<LpdMessage> LpdMessageReceiver::receiveMessage()
       return msg;
       return msg;
     }
     }
     SharedHandle<HttpHeader> header = proc.getHttpRequestHeader();
     SharedHandle<HttpHeader> header = proc.getHttpRequestHeader();
-    const std::string& infoHashString = header->getFirst("Infohash");
-    uint16_t port = header->getFirstAsUInt("Port");
+    static const std::string A2_INFOHASH = "infohash";
+    static const std::string A2_PORT = "port";
+    const std::string& infoHashString = header->find(A2_INFOHASH);
+    uint16_t port = header->findAsUInt(A2_PORT);
     A2_LOG_INFO(fmt("LPD message received infohash=%s, port=%u from %s",
     A2_LOG_INFO(fmt("LPD message received infohash=%s, port=%u from %s",
                     infoHashString.c_str(),
                     infoHashString.c_str(),
                     port,
                     port,

+ 10 - 0
src/util.h

@@ -728,6 +728,16 @@ struct CaseCmp {
   }
   }
 };
 };
 
 
+template<typename InputIterator1, typename InputIterator2>
+InputIterator1 strifind
+(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2)
+{
+  return std::search(first1, last1, first2, last2, CaseCmp());
+}
+
 template<typename InputIterator1, typename InputIterator2>
 template<typename InputIterator1, typename InputIterator2>
 bool strieq
 bool strieq
 (InputIterator1 first1,
 (InputIterator1 first1,

+ 6 - 5
test/HttpHeaderProcessorTest.cc

@@ -114,12 +114,13 @@ void HttpHeaderProcessorTest::testGetHttpResponseHeader()
   CPPUNIT_ASSERT_EQUAL(200, header->getStatusCode());
   CPPUNIT_ASSERT_EQUAL(200, header->getStatusCode());
   CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion());
   CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion());
   CPPUNIT_ASSERT_EQUAL(std::string("Mon, 25 Jun 2007 16:04:59 GMT"),
   CPPUNIT_ASSERT_EQUAL(std::string("Mon, 25 Jun 2007 16:04:59 GMT"),
-                       header->getFirst("Date"));
+                       header->find("date"));
   CPPUNIT_ASSERT_EQUAL(std::string("Apache/2.2.3 (Debian)"),
   CPPUNIT_ASSERT_EQUAL(std::string("Apache/2.2.3 (Debian)"),
-                       header->getFirst("Server"));
-  CPPUNIT_ASSERT_EQUAL((uint64_t)9187ULL, header->getFirstAsULLInt("Content-Length"));
+                       header->find("server"));
+  CPPUNIT_ASSERT_EQUAL((uint64_t)9187ULL,
+                       header->findAsULLInt("content-length"));
   CPPUNIT_ASSERT_EQUAL(std::string("text/html; charset=UTF-8"),
   CPPUNIT_ASSERT_EQUAL(std::string("text/html; charset=UTF-8"),
-                       header->getFirst("Content-Type"));
+                       header->find("content-type"));
   CPPUNIT_ASSERT(!header->defined("entity"));
   CPPUNIT_ASSERT(!header->defined("entity"));
 }
 }
 
 
@@ -223,7 +224,7 @@ void HttpHeaderProcessorTest::testGetHttpRequestHeader()
   CPPUNIT_ASSERT_EQUAL(std::string("GET"), httpHeader->getMethod());
   CPPUNIT_ASSERT_EQUAL(std::string("GET"), httpHeader->getMethod());
   CPPUNIT_ASSERT_EQUAL(std::string("/index.html"),httpHeader->getRequestPath());
   CPPUNIT_ASSERT_EQUAL(std::string("/index.html"),httpHeader->getRequestPath());
   CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), httpHeader->getVersion());
   CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), httpHeader->getVersion());
-  CPPUNIT_ASSERT_EQUAL(std::string("close"),httpHeader->getFirst("Connection"));
+  CPPUNIT_ASSERT_EQUAL(std::string("close"),httpHeader->find("connection"));
   CPPUNIT_ASSERT(!httpHeader->defined("entity"));
   CPPUNIT_ASSERT(!httpHeader->defined("entity"));
 }
 }
 
 

+ 21 - 21
test/HttpHeaderTest.cc

@@ -11,14 +11,14 @@ class HttpHeaderTest:public CppUnit::TestFixture {
 
 
   CPPUNIT_TEST_SUITE(HttpHeaderTest);
   CPPUNIT_TEST_SUITE(HttpHeaderTest);
   CPPUNIT_TEST(testGetRange);
   CPPUNIT_TEST(testGetRange);
-  CPPUNIT_TEST(testGet);
+  CPPUNIT_TEST(testFindAll);
   CPPUNIT_TEST(testClearField);
   CPPUNIT_TEST(testClearField);
   CPPUNIT_TEST(testFill);
   CPPUNIT_TEST(testFill);
   CPPUNIT_TEST_SUITE_END();
   CPPUNIT_TEST_SUITE_END();
   
   
 public:
 public:
   void testGetRange();
   void testGetRange();
-  void testGet();
+  void testFindAll();
   void testClearField();
   void testClearField();
   void testFill();
   void testFill();
 };
 };
@@ -30,7 +30,7 @@ void HttpHeaderTest::testGetRange()
 {
 {
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range",
+    httpHeader.put("content-range",
                    "9223372036854775800-9223372036854775801/9223372036854775807");
                    "9223372036854775800-9223372036854775801/9223372036854775807");
     
     
     SharedHandle<Range> range = httpHeader.getRange();
     SharedHandle<Range> range = httpHeader.getRange();
@@ -41,7 +41,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range",
+    httpHeader.put("content-range",
                    "9223372036854775800-9223372036854775801/9223372036854775807");
                    "9223372036854775800-9223372036854775801/9223372036854775807");
      
      
     SharedHandle<Range> range = httpHeader.getRange();
     SharedHandle<Range> range = httpHeader.getRange();
@@ -52,7 +52,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range", "bytes */1024");
+    httpHeader.put("content-range", "bytes */1024");
 
 
     SharedHandle<Range> range = httpHeader.getRange();
     SharedHandle<Range> range = httpHeader.getRange();
 
 
@@ -62,7 +62,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range", "bytes 0-9/*");
+    httpHeader.put("content-range", "bytes 0-9/*");
 
 
     SharedHandle<Range> range = httpHeader.getRange();
     SharedHandle<Range> range = httpHeader.getRange();
 
 
@@ -72,7 +72,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range", "bytes */*");
+    httpHeader.put("content-range", "bytes */*");
 
 
     SharedHandle<Range> range = httpHeader.getRange();
     SharedHandle<Range> range = httpHeader.getRange();
 
 
@@ -82,7 +82,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range", "bytes 0");
+    httpHeader.put("content-range", "bytes 0");
 
 
     SharedHandle<Range> range = httpHeader.getRange();
     SharedHandle<Range> range = httpHeader.getRange();
 
 
@@ -92,7 +92,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range", "bytes 0/");
+    httpHeader.put("content-range", "bytes 0/");
 
 
     SharedHandle<Range> range = httpHeader.getRange();
     SharedHandle<Range> range = httpHeader.getRange();
 
 
@@ -102,7 +102,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range", "bytes 0-/3");
+    httpHeader.put("content-range", "bytes 0-/3");
     try {
     try {
       httpHeader.getRange();
       httpHeader.getRange();
       CPPUNIT_FAIL("Exception must be thrown");
       CPPUNIT_FAIL("Exception must be thrown");
@@ -112,7 +112,7 @@ void HttpHeaderTest::testGetRange()
   }
   }
   {
   {
     HttpHeader httpHeader;
     HttpHeader httpHeader;
-    httpHeader.put("Content-Range", "bytes -0/3");
+    httpHeader.put("content-range", "bytes -0/3");
     try {
     try {
       httpHeader.getRange();
       httpHeader.getRange();
       CPPUNIT_FAIL("Exception must be thrown");
       CPPUNIT_FAIL("Exception must be thrown");
@@ -122,14 +122,14 @@ void HttpHeaderTest::testGetRange()
   }
   }
 }
 }
 
 
-void HttpHeaderTest::testGet()
+void HttpHeaderTest::testFindAll()
 {
 {
   HttpHeader h;
   HttpHeader h;
   h.put("A", "100");
   h.put("A", "100");
-  h.put("a", "101");
+  h.put("A", "101");
   h.put("B", "200");
   h.put("B", "200");
   
   
-  std::vector<std::string> r(h.get("A"));
+  std::vector<std::string> r(h.findAll("A"));
   CPPUNIT_ASSERT_EQUAL((size_t)2, r.size());
   CPPUNIT_ASSERT_EQUAL((size_t)2, r.size());
   CPPUNIT_ASSERT_EQUAL(std::string("100"), r[0]);
   CPPUNIT_ASSERT_EQUAL(std::string("100"), r[0]);
   CPPUNIT_ASSERT_EQUAL(std::string("101"), r[1]);
   CPPUNIT_ASSERT_EQUAL(std::string("101"), r[1]);
@@ -142,11 +142,11 @@ void HttpHeaderTest::testClearField()
   h.setVersion(HttpHeader::HTTP_1_1);
   h.setVersion(HttpHeader::HTTP_1_1);
   h.put("Foo", "Bar");
   h.put("Foo", "Bar");
   
   
-  CPPUNIT_ASSERT_EQUAL(std::string("Bar"), h.getFirst("Foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("Bar"), h.find("Foo"));
 
 
   h.clearField();
   h.clearField();
 
 
-  CPPUNIT_ASSERT_EQUAL(std::string(""), h.getFirst("Foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string(""), h.find("Foo"));
   CPPUNIT_ASSERT_EQUAL(200, h.getStatusCode());
   CPPUNIT_ASSERT_EQUAL(200, h.getStatusCode());
   CPPUNIT_ASSERT_EQUAL(std::string(HttpHeader::HTTP_1_1), h.getVersion());
   CPPUNIT_ASSERT_EQUAL(std::string(HttpHeader::HTTP_1_1), h.getVersion());
 }
 }
@@ -164,15 +164,15 @@ void HttpHeaderTest::testFill()
   HttpHeader h;
   HttpHeader h;
   h.fill(s.begin(), s.end());
   h.fill(s.begin(), s.end());
   CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.net"),
   CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.net"),
-                       h.getFirst("Host"));
+                       h.find("host"));
   CPPUNIT_ASSERT_EQUAL(std::string("close"),
   CPPUNIT_ASSERT_EQUAL(std::string("close"),
-                       h.getFirst("Connection"));
+                       h.find("connection"));
   CPPUNIT_ASSERT_EQUAL(std::string("text1 text2 text3"),
   CPPUNIT_ASSERT_EQUAL(std::string("text1 text2 text3"),
-                       h.getFirst("Multi-Line"));
+                       h.find("multi-line"));
   CPPUNIT_ASSERT_EQUAL(std::string("foo"),
   CPPUNIT_ASSERT_EQUAL(std::string("foo"),
-                       h.get("Duplicate")[0]);
+                       h.findAll("duplicate")[0]);
   CPPUNIT_ASSERT_EQUAL(std::string("bar"),
   CPPUNIT_ASSERT_EQUAL(std::string("bar"),
-                       h.get("Duplicate")[1]);
+                       h.findAll("duplicate")[1]);
 }
 }
 
 
 } // namespace aria2
 } // namespace aria2

+ 53 - 53
test/HttpResponseTest.cc

@@ -109,7 +109,7 @@ void HttpResponseTest::testGetContentLength_contentLength()
   HttpResponse httpResponse;
   HttpResponse httpResponse;
 
 
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
-  httpHeader->put("Content-Length", "4294967296");
+  httpHeader->put("content-length", "4294967296");
 
 
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
 
 
@@ -121,13 +121,13 @@ void HttpResponseTest::testGetEntityLength()
   HttpResponse httpResponse;
   HttpResponse httpResponse;
 
 
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
-  httpHeader->put("Content-Length", "4294967296");
+  httpHeader->put("content-length", "4294967296");
 
 
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
 
 
   CPPUNIT_ASSERT_EQUAL((uint64_t)4294967296ULL, httpResponse.getEntityLength());
   CPPUNIT_ASSERT_EQUAL((uint64_t)4294967296ULL, httpResponse.getEntityLength());
 
 
-  httpHeader->put("Content-Range", "bytes 1-4294967296/4294967297");
+  httpHeader->put("content-range", "bytes 1-4294967296/4294967297");
 
 
   CPPUNIT_ASSERT_EQUAL((uint64_t)4294967297ULL, httpResponse.getEntityLength());
   CPPUNIT_ASSERT_EQUAL((uint64_t)4294967297ULL, httpResponse.getEntityLength());
 
 
@@ -165,7 +165,7 @@ void HttpResponseTest::testDeterminFilename_with_ContentDisposition_zero_length
 {
 {
   HttpResponse httpResponse;
   HttpResponse httpResponse;
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
-  httpHeader->put("Content-Disposition", "attachment; filename=\"\"");
+  httpHeader->put("content-disposition", "attachment; filename=\"\"");
   SharedHandle<HttpRequest> httpRequest(new HttpRequest());
   SharedHandle<HttpRequest> httpRequest(new HttpRequest());
   SharedHandle<Request> request(new Request());
   SharedHandle<Request> request(new Request());
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
@@ -182,7 +182,7 @@ void HttpResponseTest::testDeterminFilename_with_ContentDisposition()
 {
 {
   HttpResponse httpResponse;
   HttpResponse httpResponse;
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
-  httpHeader->put("Content-Disposition",
+  httpHeader->put("content-disposition",
                   "attachment; filename=\"aria2-current.tar.bz2\"");
                   "attachment; filename=\"aria2-current.tar.bz2\"");
   SharedHandle<HttpRequest> httpRequest(new HttpRequest());
   SharedHandle<HttpRequest> httpRequest(new HttpRequest());
   SharedHandle<Request> request(new Request());
   SharedHandle<Request> request(new Request());
@@ -211,7 +211,7 @@ void HttpResponseTest::testGetRedirectURI_with_Location()
 {
 {
   HttpResponse httpResponse;
   HttpResponse httpResponse;
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
-  httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
+  httpHeader->put("location", "http://localhost/download/aria2-1.0.0.tar.bz2");
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
 
 
   CPPUNIT_ASSERT_EQUAL
   CPPUNIT_ASSERT_EQUAL
@@ -224,7 +224,7 @@ void HttpResponseTest::testIsRedirect()
   HttpResponse httpResponse;
   HttpResponse httpResponse;
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   httpHeader->setStatusCode(200);
   httpHeader->setStatusCode(200);
-  httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
+  httpHeader->put("location", "http://localhost/download/aria2-1.0.0.tar.bz2");
 
 
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
 
 
@@ -244,7 +244,7 @@ void HttpResponseTest::testIsTransferEncodingSpecified()
 
 
   CPPUNIT_ASSERT(!httpResponse.isTransferEncodingSpecified());  
   CPPUNIT_ASSERT(!httpResponse.isTransferEncodingSpecified());  
 
 
-  httpHeader->put("Transfer-Encoding", "chunked");
+  httpHeader->put("transfer-encoding", "chunked");
 
 
   CPPUNIT_ASSERT(httpResponse.isTransferEncodingSpecified());
   CPPUNIT_ASSERT(httpResponse.isTransferEncodingSpecified());
 }
 }
@@ -258,7 +258,7 @@ void HttpResponseTest::testGetTransferEncoding()
 
 
   CPPUNIT_ASSERT_EQUAL(std::string(""), httpResponse.getTransferEncoding());  
   CPPUNIT_ASSERT_EQUAL(std::string(""), httpResponse.getTransferEncoding());  
 
 
-  httpHeader->put("Transfer-Encoding", "chunked");
+  httpHeader->put("transfer-encoding", "chunked");
 
 
   CPPUNIT_ASSERT_EQUAL(std::string("chunked"),
   CPPUNIT_ASSERT_EQUAL(std::string("chunked"),
                        httpResponse.getTransferEncoding());
                        httpResponse.getTransferEncoding());
@@ -273,7 +273,7 @@ void HttpResponseTest::testGetTransferEncodingStreamFilter()
 
 
   CPPUNIT_ASSERT(!httpResponse.getTransferEncodingStreamFilter());
   CPPUNIT_ASSERT(!httpResponse.getTransferEncodingStreamFilter());
 
 
-  httpHeader->put("Transfer-Encoding", "chunked");
+  httpHeader->put("transfer-encoding", "chunked");
 
 
   CPPUNIT_ASSERT(httpResponse.getTransferEncodingStreamFilter());
   CPPUNIT_ASSERT(httpResponse.getTransferEncodingStreamFilter());
 }
 }
@@ -287,7 +287,7 @@ void HttpResponseTest::testIsContentEncodingSpecified()
 
 
   CPPUNIT_ASSERT(!httpResponse.isContentEncodingSpecified());
   CPPUNIT_ASSERT(!httpResponse.isContentEncodingSpecified());
 
 
-  httpHeader->put("Content-Encoding", "gzip");
+  httpHeader->put("content-encoding", "gzip");
 
 
   CPPUNIT_ASSERT(httpResponse.isContentEncodingSpecified());
   CPPUNIT_ASSERT(httpResponse.isContentEncodingSpecified());
 }
 }
@@ -301,7 +301,7 @@ void HttpResponseTest::testGetContentEncoding()
 
 
   CPPUNIT_ASSERT_EQUAL(A2STR::NIL, httpResponse.getContentEncoding());
   CPPUNIT_ASSERT_EQUAL(A2STR::NIL, httpResponse.getContentEncoding());
 
 
-  httpHeader->put("Content-Encoding", "gzip");
+  httpHeader->put("content-encoding", "gzip");
 
 
   CPPUNIT_ASSERT_EQUAL(std::string("gzip"), httpResponse.getContentEncoding());
   CPPUNIT_ASSERT_EQUAL(std::string("gzip"), httpResponse.getContentEncoding());
 }
 }
@@ -316,7 +316,7 @@ void HttpResponseTest::testGetContentEncodingStreamFilter()
   CPPUNIT_ASSERT(!httpResponse.getContentEncodingStreamFilter());
   CPPUNIT_ASSERT(!httpResponse.getContentEncodingStreamFilter());
 
 
 #ifdef HAVE_ZLIB
 #ifdef HAVE_ZLIB
-  httpHeader->put("Content-Encoding", "gzip");
+  httpHeader->put("content-encoding", "gzip");
   {
   {
     SharedHandle<StreamFilter> filter =
     SharedHandle<StreamFilter> filter =
       httpResponse.getContentEncodingStreamFilter();
       httpResponse.getContentEncodingStreamFilter();
@@ -326,7 +326,7 @@ void HttpResponseTest::testGetContentEncodingStreamFilter()
   }
   }
   httpHeader.reset(new HttpHeader());
   httpHeader.reset(new HttpHeader());
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
-  httpHeader->put("Content-Encoding", "deflate");
+  httpHeader->put("content-encoding", "deflate");
   {
   {
     SharedHandle<StreamFilter> filter =
     SharedHandle<StreamFilter> filter =
       httpResponse.getContentEncodingStreamFilter();
       httpResponse.getContentEncodingStreamFilter();
@@ -337,7 +337,7 @@ void HttpResponseTest::testGetContentEncodingStreamFilter()
 #endif // HAVE_ZLIB
 #endif // HAVE_ZLIB
   httpHeader.reset(new HttpHeader());
   httpHeader.reset(new HttpHeader());
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
-  httpHeader->put("Content-Encoding", "bzip2");
+  httpHeader->put("content-encoding", "bzip2");
   {
   {
     SharedHandle<StreamFilter> filter =
     SharedHandle<StreamFilter> filter =
       httpResponse.getContentEncodingStreamFilter();
       httpResponse.getContentEncodingStreamFilter();
@@ -359,7 +359,7 @@ void HttpResponseTest::testValidateResponse()
   } catch(Exception& e) {
   } catch(Exception& e) {
   }
   }
 
 
-  httpHeader->put("Location", "http://localhost/archives/aria2-1.0.0.tar.bz2");
+  httpHeader->put("location", "http://localhost/archives/aria2-1.0.0.tar.bz2");
   try {
   try {
     httpResponse.validateResponse();
     httpResponse.validateResponse();
   } catch(Exception& e) {
   } catch(Exception& e) {
@@ -384,7 +384,7 @@ void HttpResponseTest::testValidateResponse_good_range()
   httpRequest->setRequest(request);
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
   httpResponse.setHttpRequest(httpRequest);
   httpHeader->setStatusCode(206);
   httpHeader->setStatusCode(206);
-  httpHeader->put("Content-Range", "bytes 1048576-10485760/10485760");
+  httpHeader->put("content-range", "bytes 1048576-10485760/10485760");
   
   
   try {
   try {
     httpResponse.validateResponse();
     httpResponse.validateResponse();
@@ -411,7 +411,7 @@ void HttpResponseTest::testValidateResponse_bad_range()
   httpRequest->setRequest(request);
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
   httpResponse.setHttpRequest(httpRequest);
   httpHeader->setStatusCode(206);
   httpHeader->setStatusCode(206);
-  httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
+  httpHeader->put("content-range", "bytes 0-10485760/10485761");
 
 
   try {
   try {
     httpResponse.validateResponse();
     httpResponse.validateResponse();
@@ -437,8 +437,8 @@ void HttpResponseTest::testValidateResponse_chunked()
   httpRequest->setRequest(request);
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
   httpResponse.setHttpRequest(httpRequest);
   httpHeader->setStatusCode(206);
   httpHeader->setStatusCode(206);
-  httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
-  httpHeader->put("Transfer-Encoding", "chunked");
+  httpHeader->put("content-range", "bytes 0-10485760/10485761");
+  httpHeader->put("transfer-encoding", "chunked");
 
 
   // if transfer-encoding is specified, then range validation is skipped.
   // if transfer-encoding is specified, then range validation is skipped.
   try {
   try {
@@ -471,7 +471,7 @@ void HttpResponseTest::testHasRetryAfter()
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   SharedHandle<HttpHeader> httpHeader(new HttpHeader());
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
 
 
-  httpHeader->put("Retry-After", "60");
+  httpHeader->put("retry-after", "60");
 
 
   CPPUNIT_ASSERT(httpResponse.hasRetryAfter());
   CPPUNIT_ASSERT(httpResponse.hasRetryAfter());
   CPPUNIT_ASSERT_EQUAL((time_t)60, httpResponse.getRetryAfter());
   CPPUNIT_ASSERT_EQUAL((time_t)60, httpResponse.getRetryAfter());
@@ -489,13 +489,13 @@ void HttpResponseTest::testProcessRedirect()
   httpRequest->setRequest(request);
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
   httpResponse.setHttpRequest(httpRequest);
   
   
-  httpHeader->put("Location", "http://mirror/aria2-1.0.0.tar.bz2");
+  httpHeader->put("location", "http://mirror/aria2-1.0.0.tar.bz2");
   httpResponse.processRedirect();
   httpResponse.processRedirect();
 
 
   httpHeader->clearField();
   httpHeader->clearField();
 
 
   // Test for percent-encode
   // Test for percent-encode
-  httpHeader->put("Location", "http://example.org/white space#aria2");
+  httpHeader->put("location", "http://example.org/white space#aria2");
   httpResponse.processRedirect();
   httpResponse.processRedirect();
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"),
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"),
                        request->getCurrentUri());
                        request->getCurrentUri());
@@ -503,7 +503,7 @@ void HttpResponseTest::testProcessRedirect()
   httpHeader->clearField();
   httpHeader->clearField();
 
 
   // Give unsupported scheme
   // Give unsupported scheme
-  httpHeader->put("Location", "unsupported://mirror/aria2-1.0.0.tar.bz2");
+  httpHeader->put("location", "unsupported://mirror/aria2-1.0.0.tar.bz2");
   try {
   try {
     httpResponse.processRedirect();
     httpResponse.processRedirect();
     CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
     CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
@@ -528,11 +528,11 @@ void HttpResponseTest::testRetrieveCookie()
   httpRequest->setCookieStorage(st);
   httpRequest->setCookieStorage(st);
   httpResponse.setHttpRequest(httpRequest);
   httpResponse.setHttpRequest(httpRequest);
 
 
-  httpHeader->put("Set-Cookie", "k1=v1; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
+  httpHeader->put("set-cookie", "k1=v1; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
                   "path=/; domain=.aria2.org;");
                   "path=/; domain=.aria2.org;");
-  httpHeader->put("Set-Cookie", "k2=v2; expires=Sun, 01-Jan-38 00:00:00 GMT;"
+  httpHeader->put("set-cookie", "k2=v2; expires=Sun, 01-Jan-38 00:00:00 GMT;"
                   "path=/; domain=.aria2.org;");
                   "path=/; domain=.aria2.org;");
-  httpHeader->put("Set-Cookie", "k3=v3;");
+  httpHeader->put("set-cookie", "k3=v3;");
 
 
   httpResponse.retrieveCookie();
   httpResponse.retrieveCookie();
 
 
@@ -554,19 +554,19 @@ void HttpResponseTest::testSupportsPersistentConnection()
 
 
   httpHeader->setVersion("HTTP/1.1");
   httpHeader->setVersion("HTTP/1.1");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->put("Connection", "close");
+  httpHeader->put("connection", "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Connection", "keep-alive");
+  httpHeader->put("connection", "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
 
 
   httpHeader->setVersion("HTTP/1.0");
   httpHeader->setVersion("HTTP/1.0");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->put("Connection", "close");
+  httpHeader->put("connection", "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Connection", "keep-alive");
+  httpHeader->put("connection", "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
 
 
@@ -576,35 +576,35 @@ void HttpResponseTest::testSupportsPersistentConnection()
   
   
   httpHeader->setVersion("HTTP/1.1");
   httpHeader->setVersion("HTTP/1.1");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->put("Connection", "close");
+  httpHeader->put("connection", "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Connection", "keep-alive");
+  httpHeader->put("connection", "keep-alive");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Proxy-Connection", "keep-alive");
+  httpHeader->put("proxy-connection", "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->put("Connection", "close");
+  httpHeader->put("connection", "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Proxy-Connection", "close");
+  httpHeader->put("proxy-connection", "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
 
 
   httpHeader->setVersion("HTTP/1.0");
   httpHeader->setVersion("HTTP/1.0");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->put("Connection", "close");
+  httpHeader->put("connection", "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Connection", "keep-alive");
+  httpHeader->put("connection", "keep-alive");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->put("Proxy-Connection", "keep-alive");
+  httpHeader->put("proxy-connection", "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Proxy-Connection", "keep-alive");
+  httpHeader->put("proxy-connection", "keep-alive");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
-  httpHeader->put("Proxy-Connection", "close");
+  httpHeader->put("proxy-connection", "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
   httpHeader->clearField();
   httpHeader->clearField();
 }
 }
@@ -616,13 +616,13 @@ void HttpResponseTest::testGetMetalinKHttpEntries()
   httpResponse.setHttpHeader(httpHeader);
   httpResponse.setHttpHeader(httpHeader);
   SharedHandle<Option> option(new Option());
   SharedHandle<Option> option(new Option());
 
 
-  httpHeader->put("Link", "<http://uri1/>; rel=duplicate; pri=1; pref; geo=JP");
-  httpHeader->put("Link", "<http://uri2/>; rel=duplicate");
-  httpHeader->put("Link", "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
-  httpHeader->put("Link", "<http://uri4/>;rel=duplicate;=pri=1;pref");
-  httpHeader->put("Link", "<http://describedby>; rel=describedby");
-  httpHeader->put("Link", "<http://norel/>");
-  httpHeader->put("Link", "<baduri>; rel=duplicate; pri=-1;");
+  httpHeader->put("link", "<http://uri1/>; rel=duplicate; pri=1; pref; geo=JP");
+  httpHeader->put("link", "<http://uri2/>; rel=duplicate");
+  httpHeader->put("link", "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
+  httpHeader->put("link", "<http://uri4/>;rel=duplicate;=pri=1;pref");
+  httpHeader->put("link", "<http://describedby>; rel=describedby");
+  httpHeader->put("link", "<http://norel/>");
+  httpHeader->put("link", "<baduri>; rel=duplicate; pri=-1;");
   std::vector<MetalinkHttpEntry> result;
   std::vector<MetalinkHttpEntry> result;
   httpResponse.getMetalinKHttpEntries(result, option);
   httpResponse.getMetalinKHttpEntries(result, option);
   CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
   CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
@@ -667,11 +667,11 @@ void HttpResponseTest::testGetDigest()
   SharedHandle<Option> option(new Option());
   SharedHandle<Option> option(new Option());
   // Python binascii.hexlify(base64.b64decode(B64ED_HASH)) is handy to
   // Python binascii.hexlify(base64.b64decode(B64ED_HASH)) is handy to
   // retrieve ascii hex hash string.
   // retrieve ascii hex hash string.
-  httpHeader->put("Digest", "SHA-1=82AD8itGL/oYQ5BTPFANiYnp9oE=");
-  httpHeader->put("Digest", "NOT_SUPPORTED");
-  httpHeader->put("Digest", "SHA-224=rQdowoLHQJTMVZ3rF7vmYOIzUXlu7F+FcMbPnA==");
-  httpHeader->put("Digest", "SHA-224=6Ik6LNZ1iPy6cbmlKO4NHfvxzaiurmHilMyhGA==");
-  httpHeader->put("Digest",
+  httpHeader->put("digest", "SHA-1=82AD8itGL/oYQ5BTPFANiYnp9oE=");
+  httpHeader->put("digest", "NOT_SUPPORTED");
+  httpHeader->put("digest", "SHA-224=rQdowoLHQJTMVZ3rF7vmYOIzUXlu7F+FcMbPnA==");
+  httpHeader->put("digest", "SHA-224=6Ik6LNZ1iPy6cbmlKO4NHfvxzaiurmHilMyhGA==");
+  httpHeader->put("digest",
                   "SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
                   "SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
                   "MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
                   "MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
   std::vector<Checksum> result;
   std::vector<Checksum> result;

+ 18 - 0
test/UtilTest.cc

@@ -32,6 +32,7 @@ class UtilTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testSplitIterM);
   CPPUNIT_TEST(testSplitIterM);
   CPPUNIT_TEST(testStreq);
   CPPUNIT_TEST(testStreq);
   CPPUNIT_TEST(testStrieq);
   CPPUNIT_TEST(testStrieq);
+  CPPUNIT_TEST(testStrifind);
   CPPUNIT_TEST(testEndsWith);
   CPPUNIT_TEST(testEndsWith);
   CPPUNIT_TEST(testIendsWith);
   CPPUNIT_TEST(testIendsWith);
   CPPUNIT_TEST(testReplace);
   CPPUNIT_TEST(testReplace);
@@ -101,6 +102,7 @@ public:
   void testSplitIterM();
   void testSplitIterM();
   void testStreq();
   void testStreq();
   void testStrieq();
   void testStrieq();
+  void testStrifind();
   void testEndsWith();
   void testEndsWith();
   void testIendsWith();
   void testIendsWith();
   void testReplace();
   void testReplace();
@@ -734,6 +736,22 @@ void UtilTest::testStrieq()
   CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
   CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
 }
 }
 
 
+void UtilTest::testStrifind()
+{
+  std::string s1, s2;
+  s1 = "yamagakani mukashi wo toheba hARU no tuki";
+  s2 = "HaRu";
+  CPPUNIT_ASSERT(util::strifind(s1.begin(), s1.end(), s2.begin(), s2.end())
+                 != s1.end());
+  s2 = "aki";
+  CPPUNIT_ASSERT(util::strifind(s1.begin(), s1.end(), s2.begin(), s2.end())
+                 == s1.end());
+  s1 = "h";
+  s2 = "HH";
+  CPPUNIT_ASSERT(util::strifind(s1.begin(), s1.end(), s2.begin(), s2.end())
+                 == s1.end());
+}
+
 void UtilTest::testReplace() {
 void UtilTest::testReplace() {
   CPPUNIT_ASSERT_EQUAL(std::string("abc\n"), util::replace("abc\r\n", "\r", ""));
   CPPUNIT_ASSERT_EQUAL(std::string("abc\n"), util::replace("abc\r\n", "\r", ""));
   CPPUNIT_ASSERT_EQUAL(std::string("abc"), util::replace("abc\r\n", "\r\n", ""));
   CPPUNIT_ASSERT_EQUAL(std::string("abc"), util::replace("abc\r\n", "\r\n", ""));