소스 검색

Refactor HttpConnection and its neighbor objects

Tatsuhiro Tsujikawa 12 년 전
부모
커밋
47402c5f29
11개의 변경된 파일190개의 추가작업 그리고 194개의 파일을 삭제
  1. 23 22
      src/HttpConnection.cc
  2. 5 6
      src/HttpConnection.h
  3. 2 2
      src/HttpHeaderProcessor.cc
  4. 5 4
      src/HttpHeaderProcessor.h
  5. 1 1
      src/HttpRequest.cc
  6. 2 2
      src/HttpRequest.h
  7. 7 2
      src/HttpResponse.cc
  8. 3 6
      src/HttpResponse.h
  9. 1 1
      src/HttpResponseCommand.cc
  10. 4 4
      test/HttpHeaderProcessorTest.cc
  11. 137 144
      test/HttpResponseTest.cc

+ 23 - 22
src/HttpConnection.cc

@@ -69,6 +69,12 @@ HttpRequestEntry::HttpRequestEntry
 
 HttpRequestEntry::~HttpRequestEntry() {}
 
+const std::unique_ptr<HttpHeaderProcessor>&
+HttpRequestEntry::getHttpHeaderProcessor() const
+{
+  return proc_;
+}
+
 HttpConnection::HttpConnection
 (cuid_t cuid,
  const std::shared_ptr<SocketCore>& socket,
@@ -99,29 +105,28 @@ std::string HttpConnection::eraseConfidentialInfo(const std::string& request)
   return result;
 }
 
-void HttpConnection::sendRequest(const std::shared_ptr<HttpRequest>& httpRequest)
+void HttpConnection::sendRequest
+(const std::shared_ptr<HttpRequest>& httpRequest, std::string request)
 {
-  std::string request = httpRequest->createRequest();
   A2_LOG_INFO(fmt(MSG_SENDING_REQUEST,
                   cuid_,
                   eraseConfidentialInfo(request).c_str()));
   socketBuffer_.pushStr(std::move(request));
   socketBuffer_.send();
-  std::shared_ptr<HttpRequestEntry> entry(new HttpRequestEntry(httpRequest));
-  outstandingHttpRequests_.push_back(entry);
+  outstandingHttpRequests_.push_back(make_unique<HttpRequestEntry>
+                                     (httpRequest));
+}
+
+void HttpConnection::sendRequest
+(const std::shared_ptr<HttpRequest>& httpRequest)
+{
+  sendRequest(httpRequest, httpRequest->createRequest());
 }
 
 void HttpConnection::sendProxyRequest
 (const std::shared_ptr<HttpRequest>& httpRequest)
 {
-  std::string request = httpRequest->createProxyRequest();
-  A2_LOG_INFO(fmt(MSG_SENDING_REQUEST,
-                  cuid_,
-                  eraseConfidentialInfo(request).c_str()));
-  socketBuffer_.pushStr(std::move(request));
-  socketBuffer_.send();
-  std::shared_ptr<HttpRequestEntry> entry(new HttpRequestEntry(httpRequest));
-  outstandingHttpRequests_.push_back(entry);
+  sendRequest(httpRequest, httpRequest->createProxyRequest());
 }
 
 std::shared_ptr<HttpResponse> HttpConnection::receiveResponse()
@@ -129,9 +134,6 @@ std::shared_ptr<HttpResponse> HttpConnection::receiveResponse()
   if(outstandingHttpRequests_.empty()) {
     throw DL_ABORT_EX(EX_NO_HTTP_REQUEST_ENTRY_FOUND);
   }
-  std::shared_ptr<HttpRequestEntry> entry = outstandingHttpRequests_.front();
-  const std::shared_ptr<HttpHeaderProcessor>& proc =
-    entry->getHttpHeaderProcessor();
   if(socketRecvBuffer_->bufferEmpty()) {
     if(socketRecvBuffer_->recv() == 0 &&
        !socket_->wantRead() && !socket_->wantWrite()) {
@@ -139,16 +141,17 @@ std::shared_ptr<HttpResponse> HttpConnection::receiveResponse()
     }
   }
   std::shared_ptr<HttpResponse> httpResponse;
