mirror of https://github.com/aria2/aria2
2007-01-30 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To fix segfault in Metalink download: * src/UrlRequestInfo.h (filename): Removed. (totalLength): Removed. (setTotalLength): Removed. (setFilename): Removed. * src/MetalinkRequestInfo.cc (execute): Do not set filename and totalLength to reqInfo. Set chunk checksum to reqInfo if it is not null. * src/HttpResponseCommand.cc (executeInternal): Fixed filename in log. (handleDefaultEncoding): Removed the call to initBitfield() and markAllPiecesDone(). (handleOtherEncoding): Added HEAD method handling. * src/FtpNegotiateCommand.cc (executeInternal): Added SEQ_HEAD_OK handling. (recvSize): In HEAD handling, set sequence to SEQ_HEAD_OK and return false. * src/FtpNegotiateCommand.h (SEQ_HEAD_OK): New definition. * src/SegmentMan.cc (initBitfield): Delete bitfield. (isChunkChecksumValidationReady): Fixed the condition. * src/UrlRequestInfo.cc: Fixed so that Metalink and Torrent download works fine.pull/1/head
parent
2ab41c4f17
commit
77a05c00b1
34
ChangeLog
34
ChangeLog
|
@ -1,3 +1,37 @@
|
|||
2007-01-30 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
To fix segfault in Metalink download:
|
||||
|
||||
* src/UrlRequestInfo.h
|
||||
(filename): Removed.
|
||||
(totalLength): Removed.
|
||||
(setTotalLength): Removed.
|
||||
(setFilename): Removed.
|
||||
* src/MetalinkRequestInfo.cc
|
||||
(execute): Do not set filename and totalLength to reqInfo.
|
||||
Set chunk checksum to reqInfo if it is not null.
|
||||
|
||||
* src/HttpResponseCommand.cc
|
||||
(executeInternal): Fixed filename in log.
|
||||
(handleDefaultEncoding): Removed the call to initBitfield() and
|
||||
markAllPiecesDone().
|
||||
(handleOtherEncoding): Added HEAD method handling.
|
||||
|
||||
* src/FtpNegotiateCommand.cc
|
||||
(executeInternal): Added SEQ_HEAD_OK handling.
|
||||
(recvSize): In HEAD handling, set sequence to SEQ_HEAD_OK and
|
||||
return false.
|
||||
|
||||
* src/FtpNegotiateCommand.h
|
||||
(SEQ_HEAD_OK): New definition.
|
||||
|
||||
* src/SegmentMan.cc
|
||||
(initBitfield): Delete bitfield.
|
||||
(isChunkChecksumValidationReady): Fixed the condition.
|
||||
|
||||
* src/UrlRequestInfo.cc: Fixed so that Metalink and Torrent download
|
||||
works fine.
|
||||
|
||||
2007-01-28 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
* src/Xml2MetalinkProcessor.h
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.61 for aria2c 0.10.0.
|
||||
# Generated by GNU Autoconf 2.61 for aria2c 0.10.0+1.
|
||||
#
|
||||
# Report bugs to <t-tujikawa@users.sourceforge.net>.
|
||||
#
|
||||
|
@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='aria2c'
|
||||
PACKAGE_TARNAME='aria2c'
|
||||
PACKAGE_VERSION='0.10.0'
|
||||
PACKAGE_STRING='aria2c 0.10.0'
|
||||
PACKAGE_VERSION='0.10.0+1'
|
||||
PACKAGE_STRING='aria2c 0.10.0+1'
|
||||
PACKAGE_BUGREPORT='t-tujikawa@users.sourceforge.net'
|
||||
|
||||
ac_unique_file="src/Socket.h"
|
||||
|
@ -1275,7 +1275,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures aria2c 0.10.0 to adapt to many kinds of systems.
|
||||
\`configure' configures aria2c 0.10.0+1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1345,7 +1345,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of aria2c 0.10.0:";;
|
||||
short | recursive ) echo "Configuration of aria2c 0.10.0+1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1466,7 +1466,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
aria2c configure 0.10.0
|
||||
aria2c configure 0.10.0+1
|
||||
generated by GNU Autoconf 2.61
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
|
@ -1480,7 +1480,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by aria2c $as_me 0.10.0, which was
|
||||
It was created by aria2c $as_me 0.10.0+1, which was
|
||||
generated by GNU Autoconf 2.61. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -2150,7 +2150,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='aria2c'
|
||||
VERSION='0.10.0'
|
||||
VERSION='0.10.0+1'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -12941,7 +12941,7 @@ exec 6>&1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by aria2c $as_me 0.10.0, which was
|
||||
This file was extended by aria2c $as_me 0.10.0+1, which was
|
||||
generated by GNU Autoconf 2.61. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -12994,7 +12994,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
|||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
aria2c config.status 0.10.0
|
||||
aria2c config.status 0.10.0+1
|
||||
configured by $0, generated by GNU Autoconf 2.61,
|
||||
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT(aria2c, 0.10.0, t-tujikawa@users.sourceforge.net)
|
||||
AC_INIT(aria2c, 0.10.0+1, t-tujikawa@users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE()
|
||||
AM_PATH_CPPUNIT(1.10.2)
|
||||
AC_CONFIG_SRCDIR([src/Socket.h])
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# General Public License and is *not* in the public domain.
|
||||
|
||||
PACKAGE = aria2c
|
||||
VERSION = 0.10.0
|
||||
VERSION = 0.10.0+1
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ bool FtpNegotiationCommand::executeInternal(Segment& segment) {
|
|||
command->setLowestDownloadSpeedLimit(e->option->getAsInt(PREF_LOWEST_SPEED_LIMIT));
|
||||
e->commands.push_back(command);
|
||||
return true;
|
||||
} else if(sequence == SEQ_HEAD_OK) {
|
||||
return true;
|
||||
} else {
|
||||
e->commands.push_back(this);
|
||||
return false;
|
||||
|
@ -186,21 +188,16 @@ bool FtpNegotiationCommand::recvSize() {
|
|||
throw new DlAbortEx(EX_TOO_LARGE_FILE, size);
|
||||
}
|
||||
if(!e->segmentMan->downloadStarted) {
|
||||
if(req->getMethod() == Request::METHOD_HEAD) {
|
||||
e->segmentMan->downloadStarted = true;
|
||||
e->segmentMan->totalSize = size;
|
||||
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
|
||||
e->segmentMan->totalSize);
|
||||
e->segmentMan->markAllPiecesDone();
|
||||
e->segmentMan->isSplittable = false; // TODO because we don't want segment file to be saved.
|
||||
return true;
|
||||
}
|
||||
e->segmentMan->downloadStarted = true;
|
||||
e->segmentMan->totalSize = size;
|
||||
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
|
||||
e->segmentMan->totalSize);
|
||||
|
||||
e->segmentMan->filename = Util::urldecode(req->getFile());
|
||||
if(req->getMethod() == Request::METHOD_HEAD) {
|
||||
e->segmentMan->isSplittable = false; // TODO because we don't want segment file to be saved.
|
||||
sequence = SEQ_HEAD_OK;
|
||||
return false;
|
||||
}
|
||||
bool segFileExists = e->segmentMan->segmentFileExists();
|
||||
if(segFileExists) {
|
||||
e->segmentMan->load();
|
||||
|
|
|
@ -62,7 +62,8 @@ private:
|
|||
SEQ_SEND_RETR,
|
||||
SEQ_RECV_RETR,
|
||||
SEQ_NEGOTIATION_COMPLETED,
|
||||
SEQ_RETRY
|
||||
SEQ_RETRY,
|
||||
SEQ_HEAD_OK
|
||||
};
|
||||
bool recvGreeting();
|
||||
bool sendUser();
|
||||
|
|
|
@ -91,8 +91,11 @@ bool HttpResponseCommand::executeInternal(Segment& segment) {
|
|||
return handleDefaultEncoding(headers);
|
||||
}
|
||||
} else {
|
||||
if(determinFilename(headers) != e->segmentMan->filename) {
|
||||
throw new DlAbortEx(EX_FILENAME_MISMATCH, req->getFile().c_str(), e->segmentMan->filename.c_str());
|
||||
string filenameInHeader = determinFilename(headers);
|
||||
if(filenameInHeader != e->segmentMan->filename) {
|
||||
throw new DlAbortEx(EX_FILENAME_MISMATCH,
|
||||
filenameInHeader.c_str(),
|
||||
e->segmentMan->filename.c_str());
|
||||
}
|
||||
createHttpDownloadCommand();
|
||||
return true;
|
||||
|
@ -158,9 +161,6 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
|
|||
if(req->getMethod() == Request::METHOD_HEAD) {
|
||||
e->segmentMan->downloadStarted = true;
|
||||
e->segmentMan->totalSize = size;
|
||||
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
|
||||
e->segmentMan->totalSize);
|
||||
e->segmentMan->markAllPiecesDone();
|
||||
e->segmentMan->isSplittable = false; // TODO because we don't want segment file to be saved.
|
||||
return true;
|
||||
}
|
||||
|
@ -182,6 +182,14 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
|
|||
}
|
||||
|
||||
bool HttpResponseCommand::handleOtherEncoding(const string& transferEncoding, const HttpHeader& headers) {
|
||||
// quick hack for method 'head'
|
||||
if(req->getMethod() == Request::METHOD_HEAD) {
|
||||
e->segmentMan->downloadStarted = true;
|
||||
e->segmentMan->isSplittable = false;
|
||||
e->segmentMan->filename = determinFilename(headers);
|
||||
e->segmentMan->totalSize = 0;
|
||||
return true;
|
||||
}
|
||||
if(e->segmentMan->shouldCancelDownloadForSafety()) {
|
||||
throw new FatalException(EX_FILE_ALREADY_EXISTS,
|
||||
e->segmentMan->getFilePath().c_str(),
|
||||
|
|
|
@ -122,13 +122,13 @@ RequestInfos MetalinkRequestInfo::execute() {
|
|||
urls.push_back((*itr)->url);
|
||||
}
|
||||
UrlRequestInfoHandle reqInfo = new UrlRequestInfo(urls, maxConnection, op);
|
||||
reqInfo->setFilename(entry->filename);
|
||||
reqInfo->setTotalLength(entry->size);
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
reqInfo->setChecksum(checksum);
|
||||
reqInfo->setDigestAlgo(entry->chunkChecksum->digestAlgo);
|
||||
reqInfo->setChunkChecksumLength(entry->chunkChecksum->pieceLength);
|
||||
reqInfo->setChunkChecksums(entry->chunkChecksum->pieceHashes);
|
||||
if(!entry->chunkChecksum.isNull()) {
|
||||
reqInfo->setDigestAlgo(entry->chunkChecksum->digestAlgo);
|
||||
reqInfo->setChunkChecksumLength(entry->chunkChecksum->pieceLength);
|
||||
reqInfo->setChunkChecksums(entry->chunkChecksum->pieceHashes);
|
||||
}
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
nextReqInfos.push_front(reqInfo);
|
||||
}
|
||||
|
|
|
@ -237,6 +237,7 @@ void SegmentMan::init() {
|
|||
}
|
||||
|
||||
void SegmentMan::initBitfield(int segmentLength, long long int totalLength) {
|
||||
delete bitfield;
|
||||
this->bitfield = BitfieldManFactory::getNewFactory()->createBitfieldMan(segmentLength, totalLength);
|
||||
}
|
||||
|
||||
|
@ -479,8 +480,8 @@ void SegmentMan::checkIntegrity()
|
|||
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
bool SegmentMan::isChunkChecksumValidationReady() const {
|
||||
return bitfield &&
|
||||
((int64_t)pieceHashes.size())*chunkHashLength == ((int64_t)bitfield->getBlockLength())*(bitfield->getMaxIndex()+1);
|
||||
return bitfield && totalSize > 0 &&
|
||||
((int64_t)pieceHashes.size())*chunkHashLength >= totalSize;
|
||||
}
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
|
||||
|
|
|
@ -127,6 +127,10 @@ HeadResult UrlRequestInfo::getHeadResult() {
|
|||
op->get(PREF_REFERER),
|
||||
1,
|
||||
Request::METHOD_HEAD));
|
||||
if(requests.size() == 0) {
|
||||
fail = true;
|
||||
return HeadResult();
|
||||
}
|
||||
Requests reserved(requests.begin()+1, requests.end());
|
||||
requests.erase(requests.begin()+1, requests.end());
|
||||
|
||||
|
@ -135,8 +139,12 @@ HeadResult UrlRequestInfo::getHeadResult() {
|
|||
HeadResult hr;
|
||||
try {
|
||||
e->run();
|
||||
hr.filename = e->segmentMan->filename;
|
||||
hr.totalLength = e->segmentMan->totalSize;
|
||||
if(e->segmentMan->errors > 0) {
|
||||
fail = true;
|
||||
} else {
|
||||
hr.filename = e->segmentMan->filename;
|
||||
hr.totalLength = e->segmentMan->totalSize;
|
||||
}
|
||||
} catch(RecoverableException *ex) {
|
||||
logger->error("Exception caught", ex);
|
||||
delete ex;
|
||||
|
@ -150,34 +158,33 @@ RequestInfos UrlRequestInfo::execute() {
|
|||
Requests requests;
|
||||
Requests reserved;
|
||||
printUrls(urls);
|
||||
HeadResult hr = getHeadResult();
|
||||
if(fail) {
|
||||
return RequestInfos();
|
||||
}
|
||||
|
||||
for_each(urls.begin(), urls.end(),
|
||||
CreateRequest(&requests,
|
||||
op->get(PREF_REFERER),
|
||||
op->getAsInt(PREF_SPLIT)));
|
||||
|
||||
logger->info("Head result: filename=%s, total length=%s",
|
||||
hr.filename.c_str(), Util::ullitos(hr.totalLength, true).c_str());
|
||||
|
||||
HeadResult hr;
|
||||
if(filename.size() && totalLength > 0) {
|
||||
hr.filename = filename;
|
||||
hr.totalLength = totalLength;
|
||||
} else {
|
||||
hr = getHeadResult();
|
||||
if(fail) {
|
||||
return RequestInfos();
|
||||
}
|
||||
|
||||
logger->info("Head result: filename=%s, total length=%s",
|
||||
hr.filename.c_str(), Util::ullitos(hr.totalLength, true).c_str());
|
||||
}
|
||||
adjustRequestSize(requests, reserved, maxConnections);
|
||||
|
||||
SharedHandle<ConsoleDownloadEngine> e(DownloadEngineFactory::newConsoleEngine(op, requests, reserved));
|
||||
e->segmentMan->filename = hr.filename;
|
||||
e->segmentMan->totalSize = hr.totalLength;
|
||||
e->segmentMan->downloadStarted = true;
|
||||
if(hr.totalLength > 0) {
|
||||
e->segmentMan->filename = hr.filename;
|
||||
e->segmentMan->totalSize = hr.totalLength;
|
||||
e->segmentMan->downloadStarted = true;
|
||||
}
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
e->segmentMan->digestAlgo = digestAlgo;
|
||||
e->segmentMan->chunkHashLength = chunkChecksumLength;
|
||||
e->segmentMan->pieceHashes = chunkChecksums;
|
||||
if(chunkChecksumLength > 0) {
|
||||
e->segmentMan->digestAlgo = digestAlgo;
|
||||
e->segmentMan->chunkHashLength = chunkChecksumLength;
|
||||
e->segmentMan->pieceHashes = chunkChecksums;
|
||||
}
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
|
||||
if(e->segmentMan->segmentFileExists()) {
|
||||
|
@ -194,17 +201,19 @@ RequestInfos UrlRequestInfo::execute() {
|
|||
e->segmentMan->getFilePath().c_str(),
|
||||
e->segmentMan->getSegmentFilePath().c_str());
|
||||
}
|
||||
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
|
||||
e->segmentMan->totalSize);
|
||||
if(e->segmentMan->fileExists() && e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
|
||||
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath());
|
||||
if(e->segmentMan->totalSize > 0) {
|
||||
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
|
||||
e->segmentMan->totalSize);
|
||||
if(e->segmentMan->fileExists() && e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
|
||||
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath());
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
e->segmentMan->markAllPiecesDone();
|
||||
e->segmentMan->checkIntegrity();
|
||||
e->segmentMan->markAllPiecesDone();
|
||||
e->segmentMan->checkIntegrity();
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
} else {
|
||||
e->segmentMan->diskWriter->initAndOpenFile(e->segmentMan->getFilePath(),
|
||||
e->segmentMan->totalSize);
|
||||
} else {
|
||||
e->segmentMan->diskWriter->initAndOpenFile(e->segmentMan->getFilePath(),
|
||||
e->segmentMan->totalSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
Util::setGlobalSignalHandler(SIGINT, handler, 0);
|
||||
|
|
|
@ -39,9 +39,10 @@
|
|||
|
||||
class HeadResult {
|
||||
public:
|
||||
HeadResult():totalLength(0) {}
|
||||
string filename;
|
||||
int64_t totalLength;
|
||||
public:
|
||||
HeadResult():totalLength(0) {}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const HeadResult& hr);
|
||||
|
@ -55,8 +56,6 @@ private:
|
|||
int32_t chunkChecksumLength;
|
||||
Strings chunkChecksums;
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
string filename;
|
||||
int64_t totalLength;
|
||||
|
||||
RequestInfo* createNextRequestInfo() const;
|
||||
void adjustRequestSize(Requests& requests,
|
||||
|
@ -68,12 +67,13 @@ public:
|
|||
UrlRequestInfo(const Strings& urls, int maxConnections, Option* op):
|
||||
RequestInfo(op),
|
||||
urls(urls),
|
||||
maxConnections(maxConnections),
|
||||
maxConnections(maxConnections)
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
,
|
||||
digestAlgo(DIGEST_ALGO_SHA1),
|
||||
chunkChecksumLength(0),
|
||||
chunkChecksumLength(0)
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
totalLength(0) {}
|
||||
{}
|
||||
|
||||
virtual ~UrlRequestInfo() {}
|
||||
|
||||
|
@ -96,14 +96,6 @@ public:
|
|||
this->chunkChecksums = chunkChecksums;
|
||||
}
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
|
||||
void setTotalLength(int64_t totalLength) {
|
||||
this->totalLength = totalLength;
|
||||
}
|
||||
|
||||
void setFilename(const string& filename) {
|
||||
this->filename = filename;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<UrlRequestInfo> UrlRequestInfoHandle;
|
||||
|
|
Loading…
Reference in New Issue