summaryrefslogtreecommitdiff
path: root/src/HttpResponse.cc
diff options
context:
space:
mode:
authorNils Maier <maierman@web.de>2013-09-15 21:52:02 +0200
committerNils Maier <maierman@web.de>2013-09-20 23:06:49 +0200
commite2700f50a5d8da1596cefccc01d70aa4696e3f4a (patch)
tree86821bba593efefe83fe31da28b7c6a944f5d171 /src/HttpResponse.cc
parent29d569eef98cdcabe52c365e75ca4da2174d8bf0 (diff)
Code cleanup in Http*
Diffstat (limited to 'src/HttpResponse.cc')
-rw-r--r--src/HttpResponse.cc245
1 files changed, 130 insertions, 115 deletions
diff --git a/src/HttpResponse.cc b/src/HttpResponse.cc
index fa330867..c4562532 100644
--- a/src/HttpResponse.cc
+++ b/src/HttpResponse.cc
@@ -32,6 +32,7 @@
* files in the program, then also delete it here.
*/
/* copyright --> */
+
#include "HttpResponse.h"
#include "Request.h"
#include "Segment.h"
@@ -74,40 +75,43 @@ HttpResponse::HttpResponse()
void HttpResponse::validateResponse() const
{
int statusCode = getStatusCode();
- if(statusCode >= 400) {
+ if (statusCode >= 400) {
return;
}
- if(statusCode == 304) {
- if(!httpRequest_->conditionalRequest()) {
+
+ if (statusCode == 304) {
+ if (!httpRequest_->conditionalRequest()) {
throw DL_ABORT_EX2("Got 304 without If-Modified-Since or If-None-Match",
error_code::HTTP_PROTOCOL_ERROR);
}
- } else if(statusCode == 301 ||
- statusCode == 302 ||
- statusCode == 303 ||
- statusCode == 307) {
- if(!httpHeader_->defined(HttpHeader::LOCATION)) {
+ }
+ else if (statusCode == 301 ||
+ statusCode == 302 ||
+ statusCode == 303 ||
+ statusCode == 307) {
+ if (!httpHeader_->defined(HttpHeader::LOCATION)) {
throw DL_ABORT_EX2(fmt(EX_LOCATION_HEADER_REQUIRED, statusCode),
error_code::HTTP_PROTOCOL_ERROR);
}
return;
- } else if(statusCode == 200 || statusCode == 206) {
- if(!httpHeader_->defined(HttpHeader::TRANSFER_ENCODING)) {
+ }
+ else if (statusCode == 200 || statusCode == 206) {
+ if (!httpHeader_->defined(HttpHeader::TRANSFER_ENCODING)) {
// compare the received range against the requested range
- Range responseRange = httpHeader_->getRange();
- if(!httpRequest_->isRangeSatisfied(responseRange)) {
- throw DL_ABORT_EX2
- (fmt(EX_INVALID_RANGE_HEADER,
- httpRequest_->getStartByte(),
- httpRequest_->getEndByte(),
- httpRequest_->getEntityLength(),
- responseRange.startByte,
- responseRange.endByte,
- responseRange.entityLength),
- error_code::CANNOT_RESUME);
+ auto responseRange = httpHeader_->getRange();
+ if (!httpRequest_->isRangeSatisfied(responseRange)) {
+ throw DL_ABORT_EX2(fmt(EX_INVALID_RANGE_HEADER,
+ httpRequest_->getStartByte(),
+ httpRequest_->getEndByte(),
+ httpRequest_->getEntityLength(),
+ responseRange.startByte,
+ responseRange.endByte,
+ responseRange.entityLength),
+ error_code::CANNOT_RESUME);
}
}
- } else {
+ }
+ else {
throw DL_ABORT_EX2(fmt("Unexpected status %d", statusCode),
error_code::HTTP_PROTOCOL_ERROR);
}
@@ -115,18 +119,17 @@ void HttpResponse::validateResponse() const
std::string HttpResponse::determinFilename() const
{
- std::string contentDisposition =
- util::getContentDispositionFilename
- (httpHeader_->find(HttpHeader::CONTENT_DISPOSITION));
- if(contentDisposition.empty()) {
- std::string file =
- util::percentDecode(httpRequest_->getFile().begin(),
- httpRequest_->getFile().end());
- if(file.empty()) {
+ std::string contentDisposition = util::getContentDispositionFilename(
+ httpHeader_->find(HttpHeader::CONTENT_DISPOSITION));
+ if (contentDisposition.empty()) {
+ auto file = httpRequest_->getFile();
+ file = util::percentDecode(file.begin(), file.end());
+ if (file.empty()) {
return "index.html";
}
return file;
}
+
A2_LOG_INFO(fmt(MSG_CONTENT_DISPOSITION_DETECTED,
cuid_,
contentDisposition.c_str()));
@@ -136,39 +139,36 @@ std::string HttpResponse::determinFilename() const
void HttpResponse::retrieveCookie()
{
Time now;
- std::pair<std::multimap<int, std::string>::const_iterator,
- std::multimap<int, std::string>::const_iterator> r =
- httpHeader_->equalRange(HttpHeader::SET_COOKIE);
- for(; r.first != r.second; ++r.first) {
- httpRequest_->getCookieStorage()->parseAndStore
- ((*r.first).second, httpRequest_->getHost(), httpRequest_->getDir(),
- now.getTime());
+ auto r = httpHeader_->equalRange(HttpHeader::SET_COOKIE);
+ for (; r.first != r.second; ++r.first) {
+ httpRequest_->getCookieStorage()->parseAndStore(
+ (*r.first).second,
+ httpRequest_->getHost(),
+ httpRequest_->getDir(),
+ now.getTime());
}
}
bool HttpResponse::isRedirect() const
{
- int statusCode = getStatusCode();
- return (301 == statusCode ||
- 302 == statusCode ||
- 303 == statusCode ||
- 307 == statusCode) &&
- httpHeader_->defined(HttpHeader::LOCATION);
+ auto code = getStatusCode();
+ return (301 == code || 302 == code || 303 == code || 307 == code) &&
+ httpHeader_->defined(HttpHeader::LOCATION);
}
void HttpResponse::processRedirect()
{
- if(httpRequest_->getRequest()->redirectUri
- (util::percentEncodeMini(getRedirectURI()))) {
- A2_LOG_INFO(fmt(MSG_REDIRECT,
- cuid_,
- httpRequest_->getRequest()->getCurrentUri().c_str()));
- } else {
- throw DL_RETRY_EX
- (fmt("CUID#%" PRId64 " - Redirect to %s failed. It may not be a valid URI.",
- cuid_,
- httpRequest_->getRequest()->getCurrentUri().c_str()));
+ const auto& req = httpRequest_->getRequest();
+ if (!req->redirectUri(util::percentEncodeMini(getRedirectURI()))) {
+ throw DL_RETRY_EX(fmt("CUID#%" PRId64
+ " - Redirect to %s failed. It may not be a valid URI.",
+ cuid_,
+ req->getCurrentUri().c_str()));
}
+
+ A2_LOG_INFO(fmt(MSG_REDIRECT,
+ cuid_,
+ httpRequest_->getRequest()->getCurrentUri().c_str()));
}
const std::string& HttpResponse::getRedirectURI() const
@@ -192,8 +192,8 @@ HttpResponse::getTransferEncodingStreamFilter() const
{
// TODO Transfer-Encoding header field can contains multiple tokens. We should
// parse the field and retrieve each token.
- if(isTransferEncodingSpecified()) {
- if(util::strieq(getTransferEncoding(), "chunked")) {
+ if (isTransferEncodingSpecified()) {
+ if (util::strieq(getTransferEncoding(), "chunked")) {
return make_unique<ChunkedDecodingStreamFilter>();
}
}
@@ -219,6 +219,7 @@ HttpResponse::getContentEncodingStreamFilter() const
return make_unique<GZipDecodingStreamFilter>();
}
#endif // HAVE_ZLIB
+
return nullptr;
}
@@ -226,30 +227,30 @@ int64_t HttpResponse::getContentLength() const
{
if(!httpHeader_) {
return 0;
- } else {
- return httpHeader_->getRange().getContentLength();
}
+
+ return httpHeader_->getRange().getContentLength();
}
int64_t HttpResponse::getEntityLength() const
{
if(!httpHeader_) {
return 0;
- } else {
- return httpHeader_->getRange().entityLength;
}
+
+ return httpHeader_->getRange().entityLength;
}
std::string HttpResponse::getContentType() const
{
if(!httpHeader_) {
return A2STR::NIL;
- } else {
- 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);
}
+
+ const auto& ctype = httpHeader_->find(HttpHeader::CONTENT_TYPE);
+ auto i = std::find(ctype.begin(), ctype.end(), ';');
+ Scip p = util::stripIter(ctype.begin(), i);
+ return std::string(p.first, p.second);
}
void HttpResponse::setHttpHeader(std::unique_ptr<HttpHeader> httpHeader)
@@ -283,81 +284,93 @@ bool HttpResponse::supportsPersistentConnection() const
}
namespace {
+
bool parseMetalinkHttpLink(MetalinkHttpEntry& result, const std::string& s)
{
- std::string::const_iterator first = std::find(s.begin(), s.end(), '<');
- if(first == s.end()) {
+ const auto first = std::find(s.begin(), s.end(), '<');
+ if (first == s.end()) {
return false;
}
- std::string::const_iterator last = std::find(first, s.end(), '>');
+
+ auto last = std::find(first, s.end(), '>');
if(last == s.end()) {
return false;
}
- std::pair<std::string::const_iterator,
- std::string::const_iterator> p = util::stripIter(first+1, last);
- if(p.first == p.second) {
+
+ auto p = util::stripIter(first+1, last);
+ if (p.first == p.second) {
return false;
}
+
result.uri.assign(p.first, p.second);
last = std::find(last, s.end(), ';');
- if(last != s.end()) {
+ if (last != s.end()) {
++last;
}
bool ok = false;
- while(1) {
+ while (1) {
std::string name, value;
- std::pair<std::string::const_iterator, bool> r =
- util::nextParam(name, value, last, s.end(), ';');
+ auto r = util::nextParam(name, value, last, s.end(), ';');
last = r.first;
- if(!r.second) {
+
+ if (!r.second) {
break;
}
+
if(value.empty()) {
if(name == "pref") {
result.pref = true;
}
- } else {
- if(name == "rel") {
- if(value == "duplicate") {
- ok = true;
- } else {
- ok = false;
- }
- } else if(name == "pri") {
- int32_t priValue;
- if(util::parseIntNoThrow(priValue, value)) {
- if(1 <= priValue && priValue <= 999999) {
- result.pri = priValue;
- }
+ continue;
+ }
+
+ if(name == "rel") {
+ if(value == "duplicate") {
+ ok = true;
+ } else {
+ ok = false;
+ }
+ continue;
+ }
+
+ if (name == "pri") {
+ int32_t priValue;
+ if(util::parseIntNoThrow(priValue, value)) {
+ if(1 <= priValue && priValue <= 999999) {
+ result.pri = priValue;
}
- } else if(name == "geo") {
- util::lowercase(value);
- result.geo = value;
}
+ continue;
+ }
+
+ if (name == "geo") {
+ util::lowercase(value);
+ result.geo = value;
+ continue;
}
}
return ok;
}
+
} // namespace
// Metalink/HTTP is defined by http://tools.ietf.org/html/rfc6249.
// Link header field is defined by http://tools.ietf.org/html/rfc5988.
-void HttpResponse::getMetalinKHttpEntries
-(std::vector<MetalinkHttpEntry>& result,
- const std::shared_ptr<Option>& option) const
+void HttpResponse::getMetalinKHttpEntries(
+ std::vector<MetalinkHttpEntry>& result,
+ const std::shared_ptr<Option>& option) const
{
- std::pair<std::multimap<int, std::string>::const_iterator,
- std::multimap<int, std::string>::const_iterator> p =
- httpHeader_->equalRange(HttpHeader::LINK);
- for(; p.first != p.second; ++p.first) {
+ auto p = httpHeader_->equalRange(HttpHeader::LINK);
+ for (; p.first != p.second; ++p.first) {
MetalinkHttpEntry e;
if(parseMetalinkHttpLink(e, (*p.first).second)) {
result.push_back(e);
}
}
- if(!result.empty()) {
+
+ if (!result.empty()) {
std::vector<std::string> locs;
- if(option->defined(PREF_METALINK_LOCATION)) {
+ if (option->defined(PREF_METALINK_LOCATION)) {
const std::string& loc = option->get(PREF_METALINK_LOCATION);
util::split(loc.begin(), loc.end(), std::back_inserter(locs), ',', true);
for (auto& l: locs) {
@@ -370,6 +383,7 @@ void HttpResponse::getMetalinKHttpEntries
}
}
}
+
std::sort(result.begin(), result.end());
}
@@ -378,49 +392,50 @@ void HttpResponse::getMetalinKHttpEntries
// http://tools.ietf.org/html/rfc3230.
void HttpResponse::getDigest(std::vector<Checksum>& result) const
{
- using std::swap;
- std::pair<std::multimap<int, std::string>::const_iterator,
- std::multimap<int, std::string>::const_iterator> p =
- httpHeader_->equalRange(HttpHeader::DIGEST);
- for(; p.first != p.second; ++p.first) {
+ auto p = 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();
- while(1) {
+ while (1) {
std::string hashType, digest;
- std::pair<std::string::const_iterator, bool> r =
- util::nextParam(hashType, digest, itr, s.end(), ',');
+ auto r = util::nextParam(hashType, digest, itr, s.end(), ',');
itr = r.first;
- if(!r.second) {
+ if (!r.second) {
break;
}
+
util::lowercase(hashType);
digest = base64::decode(digest.begin(), digest.end());
- if(!MessageDigest::supports(hashType) ||
+ if (!MessageDigest::supports(hashType) ||
MessageDigest::getDigestLength(hashType) != digest.size()) {
continue;
}
+
result.push_back(Checksum(hashType, digest));
}
}
+
std::sort(result.begin(), result.end(), HashTypeStronger());
std::vector<Checksum> temp;
- for(auto i = result.begin(), eoi = result.end(); i != eoi;) {
+ for (auto i = result.begin(), eoi = result.end(); i != eoi;) {
bool ok = true;
- auto j = i+1;
+ auto j = i + 1;
for(; j != eoi; ++j) {
if((*i).getHashType() != (*j).getHashType()) {
break;
}
- if((*i).getDigest() != (*j).getDigest()) {
+
+ if ((*i).getDigest() != (*j).getDigest()) {
ok = false;
}
}
- if(ok) {
+
+ if (ok) {
temp.push_back(*i);
}
i = j;
}
- swap(temp, result);
+ std::swap(temp, result);
}
#endif // ENABLE_MESSAGE_DIGEST