+  const auto& proc = outstandingHttpRequests_.front()->getHttpHeaderProcessor();
   if(proc->parse(socketRecvBuffer_->getBuffer(),
                  socketRecvBuffer_->getBufferLength())) {
-    const std::shared_ptr<HttpHeader>& httpHeader = proc->getResult();
     A2_LOG_INFO(fmt(MSG_RECEIVE_RESPONSE,
                     cuid_,
                     proc->getHeaderString().c_str()));
     httpResponse.reset(new HttpResponse());
     httpResponse->setCuid(cuid_);
-    httpResponse->setHttpHeader(httpHeader);
-    httpResponse->setHttpRequest(entry->getHttpRequest());
+    httpResponse->setHttpHeader(proc->getResult());
+    httpResponse->setHttpRequest(outstandingHttpRequests_.front()->
+                                 getHttpRequest());
     outstandingHttpRequests_.pop_front();
   }
   socketRecvBuffer_->shiftBuffer(proc->getLastBytesProcessed());
@@ -157,10 +160,8 @@ std::shared_ptr<HttpResponse> HttpConnection::receiveResponse()
 
 bool HttpConnection::isIssued(const std::shared_ptr<Segment>& segment) const
 {
-  for(HttpRequestEntries::const_iterator itr = outstandingHttpRequests_.begin(),
-        eoi = outstandingHttpRequests_.end(); itr != eoi; ++itr) {
-    std::shared_ptr<HttpRequest> httpRequest = (*itr)->getHttpRequest();
-    if(*httpRequest->getSegment() == *segment) {
+  for(const auto& entry : outstandingHttpRequests_) {
+    if(*entry->getHttpRequest()->getSegment() == *segment) {
       return true;
     }
   }

+ 5 - 6
src/HttpConnection.h

@@ -57,7 +57,7 @@ class SocketRecvBuffer;
 class HttpRequestEntry {
 private:
   std::shared_ptr<HttpRequest> httpRequest_;
-  std::shared_ptr<HttpHeaderProcessor> proc_;
+  std::unique_ptr<HttpHeaderProcessor> proc_;
 public:
   HttpRequestEntry(const std::shared_ptr<HttpRequest>& httpRequest);
 
@@ -68,13 +68,10 @@ public:
     return httpRequest_;
   }
 
-  const std::shared_ptr<HttpHeaderProcessor>& getHttpHeaderProcessor() const
-  {
-    return proc_;
-  }
+  const std::unique_ptr<HttpHeaderProcessor>& getHttpHeaderProcessor() const;
 };
 
-typedef std::deque<std::shared_ptr<HttpRequestEntry> > HttpRequestEntries;
+typedef std::deque<std::unique_ptr<HttpRequestEntry>> HttpRequestEntries;
 
 class HttpConnection {
 private:
@@ -86,6 +83,8 @@ private:
   HttpRequestEntries outstandingHttpRequests_;
 
   std::string eraseConfidentialInfo(const std::string& request);
+  void sendRequest
+  (const std::shared_ptr<HttpRequest>& httpRequest, std::string request);
 public:
   HttpConnection
   (cuid_t cuid,

+ 2 - 2
src/HttpHeaderProcessor.cc

@@ -391,9 +391,9 @@ void HttpHeaderProcessor::clear()
   headers_.clear();
 }
 
-const std::shared_ptr<HttpHeader>& HttpHeaderProcessor::getResult() const
+std::unique_ptr<HttpHeader> HttpHeaderProcessor::getResult()
 {
-  return result_;
+  return std::move(result_);
 }
 
 std::string HttpHeaderProcessor::getHeaderString() const

+ 5 - 4
src/HttpHeaderProcessor.h

@@ -70,10 +70,11 @@ public:
   size_t getLastBytesProcessed() const;
 
   /**
-   * Processes the received header as a http response header and returns
-   * HttpHeader object.
+   * Processes the received header as a http response header and
+   * returns HttpHeader object. This method transfers the ownership of
+   * resulting HttpHeader to the caller.
    */
-  const std::shared_ptr<HttpHeader>& getResult() const;
+  std::unique_ptr<HttpHeader> getResult();
 
   std::string getHeaderString() const;
 
@@ -88,7 +89,7 @@ private:
   std::string buf_;
   std::string lastFieldName_;
   int lastFieldHdKey_;
-  std::shared_ptr<HttpHeader> result_;
+  std::unique_ptr<HttpHeader> result_;
   std::string headers_;
 };
 

+ 1 - 1
src/HttpRequest.cc

@@ -365,7 +365,7 @@ bool HttpRequest::authenticationUsed() const
   return authConfig_.get();
 }
 
-const std::shared_ptr<AuthConfig>& HttpRequest::getAuthConfig() const
+const std::unique_ptr<AuthConfig>& HttpRequest::getAuthConfig() const
 {
   return authConfig_;
 }

+ 2 - 2
src/HttpRequest.h

@@ -80,7 +80,7 @@ private:
 
   const Option* option_;
 
-  std::shared_ptr<AuthConfig> authConfig_;
+  std::unique_ptr<AuthConfig> authConfig_;
 
   std::shared_ptr<Request> proxyRequest_;
 
@@ -210,7 +210,7 @@ public:
 
   // Returns AuthConfig used in the last invocation of
   // createRequest().
-  const std::shared_ptr<AuthConfig>& getAuthConfig() const;
+  const std::unique_ptr<AuthConfig>& getAuthConfig() const;
 
   void setFileEntry(const std::shared_ptr<FileEntry>& fileEntry);
 

+ 7 - 2
src/HttpResponse.cc

@@ -256,9 +256,14 @@ std::string HttpResponse::getContentType() const
   }
 }
 
