2010-04-08 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Added --save-session=FILE option.  This option saves
	error/unfinished downloads to FILE on exit.  You can pass this
	output file to aria2c with -i option on restart. Please note that
	downloads added by aria2.addTorrent and aria2.addMetalink XML-RPC
	method are not saved.
	* src/BtPostDownloadHandler.cc
	* src/DownloadResult.h
	* src/Makefile.am
	* src/MetadataInfo.cc
	* src/MetadataInfo.h
	* src/Metalink2RequestGroup.cc
	* src/MetalinkPostDownloadHandler.cc
	* src/MultiUrlRequestInfo.cc
	* src/OptionHandlerFactory.cc
	* src/RequestGroup.cc
	* src/RequestGroup.h
	* src/SessionSerializer.cc
	* src/SessionSerializer.h
	* src/UTMetadataPostDownloadHandler.cc
	* src/download_helper.cc
	* src/download_helper.h
	* src/prefs.cc
	* src/prefs.h
	* src/usage_text.h
	* test/Makefile.am
	* test/SessionSerializerTest.cc
	* test/XmlRpcMethodTest.cc
	* test/serialize_session.meta4
pull/1/head
Tatsuhiro Tsujikawa 2010-04-08 12:54:14 +00:00
parent dd7590f927
commit 5cd0108f93
29 changed files with 707 additions and 35 deletions

View File

@ -1,3 +1,34 @@
2010-04-08 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added --save-session=FILE option. This option saves
error/unfinished downloads to FILE on exit. You can pass this
output file to aria2c with -i option on restart. Please note that
downloads added by aria2.addTorrent and aria2.addMetalink XML-RPC
method are not saved.
* src/BtPostDownloadHandler.cc
* src/DownloadResult.h
* src/Makefile.am
* src/MetadataInfo.cc
* src/MetadataInfo.h
* src/Metalink2RequestGroup.cc
* src/MetalinkPostDownloadHandler.cc
* src/MultiUrlRequestInfo.cc
* src/OptionHandlerFactory.cc
* src/RequestGroup.cc
* src/RequestGroup.h
* src/SessionSerializer.cc
* src/SessionSerializer.h
* src/UTMetadataPostDownloadHandler.cc
* src/download_helper.cc
* src/download_helper.h
* src/prefs.cc
* src/prefs.h
* src/usage_text.h
* test/Makefile.am
* test/SessionSerializerTest.cc
* test/XmlRpcMethodTest.cc
* test/serialize_session.meta4
2010-04-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> 2010-04-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed the bug that FTP data connection is not established via Fixed the bug that FTP data connection is not established via

View File

@ -2,12 +2,12 @@
.\" Title: aria2c .\" Title: aria2c
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 04/03/2010 .\" Date: 04/08/2010
.\" Manual: Aria2 Manual .\" Manual: Aria2 Manual
.\" Source: Aria2 1.9.1a .\" Source: Aria2 1.9.1a
.\" Language: English .\" Language: English
.\" .\"
.TH "ARIA2C" "1" "04/03/2010" "Aria2 1\&.9\&.1a" "Aria2 Manual" .TH "ARIA2C" "1" "04/08/2010" "Aria2 1\&.9\&.1a" "Aria2 Manual"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * Define some portability stuff .\" * Define some portability stuff
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@ -1354,6 +1354,17 @@ For Metalink downloads, \-C1 is recommended for proxy server which disables resu
.sp .5v .sp .5v
.RE .RE
.PP .PP
\fB\-\-save\-session\fR=FILE
.RS 4
Save error/unfinished downloads to FILE on exit\&. You can pass this output file to aria2c with
\fB\-i\fR
option on restart\&. Please note that downloads added by
\fBaria2\&.addTorrent\fR
and
\fBaria2\&.addMetalink\fR
XML\-RPC method are not saved\&.
.RE
.PP
\fB\-\-stop\fR=SEC \fB\-\-stop\fR=SEC
.RS 4 .RS 4
Stop application after SEC seconds has passed\&. If Stop application after SEC seconds has passed\&. If

View File

@ -2201,6 +2201,17 @@ connections.</td>
</div> </div>
<div class="dlist"><dl> <div class="dlist"><dl>
<dt class="hdlist1"> <dt class="hdlist1">
<strong>--save-session</strong>=FILE
</dt>
<dd>
<p>
Save error/unfinished downloads to FILE on exit. You can pass this
output file to aria2c with <strong>-i</strong> option on restart. Please note that
downloads added by <strong>aria2.addTorrent</strong> and <strong>aria2.addMetalink</strong>
XML-RPC method are not saved.
</p>
</dd>
<dt class="hdlist1">
<strong>--stop</strong>=SEC <strong>--stop</strong>=SEC
</dt> </dt>
<dd> <dd>
@ -4137,7 +4148,7 @@ files in the program, then also delete it here.</p></div>
<div id="footnotes"><hr /></div> <div id="footnotes"><hr /></div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2010-04-03 13:10:23 JST Last updated 2010-04-08 21:48:17 JST
</div> </div>
</div> </div>
</body> </body>

View File

