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>
|
||||
|
||||
Rewritten array operation functions.
|
||||
|
|
|
@ -156,17 +156,14 @@ bool DownloadCommand::executeInternal() {
|
|||
}
|
||||
|
||||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
|
||||
segment->updateWrittenLength(bufSizeFinal);
|
||||
if(bufSizeFinal > 0) {
|
||||
segment->updateWrittenLength(bufSizeFinal);
|
||||
}
|
||||
|
||||
peerStat->updateDownloadLength(bufSize);
|
||||
|
||||
_requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
|
||||
|
||||
if(_requestGroup->getTotalLength() != 0 && bufSize == 0 &&
|
||||
!socket->wantRead() && !socket->wantWrite()) {
|
||||
throw DlRetryEx(EX_GOT_EOF);
|
||||
}
|
||||
bool segmentComplete = false;
|
||||
if(_transferEncodingDecoder.isNull() && _contentEncodingDecoder.isNull()) {
|
||||
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) {
|
||||
logger->info(MSG_SEGMENT_DOWNLOAD_COMPLETED, cuid);
|
||||
#ifdef ENABLE_MESSAGE_DIGEST
|
||||
|
|
|
@ -68,6 +68,12 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
static SharedHandle<Decoder> getTransferEncodingDecoder
|
||||
(const SharedHandle<HttpResponse>& httpResponse);
|
||||
|
||||
static SharedHandle<Decoder> getContentEncodingDecoder
|
||||
(const SharedHandle<HttpResponse>& httpResponse);
|
||||
|
||||
HttpResponseCommand::HttpResponseCommand(int32_t cuid,
|
||||
const RequestHandle& req,
|
||||
RequestGroup* requestGroup,
|
||||
|
@ -147,6 +153,8 @@ bool HttpResponseCommand::executeInternal()
|
|||
if(req->getMethod() == Request::METHOD_GET &&
|
||||
(totalLength != 0 ||
|
||||
!httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
|
||||
// dctx->knowsTotalLength() == true only when server says the
|
||||
// size of file is 0 explicitly.
|
||||
dctx->markTotalLengthIsUnknown();
|
||||
}
|
||||
return handleOtherEncoding(httpResponse);
|
||||
|
@ -158,8 +166,19 @@ bool HttpResponseCommand::executeInternal()
|
|||
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
|
||||
// update last modified time
|
||||
updateLastModifiedTime(httpResponse->getLastModifiedTime());
|
||||
|
||||
e->commands.push_back(createHttpDownloadCommand(httpResponse));
|
||||
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));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -299,11 +318,12 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp
|
|||
_requestGroup->shouldCancelDownloadForSafety();
|
||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
|
||||
|
||||
// In this context, knowsTotalLength() is true only when the file is
|
||||
// really zero-length.
|
||||
if(_requestGroup->getDownloadContext()->knowsTotalLength()) {
|
||||
poolConnection();
|
||||
return true;
|
||||
}
|
||||
|
||||
e->commands.push_back
|
||||
(createHttpDownloadCommand(httpResponse,
|
||||
getTransferEncodingDecoder(httpResponse),
|
||||
|
|
|
@ -91,6 +91,9 @@ inline size_t countBit32(uint32_t n)
|
|||
// Counts set bit in bitfield.
|
||||
inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
|
||||
{
|
||||
if(nbits == 0) {
|
||||
return 0;
|
||||
}
|
||||
size_t count = 0;
|
||||
size_t size = sizeof(uint32_t);
|
||||
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)36, bitfield::countSetBit(bitfield, 47));
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)28, bitfield::countSetBit(bitfield, 32));
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)0, bitfield::countSetBit(bitfield, 0));
|
||||
}
|
||||
|
||||
void bitfieldTest::testLastByteMask()
|
||||
|
|
Loading…
Reference in New Issue