summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/HttpHeader.cc127
-rw-r--r--src/HttpHeader.h69
-rw-r--r--src/HttpResponse.cc45
-rw-r--r--src/HttpServer.cc13
-rw-r--r--src/LpdMessageReceiver.cc6
-rw-r--r--src/util.h10
6 files changed, 140 insertions, 130 deletions
diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
index 363ffcb3..efb036ec 100644
--- a/src/HttpHeader.cc
+++ b/src/HttpHeader.cc
@@ -39,56 +39,48 @@
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() {}
-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);
}
-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 =
- table_.find(util::toLower(name));
+ table_.find(name);
if(itr == table_.end()) {
return A2STR::NIL;
} 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::string n(util::toLower(name));
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;
}
std::pair<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()) {
return 0;
} else {
@@ -134,9 +123,9 @@ uint64_t HttpHeader::getFirstAsULLInt(const std::string& name) const {
RangeHandle HttpHeader::getRange() const
{
- const std::string& rangeStr = getFirst(CONTENT_RANGE);
+ const std::string& rangeStr = find(CONTENT_RANGE);
if(rangeStr.empty()) {
- const std::string& clenStr = getFirst(CONTENT_LENGTH);
+ const std::string& clenStr = find(CONTENT_LENGTH);
if(clenStr.empty()) {
return SharedHandle<Range>(new Range());
} else {
@@ -231,6 +220,7 @@ void HttpHeader::fill
std::pair<std::string::const_iterator,
std::string::const_iterator> p = util::stripIter(first, sep);
name.assign(p.first, p.second);
+ util::lowercase(name);
p = util::stripIter(sep+1, j);
value.assign(p.first, p.second);
}
@@ -250,4 +240,29 @@ void HttpHeader::clearField()
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
diff --git a/src/HttpHeader.h b/src/HttpHeader.h
index 776fcdbd..547a7615 100644
--- a/src/HttpHeader.h
+++ b/src/HttpHeader.h
@@ -68,30 +68,21 @@ public:
void put(const std::string& name, const std::string& value);
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::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;
- 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);
@@ -101,10 +92,7 @@ public:
version_.assign(first, last);
}
- const std::string& getMethod() const
- {
- return method_;
- }
+ const std::string& getMethod() const;
void setMethod(const std::string& method);
@@ -114,10 +102,7 @@ public:
method_.assign(first, last);
}
- const std::string& getRequestPath() const
- {
- return requestPath_;
- }
+ const std::string& getRequestPath() const;
void setRequestPath(const std::string& requestPath);
@@ -127,6 +112,8 @@ public:
requestPath_.assign(first, last);
}
+ // Parses header fields in [first, last). Field name is stored in
+ // lowercase.
void fill
(std::string::const_iterator first,
std::string::const_iterator last);
@@ -135,42 +122,28 @@ public:
void clearField();
static const std::string LOCATION;
-
static const std::string TRANSFER_ENCODING;
-
static const std::string CONTENT_ENCODING;
-
static const std::string CONTENT_DISPOSITION;
-
static const std::string SET_COOKIE;
-
static const std::string CONTENT_TYPE;
-
static const std::string RETRY_AFTER;
-
static const std::string CONNECTION;
-
static const std::string CONTENT_LENGTH;
-
static const std::string CONTENT_RANGE;
-
static const std::string LAST_MODIFIED;
-
static const std::string ACCEPT_ENCODING;
-
static const std::string LINK;
-
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;
diff --git a/src/HttpResponse.cc b/src/HttpResponse.cc
index 59438d1a..d1cad443 100644
--- a/src/HttpResponse.cc
+++ b/src/HttpResponse.cc
@@ -57,6 +57,7 @@
#include "uri.h"
#include "MetalinkHttpEntry.h"
#include "base64.h"
+#include "array_fun.h"
#ifdef ENABLE_MESSAGE_DIGEST
#include "MessageDigest.h"
#endif // ENABLE_MESSAGE_DIGEST
@@ -118,7 +119,7 @@ std::string HttpResponse::determinFilename() const
{
std::string contentDisposition =
util::getContentDispositionFilename
- (httpHeader_->getFirst(HttpHeader::CONTENT_DISPOSITION));
+ (httpHeader_->find(HttpHeader::CONTENT_DISPOSITION));
if(contentDisposition.empty()) {
std::string file =
util::percentDecode(httpRequest_->getFile().begin(),
@@ -141,7 +142,7 @@ void HttpResponse::retrieveCookie()
Time now;
std::pair<std::multimap<std::string, std::string>::const_iterator,
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) {
httpRequest_->getCookieStorage()->parseAndStore
((*r.first).second, httpRequest_->getHost(), httpRequest_->getDir(),
@@ -177,7 +178,7 @@ void HttpResponse::processRedirect()
const std::string& HttpResponse::getRedirectURI() const
{
- return httpHeader_->getFirst(HttpHeader::LOCATION);
+ return httpHeader_->find(HttpHeader::LOCATION);
}
bool HttpResponse::isTransferEncodingSpecified() const
@@ -188,7 +189,7 @@ bool HttpResponse::isTransferEncodingSpecified() const
const std::string& HttpResponse::getTransferEncoding() const
{
// TODO See TODO in getTransferEncodingStreamFilter()
- return httpHeader_->getFirst(HttpHeader::TRANSFER_ENCODING);
+ return httpHeader_->find(HttpHeader::TRANSFER_ENCODING);
}
SharedHandle<StreamFilter> HttpResponse::getTransferEncodingStreamFilter() const
@@ -211,7 +212,7 @@ bool HttpResponse::isContentEncodingSpecified() const
const std::string& HttpResponse::getContentEncoding() const
{
- return httpHeader_->getFirst(HttpHeader::CONTENT_ENCODING);
+ return httpHeader_->find(HttpHeader::CONTENT_ENCODING);
}
SharedHandle<StreamFilter> HttpResponse::getContentEncodingStreamFilter() const
@@ -249,7 +250,7 @@ std::string HttpResponse::getContentType() const
if(!httpHeader_) {
return A2STR::NIL;
} 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(), ';');
Scip p = util::stripIter(ctype.begin(), i);
return std::string(p.first, p.second);
@@ -278,27 +279,35 @@ bool HttpResponse::hasRetryAfter() const
time_t HttpResponse::getRetryAfter() const
{
- return httpHeader_->getFirstAsUInt(HttpHeader::RETRY_AFTER);
+ return httpHeader_->findAsUInt(HttpHeader::RETRY_AFTER);
}
Time HttpResponse::getLastModifiedTime() const
{
- return Time::parseHTTPDate(httpHeader_->getFirst(HttpHeader::LAST_MODIFIED));
+ return Time::parseHTTPDate(httpHeader_->find(HttpHeader::LAST_MODIFIED));
}
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
- 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 ||
- 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() ||
- 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 {
@@ -368,7 +377,7 @@ void HttpResponse::getMetalinKHttpEntries
{
std::pair<std::multimap<std::string, std::string>::const_iterator,
std::multimap<std::string, std::string>::const_iterator> p =
- httpHeader_->getIterator(HttpHeader::LINK);
+ httpHeader_->equalRange(HttpHeader::LINK);
for(; p.first != p.second; ++p.first) {
MetalinkHttpEntry e;
if(parseMetalinkHttpLink(e, (*p.first).second)) {
@@ -403,7 +412,7 @@ void HttpResponse::getDigest(std::vector<Checksum>& result) const
using std::swap;
std::pair<std::multimap<std::string, std::string>::const_iterator,
std::multimap<std::string, std::string>::const_iterator> p =
- httpHeader_->getIterator(HttpHeader::DIGEST);
+ httpHeader_->equalRange(HttpHeader::DIGEST);
for(; p.first != p.second; ++p.first) {
const std::string& s = (*p.first).second;
std::string::const_iterator itr = s.begin();
diff --git a/src/HttpServer.cc b/src/HttpServer.cc
index d55c1e34..22dd22f8 100644
--- a/src/HttpServer.cc
+++ b/src/HttpServer.cc
@@ -90,11 +90,11 @@ SharedHandle<HttpHeader> HttpServer::receiveRequest()
lastBody_.clear();
lastBody_.str("");
lastContentLength_ =
- lastRequestHeader_->getFirstAsUInt(HttpHeader::CONTENT_LENGTH);
+ lastRequestHeader_->findAsUInt(HttpHeader::CONTENT_LENGTH);
headerProcessor_->clear();
std::string connection =
- util::toLower(lastRequestHeader_->getFirst(HttpHeader::CONNECTION));
+ util::toLower(lastRequestHeader_->find(HttpHeader::CONNECTION));
acceptsPersistentConnection_ =
connection.find(HttpHeader::CLOSE) == std::string::npos &&
(lastRequestHeader_->getVersion() == HttpHeader::HTTP_1_1 ||
@@ -102,14 +102,14 @@ SharedHandle<HttpHeader> HttpServer::receiveRequest()
std::vector<Scip> acceptEncodings;
const std::string& acceptEnc =
- lastRequestHeader_->getFirst(HttpHeader::ACCEPT_ENCODING);
+ lastRequestHeader_->find(HttpHeader::ACCEPT_ENCODING);
util::splitIter(acceptEnc.begin(), acceptEnc.end(),
std::back_inserter(acceptEncodings), ',', true);
- const char A2_GZIP[] = "gzip";
acceptsGZip_ = false;
for(std::vector<Scip>::const_iterator i = acceptEncodings.begin(),
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;
break;
}
@@ -214,7 +214,8 @@ bool HttpServer::authenticate()
return true;
}
- const std::string& authHeader = lastRequestHeader_->getFirst("Authorization");
+ const std::string& authHeader =
+ lastRequestHeader_->find(HttpHeader::AUTHORIZATION);
if(authHeader.empty()) {
return false;
}
diff --git a/src/LpdMessageReceiver.cc b/src/LpdMessageReceiver.cc
index e46dc915..0d817776 100644
--- a/src/LpdMessageReceiver.cc
+++ b/src/LpdMessageReceiver.cc
@@ -94,8 +94,10 @@ SharedHandle<LpdMessage> LpdMessageReceiver::receiveMessage()
return msg;
}
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",
infoHashString.c_str(),
port,
diff --git a/src/util.h b/src/util.h
index 3b5f3e88..9aa1f58a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -729,6 +729,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>
bool strieq
(InputIterator1 first1,
InputIterator1 last1,