2009-05-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Added --save-cookies option.
	* src/Cookie.cc
	* src/Cookie.h
	* src/CookieStorage.cc
	* src/CookieStorage.h
	* src/MultiUrlRequestInfo.cc
	* src/OptionHandlerFactory.cc
	* src/prefs.cc
	* src/prefs.h
	* src/usage_text.h
	* test/CookieStorageTest.cc
	* test/CookieTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2009-05-22 14:51:57 +00:00
parent 5bad3a1c91
commit 383b12d7f1
12 changed files with 142 additions and 2 deletions

View File

@ -1,3 +1,18 @@
2009-05-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added --save-cookies option.
* src/Cookie.cc
* src/Cookie.h
* src/CookieStorage.cc
* src/CookieStorage.h
* src/MultiUrlRequestInfo.cc
* src/OptionHandlerFactory.cc
* src/prefs.cc
* src/prefs.h
* src/usage_text.h
* test/CookieStorageTest.cc
* test/CookieTest.cc
2009-05-22 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Removed tellAll XML-RPC command because its reponse tends to be

View File

@ -35,6 +35,7 @@
#include "Cookie.h"
#include <algorithm>
#include <sstream>
#include "Util.h"
#include "A2STR.h"
@ -240,4 +241,27 @@ bool Cookie::isSessionCookie() const
return _expiry == 0;
}
std::string Cookie::toNsCookieFormat() const
{
std::stringstream ss;
ss << _domain << "\t";
if(Util::startsWith(_domain, ".")) {
ss << "TRUE";
} else {
ss << "FALSE";
}
ss << "\t";
ss << _path << "\t";
if(_secure) {
ss << "TRUE";
} else {
ss << "FALSE";
}
ss << "\t";
ss << _expiry << "\t";
ss << _name << "\t";
ss << _value;
return ss.str();
}
} // namespace aria2

View File

@ -104,6 +104,8 @@ public:
bool isSecureCookie() const;
bool isSessionCookie() const;
std::string toNsCookieFormat() const;
};
typedef std::deque<Cookie> Cookies;

View File

@ -34,6 +34,7 @@
/* copyright --> */
#include "CookieStorage.h"
#include <cstring>
#include <algorithm>
#include <fstream>
@ -171,4 +172,22 @@ void CookieStorage::load(const std::string& filename)
}
}
void CookieStorage::saveNsFormat(const std::string& filename)
{
std::ofstream o(filename.c_str(), std::ios::binary);
if(!o) {
throw DL_ABORT_EX
(StringFormat("Cannot create cookie file %s, cause %s",
filename.c_str(), strerror(errno)).str());
}
for(std::deque<Cookie>::const_iterator i = _cookies.begin();
i != _cookies.end(); ++i) {
o << (*i).toNsCookieFormat() << "\n";
if(!o) {
throw DL_ABORT_EX
(StringFormat("Failed to save cookies to %s", filename.c_str()).str());
}
}
}
} // namespace aria2

View File