-void HttpResponse::setHttpHeader(const std::shared_ptr<HttpHeader>& httpHeader)
+void HttpResponse::setHttpHeader(std::unique_ptr<HttpHeader> httpHeader)
 {
-  httpHeader_ = httpHeader;
+  httpHeader_ = std::move(httpHeader);
+}
+
+const std::unique_ptr<HttpHeader>& HttpResponse::getHttpHeader() const
+{
+  return httpHeader_;
 }
 
 void HttpResponse::setHttpRequest(const std::shared_ptr<HttpRequest>& httpRequest)

+ 3 - 6
src/HttpResponse.h

@@ -57,7 +57,7 @@ class HttpResponse {
 private:
   cuid_t cuid_;
   std::shared_ptr<HttpRequest> httpRequest_;
-  std::shared_ptr<HttpHeader> httpHeader_;
+  std::unique_ptr<HttpHeader> httpHeader_;
 public:
   HttpResponse();
 
@@ -103,12 +103,9 @@ public:
   // Returns type "/" subtype. The parameter is removed.
   std::string getContentType() const;
 
-  void setHttpHeader(const std::shared_ptr<HttpHeader>& httpHeader);
+  void setHttpHeader(std::unique_ptr<HttpHeader> httpHeader);
 
-  const std::shared_ptr<HttpHeader>& getHttpHeader() const
-  {
-    return httpHeader_;
-  }
+  const std::unique_ptr<HttpHeader>& getHttpHeader() const;
 
   int getStatusCode() const;
 

+ 1 - 1
src/HttpResponseCommand.cc

@@ -165,7 +165,7 @@ bool HttpResponseCommand::executeInternal()
   httpResponse->validateResponse();
   httpResponse->retrieveCookie();
 
-  std::shared_ptr<HttpHeader> httpHeader = httpResponse->getHttpHeader();
+  const auto& httpHeader = httpResponse->getHttpHeader();
   // Disable persistent connection if:
   //   Connection: close is received or the remote server is not HTTP/1.1.
   // We don't care whether non-HTTP/1.1 server returns Connection: keep-alive.

+ 4 - 4
test/HttpHeaderProcessorTest.cc

@@ -76,7 +76,7 @@ void HttpHeaderProcessorTest::testParse3()
     "Content-Type:\r\n"
     "\r\n";
   CPPUNIT_ASSERT(proc.parse(s));
-  std::shared_ptr<HttpHeader> h = proc.getResult();
+  auto h = proc.getResult();
   CPPUNIT_ASSERT_EQUAL(std::string("close"), h->find(HttpHeader::CONNECTION));
   CPPUNIT_ASSERT_EQUAL(std::string("text1 text2 text3"),
                        h->find(HttpHeader::ACCEPT_ENCODING));
@@ -136,7 +136,7 @@ void HttpHeaderProcessorTest::testGetHttpResponseHeader()
 
   CPPUNIT_ASSERT(proc.parse(hd));
 
-  std::shared_ptr<HttpHeader> header = proc.getResult();
+  auto header = proc.getResult();
   CPPUNIT_ASSERT_EQUAL(404, header->getStatusCode());
   CPPUNIT_ASSERT_EQUAL(std::string("Not Found"), header->getReasonPhrase());
   CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion());
