2007-07-01 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Create directory structure specified in metalink file.
	* src/RequestGroup.h, src/RequestGroup.cc
	(initAndOpenFile): Create a directory to store files if it does 
not
	exist.
	(getDir): New function.
pull/1/head
Tatsuhiro Tsujikawa 2007-07-01 10:40:30 +00:00
parent 7e99d4d2a1
commit 055c9e0b21
10 changed files with 285 additions and 9 deletions

View File

@ -1,3 +1,11 @@
2007-07-01 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Create directory structure specified in metalink file.
* src/RequestGroup.h, src/RequestGroup.cc
(initAndOpenFile): Create a directory to store files if it does not
exist.
(getDir): New function.
2007-06-30 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-06-30 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Made -S option work with metalink file and provided selective download Made -S option work with metalink file and provided selective download
@ -49,6 +57,7 @@
HttpRequestEntryHandle. HttpRequestEntryHandle.
(findEndOfHeader): Removed. (findEndOfHeader): Removed.
(receiveResponse): Rewritten. (receiveResponse): Rewritten.
* src/HttpHeaderProcessor.h, src/HttpHeaderProcessor.cc: New class.
Updated doc for -j option to notice that it should be used with -i Updated doc for -j option to notice that it should be used with -i
option. option.

6
TODO
View File

@ -26,3 +26,9 @@
* exit status: all downloads have been successful-> EXIT_SUCCESS, * exit status: all downloads have been successful-> EXIT_SUCCESS,
some of downloads have been failed -> EXIT_FAILURE some of downloads have been failed -> EXIT_FAILURE
* Create directory structure before initAndOpen:
HttpResponseCommand.cc
RequestGroup.cc
TorrentRequestInfo.cc: <- not the case
* Add ETA like: ETA:01.23'45"

View File

@ -48,6 +48,7 @@
#include "FatalException.h" #include "FatalException.h"
#include "CheckIntegrityEntry.h" #include "CheckIntegrityEntry.h"
#include "DownloadCommand.h" #include "DownloadCommand.h"
#include <cerrno>
SegmentManHandle RequestGroup::initSegmentMan() SegmentManHandle RequestGroup::initSegmentMan()
{ {
@ -123,6 +124,13 @@ void RequestGroup::shouldCancelDownloadForSafety()
void RequestGroup::initAndOpenFile() void RequestGroup::initAndOpenFile()
{ {
File d(getDir());
if(d.isDir()) {
} else if(d.exists()) {
throw new FatalException(EX_MAKE_DIR, getDir().c_str(), "not a directory");
} else if(!d.mkdirs()) {
throw new FatalException(EX_MAKE_DIR, getDir().c_str(), strerror(errno));
}
_segmentMan->diskWriter->initAndOpenFile(_segmentMan->getFilePath()); _segmentMan->diskWriter->initAndOpenFile(_segmentMan->getFilePath());
} }
@ -151,6 +159,15 @@ string RequestGroup::getFilePath() const
} }
} }
string RequestGroup::getDir() const
{
if(_segmentMan.isNull()) {
return "";
} else {
return _segmentMan->dir;
}
}
void RequestGroup::loadAndOpenFile() void RequestGroup::loadAndOpenFile()
{ {
bool segFileExists = segmentFileExists(); bool segFileExists = segmentFileExists();

View File

@ -187,6 +187,8 @@ public:
string getFilePath() const; string getFilePath() const;
string getDir() const;
int64_t getExistingFileLength() const; int64_t getExistingFileLength() const;
int64_t getTotalLength() const int64_t getTotalLength() const

View File

@ -16,6 +16,8 @@ class FileTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testRemove); CPPUNIT_TEST(testRemove);
CPPUNIT_TEST(testSize); CPPUNIT_TEST(testSize);
CPPUNIT_TEST(testMkdir); CPPUNIT_TEST(testMkdir);
CPPUNIT_TEST(testGetDirname);
CPPUNIT_TEST(testGetBasename);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -29,6 +31,8 @@ public:
void testRemove(); void testRemove();
void testSize(); void testSize();
void testMkdir(); void testMkdir();
void testGetDirname();
void testGetBasename();
}; };
@ -112,3 +116,15 @@ void FileTest::testMkdir() {
// already exists. // already exists.
CPPUNIT_ASSERT(!d.mkdirs()); CPPUNIT_ASSERT(!d.mkdirs());
} }
void FileTest::testGetDirname()
{
File f("/tmp/dist/aria2.tar.bz2");
CPPUNIT_ASSERT_EQUAL(string("/tmp/dist"), f.getDirname());
}
void FileTest::testGetBasename()
{
File f("/tmp/dist/aria2.tar.bz2");
CPPUNIT_ASSERT_EQUAL(string("aria2.tar.bz2"), f.getBasename());
}