@ -914,6 +914,13 @@ For Metalink downloads, -C1 is recommended for proxy server which
disables resume, in order to avoid establishing unnecessary disables resume, in order to avoid establishing unnecessary
connections. connections.
*--save-session*=FILE::
Save error/unfinished downloads to FILE on exit. You can pass this
output file to aria2c with *-i* option on restart. Please note that
downloads added by *aria2.addTorrent* and *aria2.addMetalink*
XML-RPC method are not saved.
*--stop*=SEC:: *--stop*=SEC::
Stop application after SEC seconds has passed. Stop application after SEC seconds has passed.
If '0' is given, this feature is disabled. If '0' is given, this feature is disabled.

View File

@ -82,6 +82,11 @@ void BtPostDownloadHandler::getNextRequestGroups
std::vector<std::string>(), std::vector<std::string>(),
content); content);
requestGroup->followedBy(newRgs.begin(), newRgs.end()); requestGroup->followedBy(newRgs.begin(), newRgs.end());
SharedHandle<MetadataInfo> mi =
createMetadataInfoFromFirstFileEntry(requestGroup->getDownloadContext());
if(!mi.isNull()) {
setMetadataInfo(newRgs.begin(), newRgs.end(), mi);
}
groups.insert(groups.end(), newRgs.begin(), newRgs.end()); groups.insert(groups.end(), newRgs.begin(), newRgs.end());
} }

View File

@ -45,6 +45,8 @@
#include "SharedHandle.h" #include "SharedHandle.h"
#include "DownloadResultCode.h" #include "DownloadResultCode.h"
#include "RequestGroup.h" #include "RequestGroup.h"
#include "Option.h"
#include "MetadataInfo.h"
namespace aria2 { namespace aria2 {
@ -74,6 +76,10 @@ public:
// RequestGroup.cc::_belongsToGID. // RequestGroup.cc::_belongsToGID.
gid_t belongsTo; gid_t belongsTo;
SharedHandle<Option> option;
SharedHandle<MetadataInfo> metadataInfo;
DownloadResult(gid_t gid, DownloadResult(gid_t gid,
const std::vector<SharedHandle<FileEntry> >& fileEntries, const std::vector<SharedHandle<FileEntry> >& fileEntries,
bool inMemoryDownload, bool inMemoryDownload,
@ -81,7 +87,9 @@ public:
int64_t sessionTime, int64_t sessionTime,
downloadresultcode::RESULT result, downloadresultcode::RESULT result,
const std::vector<gid_t> followedBy, const std::vector<gid_t> followedBy,
gid_t belongsTo): gid_t belongsTo,
const SharedHandle<Option>& option,
const SharedHandle<MetadataInfo>& metadataInfo):
gid(gid), gid(gid),
fileEntries(fileEntries), fileEntries(fileEntries),
inMemoryDownload(inMemoryDownload), inMemoryDownload(inMemoryDownload),
@ -89,7 +97,9 @@ public:
sessionTime(sessionTime), sessionTime(sessionTime),
result(result), result(result),
followedBy(followedBy), followedBy(followedBy),
belongsTo(belongsTo) {} belongsTo(belongsTo),
option(option),
metadataInfo(metadataInfo) {}
}; };
typedef SharedHandle<DownloadResult> DownloadResultHandle; typedef SharedHandle<DownloadResult> DownloadResultHandle;

View File

@ -198,7 +198,9 @@ SRCS = Socket.h\
CreateRequestCommand.cc CreateRequestCommand.h\ CreateRequestCommand.cc CreateRequestCommand.h\
DownloadResultCode.h\ DownloadResultCode.h\
wallclock.h\ wallclock.h\
download_helper.cc download_helper.h download_helper.cc download_helper.h\
MetadataInfo.cc MetadataInfo.h\
SessionSerializer.cc SessionSerializer.h
if ENABLE_XML_RPC if ENABLE_XML_RPC
SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\ SRCS += XmlRpcRequestParserController.cc XmlRpcRequestParserController.h\

View File

