From 65a358c68b4e9411ac3a8667db3f3150f93a106d Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 17 Apr 2009 13:19:17 +0000 Subject: 2009-04-17 Tatsuhiro Tsujikawa 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 --- src/HttpResponseCommand.cc | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'src/HttpResponseCommand.cc') diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index 62723a87..d1704418 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -68,6 +68,12 @@ namespace aria2 { +static SharedHandle getTransferEncodingDecoder +(const SharedHandle& httpResponse); + +static SharedHandle getContentEncodingDecoder +(const SharedHandle& 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), -- cgit