@@ -153,7 +153,7 @@ void HttpHeaderProcessorTest::testGetHttpResponseHeader_statusOnly()
 
   std::string hd = "HTTP/1.1 200\r\n\r\n";
   CPPUNIT_ASSERT(proc.parse(hd));
-  std::shared_ptr<HttpHeader> header = proc.getResult();
+  auto header = proc.getResult();
   CPPUNIT_ASSERT_EQUAL(200, header->getStatusCode());
 }
 
@@ -269,7 +269,7 @@ void HttpHeaderProcessorTest::testGetHttpRequestHeader()
 
   CPPUNIT_ASSERT(proc.parse(request));
 
-  std::shared_ptr<HttpHeader> httpHeader = proc.getResult();
+  auto httpHeader = proc.getResult();
   CPPUNIT_ASSERT_EQUAL(std::string("GET"), httpHeader->getMethod());
   CPPUNIT_ASSERT_EQUAL(std::string("/index.html"),httpHeader->getRequestPath());
   CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), httpHeader->getVersion());

+ 137 - 144
test/HttpResponseTest.cc

@@ -106,10 +106,10 @@ void HttpResponseTest::testGetContentLength_contentLength()
 {
   HttpResponse httpResponse;
 
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
+  auto httpHeader = make_unique<HttpHeader>();
   httpHeader->put(HttpHeader::CONTENT_LENGTH, "4294967296");
 
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(std::move(httpHeader));
 
   CPPUNIT_ASSERT_EQUAL((int64_t)4294967296LL, httpResponse.getContentLength());
 }
@@ -118,15 +118,14 @@ void HttpResponseTest::testGetEntityLength()
 {
   HttpResponse httpResponse;
 
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
+  auto httpHeader = make_unique<HttpHeader>();
   httpHeader->put(HttpHeader::CONTENT_LENGTH, "4294967296");
 
-  httpResponse.setHttpHeader(httpHeader);
-
+  httpResponse.setHttpHeader(std::move(httpHeader));
   CPPUNIT_ASSERT_EQUAL((int64_t)4294967296LL, httpResponse.getEntityLength());
 
-  httpHeader->put(HttpHeader::CONTENT_RANGE, "bytes 1-4294967296/4294967297");
-
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
+                                    "bytes 1-4294967296/4294967297");
   CPPUNIT_ASSERT_EQUAL((int64_t)4294967297LL, httpResponse.getEntityLength());
 
 }
@@ -134,10 +133,10 @@ void HttpResponseTest::testGetEntityLength()
 void HttpResponseTest::testGetContentType()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
+  auto httpHeader = make_unique<HttpHeader>();
   httpHeader->put(HttpHeader::CONTENT_TYPE,
                   "application/metalink+xml; charset=UTF-8");
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(std::move(httpHeader));
   // See paramter is ignored.
   CPPUNIT_ASSERT_EQUAL(std::string("application/metalink+xml"),
                        httpResponse.getContentType());
@@ -146,13 +145,12 @@ void HttpResponseTest::testGetContentType()
 void HttpResponseTest::testDeterminFilename_without_ContentDisposition()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   std::shared_ptr<Request> request(new Request());
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
   httpRequest->setRequest(request);
 
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   httpResponse.setHttpRequest(httpRequest);
 
   CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
@@ -163,14 +161,14 @@ void HttpResponseTest::testDeterminFilename_with_ContentDisposition_zero_length
 ()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
+  auto httpHeader = make_unique<HttpHeader>();
   httpHeader->put(HttpHeader::CONTENT_DISPOSITION, "attachment; filename=\"\"");
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   std::shared_ptr<Request> request(new Request());
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
   httpRequest->setRequest(request);
 
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(std::move(httpHeader));
   httpResponse.setHttpRequest(httpRequest);
 
   CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
@@ -180,7 +178,7 @@ void HttpResponseTest::testDeterminFilename_with_ContentDisposition_zero_length
 void HttpResponseTest::testDeterminFilename_with_ContentDisposition()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