View File

@ -0,0 +1,198 @@
#include "HttpHeaderProcessor.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
#include <cppunit/extensions/HelperMacros.h>
class HttpHeaderProcessorTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(HttpHeaderProcessorTest);
CPPUNIT_TEST(testUpdate1);
CPPUNIT_TEST(testUpdate2);
CPPUNIT_TEST(testGetPutBackDataLength);
CPPUNIT_TEST(testGetPutBackDataLength_nullChar);
CPPUNIT_TEST(testGetHttpStatusHeader);
CPPUNIT_TEST(testGetHttpStatusHeader_empty);
CPPUNIT_TEST(testGetHttpStatusHeader_statusOnly);
CPPUNIT_TEST(testGetHttpStatusHeader_insufficientStatusLength);
CPPUNIT_TEST(testBeyondLimit);
CPPUNIT_TEST(testGetHeaderString);
CPPUNIT_TEST_SUITE_END();
public:
void testUpdate1();
void testUpdate2();
void testGetPutBackDataLength();
void testGetPutBackDataLength_nullChar();
void testGetHttpStatusHeader();
void testGetHttpStatusHeader_empty();
void testGetHttpStatusHeader_statusOnly();
void testGetHttpStatusHeader_insufficientStatusLength();
void testBeyondLimit();
void testGetHeaderString();
};
CPPUNIT_TEST_SUITE_REGISTRATION( HttpHeaderProcessorTest );
void HttpHeaderProcessorTest::testUpdate1()
{
HttpHeaderProcessor proc;
string hd1 = "HTTP/1.1 200 OK\r\n";
proc.update(hd1);
CPPUNIT_ASSERT(!proc.eoh());
proc.update("\r\n");
CPPUNIT_ASSERT(proc.eoh());
}
void HttpHeaderProcessorTest::testUpdate2()
{
HttpHeaderProcessor proc;
string hd1 = "HTTP/1.1 200 OK\n";
proc.update(hd1);
CPPUNIT_ASSERT(!proc.eoh());
proc.update("\n");
CPPUNIT_ASSERT(proc.eoh());
}
void HttpHeaderProcessorTest::testGetPutBackDataLength()
{
HttpHeaderProcessor proc;
string hd1 = "HTTP/1.1 200 OK\r\n"
"\r\nputbackme";
proc.update(hd1);
CPPUNIT_ASSERT(proc.eoh());
CPPUNIT_ASSERT_EQUAL(9, proc.getPutBackDataLength());
proc.clear();
string hd2 = "HTTP/1.1 200 OK\n"
"\nputbackme";
proc.update(hd2);
CPPUNIT_ASSERT(proc.eoh());
CPPUNIT_ASSERT_EQUAL(9, proc.getPutBackDataLength());
}
void HttpHeaderProcessorTest::testGetPutBackDataLength_nullChar()
{
HttpHeaderProcessor proc;
proc.update("HTTP/1.1 200 OK\r\n"
"foo: foo\0bar\r\n"
"\r\nputbackme", 35+7);
CPPUNIT_ASSERT(proc.eoh());
CPPUNIT_ASSERT_EQUAL(9, proc.getPutBackDataLength());
}
void HttpHeaderProcessorTest::testGetHttpStatusHeader()
{
HttpHeaderProcessor proc;
string hd = "HTTP/1.1 200 OK\r\n"
"Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n"
"Server: Apache/2.2.3 (Debian)\r\n"
"Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n"
"ETag: \"594065-23e3-50825cc0\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 9187\r\n"
"Connection: close\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"
"\r\n";
proc.update(hd);
pair<string, HttpHeaderHandle> statusHeader = proc.getHttpStatusHeader();
string status = statusHeader.first;
HttpHeaderHandle header = statusHeader.second;
CPPUNIT_ASSERT_EQUAL(string("200"), status);
CPPUNIT_ASSERT_EQUAL(string("Mon, 25 Jun 2007 16:04:59 GMT"), header->getFirst("Date"));
CPPUNIT_ASSERT_EQUAL(string("Apache/2.2.3 (Debian)"), header->getFirst("Server"));
CPPUNIT_ASSERT_EQUAL(9187LL, header->getFirstAsLLInt("Content-Length"));
CPPUNIT_ASSERT_EQUAL(string("text/html; charset=UTF-8"), header->getFirst("Content-Type"));
}
void HttpHeaderProcessorTest::testGetHttpStatusHeader_empty()
{
HttpHeaderProcessor proc;
try {
pair<string, HttpHeaderHandle> statusHeader = proc.getHttpStatusHeader();
CPPUNIT_FAIL("Exception must be threw.");
} catch(DlRetryEx* ex) {
cout << ex->getMsg() << endl;
delete ex;
}
}
void HttpHeaderProcessorTest::testGetHttpStatusHeader_statusOnly()
{
HttpHeaderProcessor proc;
string hd = "HTTP/1.1 200\r\n\r\n";
proc.update(hd);
pair<string, HttpHeaderHandle> statusHeader = proc.getHttpStatusHeader();
CPPUNIT_ASSERT_EQUAL(string("200"), statusHeader.first);
CPPUNIT_ASSERT(!statusHeader.second.isNull());
}
void HttpHeaderProcessorTest::testGetHttpStatusHeader_insufficientStatusLength()
{
HttpHeaderProcessor proc;
string hd = "HTTP/1.1 20\r\n\r\n";
proc.update(hd);
try {
pair<string, HttpHeaderHandle> statusHeader = proc.getHttpStatusHeader();
CPPUNIT_FAIL("Exception must be threw.");
} catch(DlRetryEx* ex) {
cout << ex->getMsg() << endl;
delete ex;
}
}
void HttpHeaderProcessorTest::testBeyondLimit()
{
HttpHeaderProcessor proc;
proc.setHeaderLimit(20);
string hd1 = "HTTP/1.1 200 OK\r\n";
string hd2 = "Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n";
proc.update(hd1);
try {
proc.update(hd2);
CPPUNIT_FAIL("Exception must be threw.");
} catch(DlAbortEx* ex) {
cout << ex->getMsg() << endl;
delete ex;
}
}
void HttpHeaderProcessorTest::testGetHeaderString()
{
HttpHeaderProcessor proc;
string hd = "HTTP/1.1 200 OK\r\n"
"Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n"
"Server: Apache/2.2.3 (Debian)\r\n"
"Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n"
"ETag: \"594065-23e3-50825cc0\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 9187\r\n"
"Connection: close\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"
"\r\nputbackme";
proc.update(hd);
CPPUNIT_ASSERT_EQUAL(string("HTTP/1.1 200 OK\r\n"
"Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n"
"Server: Apache/2.2.3 (Debian)\r\n"
"Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n"
"ETag: \"594065-23e3-50825cc0\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 9187\r\n"
"Connection: close\r\n"
"Content-Type: text/html; charset=UTF-8"),
proc.getHeaderString());
}