@ -429,7 +429,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
LongestSequencePieceSelector.cc LongestSequencePieceSelector.h \ LongestSequencePieceSelector.cc LongestSequencePieceSelector.h \
bitfield.cc bitfield.h BDE.cc BDE.h CreateRequestCommand.cc \ bitfield.cc bitfield.h BDE.cc BDE.h CreateRequestCommand.cc \
CreateRequestCommand.h DownloadResultCode.h wallclock.h \ CreateRequestCommand.h DownloadResultCode.h wallclock.h \
download_helper.cc download_helper.h \ download_helper.cc download_helper.h MetadataInfo.cc \
MetadataInfo.h SessionSerializer.cc SessionSerializer.h \
XmlRpcRequestParserController.cc \ XmlRpcRequestParserController.cc \
XmlRpcRequestParserController.h \ XmlRpcRequestParserController.h \
XmlRpcRequestParserStateMachine.cc \ XmlRpcRequestParserStateMachine.cc \
@ -855,7 +856,8 @@ am__objects_27 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
URIResult.$(OBJEXT) SelectEventPoll.$(OBJEXT) \ URIResult.$(OBJEXT) SelectEventPoll.$(OBJEXT) \
LongestSequencePieceSelector.$(OBJEXT) bitfield.$(OBJEXT) \ LongestSequencePieceSelector.$(OBJEXT) bitfield.$(OBJEXT) \
BDE.$(OBJEXT) CreateRequestCommand.$(OBJEXT) \ BDE.$(OBJEXT) CreateRequestCommand.$(OBJEXT) \
download_helper.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ download_helper.$(OBJEXT) MetadataInfo.$(OBJEXT) \
SessionSerializer.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \ $(am__objects_6) $(am__objects_7) $(am__objects_8) \
$(am__objects_9) $(am__objects_10) $(am__objects_11) \ $(am__objects_9) $(am__objects_10) $(am__objects_11) \
@ -1189,16 +1191,17 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
LongestSequencePieceSelector.cc LongestSequencePieceSelector.h \ LongestSequencePieceSelector.cc LongestSequencePieceSelector.h \
bitfield.cc bitfield.h BDE.cc BDE.h CreateRequestCommand.cc \ bitfield.cc bitfield.h BDE.cc BDE.h CreateRequestCommand.cc \
CreateRequestCommand.h DownloadResultCode.h wallclock.h \ CreateRequestCommand.h DownloadResultCode.h wallclock.h \
download_helper.cc download_helper.h $(am__append_1) \ download_helper.cc download_helper.h MetadataInfo.cc \
$(am__append_2) $(am__append_3) $(am__append_4) \ MetadataInfo.h SessionSerializer.cc SessionSerializer.h \
$(am__append_5) $(am__append_6) $(am__append_7) \ $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_8) $(am__append_9) $(am__append_10) \ $(am__append_4) $(am__append_5) $(am__append_6) \
$(am__append_11) $(am__append_12) $(am__append_13) \ $(am__append_7) $(am__append_8) $(am__append_9) \
$(am__append_14) $(am__append_15) $(am__append_16) \ $(am__append_10) $(am__append_11) $(am__append_12) \
$(am__append_17) $(am__append_18) $(am__append_19) \ $(am__append_13) $(am__append_14) $(am__append_15) \
$(am__append_20) $(am__append_21) $(am__append_22) \ $(am__append_16) $(am__append_17) $(am__append_18) \
$(am__append_23) $(am__append_24) $(am__append_25) \ $(am__append_19) $(am__append_20) $(am__append_21) \
$(am__append_26) $(am__append_22) $(am__append_23) $(am__append_24) \
$(am__append_25) $(am__append_26)
noinst_LIBRARIES = libaria2c.a noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@ -1495,6 +1498,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshake.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshake.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryBufferPreDownloadHandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryBufferPreDownloadHandler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetadataInfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Metalink2RequestGroup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Metalink2RequestGroup.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkHelper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkHelper.Po@am__quote@
@ -1552,6 +1556,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SelectEventPoll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SelectEventPoll.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStatMan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStatMan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SessionSerializer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Signature.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Signature.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleBtMessage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleBtMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleLogger.Po@am__quote@

49
src/MetadataInfo.cc Normal file
View File

@ -0,0 +1,49 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "MetadataInfo.h"
namespace aria2 {
int64_t MetadataInfo::_count = 0;
int64_t MetadataInfo::genId()
{
if(_count == INT64_MAX) {
_count = 0;
}
return ++_count;
}
} // namespace aria2

76
src/MetadataInfo.h Normal file
View File

@ -0,0 +1,76 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_METADATA_INFO_H_
#define _D_METADATA_INFO_H_
#include "common.h"
#include <string>
namespace aria2 {
class MetadataInfo {
private:
int64_t _id;
std::string _uri;
bool _dataOnly;
static int64_t _count;
public:
MetadataInfo(const std::string& uri):_id(genId()), _uri(uri), _dataOnly(false)
{}
MetadataInfo():_id(genId()), _dataOnly(true) {}
bool dataOnly() const
{
return _dataOnly;
}
const std::string& getUri() const
{
return _uri;
}
int64_t getId() const
{
return _id;
}
static int64_t genId();
};
} // namespace aria2
#endif // _D_METADATA_INFO_H_

View File

@ -109,7 +109,16 @@ Metalink2RequestGroup::generate
{ {
std::vector<SharedHandle<MetalinkEntry> > entries; std::vector<SharedHandle<MetalinkEntry> > entries;
MetalinkHelper::parseAndQuery(entries, metalinkFile, option.get()); MetalinkHelper::parseAndQuery(entries, metalinkFile, option.get());
createRequestGroup(groups, entries, option); std::vector<SharedHandle<RequestGroup> > tempgroups;
createRequestGroup(tempgroups, entries, option);
SharedHandle<MetadataInfo> mi;
if(metalinkFile == "-") {
mi.reset(new MetadataInfo());
} else {
mi.reset(new MetadataInfo(metalinkFile));
}
setMetadataInfo(tempgroups.begin(), tempgroups.end(), mi);
groups.insert(groups.end(), tempgroups.begin(), tempgroups.end());
} }
void void
@ -120,7 +129,11 @@ Metalink2RequestGroup::generate
{ {
std::vector<SharedHandle<MetalinkEntry> > entries; std::vector<SharedHandle<MetalinkEntry> > entries;
MetalinkHelper::parseAndQuery(entries, binaryStream, option.get()); MetalinkHelper::parseAndQuery(entries, binaryStream, option.get());
createRequestGroup(groups, entries, option); std::vector<SharedHandle<RequestGroup> > tempgroups;
createRequestGroup(tempgroups, entries, option);
SharedHandle<MetadataInfo> mi(new MetadataInfo());
setMetadataInfo(tempgroups.begin(), tempgroups.end(), mi);
groups.insert(groups.end(), tempgroups.begin(), tempgroups.end());
} }
void void

