From c5b83fed361b91d0f3356557e53a60ca2df48e43 Mon Sep 17 00:00:00 2001 From: Mingye Wang Date: Sat, 7 May 2016 16:22:26 -0400 Subject: [PATCH 01/12] import-po: iterate on glob, not ls output --- import-po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import-po b/import-po index 5eaf6fd4..49cb8c83 100755 --- a/import-po +++ b/import-po @@ -30,7 +30,7 @@ echo "Renaming po files..." mv "$WORK_DIR"/aria2/*.po "$WORK_DIR" echo -n "en@quot en@boldquot" > "$PO_DIR"/LINGUAS -for file in `ls "$WORK_DIR"/*.po`; do +for file in "$WORK_DIR"/*.po; do # First remove useless '\r' in messages sed -i -e 's/\\r//' "$file" bn=`basename "$file"` From c140a5246864468730d479a15109d6d1ad7c7ac0 Mon Sep 17 00:00:00 2001 From: Mingye Wang Date: Sat, 7 May 2016 16:23:18 -0400 Subject: [PATCH 02/12] po/README: deflate -> inflate --- po/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/README.rst b/po/README.rst index 7cc38246..ebffbb84 100644 --- a/po/README.rst +++ b/po/README.rst @@ -21,5 +21,5 @@ Importing PO files from launchpad-export.tar.gz The downloaded file is named as launchpad-export.tar.gz at the time of this writing. It includes all PO files translated at launchpad. To import those files, use ``import-po`` script in the top directory. It -will deflate the tar.gz file and rename PO files and move them to po +will inflate the tar.gz file and rename PO files and move them to po directory and run ``make update-po``. From 3443349fc3ea9b99a796bf4f2835950f75de729a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 14 May 2016 19:50:58 +0900 Subject: [PATCH 03/12] Refactor --- src/DHTGetPeersReplyMessage.cc | 43 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/DHTGetPeersReplyMessage.cc b/src/DHTGetPeersReplyMessage.cc index 80464810..2ae92f3b 100644 --- a/src/DHTGetPeersReplyMessage.cc +++ b/src/DHTGetPeersReplyMessage.cc @@ -35,6 +35,7 @@ #include "DHTGetPeersReplyMessage.h" #include +#include #include "DHTNode.h" #include "DHTBucket.h" @@ -81,24 +82,24 @@ std::unique_ptr DHTGetPeersReplyMessage::getResponse() rDict->put(TOKEN, token_); // TODO want parameter if (!closestKNodes_.empty()) { - unsigned char buffer[DHTBucket::K * 38]; - const int clen = bittorrent::getCompactLength(family_); - const int unit = clen + 20; - size_t offset = 0; + std::array buffer; + const auto clen = bittorrent::getCompactLength(family_); + const auto unit = clen + DHT_ID_LENGTH; + auto last = std::begin(buffer); size_t k = 0; - for (auto i = std::begin(closestKNodes_), eoi = std::end(closestKNodes_); - i != eoi && k < DHTBucket::K; ++i) { - memcpy(buffer + offset, (*i)->getID(), DHT_ID_LENGTH); - unsigned char compact[COMPACT_LEN_IPV6]; - int compactlen = bittorrent::packcompact(compact, (*i)->getIPAddress(), - (*i)->getPort()); + for (auto i = std::begin(closestKNodes_); + i != std::end(closestKNodes_) && k < DHTBucket::K; ++i) { + std::array compact; + auto compactlen = bittorrent::packcompact( + compact.data(), (*i)->getIPAddress(), (*i)->getPort()); if (compactlen == clen) { - memcpy(buffer + 20 + offset, compact, compactlen); - offset += unit; + last = std::copy_n((*i)->getID(), DHT_ID_LENGTH, last); + last = std::copy_n(std::begin(compact), compactlen, last); ++k; } } - rDict->put(family_ == AF_INET ? NODES : NODES6, String::g(buffer, offset)); + rDict->put(family_ == AF_INET ? NODES : NODES6, + String::g(std::begin(buffer), last)); } if (!values_.empty()) { // Limit the size of values list. The maximum size of UDP datagram @@ -123,16 +124,16 @@ std::unique_ptr DHTGetPeersReplyMessage::getResponse() // doesn't specify the maximum size of token, reply message // template may get bigger than 395 bytes. So we use 25 as maximum // number of peer info that a message can carry. - static const size_t MAX_VALUES_SIZE = 25; + constexpr size_t MAX_VALUES_SIZE = 25; auto valuesList = List::g(); - for (auto i = std::begin(values_), eoi = std::end(values_); - i != eoi && valuesList->size() < MAX_VALUES_SIZE; ++i) { - unsigned char compact[COMPACT_LEN_IPV6]; - const int clen = bittorrent::getCompactLength(family_); - int compactlen = bittorrent::packcompact(compact, (*i)->getIPAddress(), - (*i)->getPort()); + for (auto i = std::begin(values_); + i != std::end(values_) && valuesList->size() < MAX_VALUES_SIZE; ++i) { + std::array compact; + const auto clen = bittorrent::getCompactLength(family_); + auto compactlen = bittorrent::packcompact( + compact.data(), (*i)->getIPAddress(), (*i)->getPort()); if (compactlen == clen) { - valuesList->append(String::g(compact, compactlen)); + valuesList->append(String::g(compact.data(), compactlen)); } } rDict->put(VALUES, std::move(valuesList)); From 6976ffed9e96ccc70f161aa5a38abddaf9d9befe Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 17:58:01 +0900 Subject: [PATCH 04/12] Adjust chromium cookie time --- src/Sqlite3CookieParserImpl.cc | 9 +++++++-- test/chromium_cookies.sqlite | Bin 3072 -> 3072 bytes 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Sqlite3CookieParserImpl.cc b/src/Sqlite3CookieParserImpl.cc index 5d1ce849..751ead1c 100644 --- a/src/Sqlite3CookieParserImpl.cc +++ b/src/Sqlite3CookieParserImpl.cc @@ -59,8 +59,13 @@ Sqlite3ChromiumCookieParser::~Sqlite3ChromiumCookieParser() {} const char* Sqlite3ChromiumCookieParser::getQuery() const { - return "SELECT host_key, path, secure, expires_utc, name, value, " - "last_access_utc" + // chrome's time is microsecond resolution, and its epoc is Jan 1 + // 00:00:00 +0000 1601, so we have to convert it to second from UNIX + // epoc. 11644473600 is the second between chrome's epoc and UNIX + // epoc. e.g., date +%s -d 'Jan 1 00:00:00 +0000 1601' + return "SELECT host_key, path, secure, expires_utc / 1000000 - 11644473600 " + "as expires_utc, name, value, " + "last_access_utc / 1000000 - 11644473600 as last_access_utc" " FROM cookies"; } diff --git a/test/chromium_cookies.sqlite b/test/chromium_cookies.sqlite index c3e98fc876f6eec302067e30f7c06321486d92c8..e653715b210ea39c2c6a145746c3a0bfb4fe505c 100644 GIT binary patch delta 190 zcmZpWXpop7&B!%T##xYyLHFw-UgkdxOiaren3gl2-7Lsr&a`N6Pp-{w*F z_W%O}gJ#^c-(m9@Tp76-Ol8GoK{_U1V%L%dihHy%pEaG4R0B$HU1^@s6 delta 161 zcmZpWXpop7&B!rP##xYqLHCgqFY_M;CZ^>KOv{;$UTlmPUGpW)^w|dWPAlm1T)JrK$S$|NsAIVBp?i!N|p6Dl0C_2r@35T?=R| J_l`vzEC7>VB>?~c From bafbbe7c1d5ea39e67e233f9c32975fda7843874 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 18:40:50 +0900 Subject: [PATCH 05/12] Allow subsecond value in ns cookie.txt file's expiry time field --- src/NsCookieParser.cc | 11 ++++++++--- src/util.cc | 27 +++++++++++++++++++++++++++ src/util.h | 4 ++++ test/CookieStorageTest.cc | 4 ++-- test/NsCookieParserTest.cc | 4 ++-- test/UtilTest2.cc | 19 +++++++++++++++++++ test/nscookietest.txt | 4 ++-- 7 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/NsCookieParser.cc b/src/NsCookieParser.cc index e484df8e..77ca25ab 100644 --- a/src/NsCookieParser.cc +++ b/src/NsCookieParser.cc @@ -69,9 +69,14 @@ std::unique_ptr parseNsCookie(const std::string& cookieStr, return nullptr; } int64_t expiryTime; - if (!util::parseLLIntNoThrow(expiryTime, - std::string(vs[4].first, vs[4].second))) { - return nullptr; + { + // chrome extension uses subsecond resolution for expiry time. + double expiryTimeDouble; + if (!util::parseDoubleNoThrow(expiryTimeDouble, + std::string(vs[4].first, vs[4].second))) { + return nullptr; + } + expiryTime = static_cast(expiryTimeDouble); } if (std::numeric_limits::max() < expiryTime) { expiryTime = std::numeric_limits::max(); diff --git a/src/util.cc b/src/util.cc index a2590235..3c9c19b1 100644 --- a/src/util.cc +++ b/src/util.cc @@ -596,6 +596,33 @@ bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base) } } +bool parseDoubleNoThrow(double& res, const std::string& s) +{ + if (s.empty()) { + return false; + } + + errno = 0; + char* endptr; + auto d = strtod(s.c_str(), &endptr); + + if (errno == ERANGE) { + return false; + } + + if (endptr != s.c_str() + s.size()) { + for (auto i = std::begin(s) + (endptr - s.c_str()); i != std::end(s); ++i) { + if (!isspace(*i)) { + return false; + } + } + } + + res = d; + + return true; +} + SegList parseIntSegments(const std::string& src) { SegList sgl; diff --git a/src/util.h b/src/util.h index 25183b5c..76ecb549 100644 --- a/src/util.h +++ b/src/util.h @@ -280,6 +280,10 @@ bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10); bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10); +// Parses |s| as floating point number, and stores the result into +// |res|. This function returns true if it succeeds. +bool parseDoubleNoThrow(double& res, const std::string& s); + SegList parseIntSegments(const std::string& src); // Parses string which specifies the range of piece index for higher diff --git a/test/CookieStorageTest.cc b/test/CookieStorageTest.cc index b9e741b6..a9966a64 100644 --- a/test/CookieStorageTest.cc +++ b/test/CookieStorageTest.cc @@ -328,10 +328,10 @@ void CookieStorageTest::testLoad() c = cookies[3]; CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName()); CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue()); - CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime()); + CPPUNIT_ASSERT_EQUAL((time_t)1463304912, c->getExpiryTime()); CPPUNIT_ASSERT(c->getPersistent()); CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath()); - CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("something"), c->getDomain()); CPPUNIT_ASSERT(!c->getSecure()); } diff --git a/test/NsCookieParserTest.cc b/test/NsCookieParserTest.cc index 45d81004..23fb4016 100644 --- a/test/NsCookieParserTest.cc +++ b/test/NsCookieParserTest.cc @@ -69,9 +69,9 @@ void NsCookieParserTest::testParse() c = cookies[3].get(); CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName()); CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue()); - CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime()); + CPPUNIT_ASSERT_EQUAL((time_t)1463304912, c->getExpiryTime()); CPPUNIT_ASSERT(c->getPersistent()); - CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("something"), c->getDomain()); CPPUNIT_ASSERT(c->getHostOnly()); CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath()); CPPUNIT_ASSERT(!c->getSecure()); diff --git a/test/UtilTest2.cc b/test/UtilTest2.cc index 03a28411..544df0d5 100644 --- a/test/UtilTest2.cc +++ b/test/UtilTest2.cc @@ -66,6 +66,7 @@ class UtilTest2 : public CppUnit::TestFixture { CPPUNIT_TEST(testInPrivateAddress); CPPUNIT_TEST(testSecfmt); CPPUNIT_TEST(testTlsHostnameMatch); + CPPUNIT_TEST(testParseDoubleNoThrow); CPPUNIT_TEST_SUITE_END(); private: @@ -115,6 +116,7 @@ public: void testInPrivateAddress(); void testSecfmt(); void testTlsHostnameMatch(); + void testParseDoubleNoThrow(); }; CPPUNIT_TEST_SUITE_REGISTRATION(UtilTest2); @@ -978,4 +980,21 @@ void UtilTest2::testTlsHostnameMatch() CPPUNIT_ASSERT(!util::tlsHostnameMatch("xn--*.a.b", "xn--c.a.b")); } +void UtilTest2::testParseDoubleNoThrow() +{ + double n; + + CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, " 123 ")); + CPPUNIT_ASSERT_EQUAL(123., n); + + CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, "3.14")); + CPPUNIT_ASSERT_EQUAL(3.14, n); + + CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, "-3.14")); + CPPUNIT_ASSERT_EQUAL(-3.14, n); + + CPPUNIT_ASSERT(!util::parseDoubleNoThrow(n, "")); + CPPUNIT_ASSERT(!util::parseDoubleNoThrow(n, "123x")); +} + } // namespace aria2 diff --git a/test/nscookietest.txt b/test/nscookietest.txt index 7b7d9e84..5eed9f33 100644 --- a/test/nscookietest.txt +++ b/test/nscookietest.txt @@ -5,5 +5,5 @@ expired FALSE / FALSE 1000 user me 192.168.0.1 TRUE /cgi-bin FALSE 0 passwd secret badformat -overflow FALSE / FALSE 9223372036854775807 TAX 1000 -.example.org TRUE / FALSE 2147483647 novalue +something FALSE / FALSE 1463304912.5 TAX 1000 +.example.org TRUE / FALSE 2147483647.123 novalue From 2449ee6a760a1857100ff2210e739baf8a4899a4 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 14 May 2016 23:08:42 +0900 Subject: [PATCH 06/12] Simplify cache write The previous cache write routine was too complex. I'm sure I can rewrite it to more elegantly. But the primary motivation of this complex logic is for disk activity reduction on Windows 7, and I observed it on my old IDE disk. I checked it again recently, and there is no difference between with and without this complex logic. For this reason, it was removed. Will revert this change if many of users are not happy with this. --- src/AbstractSingleDiskAdaptor.cc | 45 +-------------- src/MultiDiskAdaptor.cc | 94 +------------------------------- 2 files changed, 6 insertions(+), 133 deletions(-) diff --git a/src/AbstractSingleDiskAdaptor.cc b/src/AbstractSingleDiskAdaptor.cc index 470beb37..57881755 100644 --- a/src/AbstractSingleDiskAdaptor.cc +++ b/src/AbstractSingleDiskAdaptor.cc @@ -96,49 +96,10 @@ ssize_t AbstractSingleDiskAdaptor::readDataDropCache(unsigned char* data, void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry) { - // Write cached data in 4KiB aligned offset. This reduces disk - // activity especially on Windows 7 NTFS. In this code, we assume - // that maximum length of DataCell data is 16KiB to simplify the - // code. - unsigned char buf[16_k]; - int64_t start = 0; - size_t buflen = 0; - size_t buffoffset = 0; - const WrDiskCacheEntry::DataCellSet& dataSet = entry->getDataSet(); - for (auto& d : dataSet) { - if (start + static_cast(buflen) < d->goff) { - A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start, - static_cast(buflen))); - writeData(buf + buffoffset, buflen - buffoffset, start); - start = d->goff; - buflen = buffoffset = 0; - } - if (buflen == 0 && (d->goff & 0xfff) == 0 && (d->len & 0xfff) == 0) { - // Already aligned. Write it without copy. - A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start, - static_cast(d->len))); - writeData(d->data + d->offset, d->len, start); - start += d->len; - } - else { - if (buflen == 0) { - buflen = buffoffset = d->goff & 0xfff; - } - size_t wlen = std::min(sizeof(buf) - buflen, d->len); - memcpy(buf + buflen, d->data + d->offset, wlen); - buflen += wlen; - if (buflen == sizeof(buf)) { - A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start, - static_cast(buflen))); - writeData(buf + buffoffset, buflen - buffoffset, start); - memcpy(buf, d->data + d->offset + wlen, d->len - wlen); - start += sizeof(buf) - buffoffset; - buflen = d->len - wlen; - buffoffset = 0; - } - } + for (auto& d : entry->getDataSet()) { + A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", d->goff, d->len)); + writeData(d->data + d->offset, d->len, d->goff); } - writeData(buf + buffoffset, buflen - buffoffset, start); } bool AbstractSingleDiskAdaptor::fileExists() diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc index 3e6a5ea0..13c7364f 100644 --- a/src/MultiDiskAdaptor.cc +++ b/src/MultiDiskAdaptor.cc @@ -412,98 +412,10 @@ ssize_t MultiDiskAdaptor::readData(unsigned char* data, size_t len, void MultiDiskAdaptor::writeCache(const WrDiskCacheEntry* entry) { - // Write cached data in 4KiB aligned offset. This reduces disk - // activity especially on Windows 7 NTFS. - unsigned char buf[16_k]; - size_t buflen = 0; - size_t buffoffset = 0; - auto& dataSet = entry->getDataSet(); - if (dataSet.empty()) { - return; + for (auto& d : entry->getDataSet()) { + A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", d->goff, d->len)); + writeData(d->data + d->offset, d->len, d->goff); } - auto dent = - findFirstDiskWriterEntry(diskWriterEntries_, (*dataSet.begin())->goff), - eod = diskWriterEntries_.cend(); - auto i = std::begin(dataSet), eoi = std::end(dataSet); - size_t celloff = 0; - for (; dent != eod; ++dent) { - int64_t lstart = 0, lp = 0; - auto& fent = (*dent)->getFileEntry(); - if (fent->getLength() == 0) { - continue; - } - for (; i != eoi;) { - if (std::max(fent->getOffset(), - static_cast((*i)->goff + celloff)) < - std::min(fent->getLastOffset(), - static_cast((*i)->goff + (*i)->len))) { - openIfNot((*dent).get(), &DiskWriterEntry::openFile); - if (!(*dent)->isOpen()) { - throwOnDiskWriterNotOpened((*dent).get(), (*i)->goff + celloff); - } - } - else { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, - buflen - buffoffset, lstart); - buflen = buffoffset = 0; - break; - } - int64_t loff = fent->gtoloff((*i)->goff + celloff); - if (static_cast(lstart + buflen) < loff) { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, - buflen - buffoffset, lstart); - lstart = lp = loff; - buflen = buffoffset = 0; - } - // If the position of the cache data is not aligned, offset - // buffer so that next write can be aligned. - if (buflen == 0) { - buflen = buffoffset = loff & 0xfff; - } - assert((*i)->len > celloff); - for (;;) { - size_t wlen = std::min(static_cast((*i)->len - celloff), - fent->getLength() - lp); - wlen = std::min(wlen, sizeof(buf) - buflen); - memcpy(buf + buflen, (*i)->data + (*i)->offset + celloff, wlen); - buflen += wlen; - celloff += wlen; - lp += wlen; - if (lp == fent->getLength() || buflen == sizeof(buf)) { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, - buflen - buffoffset, lstart); - lstart += buflen - buffoffset; - lp = lstart; - buflen = buffoffset = 0; - } - if (lp == fent->getLength() || celloff == (*i)->len) { - break; - } - } - if (celloff == (*i)->len) { - ++i; - celloff = 0; - } - } - if (i == eoi) { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, buflen - buffoffset, - lstart); - break; - } - } - assert(i == eoi); } bool MultiDiskAdaptor::fileExists() From d821cb3133a2199ab6711be24a4e224831ae3700 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 18:50:59 +0900 Subject: [PATCH 07/12] Update AUTHORS --- AUTHORS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index f6cc2425..9b3156e1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,13 +16,17 @@ ITriskTI Igor Khomyakov Jarda Snajdr Kcchouette +Kurt Kartaltepe +Mingye Wang Nils Maier ORiON- +ReadmeCritic Ross Smith II Ryan Steinmetz Ryo ONODERA Sarim Khan Sergey Zolotarev +Sonny Piers Tatsuhiro Tsujikawa Vasilij Schneidermann Zoltan Toth-Czifra @@ -36,6 +40,6 @@ luokar mozillazg multisnow oliviercommelarbre -Sonny Piers +rotor [1] https://gist.github.com/tatsuhiro-t/deaffeb064652104ad11 From 9d41f159cd0ac69847ee4a3f5762a86755e41ef2 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 18:51:36 +0900 Subject: [PATCH 08/12] Bump up version number to 1.23.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index fe1164cc..ae7b6f8f 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. # AC_PREREQ([2.67]) -AC_INIT([aria2],[1.22.0],[https://github.com/aria2/aria2/issues],[aria2],[https://aria2.github.io/]) +AC_INIT([aria2],[1.23.0],[https://github.com/aria2/aria2/issues],[aria2],[https://aria2.github.io/]) AC_CANONICAL_HOST AC_CANONICAL_TARGET From 724d036b3a5198bcacc0c897b56bd07b782d3677 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 18:56:05 +0900 Subject: [PATCH 09/12] Update bash_completion --- doc/bash_completion/aria2c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/bash_completion/aria2c b/doc/bash_completion/aria2c index 9ba44bd1..407beaf1 100644 --- a/doc/bash_completion/aria2c +++ b/doc/bash_completion/aria2c @@ -52,7 +52,7 @@ _aria2c() return 0 ;; --download-result) - COMPREPLY=( $( compgen -W 'default full' -- "$cur" ) ) + COMPREPLY=( $( compgen -W 'default full hide' -- "$cur" ) ) return 0 ;; --dir) @@ -70,7 +70,7 @@ _aria2c() esac case $cur in -*) - COMPREPLY=( $( compgen -W '--rpc-save-upload-metadata --rpc-save-upload-metadata=false --on-download-start --metalink-language --rpc-secret --torrent-file --enable-peer-exchange --enable-peer-exchange=false --http-proxy-passwd --bt-tracker-timeout --ftp-type --seed-time --bt-tracker-connect-timeout --bt-max-open-files --no-netrc --no-netrc=false --force-sequential --force-sequential=false --metalink-base-uri --private-key --ftp-passwd --allow-overwrite --allow-overwrite=false --rpc-allow-origin-all --rpc-allow-origin-all=false --bt-detach-seed-only --bt-detach-seed-only=false --dht-entry-point6 --summary-interval --lowest-speed-limit --bt-tracker-interval --proxy-method --metalink-preferred-protocol --enable-http-keep-alive --enable-http-keep-alive=false --metalink-version --bt-lpd-interface --force-save --force-save=false --rpc-secure --rpc-secure=false --listen-port --rpc-private-key --server-stat-of --server-stat-timeout --https-proxy-user --piece-length --dry-run --dry-run=false --truncate-console-readout --truncate-console-readout=false --async-dns-server --bt-max-peers --max-overall-upload-limit --rpc-user --optimize-concurrent-downloads --optimize-concurrent-downloads=true --optimize-concurrent-downloads=false --optimize-concurrent-downloads=A:B --dir --split --on-download-pause --auto-file-renaming --auto-file-renaming=false --http-proxy --save-session-interval --daemon --daemon=false --https-proxy --min-tls-version --save-cookies --out --rlimit-nofile --max-file-not-found --on-download-stop --certificate --bt-min-crypto-level --remove-control-file --remove-control-file=false --enable-dht --enable-dht=false --file-allocation --follow-metalink --on-bt-download-complete --ftp-proxy --show-files --show-files=false --timeout --bt-hash-check-seed --bt-hash-check-seed=false --ftp-pasv --ftp-pasv=false --check-certificate --check-certificate=false --always-resume --always-resume=false --load-cookies --bt-remove-unselected-file --bt-remove-unselected-file=false --bt-stop-timeout --version --max-concurrent-downloads --quiet --quiet=false --max-download-result --max-resume-failure-tries --header --rpc-listen-all --rpc-listen-all=false --all-proxy-user --server-stat-if --dht-file-path6 --save-session --bt-external-ip --max-tries --conditional-get --conditional-get=false --ftp-reuse-connection --ftp-reuse-connection=false --gid --dscp --max-download-limit --bt-prioritize-piece --check-integrity --check-integrity=false --log-level --remote-time --remote-time=false --uri-selector --rpc-listen-port --index-out --bt-tracker --referer --ssh-host-key-md --console-log-level --connect-timeout --stream-piece-selector --dht-message-timeout --select-file --download-result --disable-ipv6 --disable-ipv6=false --rpc-max-request-size --rpc-passwd --stop-with-process --https-proxy-passwd --continue --continue=false --no-file-allocation-limit --netrc-path --ftp-proxy-user --enable-color --enable-color=false --metalink-location --allow-piece-length-change --allow-piece-length-change=false --max-connection-per-server --no-conf --no-conf=false --rpc-certificate --metalink-os --enable-http-pipelining --enable-http-pipelining=false --http-passwd --user-agent --enable-dht6 --enable-dht6=false --dht-file-path --http-auth-challenge --http-auth-challenge=false --bt-enable-hook-after-hash-check --bt-enable-hook-after-hash-check=false --peer-id-prefix --max-mmap-limit --enable-mmap --enable-mmap=false --use-head --use-head=false --bt-require-crypto --bt-require-crypto=false --show-console-readout --show-console-readout=false --conf-path --log --no-proxy --dht-entry-point --dht-listen-port --http-user --retry-wait --on-download-complete --help --help=#basic --help=#advanced --help=#http --help=#https --help=#ftp --help=#metalink --help=#bittorrent --help=#cookie --help=#hook --help=#file --help=#rpc --help=#checksum --help=#experimental --help=#deprecated --help=#help --help=#all --max-overall-download-limit --event-poll --http-accept-gzip --http-accept-gzip=false --metalink-file --all-proxy --disk-cache --hash-check-only --hash-check-only=false --dht-listen-addr6 --human-readable --human-readable=false --ftp-user --all-proxy-passwd --bt-exclude-tracker --pause-metadata --pause-metadata=false --http-proxy-user --deferred-input --deferred-input=false --metalink-enable-unique-protocol --metalink-enable-unique-protocol=false --stop --max-upload-limit --multiple-interface --realtime-chunk-checksum --realtime-chunk-checksum=false --http-no-cache --http-no-cache=false --ca-certificate --bt-force-encryption --bt-force-encryption=false --bt-save-metadata --bt-save-metadata=false --seed-ratio --follow-torrent --pause --pause=false --checksum --auto-save-interval --async-dns --async-dns=false --bt-enable-lpd --bt-enable-lpd=false --parameterized-uri --parameterized-uri=false --ftp-proxy-passwd --enable-rpc --enable-rpc=false --min-split-size --bt-seed-unverified --bt-seed-unverified=false --input-file --interface --enable-async-dns6 --enable-async-dns6=false --reuse-uri --reuse-uri=false --socket-recv-buffer-size --bt-request-peer-speed-limit --on-download-error --bt-metadata-only --bt-metadata-only=false ' -- "$cur" ) ) + COMPREPLY=( $( compgen -W '--rpc-save-upload-metadata --rpc-save-upload-metadata=false --on-download-start --metalink-language --rpc-secret --torrent-file --enable-peer-exchange --enable-peer-exchange=false --http-proxy-passwd --bt-tracker-timeout --ftp-type --seed-time --bt-tracker-connect-timeout --bt-max-open-files --no-netrc --no-netrc=false --force-sequential --force-sequential=false --metalink-base-uri --private-key --ftp-passwd --allow-overwrite --allow-overwrite=false --rpc-allow-origin-all --rpc-allow-origin-all=false --bt-detach-seed-only --bt-detach-seed-only=false --dht-entry-point6 --summary-interval --lowest-speed-limit --bt-tracker-interval --proxy-method --metalink-preferred-protocol --enable-http-keep-alive --enable-http-keep-alive=false --metalink-version --stderr --stderr=false --bt-lpd-interface --force-save --force-save=false --rpc-secure --rpc-secure=false --listen-port --rpc-private-key --server-stat-of --server-stat-timeout --https-proxy-user --piece-length --dry-run --dry-run=false --truncate-console-readout --truncate-console-readout=false --async-dns-server --bt-max-peers --max-overall-upload-limit --rpc-user --optimize-concurrent-downloads --optimize-concurrent-downloads=true --optimize-concurrent-downloads=false --optimize-concurrent-downloads=A:B --dir --split --on-download-pause --auto-file-renaming --auto-file-renaming=false --http-proxy --save-session-interval --daemon --daemon=false --https-proxy --min-tls-version --save-cookies --out --rlimit-nofile --max-file-not-found --on-download-stop --certificate --bt-min-crypto-level --remove-control-file --remove-control-file=false --enable-dht --enable-dht=false --file-allocation --follow-metalink --on-bt-download-complete --ftp-proxy --show-files --show-files=false --timeout --bt-hash-check-seed --bt-hash-check-seed=false --ftp-pasv --ftp-pasv=false --check-certificate --check-certificate=false --always-resume --always-resume=false --load-cookies --bt-remove-unselected-file --bt-remove-unselected-file=false --bt-stop-timeout --version --max-concurrent-downloads --quiet --quiet=false --max-download-result --max-resume-failure-tries --header --rpc-listen-all --rpc-listen-all=false --all-proxy-user --server-stat-if --dht-file-path6 --save-session --bt-external-ip --max-tries --conditional-get --conditional-get=false --ftp-reuse-connection --ftp-reuse-connection=false --gid --dscp --max-download-limit --bt-prioritize-piece --check-integrity --check-integrity=false --log-level --remote-time --remote-time=false --uri-selector --rpc-listen-port --index-out --bt-tracker --referer --ssh-host-key-md --console-log-level --connect-timeout --stream-piece-selector --dht-message-timeout --select-file --download-result --disable-ipv6 --disable-ipv6=false --rpc-max-request-size --rpc-passwd --stop-with-process --https-proxy-passwd --continue --continue=false --no-file-allocation-limit --netrc-path --ftp-proxy-user --enable-color --enable-color=false --metalink-location --allow-piece-length-change --allow-piece-length-change=false --max-connection-per-server --no-conf --no-conf=false --rpc-certificate --metalink-os --enable-http-pipelining --enable-http-pipelining=false --http-passwd --user-agent --enable-dht6 --enable-dht6=false --dht-file-path --http-auth-challenge --http-auth-challenge=false --bt-enable-hook-after-hash-check --bt-enable-hook-after-hash-check=false --peer-id-prefix --max-mmap-limit --enable-mmap --enable-mmap=false --use-head --use-head=false --bt-require-crypto --bt-require-crypto=false --show-console-readout --show-console-readout=false --conf-path --log --no-proxy --dht-entry-point --dht-listen-port --http-user --retry-wait --on-download-complete --help --help=#basic --help=#advanced --help=#http --help=#https --help=#ftp --help=#metalink --help=#bittorrent --help=#cookie --help=#hook --help=#file --help=#rpc --help=#checksum --help=#experimental --help=#deprecated --help=#help --help=#all --max-overall-download-limit --event-poll --http-accept-gzip --http-accept-gzip=false --metalink-file --all-proxy --disk-cache --hash-check-only --hash-check-only=false --dht-listen-addr6 --human-readable --human-readable=false --ftp-user --all-proxy-passwd --bt-exclude-tracker --pause-metadata --pause-metadata=false --http-proxy-user --deferred-input --deferred-input=false --metalink-enable-unique-protocol --metalink-enable-unique-protocol=false --stop --max-upload-limit --multiple-interface --realtime-chunk-checksum --realtime-chunk-checksum=false --http-no-cache --http-no-cache=false --ca-certificate --bt-force-encryption --bt-force-encryption=false --bt-save-metadata --bt-save-metadata=false --seed-ratio --follow-torrent --pause --pause=false --checksum --auto-save-interval --async-dns --async-dns=false --bt-enable-lpd --bt-enable-lpd=false --parameterized-uri --parameterized-uri=false --ftp-proxy-passwd --enable-rpc --enable-rpc=false --min-split-size --bt-seed-unverified --bt-seed-unverified=false --input-file --interface --enable-async-dns6 --enable-async-dns6=false --reuse-uri --reuse-uri=false --socket-recv-buffer-size --bt-request-peer-speed-limit --on-download-error --bt-metadata-only --bt-metadata-only=false ' -- "$cur" ) ) ;; *) _filedir '@(torrent|meta4|metalink|text|txt|list|lst)' From a37e8fecddec02128401d288e0fec79d59158a60 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 18:58:40 +0900 Subject: [PATCH 10/12] Update Android third-party library --- README.android | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.android b/README.android index 017750e5..3626aa5e 100644 --- a/README.android +++ b/README.android @@ -42,7 +42,7 @@ aria2c executable was generated using android-ndk-r10d. The following libraries were statically linked. -* openssl 1.0.2g +* openssl 1.0.2h * expat 2.1.0 * c-ares 1.11.0 * libssh2 1.7.0 From 29c96d59ba3f3b833e7abc32dca18b058e2de707 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 19:26:44 +0900 Subject: [PATCH 11/12] Update NEWS --- NEWS | 84 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index 879c6d16..9f546d8d 100644 --- a/NEWS +++ b/NEWS @@ -1,37 +1,79 @@ -aria2 1.22.0 +aria2 1.23.0 ============ Release Note ------------ -This release adds new feature that manages the number of concurrent -downloads dynamically. --stream-piece-selector option gets new value -"random" which randomizes the piece selection for HTTP/FTP downloads. -This effectively randomizes the order of files on multi-file Web -Seeding. Now all contributor's names are in AUTHORS file. -Previously, aria2 shows error when it sees floating point number in a -torrent file because torrent file specification does not allow -floating point number. In this release, they are just ignored, and -aria2 continues to parse the rest of the torrent file as if there is -nothing wrong. +This release fixes several bugs reported by users, and adds several +new features. Read the following section for details. Changes ------- -* Add description about possible fragmentation with - --file-allocation=trunc +* Simplify cache write -* Make single-entry metalink download with multi-file torrent work + The previous cache write routine was too complex. I'm sure I can + rewrite it to more elegantly. But the primary motivation of this + complex logic is for disk activity reduction on Windows 7, and I + observed it on my old IDE disk. I checked it again recently, and + there is no difference between with and without this complex logic. + For this reason, it was removed. Will revert this change if many of + users are not happy with this. -* Add all contributor's names in AUTHORS +* Allow subsecond value in ns cookie.txt file's expiry time field -* Ignore floating number in torrent file + Fixes GH-655 -* Added support for a dynamic management of the number of concurrent - downloads as a function of the overall bandwidth observed +* Adjust chromium cookie time - This change adds --optimize-concurrent-downloads option. +* import-po: iterate on glob, not ls output - Patch from oliviercommelarbre + Patch from Mingye Wang -* Add --stream-piece-selector=random +* Add --stderr option to redirect all stdout log output to stderr + + Fixes GH-638 + +* Add "hide" to --download-result option + + Fixes GH-639 + +* Fix downloaded metaurl torrent filename + +* Add a little bit of color to have a better visual of important + informations + + Patch from rotor + +* Update README URLs based on HTTP redirects + + Patch from ReadmeCritic + +* Relocate from github.com/tatsuhiro-t/aria2 to github.com/aria2/aria2 + + Fixes GH-602 + +* mingw: Defer the falloc warning until falloc is specified by option + + Fixes GH-594 + +* Add bittorrent key to aria2.tellStopped status + + Fixes GH-612 + +* Addsystem.listNotifications RPC method + + Merges GH-620 + + Patch from Sonny Piers + +* Report CheckIntegrity info in tellStatus + + - Adds verifiedLength to tellStatus. Reports the length of data that + has been verified of the current RequestGroup being verified. + - Adds verifyPending to tellStatus. Reports if the RequestGroup has + a verification of integrity pending. + + Closes GH-561 + + Patch from Kurt Kartaltepe From cc8375f0b04918ace028bf58e09f9e25a0440c23 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 22:00:16 +0900 Subject: [PATCH 12/12] Refactor BtHandshakeMessage --- src/BtHandshakeMessage.cc | 53 ++++++++++++++++++--------------------- src/BtHandshakeMessage.h | 39 ++++++++++++++-------------- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/BtHandshakeMessage.cc b/src/BtHandshakeMessage.cc index c7ebfef1..95f99e0d 100644 --- a/src/BtHandshakeMessage.cc +++ b/src/BtHandshakeMessage.cc @@ -37,16 +37,13 @@ #include #include "util.h" -#include "BtConstants.h" #include "a2functional.h" namespace aria2 { +const unsigned char BtHandshakeMessage::BT_PSTR[] = "BitTorrent protocol"; const char BtHandshakeMessage::NAME[] = "handshake"; -const unsigned char* BtHandshakeMessage::BT_PSTR = - reinterpret_cast("BitTorrent protocol"); - BtHandshakeMessage::BtHandshakeMessage() : SimpleBtMessage(ID, NAME) { init(); } BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash, @@ -54,19 +51,17 @@ BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash, : SimpleBtMessage(ID, NAME) { init(); - memcpy(infoHash_, infoHash, INFO_HASH_LENGTH); - memcpy(peerId_, peerId, PEER_ID_LENGTH); + std::copy_n(infoHash, infoHash_.size(), std::begin(infoHash_)); + std::copy_n(peerId, peerId_.size(), std::begin(peerId_)); } +BtHandshakeMessage::~BtHandshakeMessage() {} + void BtHandshakeMessage::init() { pstrlen_ = 19; - pstr_ = new unsigned char[PSTR_LENGTH]; - reserved_ = new unsigned char[RESERVED_LENGTH]; - infoHash_ = new unsigned char[INFO_HASH_LENGTH]; - peerId_ = new unsigned char[PEER_ID_LENGTH]; - memcpy(pstr_, BT_PSTR, PSTR_LENGTH); - memset(reserved_, 0, RESERVED_LENGTH); + std::copy_n(BT_PSTR, pstr_.size(), std::begin(pstr_)); + std::fill(std::begin(reserved_), std::end(reserved_), 0); // fast extension reserved_[7] |= 0x04u; // extended messaging @@ -76,23 +71,25 @@ void BtHandshakeMessage::init() std::unique_ptr BtHandshakeMessage::create(const unsigned char* data, size_t dataLength) { - auto message = make_unique(); - message->pstrlen_ = data[0]; - memcpy(message->pstr_, &data[1], PSTR_LENGTH); - memcpy(message->reserved_, &data[20], RESERVED_LENGTH); - memcpy(message->infoHash_, &data[28], INFO_HASH_LENGTH); - memcpy(message->peerId_, &data[48], PEER_ID_LENGTH); - return message; + auto msg = make_unique(); + msg->pstrlen_ = data[0]; + std::copy_n(&data[1], msg->pstr_.size(), std::begin(msg->pstr_)); + std::copy_n(&data[20], msg->reserved_.size(), std::begin(msg->reserved_)); + std::copy_n(&data[28], msg->infoHash_.size(), std::begin(msg->infoHash_)); + std::copy_n(&data[48], msg->peerId_.size(), std::begin(msg->peerId_)); + + return msg; } unsigned char* BtHandshakeMessage::createMessage() { auto msg = new unsigned char[MESSAGE_LENGTH]; - msg[0] = pstrlen_; - memcpy(msg + 1, pstr_, PSTR_LENGTH); - memcpy(msg + 20, reserved_, RESERVED_LENGTH); - memcpy(msg + 28, infoHash_, INFO_HASH_LENGTH); - memcpy(msg + 48, peerId_, PEER_ID_LENGTH); + auto dst = msg; + *dst++ = pstrlen_; + dst = std::copy(std::begin(pstr_), std::end(pstr_), dst); + dst = std::copy(std::begin(reserved_), std::end(reserved_), dst); + dst = std::copy(std::begin(infoHash_), std::end(infoHash_), dst); + std::copy(std::begin(peerId_), std::end(peerId_), dst); return msg; } @@ -101,8 +98,8 @@ size_t BtHandshakeMessage::getMessageLength() { return MESSAGE_LENGTH; } std::string BtHandshakeMessage::toString() const { return fmt("%s peerId=%s, reserved=%s", NAME, - util::percentEncode(peerId_, PEER_ID_LENGTH).c_str(), - util::toHex(reserved_, RESERVED_LENGTH).c_str()); + util::percentEncode(peerId_.data(), peerId_.size()).c_str(), + util::toHex(reserved_.data(), reserved_.size()).c_str()); } bool BtHandshakeMessage::isFastExtensionSupported() const @@ -119,12 +116,12 @@ bool BtHandshakeMessage::isDHTEnabled() const { return reserved_[7] & 0x01u; } void BtHandshakeMessage::setInfoHash(const unsigned char* infoHash) { - memcpy(infoHash_, infoHash, INFO_HASH_LENGTH); + std::copy_n(infoHash, infoHash_.size(), std::begin(infoHash_)); } void BtHandshakeMessage::setPeerId(const unsigned char* peerId) { - memcpy(peerId_, peerId, PEER_ID_LENGTH); + std::copy_n(peerId, peerId_.size(), std::begin(peerId_)); } } // namespace aria2 diff --git a/src/BtHandshakeMessage.h b/src/BtHandshakeMessage.h index 51893b57..5bbb0b4f 100644 --- a/src/BtHandshakeMessage.h +++ b/src/BtHandshakeMessage.h @@ -37,21 +37,26 @@ #include "SimpleBtMessage.h" +#include + +#include "BtConstants.h" + namespace aria2 { class BtHandshakeMessage : public SimpleBtMessage { public: - static const size_t PSTR_LENGTH = 19; - static const unsigned char* BT_PSTR; - static const size_t RESERVED_LENGTH = 8; - static const size_t MESSAGE_LENGTH = 68; + constexpr static size_t PSTR_LENGTH = 19; + constexpr static size_t RESERVED_LENGTH = 8; + constexpr static size_t MESSAGE_LENGTH = 68; + const static unsigned char BT_PSTR[]; private: uint8_t pstrlen_; - unsigned char* pstr_; - unsigned char* reserved_; - unsigned char* infoHash_; - unsigned char* peerId_; + std::array pstr_; + std::array reserved_; + std::array infoHash_; + std::array peerId_; + void init(); public: @@ -66,17 +71,11 @@ public: static std::unique_ptr create(const unsigned char* data, size_t dataLength); - virtual ~BtHandshakeMessage() - { - delete[] pstr_; - delete[] reserved_; - delete[] infoHash_; - delete[] peerId_; - } + virtual ~BtHandshakeMessage(); static const uint8_t ID = INT8_MAX; - static const char NAME[]; + const static char NAME[]; virtual void doReceivedAction() CXX11_OVERRIDE{}; @@ -104,15 +103,15 @@ public: uint8_t getPstrlen() const { return pstrlen_; } - const unsigned char* getPstr() const { return pstr_; } + const unsigned char* getPstr() const { return pstr_.data(); } - const unsigned char* getReserved() const { return reserved_; } + const unsigned char* getReserved() const { return reserved_.data(); } - const unsigned char* getInfoHash() const { return infoHash_; } + const unsigned char* getInfoHash() const { return infoHash_.data(); } void setInfoHash(const unsigned char* infoHash); - const unsigned char* getPeerId() const { return peerId_; } + const unsigned char* getPeerId() const { return peerId_.data(); } void setPeerId(const unsigned char* peerId); };