+  auto httpHeader = make_unique<HttpHeader>();
   httpHeader->put(HttpHeader::CONTENT_DISPOSITION,
                   "attachment; filename=\"aria2-current.tar.bz2\"");
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
@@ -188,7 +186,7 @@ void HttpResponseTest::testDeterminFilename_with_ContentDisposition()
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
   httpRequest->setRequest(request);
 
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(std::move(httpHeader));
   httpResponse.setHttpRequest(httpRequest);
 
   CPPUNIT_ASSERT_EQUAL(std::string("aria2-current.tar.bz2"),
@@ -198,9 +196,8 @@ void HttpResponseTest::testDeterminFilename_with_ContentDisposition()
 void HttpResponseTest::testGetRedirectURI_without_Location()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
 
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
 
   CPPUNIT_ASSERT_EQUAL(std::string(""),
                        httpResponse.getRedirectURI());
@@ -209,9 +206,10 @@ void HttpResponseTest::testGetRedirectURI_without_Location()
 void HttpResponseTest::testGetRedirectURI_with_Location()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpHeader->put(HttpHeader::LOCATION, "http://localhost/download/aria2-1.0.0.tar.bz2");
-  httpResponse.setHttpHeader(httpHeader);
+  auto httpHeader = make_unique<HttpHeader>();
+  httpHeader->put(HttpHeader::LOCATION,
+                  "http://localhost/download/aria2-1.0.0.tar.bz2");
+  httpResponse.setHttpHeader(std::move(httpHeader));
 
   CPPUNIT_ASSERT_EQUAL
     (std::string("http://localhost/download/aria2-1.0.0.tar.bz2"),
@@ -221,45 +219,37 @@ void HttpResponseTest::testGetRedirectURI_with_Location()
 void HttpResponseTest::testIsRedirect()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
+  auto httpHeader = make_unique<HttpHeader>();
   httpHeader->setStatusCode(200);
   httpHeader->put(HttpHeader::LOCATION,
                   "http://localhost/download/aria2-1.0.0.tar.bz2");
 
-  httpResponse.setHttpHeader(httpHeader);
-
+  httpResponse.setHttpHeader(std::move(httpHeader));
   CPPUNIT_ASSERT(!httpResponse.isRedirect());
 
-  httpHeader->setStatusCode(301);
-
+  httpResponse.getHttpHeader()->setStatusCode(301);
   CPPUNIT_ASSERT(httpResponse.isRedirect());
 }
 
 void HttpResponseTest::testIsTransferEncodingSpecified()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-
-  httpResponse.setHttpHeader(httpHeader);
 
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   CPPUNIT_ASSERT(!httpResponse.isTransferEncodingSpecified());
 
-  httpHeader->put(HttpHeader::TRANSFER_ENCODING, "chunked");
-
+  httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
   CPPUNIT_ASSERT(httpResponse.isTransferEncodingSpecified());
 }
 
 void HttpResponseTest::testGetTransferEncoding()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-
-  httpResponse.setHttpHeader(httpHeader);
 
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   CPPUNIT_ASSERT_EQUAL(std::string(""), httpResponse.getTransferEncoding());
 
-  httpHeader->put(HttpHeader::TRANSFER_ENCODING, "chunked");
-
+  httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
   CPPUNIT_ASSERT_EQUAL(std::string("chunked"),
                        httpResponse.getTransferEncoding());
 }
@@ -267,56 +257,45 @@ void HttpResponseTest::testGetTransferEncoding()
 void HttpResponseTest::testGetTransferEncodingStreamFilter()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-
-  httpResponse.setHttpHeader(httpHeader);
 
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   CPPUNIT_ASSERT(!httpResponse.getTransferEncodingStreamFilter());
 
-  httpHeader->put(HttpHeader::TRANSFER_ENCODING, "chunked");
-
+  httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
   CPPUNIT_ASSERT(httpResponse.getTransferEncodingStreamFilter());
 }
 
 void HttpResponseTest::testIsContentEncodingSpecified()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-
-  httpResponse.setHttpHeader(httpHeader);
 
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   CPPUNIT_ASSERT(!httpResponse.isContentEncodingSpecified());
 
-  httpHeader->put(HttpHeader::CONTENT_ENCODING, "gzip");
-
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "gzip");
   CPPUNIT_ASSERT(httpResponse.isContentEncodingSpecified());
 }
 
 void HttpResponseTest::testGetContentEncoding()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-
-  httpResponse.setHttpHeader(httpHeader);
 
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   CPPUNIT_ASSERT_EQUAL(A2STR::NIL, httpResponse.getContentEncoding());
 
-  httpHeader->put(HttpHeader::CONTENT_ENCODING, "gzip");
-
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "gzip");
   CPPUNIT_ASSERT_EQUAL(std::string("gzip"), httpResponse.getContentEncoding());
 }
 
 void HttpResponseTest::testGetContentEncodingStreamFilter()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-