View File

@ -44,6 +44,7 @@
#include "prefs.h" #include "prefs.h"
#include "Option.h" #include "Option.h"
#include "DownloadContext.h" #include "DownloadContext.h"
#include "download_helper.h"
namespace aria2 { namespace aria2 {
@ -77,6 +78,11 @@ void MetalinkPostDownloadHandler::getNextRequestGroups
Metalink2RequestGroup().generate(newRgs, diskAdaptor, Metalink2RequestGroup().generate(newRgs, diskAdaptor,
requestGroup->getOption()); requestGroup->getOption());
requestGroup->followedBy(newRgs.begin(), newRgs.end()); requestGroup->followedBy(newRgs.begin(), newRgs.end());
SharedHandle<MetadataInfo> mi =
createMetadataInfoFromFirstFileEntry(requestGroup->getDownloadContext());
if(!mi.isNull()) {
setMetadataInfo(newRgs.begin(), newRgs.end(), mi);
}
groups.insert(groups.end(), newRgs.begin(), newRgs.end()); groups.insert(groups.end(), newRgs.begin(), newRgs.end());
diskAdaptor->closeFile(); diskAdaptor->closeFile();
} catch(Exception& e) { } catch(Exception& e) {

View File

@ -55,6 +55,8 @@
#include "Netrc.h" #include "Netrc.h"
#include "AuthConfigFactory.h" #include "AuthConfigFactory.h"
#include "DownloadContext.h" #include "DownloadContext.h"
#include "SessionSerializer.h"
#include "ServerStatMan.h"
#ifdef ENABLE_SSL #ifdef ENABLE_SSL
# include "SocketCore.h" # include "SocketCore.h"
# include "TLSContext.h" # include "TLSContext.h"
@ -193,6 +195,15 @@ downloadresultcode::RESULT MultiUrlRequestInfo::execute()
returnValue = s.getLastErrorResult(); returnValue = s.getLastErrorResult();
} }
} }
SessionSerializer sessionSerializer(e->_requestGroupMan);
// TODO Add option: --save-session-status=error,inprogress,waiting
if(!_option->blank(PREF_SAVE_SESSION)) {
if(sessionSerializer.save(_option->get(PREF_SAVE_SESSION))) {
_logger->notice("Serialized session successfully.");
} else {
_logger->notice("Failed to serialize session.");
}
}
} catch(RecoverableException& e) { } catch(RecoverableException& e) {
if(returnValue == downloadresultcode::FINISHED) { if(returnValue == downloadresultcode::FINISHED) {
returnValue = downloadresultcode::UNKNOWN_ERROR; returnValue = downloadresultcode::UNKNOWN_ERROR;

View File

@ -442,6 +442,15 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_ADVANCED); op->addTag(TAG_ADVANCED);
handlers.push_back(op); handlers.push_back(op);
} }
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_SAVE_SESSION,
TEXT_SAVE_SESSION,
NO_DEFAULT_VALUE,
"FILENAME"));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
{ {
SharedHandle<OptionHandler> op(new NumberOptionHandler SharedHandle<OptionHandler> op(new NumberOptionHandler
(PREF_STOP, (PREF_STOP,

View File

@ -1050,7 +1050,9 @@ DownloadResultHandle RequestGroup::createDownloadResult() const
_downloadContext->calculateSessionTime(), _downloadContext->calculateSessionTime(),
downloadResult(), downloadResult(),
_followedByGIDs, _followedByGIDs,
_belongsToGID)); _belongsToGID,
_option,
_metadataInfo));
} }
void RequestGroup::reportDownloadFinished() void RequestGroup::reportDownloadFinished()

View File

