summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--src/AbstractProxyResponseCommand.cc2
-rw-r--r--src/HttpConnection.cc7
-rw-r--r--src/HttpHeader.cc35
-rw-r--r--src/HttpHeader.h18
-rw-r--r--src/HttpHeaderProcessor.cc20
-rw-r--r--src/HttpHeaderProcessor.h6
-rw-r--r--src/HttpResponse.cc24
-rw-r--r--src/HttpResponse.h11
-rw-r--r--test/HttpHeaderProcessorTest.cc50
-rw-r--r--test/HttpResponseTest.cc21
11 files changed, 136 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index 7da797fc..bfd09471 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2008-04-21 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
+
+ Now HTTP status and version are a member variable of HttpHeader.
+ HTTP status is processed as a string, not integer.
+ * src/AbstractProxyResponseCommand.cc
+ * src/HttpConnection.cc
+ * src/HttpHeader.cc
+ * src/HttpHeader.h
+ * src/HttpHeaderProcessor.cc
+ * src/HttpHeaderProcessor.h
+ * src/HttpResponse.cc
+ * src/HttpResponse.h
+ * test/HttpHeaderProcessorTest.cc
+ * test/HttpResponseTest.cc
+
2008-04-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added --header option. You can specify any number of additional HTTP headers
diff --git a/src/AbstractProxyResponseCommand.cc b/src/AbstractProxyResponseCommand.cc
index e27ff382..e7a620be 100644
--- a/src/AbstractProxyResponseCommand.cc
+++ b/src/AbstractProxyResponseCommand.cc
@@ -65,7 +65,7 @@ bool AbstractProxyResponseCommand::executeInternal() {
e->commands.push_back(this);
return false;
}
- if(httpResponse->getStatus() != 200) {
+ if(httpResponse->getResponseStatus() != "200") {
throw new DlRetryEx(EX_PROXY_CONNECTION_FAILED);
}
e->commands.push_back(getNextCommand());
diff --git a/src/HttpConnection.cc b/src/HttpConnection.cc
index e624a040..02a9e600 100644
--- a/src/HttpConnection.cc
+++ b/src/HttpConnection.cc
@@ -134,15 +134,14 @@ HttpResponseHandle HttpConnection::receiveResponse()
// OK, we got all headers.
logger->info(MSG_RECEIVE_RESPONSE, cuid, proc->getHeaderString().c_str());
- std::pair<std::string, HttpHeaderHandle> httpStatusHeader = proc->getHttpStatusHeader();
- if(Util::toLower(httpStatusHeader.second->getFirst("Connection")).find("close") != std::string::npos) {
+ SharedHandle<HttpHeader> httpHeader = proc->getHttpResponseHeader();
+ if(Util::toLower(httpHeader->getFirst("Connection")).find("close") != std::string::npos) {
entry->getHttpRequest()->getRequest()->setKeepAlive(false);
}
HttpResponseHandle httpResponse(new HttpResponse());
httpResponse->setCuid(cuid);
- httpResponse->setStatus(Util::parseInt(httpStatusHeader.first));
- httpResponse->setHttpHeader(httpStatusHeader.second);
+ httpResponse->setHttpHeader(httpHeader);
httpResponse->setHttpRequest(entry->getHttpRequest());
outstandingHttpRequests.pop_front();
diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
index 9a9ad225..5a80665e 100644
--- a/src/HttpHeader.cc
+++ b/src/HttpHeader.cc
@@ -35,6 +35,7 @@
#include "HttpHeader.h"
#include "Range.h"
#include "Util.h"
+#include <istream>
namespace aria2 {
@@ -120,4 +121,38 @@ RangeHandle HttpHeader::getRange() const
return SharedHandle<Range>(new Range(startByte, endByte, entityLength));
}
+const std::string& HttpHeader::getResponseStatus() const
+{
+ return _responseStatus;
+}
+
+void HttpHeader::setResponseStatus(const std::string& responseStatus)
+{
+ _responseStatus = responseStatus;
+}
+
+const std::string& HttpHeader::getVersion() const
+{
+ return _version;
+}
+
+void HttpHeader::setVersion(const std::string& version)
+{
+ _version = version;
+}
+
+void HttpHeader::fill(std::istream& in)
+{
+ std::string line;
+ while(std::getline(in, line)) {
+ line = Util::trim(line);
+ if(line.empty()) {
+ break;
+ }
+ std::pair<std::string, std::string> hp;
+ Util::split(hp, line, ':');
+ put(hp.first, hp.second);
+ }
+}
+
} // namespace aria2
diff --git a/src/HttpHeader.h b/src/HttpHeader.h
index 6349a9b7..87c7c82c 100644
--- a/src/HttpHeader.h
+++ b/src/HttpHeader.h
@@ -40,6 +40,7 @@
#include <map>
#include <deque>
#include <string>
+#include <iosfwd>
namespace aria2 {
@@ -48,6 +49,13 @@ class Range;
class HttpHeader {
private:
std::multimap<std::string, std::string> table;
+
+ // for HTTP response header only
+ // response status, e.g. "200"
+ std::string _responseStatus;
+
+ // HTTP version, e.g. HTTP/1.1
+ std::string _version;
public:
HttpHeader() {}
~HttpHeader() {}
@@ -60,6 +68,16 @@ public:
uint64_t getFirstAsULLInt(const std::string& name) const;
SharedHandle<Range> getRange() const;
+
+ const std::string& getResponseStatus() const;
+
+ void setResponseStatus(const std::string& responseStatus);
+
+ const std::string& getVersion() const;
+
+ void setVersion(const std::string& version);
+
+ void fill(std::istream& in);
};
typedef SharedHandle<HttpHeader> HttpHeaderHandle;
diff --git a/src/HttpHeaderProcessor.cc b/src/HttpHeaderProcessor.cc
index 254bb737..b16d7f90 100644
--- a/src/HttpHeaderProcessor.cc
+++ b/src/HttpHeaderProcessor.cc
@@ -77,7 +77,7 @@ bool HttpHeaderProcessor::eoh() const
size_t HttpHeaderProcessor::getPutBackDataLength() const
{
- std::string str = strm.str();
+ const std::string& str = strm.str();
std::string::size_type delimpos = std::string::npos;
if((delimpos = str.find("\r\n\r\n")) != std::string::npos) {
return str.size()-(delimpos+4);
@@ -93,7 +93,7 @@ void HttpHeaderProcessor::clear()
strm.str("");
}
-std::pair<std::string, HttpHeaderHandle> HttpHeaderProcessor::getHttpStatusHeader()
+SharedHandle<HttpHeader> HttpHeaderProcessor::getHttpResponseHeader()
{
strm.seekg(0, std::ios::beg);
std::string line;
@@ -102,19 +102,11 @@ std::pair<std::string, HttpHeaderHandle> HttpHeaderProcessor::getHttpStatusHeade
if(line.size() <= 12) {
throw new DlRetryEx(EX_NO_STATUS_HEADER);
}
- std::string status = line.substr(9, 3);
HttpHeaderHandle httpHeader(new HttpHeader());
- while(getline(strm, line)) {
- line = Util::trim(line);
- if(line.empty()) {
- break;
- }
- std::pair<std::string, std::string> hp;
- Util::split(hp, line, ':');
- httpHeader->put(hp.first, hp.second);
- }
-
- return std::pair<std::string, HttpHeaderHandle>(status, httpHeader);
+ httpHeader->setResponseStatus(line.substr(9, 3));
+ httpHeader->setVersion(line.substr(0, 8));
+ httpHeader->fill(strm);
+ return httpHeader;
}
std::string HttpHeaderProcessor::getHeaderString() const
diff --git a/src/HttpHeaderProcessor.h b/src/HttpHeaderProcessor.h
index fc6814d3..e4bdc9f1 100644
--- a/src/HttpHeaderProcessor.h
+++ b/src/HttpHeaderProcessor.h
@@ -70,7 +70,11 @@ public:
*/
size_t getPutBackDataLength() const;
- std::pair<std::string, SharedHandle<HttpHeader> > getHttpStatusHeader();
+ /**
+ * Processes the recieved header as a http response header and returns
+ * HttpHeader object.
+ */
+ SharedHandle<HttpHeader> getHttpResponseHeader();
std::string getHeaderString() const;
diff --git a/src/HttpResponse.cc b/src/HttpResponse.cc
index 05946e27..90cc528c 100644
--- a/src/HttpResponse.cc
+++ b/src/HttpResponse.cc
@@ -50,7 +50,6 @@
namespace aria2 {
HttpResponse::HttpResponse():cuid(0),
- status(0),
logger(LogFactory::getInstance())
{}
@@ -58,19 +57,19 @@ HttpResponse::~HttpResponse() {}
void HttpResponse::validateResponse() const
{
- if(status == 401) {
+ const std::string& status = getResponseStatus();
+ if(status == "401") {
throw new DlAbortEx(EX_AUTH_FAILED);
}
- if(status == 404) {
+ if(status == "404") {
throw new DlAbortEx(MSG_RESOURCE_NOT_FOUND);
}
- if(status >= 400) {
- throw new DlAbortEx(EX_BAD_STATUS, status);
+ if(status >= "400") {
+ throw new DlAbortEx(EX_BAD_STATUS, Util::parseUInt(status));
}
- if(status >= 300) {
+ if(status >= "300") {
if(!httpHeader->defined("Location")) {
- throw new DlAbortEx(EX_LOCATION_HEADER_REQUIRED,
- status);
+ throw new DlAbortEx(EX_LOCATION_HEADER_REQUIRED, Util::parseUInt(status));
}
} else {
if(!httpHeader->defined("Transfer-Encoding")) {
@@ -114,7 +113,8 @@ void HttpResponse::retrieveCookie()
bool HttpResponse::isRedirect() const
{
- return 300 <= status && status < 400 && httpHeader->defined("Location");
+ const std::string& status = getResponseStatus();
+ return "300" <= status && status < "400" && httpHeader->defined("Location");
}
void HttpResponse::processRedirect()
@@ -195,4 +195,10 @@ SharedHandle<HttpRequest> HttpResponse::getHttpRequest() const
return httpRequest;
}
+// TODO return std::string
+const std::string& HttpResponse::getResponseStatus() const
+{
+ return httpHeader->getResponseStatus();
+}
+
} // namespace aria2
diff --git a/src/HttpResponse.h b/src/HttpResponse.h
index 57cfdd83..7ec54db9 100644
--- a/src/HttpResponse.h
+++ b/src/HttpResponse.h
@@ -49,7 +49,6 @@ class Logger;
class HttpResponse {
private:
int32_t cuid;
- unsigned int status;
SharedHandle<HttpRequest> httpRequest;
SharedHandle<HttpHeader> httpHeader;
const Logger* logger;
@@ -95,15 +94,7 @@ public:
SharedHandle<HttpHeader> getHttpHeader() const;
- void setStatus(unsigned int status)
- {
- this->status = status;
- }
-
- unsigned int getStatus() const
- {
- return status;
- }
+ const std::string& getResponseStatus() const;
void setHttpRequest(const SharedHandle<HttpRequest>& httpRequest);
diff --git a/test/HttpHeaderProcessorTest.cc b/test/HttpHeaderProcessorTest.cc
index 4f359e44..38e9f0fc 100644
--- a/test/HttpHeaderProcessorTest.cc
+++ b/test/HttpHeaderProcessorTest.cc
@@ -14,10 +14,10 @@ class HttpHeaderProcessorTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testUpdate2);
CPPUNIT_TEST(testGetPutBackDataLength);
CPPUNIT_TEST(testGetPutBackDataLength_nullChar);
- CPPUNIT_TEST(testGetHttpStatusHeader);
- CPPUNIT_TEST(testGetHttpStatusHeader_empty);
- CPPUNIT_TEST(testGetHttpStatusHeader_statusOnly);
- CPPUNIT_TEST(testGetHttpStatusHeader_insufficientStatusLength);
+ CPPUNIT_TEST(testGetHttpResponseHeader);
+ CPPUNIT_TEST(testGetHttpResponseHeader_empty);
+ CPPUNIT_TEST(testGetHttpResponseHeader_statusOnly);
+ CPPUNIT_TEST(testGetHttpResponseHeader_insufficientStatusLength);
CPPUNIT_TEST(testBeyondLimit);
CPPUNIT_TEST(testGetHeaderString);
CPPUNIT_TEST_SUITE_END();
@@ -27,12 +27,13 @@ public:
void testUpdate2();
void testGetPutBackDataLength();
void testGetPutBackDataLength_nullChar();
- void testGetHttpStatusHeader();
- void testGetHttpStatusHeader_empty();
- void testGetHttpStatusHeader_statusOnly();
- void testGetHttpStatusHeader_insufficientStatusLength();
+ void testGetHttpResponseHeader();
+ void testGetHttpResponseHeader_empty();
+ void testGetHttpResponseHeader_statusOnly();
+ void testGetHttpResponseHeader_insufficientStatusLength();
void testBeyondLimit();
void testGetHeaderString();
+ void testGetHttpRequestHeader();
};
@@ -88,7 +89,7 @@ void HttpHeaderProcessorTest::testGetPutBackDataLength_nullChar()
CPPUNIT_ASSERT_EQUAL((size_t)9, proc.getPutBackDataLength());
}
-void HttpHeaderProcessorTest::testGetHttpStatusHeader()
+void HttpHeaderProcessorTest::testGetHttpResponseHeader()
{
HttpHeaderProcessor proc;
std::string hd = "HTTP/1.1 200 OK\r\n"
@@ -104,22 +105,24 @@ void HttpHeaderProcessorTest::testGetHttpStatusHeader()
proc.update(hd);
- std::pair<std::string, SharedHandle<HttpHeader> > statusHeader = proc.getHttpStatusHeader();
- std::string status = statusHeader.first;
- SharedHandle<HttpHeader> header = statusHeader.second;
- CPPUNIT_ASSERT_EQUAL(std::string("200"), status);
- CPPUNIT_ASSERT_EQUAL(std::string("Mon, 25 Jun 2007 16:04:59 GMT"), header->getFirst("Date"));
- CPPUNIT_ASSERT_EQUAL(std::string("Apache/2.2.3 (Debian)"), header->getFirst("Server"));
+ SharedHandle<HttpHeader> header = proc.getHttpResponseHeader();
+ CPPUNIT_ASSERT_EQUAL(std::string("200"), header->getResponseStatus());
+ CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion());
+ CPPUNIT_ASSERT_EQUAL(std::string("Mon, 25 Jun 2007 16:04:59 GMT"),
+ header->getFirst("Date"));
+ CPPUNIT_ASSERT_EQUAL(std::string("Apache/2.2.3 (Debian)"),
+ header->getFirst("Server"));
CPPUNIT_ASSERT_EQUAL(9187ULL, header->getFirstAsULLInt("Content-Length"));
- CPPUNIT_ASSERT_EQUAL(std::string("text/html; charset=UTF-8"), header->getFirst("Content-Type"));
+ CPPUNIT_ASSERT_EQUAL(std::string("text/html; charset=UTF-8"),
+ header->getFirst("Content-Type"));
}
-void HttpHeaderProcessorTest::testGetHttpStatusHeader_empty()
+void HttpHeaderProcessorTest::testGetHttpResponseHeader_empty()
{
HttpHeaderProcessor proc;
try {
- std::pair<std::string, SharedHandle<HttpHeader> > statusHeader = proc.getHttpStatusHeader();
+ proc.getHttpResponseHeader();
CPPUNIT_FAIL("Exception must be thrown.");
} catch(DlRetryEx* ex) {
std::cout << ex->getMsg() << std::endl;
@@ -128,25 +131,24 @@ void HttpHeaderProcessorTest::testGetHttpStatusHeader_empty()
}
-void HttpHeaderProcessorTest::testGetHttpStatusHeader_statusOnly()
+void HttpHeaderProcessorTest::testGetHttpResponseHeader_statusOnly()
{
HttpHeaderProcessor proc;
std::string hd = "HTTP/1.1 200\r\n\r\n";
proc.update(hd);
- std::pair<std::string, SharedHandle<HttpHeader> > statusHeader = proc.getHttpStatusHeader();
- CPPUNIT_ASSERT_EQUAL(std::string("200"), statusHeader.first);
- CPPUNIT_ASSERT(!statusHeader.second.isNull());
+ SharedHandle<HttpHeader> header = proc.getHttpResponseHeader();
+ CPPUNIT_ASSERT_EQUAL(std::string("200"), header->getResponseStatus());
}
-void HttpHeaderProcessorTest::testGetHttpStatusHeader_insufficientStatusLength()
+void HttpHeaderProcessorTest::testGetHttpResponseHeader_insufficientStatusLength()
{
HttpHeaderProcessor proc;
std::string hd = "HTTP/1.1 20\r\n\r\n";
proc.update(hd);
try {
- std::pair<std::string, SharedHandle<HttpHeader> > statusHeader = proc.getHttpStatusHeader();
+ proc.getHttpResponseHeader();
CPPUNIT_FAIL("Exception must be thrown.");
} catch(DlRetryEx* ex) {
std::cout << ex->getMsg() << std::endl;
diff --git a/test/HttpResponseTest.cc b/test/HttpResponseTest.cc
index 44fe44b5..df01b590 100644
--- a/test/HttpResponseTest.cc
+++ b/test/HttpResponseTest.cc
@@ -184,14 +184,14 @@ void HttpResponseTest::testIsRedirect()
{
HttpResponse httpResponse;
SharedHandle<HttpHeader> httpHeader(new HttpHeader());
+ httpHeader->setResponseStatus("200");
httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
httpResponse.setHttpHeader(httpHeader);
- httpResponse.setStatus(200);
CPPUNIT_ASSERT(!httpResponse.isRedirect());
- httpResponse.setStatus(304);
+ httpHeader->setResponseStatus("304");
CPPUNIT_ASSERT(httpResponse.isRedirect());
}
@@ -242,7 +242,9 @@ void HttpResponseTest::testValidateResponse()
{
HttpResponse httpResponse;
- httpResponse.setStatus(401);
+ SharedHandle<HttpHeader> httpHeader(new HttpHeader());
+ httpHeader->setResponseStatus("401");
+ httpResponse.setHttpHeader(httpHeader);
try {
httpResponse.validateResponse();
@@ -251,7 +253,7 @@ void HttpResponseTest::testValidateResponse()
delete e;
}
- httpResponse.setStatus(505);
+ httpHeader->setResponseStatus("505");
try {
httpResponse.validateResponse();
@@ -260,9 +262,8 @@ void HttpResponseTest::testValidateResponse()
delete e;
}
- httpResponse.setStatus(304);
- SharedHandle<HttpHeader> httpHeader(new HttpHeader());
- httpResponse.setHttpHeader(httpHeader);
+ httpHeader->setResponseStatus("304");
+
try {
httpResponse.validateResponse();
CPPUNIT_FAIL("exception must be thrown.");
@@ -295,7 +296,7 @@ void HttpResponseTest::testValidateResponse_good_range()
request->setKeepAlive(false);
httpRequest->setRequest(request);
httpResponse.setHttpRequest(httpRequest);
- httpResponse.setStatus(206);
+ httpHeader->setResponseStatus("206");
httpHeader->put("Content-Range", "bytes 1048576-10485760/10485761");
try {
@@ -322,7 +323,7 @@ void HttpResponseTest::testValidateResponse_bad_range()
request->setKeepAlive(false);
httpRequest->setRequest(request);
httpResponse.setHttpRequest(httpRequest);
- httpResponse.setStatus(206);
+ httpHeader->setResponseStatus("206");
httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
try {
@@ -348,7 +349,7 @@ void HttpResponseTest::testValidateResponse_chunked()
request->setKeepAlive(false);
httpRequest->setRequest(request);
httpResponse.setHttpRequest(httpRequest);
- httpResponse.setStatus(206);
+ httpHeader->setResponseStatus("206");
httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
httpHeader->put("Transfer-Encoding", "chunked");