@ -36,11 +36,13 @@
#define _D_COOKIE_STORAGE_H_
#include "common.h"
#include <string>
#include <deque>
#include "a2time.h"
#include "Cookie.h"
#include "CookieParser.h"
#include <string>
#include <deque>
namespace aria2 {
@ -76,6 +78,8 @@ public:
void load(const std::string& filename);
void saveNsFormat(const std::string& filename);
size_t size() const;
std::deque<Cookie>::const_iterator begin() const

View File

@ -182,6 +182,14 @@ DownloadResult::RESULT MultiUrlRequestInfo::execute()
e->run();
if(!_option->blank(PREF_SAVE_COOKIES)) {
try {
e->getCookieStorage()->saveNsFormat(_option->get(PREF_SAVE_COOKIES));
} catch(RecoverableException& e) {
_logger->error(EX_EXCEPTION_CAUGHT, e);
}
}
std::string serverStatOf = _option->get(PREF_SERVER_STAT_OF);
if(!serverStatOf.empty()) {
e->_requestGroupMan->saveServerStat(serverStatOf);

View File

@ -735,6 +735,15 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_HTTP);
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new DefaultOptionHandler
(PREF_SAVE_COOKIES,
TEXT_SAVE_COOKIES,
NO_DEFAULT_VALUE,
"/path/to/file"));
op->addTag(TAG_HTTP);
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new BooleanOptionHandler
(PREF_USE_HEAD,

View File

@ -199,6 +199,8 @@ const std::string V_BASIC("basic");
const std::string PREF_USER_AGENT("user-agent");
// value: string that your file system recognizes as a file name.
const std::string PREF_LOAD_COOKIES("load-cookies");
// value: string that your file system recognizes as a file name.
const std::string PREF_SAVE_COOKIES("save-cookies");
// values: true | false
const std::string PREF_ENABLE_HTTP_KEEP_ALIVE("enable-http-keep-alive");
// values: true | false

View File

@ -203,6 +203,8 @@ extern const std::string V_BASIC;
extern const std::string PREF_USER_AGENT;
// value: string that your file system recognizes as a file name.
extern const std::string PREF_LOAD_COOKIES;
// value: string that your file system recognizes as a file name.
extern const std::string PREF_SAVE_COOKIES;
// values: true | false
extern const std::string PREF_ENABLE_HTTP_KEEP_ALIVE;
// values: true | false

View File

@ -217,6 +217,11 @@ _(" -j, --max-concurrent-downloads=N Set maximum number of parallel downloads fo
#define TEXT_LOAD_COOKIES \
_(" --load-cookies=FILE Load Cookies from FILE using the Firefox3 format\n"\
" and Mozilla/Firefox(1.x/2.x)/Netscape format.")
#define TEXT_SAVE_COOKIES \
_(" --save-cookies=FILE Save Cookies to FILE in Mozilla/Firefox(1.x/2.x)/\n"\
" Netscape format. If FILE already exists, it is\n"\
" overwritten. Session Cookies are also saved and\n"\
" their expiry values are treated as 0.")
#define TEXT_SHOW_FILES \
_(" -S, --show-files Print file listing of .torrent or .metalink file\n"\
" and exit. More detailed information will be listed\n"\

View File

@ -22,6 +22,8 @@ class CookieStorageTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testLoad);
CPPUNIT_TEST(testLoad_sqlite3);
CPPUNIT_TEST(testLoad_fileNotfound);
CPPUNIT_TEST(testSaveNsFormat);
CPPUNIT_TEST(testSaveNsFormat_fail);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
@ -34,6 +36,8 @@ public:
void testLoad();
void testLoad_sqlite3();
void testLoad_fileNotfound();
void testSaveNsFormat();
void testSaveNsFormat_fail();
};
@ -261,4 +265,37 @@ void CookieStorageTest::testLoad_fileNotfound()
}
}
void CookieStorageTest::testSaveNsFormat()
{
std::string filename = "/tmp/aria2_CookieStorageTest_testSaveNsFormat";
File(filename).remove();
CookieStorage st;
st.store(Cookie("uid","tujikawa","/",".domain.org",true));
st.store(Cookie("favorite","classic","/config",".domain.org",false));
st.saveNsFormat(filename);
CookieStorage loadst;
loadst.load(filename);
CPPUNIT_ASSERT_EQUAL((size_t)2, loadst.size());
CPPUNIT_ASSERT_EQUAL(std::string("uid"), (*loadst.begin()).getName());
CPPUNIT_ASSERT_EQUAL((time_t)0, (*loadst.begin()).getExpiry());
CPPUNIT_ASSERT((*loadst.begin()).isSessionCookie());
CPPUNIT_ASSERT_EQUAL(std::string("favorite"), (*(loadst.begin()+1)).getName());
}
void CookieStorageTest::testSaveNsFormat_fail()
{
std::string filename = "/tmp/aria2_CookieStorageTest_testSaveNsFormat_fail";
File f(filename);
if(!f.exists()) {
f.mkdirs();
}
CookieStorage st;
try {
st.saveNsFormat(filename);
CPPUNIT_FAIL("exception should be thrown.");
} catch(RecoverableException& e) {
// OK
}
}
} // namespace aria2

View File

@ -18,6 +18,7 @@ class CookieTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testMatch);
CPPUNIT_TEST(testIsExpired);
CPPUNIT_TEST(testNormalizeDomain);
CPPUNIT_TEST(testToNsCookieFormat);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
@ -29,6 +30,7 @@ public:
void testMatch();
void testIsExpired();
void testNormalizeDomain();
void testToNsCookieFormat();
};
@ -176,4 +178,15 @@ void CookieTest::testNormalizeDomain()
CPPUNIT_ASSERT_EQUAL(std::string("192.168.1.1"), ip.getDomain());
}
void CookieTest::testToNsCookieFormat()
{
CPPUNIT_ASSERT_EQUAL
(std::string(".domain.org\tTRUE\t/\tFALSE\t12345678\thello\tworld"),
Cookie("hello","world",12345678,"/",".domain.org",false).toNsCookieFormat());
// Session cookie's expiry is 0
CPPUNIT_ASSERT_EQUAL
(std::string(".domain.org\tTRUE\t/\tTRUE\t0\thello\tworld"),
Cookie("hello","world","/","domain.org",true).toNsCookieFormat());
}
} // namespace aria2