@ -46,6 +46,7 @@
#include "TimeA2.h" #include "TimeA2.h"
#include "Request.h" #include "Request.h"
#include "DownloadResultCode.h" #include "DownloadResultCode.h"
#include "MetadataInfo.h"
namespace aria2 { namespace aria2 {
@ -165,6 +166,8 @@ private:
// RequestGroup. // RequestGroup.
gid_t _belongsToGID; gid_t _belongsToGID;
SharedHandle<MetadataInfo> _metadataInfo;
RequestGroupMan* _requestGroupMan; RequestGroupMan* _requestGroupMan;
int _resumeFailureCount; int _resumeFailureCount;
@ -514,6 +517,16 @@ public:
bool p2pInvolved() const; bool p2pInvolved() const;
void setMetadataInfo(const SharedHandle<MetadataInfo>& info)
{
_metadataInfo = info;
}
const SharedHandle<MetadataInfo>& getMetadataInfo() const
{
return _metadataInfo;
}
static void resetGIDCounter() { _gidCounter = 0; } static void resetGIDCounter() { _gidCounter = 0; }
static gid_t newGID(); static gid_t newGID();

203
src/SessionSerializer.cc Normal file
View File

@ -0,0 +1,203 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "SessionSerializer.h"
#include <fstream>
#include <iterator>
#include "RequestGroupMan.h"
#include "ServerStatMan.h"
#include "a2functional.h"
#include "File.h"
#include "A2STR.h"
#include "download_helper.h"
#include "Option.h"
#include "DownloadResult.h"
#include "FileEntry.h"
#include "prefs.h"
#include "util.h"
#include "array_fun.h"
namespace aria2 {
SessionSerializer::SessionSerializer
(const SharedHandle<RequestGroupMan>& requestGroupMan):
_rgman(requestGroupMan),
_saveError(true),
_saveInProgress(true),
_saveWaiting(true) {}
bool SessionSerializer::save(const std::string& filename) const
{
std::string tempFilename = strconcat(filename, "__temp");
std::ofstream out(tempFilename.c_str(), std::ios::binary);
if(!out) {
return false;
}
save(out);
out.flush();
if(!out) {
return false;
}
return File(tempFilename).renameTo(filename);
}
static const std::vector<std::string>& getCumulativeOpts()
{
static std::string cumulativeOpts[] = { PREF_INDEX_OUT, PREF_HEADER };
static std::vector<std::string> opts
(vbegin(cumulativeOpts), vend(cumulativeOpts));
return opts;
}
static bool inCumulativeOpts(const std::string& opt)
{
const std::vector<std::string>& cumopts = getCumulativeOpts();
for(std::vector<std::string>::const_iterator itr = cumopts.begin(),
eoi = cumopts.end(); itr != eoi; ++itr) {
if(opt == *itr) {
return true;
}
}
return false;
}
static void writeOption(std::ostream& out, const SharedHandle<Option>& op)
{
const std::set<std::string>& requestOptions = listRequestOptions();
for(std::set<std::string>::const_iterator itr = requestOptions.begin(),
eoi = requestOptions.end(); itr != eoi; ++itr) {
if(inCumulativeOpts(*itr)) {
continue;
}
if(op->defined(*itr)) {
out << " " << *itr << "=" << op->get(*itr) << "\n";
}
}
const std::vector<std::string>& cumopts = getCumulativeOpts();
for(std::vector<std::string>::const_iterator opitr = cumopts.begin(),
eoi = cumopts.end(); opitr != eoi; ++opitr) {
if(op->defined(*opitr)) {
std::vector<std::string> v;
util::split(op->get(*opitr), std::back_inserter(v), "\n",
false, false);
for(std::vector<std::string>::const_iterator i = v.begin(), eoi = v.end();
i != eoi; ++i) {
out << " " << *opitr << "=" << *i << "\n";
}
}
}
}
static void writeDownloadResult
(std::ostream& out, std::set<int64_t>& metainfoCache,
const SharedHandle<DownloadResult>& dr)
{
const SharedHandle<MetadataInfo>& mi = dr->metadataInfo;
if(dr->belongsTo != 0 || (!mi.isNull() && mi->dataOnly())) {
return;
}
if(mi.isNull()) {
// only save first file entry
if(dr->fileEntries.empty()) {
return;
}
const SharedHandle<FileEntry>& file = dr->fileEntries[0];
std::vector<std::string> uris;
file->getUris(uris);
if(uris.empty()) {
return;
}
std::copy(uris.begin(), uris.end(),
std::ostream_iterator<std::string>(out, "\t"));
out << "\n";
} else {
if(metainfoCache.count(mi->getId()) != 0) {
return;
} else {
metainfoCache.insert(mi->getId());
out << mi->getUri() << "\n";
}
}
writeOption(out, dr->option);
}
void SessionSerializer::save(std::ostream& out) const
{
std::set<int64_t> metainfoCache;
const std::deque<SharedHandle<DownloadResult> >& results =
_rgman->getDownloadResults();
for(std::deque<SharedHandle<DownloadResult> >::const_iterator itr =
results.begin(), eoi = results.end(); itr != eoi; ++itr) {
if((*itr)->result == downloadresultcode::FINISHED) {
continue;
} else if((*itr)->result == downloadresultcode::IN_PROGRESS) {
if(_saveInProgress) {
writeDownloadResult(out, metainfoCache, *itr);
}
} else {
// error download
if(_saveError) {
writeDownloadResult(out, metainfoCache, *itr);
}
}
}
if(_saveInProgress) {
const std::deque<SharedHandle<RequestGroup> >& groups =
_rgman->getRequestGroups();
for(std::deque<SharedHandle<RequestGroup> >::const_iterator itr =
groups.begin(), eoi = groups.end(); itr != eoi; ++itr) {
SharedHandle<DownloadResult> result = (*itr)->createDownloadResult();
if(result->result == downloadresultcode::FINISHED) {
continue;
}
writeDownloadResult(out, metainfoCache, result);
}
}
if(_saveWaiting) {
const std::deque<SharedHandle<RequestGroup> >& groups =
_rgman->getReservedGroups();
for(std::deque<SharedHandle<RequestGroup> >::const_iterator itr =
groups.begin(), eoi = groups.end(); itr != eoi; ++itr) {
SharedHandle<DownloadResult> result = (*itr)->createDownloadResult();
writeDownloadResult(out, metainfoCache, result);
}
}
}
} // namespace aria2

65
src/SessionSerializer.h Normal file
View File

@ -0,0 +1,65 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_SESSION_SERIALIZER_H_
#define _D_SESSION_SERIALIZER_H_
#include "common.h"
#include <string>
#include <iosfwd>
#include "SharedHandle.h"
namespace aria2 {
class RequestGroupMan;
class SessionSerializer {
private:
SharedHandle<RequestGroupMan> _rgman;
bool _saveError;
bool _saveInProgress;
bool _saveWaiting;
public:
SessionSerializer(const SharedHandle<RequestGroupMan>& requestGroupMan);
bool save(const std::string& filename) const;
void save(std::ostream& out) const;
};
} // namespace aria2
#endif // _D_SESSION_SERIALIZER_H_

View File

@ -96,8 +96,11 @@ void UTMetadataPostDownloadHandler::getNextRequestGroups
std::vector<SharedHandle<RequestGroup> > newRgs; std::vector<SharedHandle<RequestGroup> > newRgs;
createRequestGroupForBitTorrent(newRgs, requestGroup->getOption(), createRequestGroupForBitTorrent(newRgs, requestGroup->getOption(),
std::vector<std::string>(), torrent); std::vector<std::string>(), torrent);
requestGroup->followedBy(newRgs.begin(), newRgs.end()); requestGroup->followedBy(newRgs.begin(), newRgs.end());
if(!requestGroup->getMetadataInfo().isNull()) {
setMetadataInfo(newRgs.begin(), newRgs.end(),
requestGroup->getMetadataInfo());
}
groups.insert(groups.end(), newRgs.begin(), newRgs.end()); groups.insert(groups.end(), newRgs.begin(), newRgs.end());
} }
} }