View File

@ -1,6 +1,7 @@
TESTS = aria2c TESTS = aria2c
check_PROGRAMS = $(TESTS) check_PROGRAMS = $(TESTS)
aria2c_SOURCES = AllTest.cc\ aria2c_SOURCES = AllTest.cc\
HttpHeaderProcessorTest.cc\
UtilTest.cc\ UtilTest.cc\
CookieBoxTest.cc\ CookieBoxTest.cc\
RequestTest.cc\ RequestTest.cc\

View File

@ -57,7 +57,8 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT) am__EXEEXT_1 = aria2c$(EXEEXT)
am_aria2c_OBJECTS = AllTest.$(OBJEXT) UtilTest.$(OBJEXT) \ am_aria2c_OBJECTS = AllTest.$(OBJEXT) \
HttpHeaderProcessorTest.$(OBJEXT) UtilTest.$(OBJEXT) \
CookieBoxTest.$(OBJEXT) RequestTest.$(OBJEXT) \ CookieBoxTest.$(OBJEXT) RequestTest.$(OBJEXT) \
CookieParserTest.$(OBJEXT) HttpRequestTest.$(OBJEXT) \ CookieParserTest.$(OBJEXT) HttpRequestTest.$(OBJEXT) \
CookieBoxFactoryTest.$(OBJEXT) \ CookieBoxFactoryTest.$(OBJEXT) \
@ -268,6 +269,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
TESTS = aria2c TESTS = aria2c
aria2c_SOURCES = AllTest.cc\ aria2c_SOURCES = AllTest.cc\
HttpHeaderProcessorTest.cc\
UtilTest.cc\ UtilTest.cc\
CookieBoxTest.cc\ CookieBoxTest.cc\
RequestTest.cc\ RequestTest.cc\
@ -450,6 +452,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfigTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfigTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GlowFileAllocatorTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GlowFileAllocatorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderProcessorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpHeaderTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpRequestTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseTest.Po@am__quote@

