mirror of https://github.com/aria2/aria2
2009-04-17 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed segmentation fault when GZipDecoder::decode() returns 0 byte. * src/DownloadCommand.cc * src/bitfield.h * test/bitfieldTest.cc Fixed the bug that causes infinite loop if broken web server returns chunked response without last "0" chunk-size marker and closes connection. * src/DownloadCommand.cc Instantiate properly configured HttpDownloadCommand for non-resumable downlaods. * src/HttpResponseCommand.ccpull/1/head
parent
d2d4f67bbe
commit
65a358c68b
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
2009-04-17 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Fixed segmentation fault when GZipDecoder::decode() returns 0
|
||||||
|
byte.
|
||||||
|
* src/DownloadCommand.cc
|
||||||
|
* src/bitfield.h
|
||||||
|
* test/bitfieldTest.cc
|
||||||
|
|
||||||
|
Fixed the bug that causes infinite loop if broken web server
|
||||||
|
returns chunked response without last "0" chunk-size marker and
|
||||||
|
closes connection.
|
||||||
|
* src/DownloadCommand.cc
|
||||||
|
|
||||||
|
Instantiate properly configured HttpDownloadCommand for
|
||||||
|
non-resumable downlaods.
|
||||||
|
* src/HttpResponseCommand.cc
|
||||||
|
|
||||||
2009-04-16 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2009-04-16 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Rewritten array operation functions.
|
Rewritten array operation functions.
|
||||||
|
|
|
@ -156,17 +156,14 @@ bool DownloadCommand::executeInternal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
if(bufSizeFinal > 0) {
|
||||||
segment->updateWrittenLength(bufSizeFinal);
|
segment->updateWrittenLength(bufSizeFinal);
|
||||||
|
}
|
||||||
|
|
||||||
peerStat->updateDownloadLength(bufSize);
|
peerStat->updateDownloadLength(bufSize);
|
||||||
|
|
||||||
_requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
|
_requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
|
||||||
|
|
||||||
if(_requestGroup->getTotalLength() != 0 && bufSize == 0 &&
|
|
||||||
!socket->wantRead() && !socket->wantWrite()) {
|
|
||||||
throw DlRetryEx(EX_GOT_EOF);
|
|
||||||
}
|
|
||||||
bool segmentComplete = false;
|
bool segmentComplete = false;
|
||||||
if(_transferEncodingDecoder.isNull() && _contentEncodingDecoder.isNull()) {
|
if(_transferEncodingDecoder.isNull() && _contentEncodingDecoder.isNull()) {
|
||||||
if(segment->complete()) {
|
if(segment->complete()) {
|
||||||
|
@ -193,6 +190,11 @@ bool DownloadCommand::executeInternal() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!segmentComplete && bufSize == 0 &&
|
||||||
|
!socket->wantRead() && !socket->wantWrite()) {
|
||||||
|
throw DlRetryEx(EX_GOT_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
if(segmentComplete) {
|
if(segmentComplete) {
|
||||||
logger->info(MSG_SEGMENT_DOWNLOAD_COMPLETED, cuid);
|
logger->info(MSG_SEGMENT_DOWNLOAD_COMPLETED, cuid);
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
|
|
|
@ -68,6 +68,12 @@
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
static SharedHandle<Decoder> getTransferEncodingDecoder
|
||||||
|
(const SharedHandle<HttpResponse>& httpResponse);
|
||||||
|
|
||||||
|
static SharedHandle<Decoder> getContentEncodingDecoder
|
||||||
|
(const SharedHandle<HttpResponse>& httpResponse);
|
||||||
|
|
||||||
HttpResponseCommand::HttpResponseCommand(int32_t cuid,
|
HttpResponseCommand::HttpResponseCommand(int32_t cuid,
|
||||||
const RequestHandle& req,
|
const RequestHandle& req,
|
||||||
RequestGroup* requestGroup,
|
RequestGroup* requestGroup,
|
||||||
|
@ -147,6 +153,8 @@ bool HttpResponseCommand::executeInternal()
|
||||||
if(req->getMethod() == Request::METHOD_GET &&
|
if(req->getMethod() == Request::METHOD_GET &&
|
||||||
(totalLength != 0 ||
|
(totalLength != 0 ||
|
||||||
!httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
|
!httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
|
||||||
|
// dctx->knowsTotalLength() == true only when server says the
|
||||||
|
// size of file is 0 explicitly.
|
||||||
dctx->markTotalLengthIsUnknown();
|
dctx->markTotalLengthIsUnknown();
|
||||||
}
|
}
|
||||||
return handleOtherEncoding(httpResponse);
|
return handleOtherEncoding(httpResponse);
|
||||||
|
@ -158,8 +166,19 @@ bool HttpResponseCommand::executeInternal()
|
||||||
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
|
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
|
||||||
// update last modified time
|
// update last modified time
|
||||||
updateLastModifiedTime(httpResponse->getLastModifiedTime());
|
updateLastModifiedTime(httpResponse->getLastModifiedTime());
|
||||||
|
if(_requestGroup->getTotalLength() == 0) {
|
||||||
|
// Since total length is unknown, the file size in previously
|
||||||
|
// failed download could be larger than the size this time.
|
||||||
|
// Also we can't resume in this case too. So truncate the file
|
||||||
|
// anyway.
|
||||||
|
_requestGroup->getPieceStorage()->getDiskAdaptor()->truncate(0);
|
||||||
|
e->commands.push_back
|
||||||
|
(createHttpDownloadCommand(httpResponse,
|
||||||
|
getTransferEncodingDecoder(httpResponse),
|
||||||
|
getContentEncodingDecoder(httpResponse)));
|
||||||
|
} else {
|
||||||
e->commands.push_back(createHttpDownloadCommand(httpResponse));
|
e->commands.push_back(createHttpDownloadCommand(httpResponse));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,11 +318,12 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp
|
||||||
_requestGroup->shouldCancelDownloadForSafety();
|
_requestGroup->shouldCancelDownloadForSafety();
|
||||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
||||||
|
|
||||||
|
// In this context, knowsTotalLength() is true only when the file is
|
||||||
|
// really zero-length.
|
||||||
if(_requestGroup->getDownloadContext()->knowsTotalLength()) {
|
if(_requestGroup->getDownloadContext()->knowsTotalLength()) {
|
||||||
poolConnection();
|
poolConnection();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->commands.push_back
|
e->commands.push_back
|
||||||
(createHttpDownloadCommand(httpResponse,
|
(createHttpDownloadCommand(httpResponse,
|
||||||
getTransferEncodingDecoder(httpResponse),
|
getTransferEncodingDecoder(httpResponse),
|
||||||
|
|
|
@ -91,6 +91,9 @@ inline size_t countBit32(uint32_t n)
|
||||||
// Counts set bit in bitfield.
|
// Counts set bit in bitfield.
|
||||||
inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
|
inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
|
||||||
{
|
{
|
||||||
|
if(nbits == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
size_t size = sizeof(uint32_t);
|
size_t size = sizeof(uint32_t);
|
||||||
size_t len = (nbits+7)/8;
|
size_t len = (nbits+7)/8;
|
||||||
|
|
|
@ -45,6 +45,7 @@ void bitfieldTest::testCountSetBit()
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)37, bitfield::countSetBit(bitfield, 48));
|
CPPUNIT_ASSERT_EQUAL((size_t)37, bitfield::countSetBit(bitfield, 48));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)36, bitfield::countSetBit(bitfield, 47));
|
CPPUNIT_ASSERT_EQUAL((size_t)36, bitfield::countSetBit(bitfield, 47));
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)28, bitfield::countSetBit(bitfield, 32));
|
CPPUNIT_ASSERT_EQUAL((size_t)28, bitfield::countSetBit(bitfield, 32));
|
||||||
|
CPPUNIT_ASSERT_EQUAL((size_t)0, bitfield::countSetBit(bitfield, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bitfieldTest::testLastByteMask()
|
void bitfieldTest::testLastByteMask()
|
||||||
|
|
Loading…
Reference in New Issue