View File

@ -61,6 +61,7 @@
#include "ByteArrayDiskWriter.h" #include "ByteArrayDiskWriter.h"
#include "a2functional.h" #include "a2functional.h"
#include "ByteArrayDiskWriterFactory.h" #include "ByteArrayDiskWriterFactory.h"
#include "MetadataInfo.h"
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
# include "bittorrent_helper.h" # include "bittorrent_helper.h"
# include "BtConstants.h" # include "BtConstants.h"
@ -212,6 +213,16 @@ static SharedHandle<RequestGroup> createRequestGroup
return rg; return rg;
} }
static SharedHandle<MetadataInfo> createMetadataInfo(const std::string& uri)
{
return SharedHandle<MetadataInfo>(new MetadataInfo(uri));
}
static SharedHandle<MetadataInfo> createMetadataInfoDataOnly()
{
return SharedHandle<MetadataInfo>(new MetadataInfo());
}
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
static static
@ -226,10 +237,12 @@ createBtRequestGroup(const std::string& torrentFilePath,
dctx->setDir(option->get(PREF_DIR)); dctx->setDir(option->get(PREF_DIR));
if(torrentData.empty()) { if(torrentData.empty()) {
bittorrent::load(torrentFilePath, dctx, auxUris);// may throw exception bittorrent::load(torrentFilePath, dctx, auxUris);// may throw exception
rg->setMetadataInfo(createMetadataInfo(torrentFilePath));
} else { } else {
bittorrent::loadFromMemory(torrentData, dctx, auxUris, "default"); // may bittorrent::loadFromMemory(torrentData, dctx, auxUris, "default"); // may
// throw // throw
// exception // exception
rg->setMetadataInfo(createMetadataInfoDataOnly());
} }
dctx->setFileFilter(util::parseIntRange(option->get(PREF_SELECT_FILE))); dctx->setFileFilter(util::parseIntRange(option->get(PREF_SELECT_FILE)));
std::istringstream indexOutIn(option->get(PREF_INDEX_OUT)); std::istringstream indexOutIn(option->get(PREF_INDEX_OUT));
@ -272,6 +285,7 @@ createBtMagnetRequestGroup(const std::string& magnetLink,
(new UTMetadataPostDownloadHandler())); (new UTMetadataPostDownloadHandler()));
rg->setDiskWriterFactory rg->setDiskWriterFactory
(SharedHandle<DiskWriterFactory>(new ByteArrayDiskWriterFactory())); (SharedHandle<DiskWriterFactory>(new ByteArrayDiskWriterFactory()));
rg->setMetadataInfo(createMetadataInfo(magnetLink));
return rg; return rg;
} }
@ -476,4 +490,19 @@ void createRequestGroupForUriList
} }
} }
SharedHandle<MetadataInfo>
createMetadataInfoFromFirstFileEntry(const SharedHandle<DownloadContext>& dctx)
{
if(dctx->getFileEntries().empty()) {
return SharedHandle<MetadataInfo>();
} else {
std::vector<std::string> uris;
dctx->getFileEntries()[0]->getUris(uris);
if(uris.empty()) {
return SharedHandle<MetadataInfo>();
}
return SharedHandle<MetadataInfo>(new MetadataInfo(uris[0]));
}
}
} // namespace aria2 } // namespace aria2

View File

@ -47,6 +47,8 @@ namespace aria2 {
class RequestGroup; class RequestGroup;
class Option; class Option;
class MetadataInfo;
class DownloadContext;
const std::set<std::string>& listRequestOptions(); const std::set<std::string>& listRequestOptions();
@ -90,6 +92,18 @@ void createRequestGroupForUri
bool ignoreForceSequential = false, bool ignoreForceSequential = false,
bool ignoreLocalPath = false); bool ignoreLocalPath = false);
template<typename InputIterator>
void setMetadataInfo
(InputIterator first, InputIterator last, const SharedHandle<MetadataInfo>& mi)
{
for(; first != last; ++first) {
(*first)->setMetadataInfo(mi);
}
}
SharedHandle<MetadataInfo>
createMetadataInfoFromFirstFileEntry(const SharedHandle<DownloadContext>& dctx);
} // namespace aria2 } // namespace aria2
#endif // _D_DOWNLOAD_HELPER_H_ #endif // _D_DOWNLOAD_HELPER_H_