View File

@ -24,6 +24,7 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testCountBit); CPPUNIT_TEST(testCountBit);
CPPUNIT_TEST(testGetRealSize); CPPUNIT_TEST(testGetRealSize);
CPPUNIT_TEST(testAbbrevSize); CPPUNIT_TEST(testAbbrevSize);
CPPUNIT_TEST(testToStream);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -48,6 +49,7 @@ public:
void testCountBit(); void testCountBit();
void testGetRealSize(); void testGetRealSize();
void testAbbrevSize(); void testAbbrevSize();
void testToStream();
}; };
@ -304,11 +306,33 @@ void UtilTest::testGetRealSize()
void UtilTest::testAbbrevSize() void UtilTest::testAbbrevSize()
{ {
CPPUNIT_ASSERT_EQUAL(string("4,096.0M"), Util::abbrevSize(4294967296LL)); CPPUNIT_ASSERT_EQUAL(string("4,096.0Mi"), Util::abbrevSize(4294967296LL));
CPPUNIT_ASSERT_EQUAL(string("1.0K"), Util::abbrevSize(1024)); CPPUNIT_ASSERT_EQUAL(string("1.0Ki"), Util::abbrevSize(1024));
CPPUNIT_ASSERT_EQUAL(string("1,023"), Util::abbrevSize(1023)); CPPUNIT_ASSERT_EQUAL(string("1,023"), Util::abbrevSize(1023));
CPPUNIT_ASSERT_EQUAL(string("0"), Util::abbrevSize(0)); CPPUNIT_ASSERT_EQUAL(string("0"), Util::abbrevSize(0));
CPPUNIT_ASSERT_EQUAL(string("1.1K"), Util::abbrevSize(1127)); CPPUNIT_ASSERT_EQUAL(string("1.1Ki"), Util::abbrevSize(1127));
CPPUNIT_ASSERT_EQUAL(string("1.5M"), Util::abbrevSize(1572864)); CPPUNIT_ASSERT_EQUAL(string("1.5Mi"), Util::abbrevSize(1572864));
} }
void UtilTest::testToStream()
{
ostringstream os;
FileEntryHandle f1 = new FileEntry("aria2.tar.bz2", 12300, 0);
FileEntryHandle f2 = new FileEntry("aria2.txt", 556, 0);
FileEntries entries;
entries.push_back(f1);
entries.push_back(f2);
Util::toStream(os, entries);
CPPUNIT_ASSERT_EQUAL(
string("Files:\n"
"idx|path/length\n"
"===+===========================================================================\n"
" 1|aria2.tar.bz2\n"
" |12,300 bytes\n"
"---+---------------------------------------------------------------------------\n"
" 2|aria2.txt\n"
" |556 bytes\n"
"---+---------------------------------------------------------------------------\n"),
os.str());
}

View File

@ -32,8 +32,8 @@ void Xml2MetalinkProcessorTest::testParseFile() {
MetalinkEntries::iterator entryItr = metalinker->entries.begin(); MetalinkEntries::iterator entryItr = metalinker->entries.begin();
MetalinkEntryHandle entry1 = *entryItr; MetalinkEntryHandle entry1 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.2.tar.bz2"), entry1->filename); CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.2.tar.bz2"), entry1->getPath());
CPPUNIT_ASSERT_EQUAL((int64_t)0, entry1->size); CPPUNIT_ASSERT_EQUAL((int64_t)0, entry1->getLength());
CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entry1->version); CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entry1->version);
CPPUNIT_ASSERT_EQUAL(string("en-US"), entry1->language); CPPUNIT_ASSERT_EQUAL(string("en-US"), entry1->language);
CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entry1->os); CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entry1->os);
@ -59,8 +59,8 @@ void Xml2MetalinkProcessorTest::testParseFile() {
entryItr++; entryItr++;
MetalinkEntryHandle entry2 = *entryItr; MetalinkEntryHandle entry2 = *entryItr;
CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.1.tar.bz2"), entry2->filename); CPPUNIT_ASSERT_EQUAL(string("aria2-0.5.1.tar.bz2"), entry2->getPath());
CPPUNIT_ASSERT_EQUAL((int64_t)345689, entry2->size); CPPUNIT_ASSERT_EQUAL((int64_t)345689, entry2->getLength());
CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entry2->version); CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entry2->version);
CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entry2->language); CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entry2->language);
CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entry2->os); CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entry2->os);