-  httpResponse.setHttpHeader(httpHeader);
 
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   CPPUNIT_ASSERT(!httpResponse.getContentEncodingStreamFilter());
 
 #ifdef HAVE_ZLIB
-  httpHeader->put(HttpHeader::CONTENT_ENCODING, "gzip");
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "gzip");
   {
     std::shared_ptr<StreamFilter> filter =
       httpResponse.getContentEncodingStreamFilter();
@@ -324,9 +303,8 @@ void HttpResponseTest::testGetContentEncodingStreamFilter()
     CPPUNIT_ASSERT_EQUAL(std::string("GZipDecodingStreamFilter"),
                          filter->getName());
   }
-  httpHeader.reset(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
-  httpHeader->put(HttpHeader::CONTENT_ENCODING, "deflate");
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "deflate");
   {
     std::shared_ptr<StreamFilter> filter =
       httpResponse.getContentEncodingStreamFilter();
@@ -335,9 +313,8 @@ void HttpResponseTest::testGetContentEncodingStreamFilter()
                          filter->getName());
   }
 #endif // HAVE_ZLIB
-  httpHeader.reset(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
-  httpHeader->put(HttpHeader::CONTENT_ENCODING, "bzip2");
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "bzip2");
   {
     std::shared_ptr<StreamFilter> filter =
       httpResponse.getContentEncodingStreamFilter();
@@ -348,10 +325,8 @@ void HttpResponseTest::testGetContentEncodingStreamFilter()
 void HttpResponseTest::testValidateResponse()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
-
-  httpHeader->setStatusCode(301);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
+  httpResponse.getHttpHeader()->setStatusCode(301);
 
   try {
     httpResponse.validateResponse();
@@ -359,8 +334,9 @@ void HttpResponseTest::testValidateResponse()
   } catch(Exception& e) {
   }
 
-  httpHeader->put(HttpHeader::LOCATION,
-                  "http://localhost/archives/aria2-1.0.0.tar.bz2");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LOCATION,
+     "http://localhost/archives/aria2-1.0.0.tar.bz2");
   try {
     httpResponse.validateResponse();
   } catch(Exception& e) {
@@ -371,8 +347,8 @@ void HttpResponseTest::testValidateResponse()
 void HttpResponseTest::testValidateResponse_good_range()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
 
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   std::shared_ptr<Piece> p(new Piece(1, 1024*1024));
@@ -384,8 +360,9 @@ void HttpResponseTest::testValidateResponse_good_range()
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
-  httpHeader->setStatusCode(206);
-  httpHeader->put(HttpHeader::CONTENT_RANGE, "bytes 1048576-10485760/10485760");
+  httpResponse.getHttpHeader()->setStatusCode(206);
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
+                                    "bytes 1048576-10485760/10485760");
 
   try {
     httpResponse.validateResponse();
@@ -398,8 +375,8 @@ void HttpResponseTest::testValidateResponse_good_range()
 void HttpResponseTest::testValidateResponse_bad_range()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
 
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   std::shared_ptr<Piece> p(new Piece(1, 1024*1024));
@@ -411,8 +388,9 @@ void HttpResponseTest::testValidateResponse_bad_range()
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
-  httpHeader->setStatusCode(206);
-  httpHeader->put(HttpHeader::CONTENT_RANGE, "bytes 0-10485760/10485761");
+  httpResponse.getHttpHeader()->setStatusCode(206);
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
+                                    "bytes 0-10485760/10485761");
 
   try {
     httpResponse.validateResponse();
@@ -424,8 +402,7 @@ void HttpResponseTest::testValidateResponse_bad_range()
 void HttpResponseTest::testValidateResponse_chunked()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
 
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   std::shared_ptr<Piece> p(new Piece(1, 1024*1024));
@@ -437,9 +414,10 @@ void HttpResponseTest::testValidateResponse_chunked()
   request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
-  httpHeader->setStatusCode(206);
-  httpHeader->put(HttpHeader::CONTENT_RANGE, "bytes 0-10485760/10485761");
-  httpHeader->put(HttpHeader::TRANSFER_ENCODING, "chunked");
+  httpResponse.getHttpHeader()->setStatusCode(206);
+  httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
+                                    "bytes 0-10485760/10485761");
+  httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
 
   // if transfer-encoding is specified, then range validation is skipped.
   try {
@@ -452,9 +430,8 @@ void HttpResponseTest::testValidateResponse_chunked()
 void HttpResponseTest::testValidateResponse_withIfModifiedSince()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
-  httpHeader->setStatusCode(304);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
+  httpResponse.getHttpHeader()->setStatusCode(304);
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   httpResponse.setHttpRequest(httpRequest);
   try {
@@ -469,8 +446,8 @@ void HttpResponseTest::testValidateResponse_withIfModifiedSince()
 void HttpResponseTest::testProcessRedirect()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
 
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   std::shared_ptr<Request> request(new Request());
@@ -478,22 +455,24 @@ void HttpResponseTest::testProcessRedirect()
   httpRequest->setRequest(request);
   httpResponse.setHttpRequest(httpRequest);
 
-  httpHeader->put(HttpHeader::LOCATION, "http://mirror/aria2-1.0.0.tar.bz2");
+  httpResponse.getHttpHeader()->put(HttpHeader::LOCATION,
+                                    "http://mirror/aria2-1.0.0.tar.bz2");
   httpResponse.processRedirect();
 
-  httpHeader->clearField();
+  httpResponse.getHttpHeader()->clearField();
 
   // Test for percent-encode
-  httpHeader->put(HttpHeader::LOCATION, "http://example.org/white space#aria2");
+  httpResponse.getHttpHeader()->put(HttpHeader::LOCATION,
+                                    "http://example.org/white space#aria2");
   httpResponse.processRedirect();
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"),
                        request->getCurrentUri());
 
-  httpHeader->clearField();
+  httpResponse.getHttpHeader()->clearField();
 
   // Give unsupported scheme
-  httpHeader->put(HttpHeader::LOCATION,
-                  "unsupported://mirror/aria2-1.0.0.tar.bz2");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LOCATION, "unsupported://mirror/aria2-1.0.0.tar.bz2");
   try {
     httpResponse.processRedirect();
     CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
@@ -507,8 +486,8 @@ void HttpResponseTest::testProcessRedirect()
 void HttpResponseTest::testRetrieveCookie()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
 
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   std::shared_ptr<Request> request(new Request());
@@ -518,13 +497,15 @@ void HttpResponseTest::testRetrieveCookie()
   httpRequest->setCookieStorage(&st);
   httpResponse.setHttpRequest(httpRequest);
 
-  httpHeader->put(HttpHeader::SET_COOKIE,
-                  "k1=v1; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
-                  "path=/; domain=.aria2.org;");
-  httpHeader->put(HttpHeader::SET_COOKIE,
-                  "k2=v2; expires=Sun, 01-Jan-38 00:00:00 GMT;"
-                  "path=/; domain=.aria2.org;");
-  httpHeader->put(HttpHeader::SET_COOKIE, "k3=v3;");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::SET_COOKIE,
+     "k1=v1; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
+     "path=/; domain=.aria2.org;");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::SET_COOKIE,
+     "k2=v2; expires=Sun, 01-Jan-38 00:00:00 GMT;"
+     "path=/; domain=.aria2.org;");
+  httpResponse.getHttpHeader()->put(HttpHeader::SET_COOKIE, "k3=v3;");
 
   httpResponse.retrieveCookie();
 
