summaryrefslogtreecommitdiff
path: root/src/HttpResponseCommand.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2011-07-27 21:02:53 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2011-07-27 21:02:53 +0900
commitc536e460aa893b20d0ff4d85b2e99b7f9e563d81 (patch)
treeee73d838258a37b7da3650463869225931a47194 /src/HttpResponseCommand.cc
parent3b9a75175729d8534e6c08763e182e3d5e89de12 (diff)
parenta533437be6fa9d4e563b91bf117e5644f6f0a7c9 (diff)
Merge branch 'rfc6249'
Diffstat (limited to 'src/HttpResponseCommand.cc')
-rw-r--r--src/HttpResponseCommand.cc70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc
index 88c19a21..c02e324b 100644
--- a/src/HttpResponseCommand.cc
+++ b/src/HttpResponseCommand.cc
@@ -72,6 +72,10 @@
#include "ChunkedDecodingStreamFilter.h"
#include "uri.h"
#include "SocketRecvBuffer.h"
+#include "MetalinkHttpEntry.h"
+#ifdef ENABLE_MESSAGE_DIGEST
+#include "Checksum.h"
+#endif // ENABLE_MESSAGE_DIGEST
#ifdef HAVE_ZLIB
# include "GZipDecodingStreamFilter.h"
#endif // HAVE_ZLIB
@@ -189,6 +193,42 @@ bool HttpResponseCommand::executeInternal()
getFileEntry()->poolRequest(getRequest());
return true;
}
+ if(!getPieceStorage()) {
+ // Metalink/HTTP
+ if(!getDownloadContext()->getMetalinkServerContacted()) {
+ if(httpHeader->defined(HttpHeader::LINK)) {
+ getDownloadContext()->setMetalinkServerContacted(true);
+ std::vector<MetalinkHttpEntry> entries;
+ httpResponse->getMetalinKHttpEntries(entries, getOption());
+ for(std::vector<MetalinkHttpEntry>::iterator i = entries.begin(),
+ eoi = entries.end(); i != eoi; ++i) {
+ getFileEntry()->addUri((*i).uri);
+ A2_LOG_DEBUG(fmt("Adding URI=%s", (*i).uri.c_str()));
+ }
+ }
+ }
+#ifdef ENABLE_MESSAGE_DIGEST
+ if(httpHeader->defined(HttpHeader::DIGEST)) {
+ std::vector<Checksum> checksums;
+ httpResponse->getDigest(checksums);
+ for(std::vector<Checksum>::iterator i = checksums.begin(),
+ eoi = checksums.end(); i != eoi; ++i) {
+ if(getDownloadContext()->getChecksumHashAlgo().empty()) {
+ A2_LOG_DEBUG(fmt("Setting digest: type=%s, digest=%s",
+ (*i).getAlgo().c_str(),
+ (*i).getMessageDigest().c_str()));
+ getDownloadContext()->setChecksumHashAlgo((*i).getAlgo());
+ getDownloadContext()->setChecksum((*i).getMessageDigest());
+ break;
+ } else {
+ if(checkChecksum(getDownloadContext(), *i)) {
+ break;
+ }
+ }
+ }
+ }
+#endif // ENABLE_MESSAGE_DIGEST
+ }
if(statusCode >= 300) {
if(statusCode == 404) {
getRequestGroup()->increaseAndValidateFileNotFoundCount();
@@ -241,6 +281,19 @@ bool HttpResponseCommand::executeInternal()
return handleDefaultEncoding(httpResponse);
}
} else {
+#ifdef ENABLE_MESSAGE_DIGEST
+ if(!getDownloadContext()->getChecksumHashAlgo().empty() &&
+ httpHeader->defined(HttpHeader::DIGEST)) {
+ std::vector<Checksum> checksums;
+ httpResponse->getDigest(checksums);
+ for(std::vector<Checksum>::iterator i = checksums.begin(),
+ eoi = checksums.end(); i != eoi; ++i) {
+ if(checkChecksum(getDownloadContext(), *i)) {
+ break;
+ }
+ }
+ }
+#endif // ENABLE_MESSAGE_DIGEST
// validate totalsize
getRequestGroup()->validateTotalLength(getFileEntry()->getLength(),
httpResponse->getEntityLength());
@@ -501,4 +554,21 @@ void HttpResponseCommand::onDryRunFileFound()
poolConnection();
}
+#ifdef ENABLE_MESSAGE_DIGEST
+bool HttpResponseCommand::checkChecksum
+(const SharedHandle<DownloadContext>& dctx,
+ const Checksum& checksum)
+{
+ if(dctx->getChecksumHashAlgo() == checksum.getAlgo()) {
+ if(dctx->getChecksum() == checksum.getMessageDigest()) {
+ A2_LOG_INFO("Valid hash found in Digest header field.");
+ return true;
+ } else {
+ throw DL_ABORT_EX("Invalid hash found in Digest header field.");
+ }
+ }
+ return false;
+}
+#endif // ENABLE_MESSAGE_DIGEST
+
} // namespace aria2