View File

@ -184,8 +184,8 @@ const std::string PREF_REMOVE_CONTROL_FILE("remove-control-file");
const std::string PREF_ALWAYS_RESUME("always-resume"); const std::string PREF_ALWAYS_RESUME("always-resume");
// value: 1*digit // value: 1*digit
const std::string PREF_MAX_RESUME_FAILURE_TRIES("max-resume-failure-tries"); const std::string PREF_MAX_RESUME_FAILURE_TRIES("max-resume-failure-tries");
// value: true | false // value: string that your file system recognizes as a file name.
const std::string PREF_HTTP_ACCEPT_GZIP("http-accept-gzip"); const std::string PREF_SAVE_SESSION("save-session");
/** /**
* FTP related preferences * FTP related preferences
@ -234,6 +234,8 @@ const std::string PREF_USE_HEAD("use-head");
const std::string PREF_HTTP_AUTH_CHALLENGE("http-auth-challenge"); const std::string PREF_HTTP_AUTH_CHALLENGE("http-auth-challenge");
// value: true | false // value: true | false
const std::string PREF_HTTP_NO_CACHE("http-no-cache"); const std::string PREF_HTTP_NO_CACHE("http-no-cache");
// value: true | false
const std::string PREF_HTTP_ACCEPT_GZIP("http-accept-gzip");
/** /**
* Proxy related preferences * Proxy related preferences

View File

@ -188,8 +188,8 @@ extern const std::string PREF_REMOVE_CONTROL_FILE;
extern const std::string PREF_ALWAYS_RESUME; extern const std::string PREF_ALWAYS_RESUME;
// value: 1*digit // value: 1*digit
extern const std::string PREF_MAX_RESUME_FAILURE_TRIES; extern const std::string PREF_MAX_RESUME_FAILURE_TRIES;
// value: true | false // value: string that your file system recognizes as a file name.
extern const std::string PREF_HTTP_ACCEPT_GZIP; extern const std::string PREF_SAVE_SESSION;
/** /**
* FTP related preferences * FTP related preferences
@ -238,6 +238,8 @@ extern const std::string PREF_USE_HEAD;
extern const std::string PREF_HTTP_AUTH_CHALLENGE; extern const std::string PREF_HTTP_AUTH_CHALLENGE;
// value: true | false // value: true | false
extern const std::string PREF_HTTP_NO_CACHE; extern const std::string PREF_HTTP_NO_CACHE;
// value: true | false
extern const std::string PREF_HTTP_ACCEPT_GZIP;
/**; /**;
* Proxy related preferences * Proxy related preferences

View File

@ -672,3 +672,9 @@
" and inflate response if remote server responds\n" \ " and inflate response if remote server responds\n" \
" with 'Content-Encoding: gzip' or\n" \ " with 'Content-Encoding: gzip' or\n" \
" 'Content-Encoding: deflate'.") " 'Content-Encoding: deflate'.")
#define TEXT_SAVE_SESSION \
_(" --save-session=FILE Save error/unfinished downloads to FILE on exit.\n" \
" You can pass this output file to aria2c with -i\n" \
" option on restart. Please note that downloads\n" \
" added by aria2.addTorrent and aria2.addMetalink\n" \
" XML-RPC method are not saved.")

View File

@ -71,7 +71,8 @@ aria2c_SOURCES = AllTest.cc\
a2algoTest.cc\ a2algoTest.cc\
bitfieldTest.cc\ bitfieldTest.cc\
BDETest.cc\ BDETest.cc\
DownloadContextTest.cc DownloadContextTest.cc\
SessionSerializerTest.cc
if ENABLE_XML_RPC if ENABLE_XML_RPC
aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\ aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\

View File

@ -213,7 +213,8 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
RarestPieceSelectorTest.cc PieceStatManTest.cc \ RarestPieceSelectorTest.cc PieceStatManTest.cc \
InOrderPieceSelector.h LongestSequencePieceSelectorTest.cc \ InOrderPieceSelector.h LongestSequencePieceSelectorTest.cc \
a2algoTest.cc bitfieldTest.cc BDETest.cc \ a2algoTest.cc bitfieldTest.cc BDETest.cc \
DownloadContextTest.cc XmlRpcRequestParserControllerTest.cc \ DownloadContextTest.cc SessionSerializerTest.cc \
XmlRpcRequestParserControllerTest.cc \
XmlRpcRequestProcessorTest.cc XmlRpcMethodTest.cc \ XmlRpcRequestProcessorTest.cc XmlRpcMethodTest.cc \
FallocFileAllocationIteratorTest.cc GZipDecoderTest.cc \ FallocFileAllocationIteratorTest.cc GZipDecoderTest.cc \
GZipEncoderTest.cc Sqlite3MozCookieParserTest.cc \ GZipEncoderTest.cc Sqlite3MozCookieParserTest.cc \
@ -406,9 +407,10 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
RarestPieceSelectorTest.$(OBJEXT) PieceStatManTest.$(OBJEXT) \ RarestPieceSelectorTest.$(OBJEXT) PieceStatManTest.$(OBJEXT) \
LongestSequencePieceSelectorTest.$(OBJEXT) \ LongestSequencePieceSelectorTest.$(OBJEXT) \
a2algoTest.$(OBJEXT) bitfieldTest.$(OBJEXT) BDETest.$(OBJEXT) \ a2algoTest.$(OBJEXT) bitfieldTest.$(OBJEXT) BDETest.$(OBJEXT) \
DownloadContextTest.$(OBJEXT) $(am__objects_1) \ DownloadContextTest.$(OBJEXT) SessionSerializerTest.$(OBJEXT) \
$(am__objects_2) $(am__objects_3) $(am__objects_4) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_5) $(am__objects_6) $(am__objects_7) $(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7)
aria2c_OBJECTS = $(am_aria2c_OBJECTS) aria2c_OBJECTS = $(am_aria2c_OBJECTS)
am__DEPENDENCIES_1 = am__DEPENDENCIES_1 =
aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1) aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@ -639,9 +641,10 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
RarestPieceSelectorTest.cc PieceStatManTest.cc \ RarestPieceSelectorTest.cc PieceStatManTest.cc \
InOrderPieceSelector.h LongestSequencePieceSelectorTest.cc \ InOrderPieceSelector.h LongestSequencePieceSelectorTest.cc \
a2algoTest.cc bitfieldTest.cc BDETest.cc \ a2algoTest.cc bitfieldTest.cc BDETest.cc \
DownloadContextTest.cc $(am__append_1) $(am__append_2) \ DownloadContextTest.cc SessionSerializerTest.cc \
$(am__append_3) $(am__append_4) $(am__append_5) \ $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_6) $(am__append_7) $(am__append_4) $(am__append_5) $(am__append_6) \
$(am__append_7)
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS} #aria2c_LDFLAGS = ${CPPUNIT_LIBS}
@ -870,6 +873,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SequentialPickerTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SequentialPickerTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStatManTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStatManTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStatTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerStatTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SessionSerializerTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShareRatioSeedCriteriaTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShareRatioSeedCriteriaTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SharedHandleTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SharedHandleTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SignatureTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SignatureTest.Po@am__quote@

View File

@ -0,0 +1,71 @@
#include "SessionSerializer.h"
#include <iostream>
#include <sstream>
#include <cppunit/extensions/HelperMacros.h>
#include "RequestGroupMan.h"
#include "ServerStatMan.h"
#include "array_fun.h"
#include "download_helper.h"
#include "FileEntry.h"
#include "prefs.h"
namespace aria2 {
class SessionSerializerTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(SessionSerializerTest);
CPPUNIT_TEST(testSave);
CPPUNIT_TEST_SUITE_END();
public:
void testSave();
};
CPPUNIT_TEST_SUITE_REGISTRATION(SessionSerializerTest);
void SessionSerializerTest::testSave()
{
#if defined(ENABLE_BITTORRENT) && defined(ENABLE_METALINK)
const std::string URIs[] =
{ "http://localhost/file",
"http://mirror/file",
"test.torrent",
"serialize_session.meta4",
"magnet:?xt=urn:btih:248D0A1CD08284299DE78D5C1ED359BB46717D8C"};
std::vector<std::string> uris(vbegin(URIs), vend(URIs));
std::vector<SharedHandle<RequestGroup> > result;
SharedHandle<Option> option(new Option());
option->put(PREF_DIR, "/tmp");
createRequestGroupForUri(result, option, uris);
CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
SharedHandle<RequestGroupMan> rgman
(new RequestGroupMan(result, 1, option.get()));
SessionSerializer s(rgman);
std::stringstream ss;
s.save(ss);
std::string line;
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(strconcat(uris[0], "\t", uris[1], "\t"), line);
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(std::string(" dir=/tmp"), line);
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(uris[2], line);
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(std::string(" dir=/tmp"), line);
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(uris[3], line);
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(std::string(" dir=/tmp"), line);
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(uris[4], line);
std::getline(ss, line);
CPPUNIT_ASSERT_EQUAL(std::string(" dir=/tmp"), line);
std::getline(ss, line);
CPPUNIT_ASSERT(!ss);
#endif // defined(ENABLE_BITTORRENT) && defined(ENABLE_METALINK)
}
} // namespace aria2

View File

@ -679,7 +679,9 @@ void XmlRpcMethodTest::testGatherStoppedDownload()
1000, 1000,
downloadresultcode::FINISHED, downloadresultcode::FINISHED,
followedBy, followedBy,
2)); 2,
SharedHandle<Option>(),
SharedHandle<MetadataInfo>()));
BDE entry = BDE::dict(); BDE entry = BDE::dict();
gatherStoppedDownload(entry, d); gatherStoppedDownload(entry, d);

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<metalink xmlns="urn:ietf:params:xml:ns:metalink">
<file name="t/README">
<url>http://example.org/README</url>
</file>
<file name="t/image.iso">
<url>http://example.org/image.iso</url>
</file>
</metalink>