@@ -539,69 +520,78 @@ void HttpResponseTest::testRetrieveCookie()
 void HttpResponseTest::testSupportsPersistentConnection()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   std::shared_ptr<HttpRequest> httpRequest(new HttpRequest());
   httpResponse.setHttpRequest(httpRequest);
 
-  httpHeader->setVersion("HTTP/1.1");
+  httpResponse.getHttpHeader()->setVersion("HTTP/1.1");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->put(HttpHeader::CONNECTION, "close");
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
-  httpHeader->put(HttpHeader::CONNECTION, "keep-alive");
+  httpResponse.getHttpHeader()->clearField();
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
+  httpResponse.getHttpHeader()->clearField();
 
-  httpHeader->setVersion("HTTP/1.0");
+  httpResponse.getHttpHeader()->setVersion("HTTP/1.0");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->put(HttpHeader::CONNECTION, "close");
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
-  httpHeader->put(HttpHeader::CONNECTION, "keep-alive");
+  httpResponse.getHttpHeader()->clearField();
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
+  httpResponse.getHttpHeader()->clearField();
 
   // test proxy connection
   std::shared_ptr<Request> proxyRequest(new Request());
   httpRequest->setProxyRequest(proxyRequest);
 
-  httpHeader->setVersion("HTTP/1.1");
+  httpResponse.getHttpHeader()->setVersion("HTTP/1.1");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->put(HttpHeader::CONNECTION, "close");
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
-  httpHeader->put(HttpHeader::CONNECTION, "keep-alive");
+  httpResponse.getHttpHeader()->clearField();
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
+  httpResponse.getHttpHeader()->clearField();
 
-  httpHeader->setVersion("HTTP/1.0");
+  httpResponse.getHttpHeader()->setVersion("HTTP/1.0");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->put(HttpHeader::CONNECTION, "close");
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
   CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
-  httpHeader->put(HttpHeader::CONNECTION, "keep-alive");
+  httpResponse.getHttpHeader()->clearField();
+  httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
   CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
-  httpHeader->clearField();
+  httpResponse.getHttpHeader()->clearField();
 }
 
 void HttpResponseTest::testGetMetalinKHttpEntries()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   std::shared_ptr<Option> option(new Option());
 
-  httpHeader->put(HttpHeader::LINK,
-                  "<http://uri1/>; rel=duplicate; pri=1; pref; geo=JP");
-  httpHeader->put(HttpHeader::LINK,
-                  "<http://uri2/>; rel=duplicate");
-  httpHeader->put(HttpHeader::LINK,
-                  "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
-  httpHeader->put(HttpHeader::LINK, "<http://uri4/>;rel=duplicate;=pri=1;pref");
-  httpHeader->put(HttpHeader::LINK, "<http://describedby>; rel=describedby");
-  httpHeader->put(HttpHeader::LINK, "<http://norel/>");
-  httpHeader->put(HttpHeader::LINK, "<baduri>; rel=duplicate; pri=-1;");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LINK,
+     "<http://uri1/>; rel=duplicate; pri=1; pref; geo=JP");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LINK,
+     "<http://uri2/>; rel=duplicate");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LINK,
+     "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LINK,
+     "<http://uri4/>;rel=duplicate;=pri=1;pref");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LINK,
+     "<http://describedby>; rel=describedby");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LINK,
+     "<http://norel/>");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::LINK,
+     "<baduri>; rel=duplicate; pri=-1;");
   std::vector<MetalinkHttpEntry> result;
   httpResponse.getMetalinKHttpEntries(result, option);
   CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
@@ -641,20 +631,23 @@ void HttpResponseTest::testGetMetalinKHttpEntries()
 void HttpResponseTest::testGetDigest()
 {
   HttpResponse httpResponse;
-  std::shared_ptr<HttpHeader> httpHeader(new HttpHeader());
-  httpResponse.setHttpHeader(httpHeader);
+  httpResponse.setHttpHeader(make_unique<HttpHeader>());
   std::shared_ptr<Option> option(new Option());
   // Python binascii.hexlify(base64.b64decode(B64ED_HASH)) is handy to
   // retrieve ascii hex hash string.
-  httpHeader->put(HttpHeader::DIGEST, "SHA-1=82AD8itGL/oYQ5BTPFANiYnp9oE=");
-  httpHeader->put(HttpHeader::DIGEST, "NOT_SUPPORTED");
-  httpHeader->put(HttpHeader::DIGEST,
-                  "SHA-224=rQdowoLHQJTMVZ3rF7vmYOIzUXlu7F+FcMbPnA==");
-  httpHeader->put(HttpHeader::DIGEST,
-                  "SHA-224=6Ik6LNZ1iPy6cbmlKO4NHfvxzaiurmHilMyhGA==");
-  httpHeader->put(HttpHeader::DIGEST,
-                  "SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
-                  "MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
+  httpResponse.getHttpHeader()->put(HttpHeader::DIGEST,
+                                    "SHA-1=82AD8itGL/oYQ5BTPFANiYnp9oE=");
+  httpResponse.getHttpHeader()->put(HttpHeader::DIGEST, "NOT_SUPPORTED");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::DIGEST,
+     "SHA-224=rQdowoLHQJTMVZ3rF7vmYOIzUXlu7F+FcMbPnA==");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::DIGEST,
+     "SHA-224=6Ik6LNZ1iPy6cbmlKO4NHfvxzaiurmHilMyhGA==");
+  httpResponse.getHttpHeader()->put
+    (HttpHeader::DIGEST,
+     "SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
+     "MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
   std::vector<Checksum> result;
   httpResponse.getDigest(result);
   CPPUNIT_ASSERT_EQUAL((size_t)3, result.size());