summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-05-16 12:27:14 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-05-16 12:27:14 +0900
commit9727b5b256bb12cff42e6aa230ba2020a933562f (patch)
tree4fe70a0d78d3a5cd11a80b2dfd8f521db47032ee
parent8897d7ec702fca9780033db42db48cced2580112 (diff)
parentcc8375f0b04918ace028bf58e09f9e25a0440c23 (diff)
Merge branch 'master' into dynamic-select-file
-rw-r--r--AUTHORS6
-rw-r--r--NEWS84
-rw-r--r--README.android2
-rw-r--r--configure.ac2
-rw-r--r--doc/bash_completion/aria2c4
-rwxr-xr-ximport-po2
-rw-r--r--po/README.rst2
-rw-r--r--src/AbstractSingleDiskAdaptor.cc45
-rw-r--r--src/BtHandshakeMessage.cc53
-rw-r--r--src/BtHandshakeMessage.h39
-rw-r--r--src/DHTGetPeersReplyMessage.cc43
-rw-r--r--src/MultiDiskAdaptor.cc94
-rw-r--r--src/NsCookieParser.cc11
-rw-r--r--src/Sqlite3CookieParserImpl.cc9
-rw-r--r--src/util.cc27
-rw-r--r--src/util.h4
-rw-r--r--test/CookieStorageTest.cc4
-rw-r--r--test/NsCookieParserTest.cc4
-rw-r--r--test/UtilTest2.cc19
-rw-r--r--test/chromium_cookies.sqlitebin3072 -> 3072 bytes
-rw-r--r--test/nscookietest.txt4
21 files changed, 217 insertions, 241 deletions
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
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
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
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
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)'
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"`
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``.
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<ssize_t>(buflen) < d->goff) {
- A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start,
- static_cast<unsigned long>(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<unsigned long>(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<unsigned long>(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/BtHandshakeMessage.cc b/src/BtHandshakeMessage.cc
index c7ebfef1..95f99e0d 100644
--- a/src/BtHandshakeMessage.cc
+++ b/src/BtHandshakeMessage.cc
@@ -37,16 +37,13 @@
#include <cstring>
#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<const unsigned char*>("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>
BtHandshakeMessage::create(const unsigned char* data, size_t dataLength)
{
- auto message = make_unique<BtHandshakeMessage>();
- 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<BtHandshakeMessage>();
+ 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 <array>
+
+#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<unsigned char, PSTR_LENGTH> pstr_;
+ std::array<unsigned char, RESERVED_LENGTH> reserved_;
+ std::array<unsigned char, INFO_HASH_LENGTH> infoHash_;
+ std::array<unsigned char, PEER_ID_LENGTH> peerId_;
+
void init();
public:
@@ -66,17 +71,11 @@ public:
static std::unique_ptr<BtHandshakeMessage> 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);
};
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 <cstring>
+#include <array>
#include "DHTNode.h"
#include "DHTBucket.h"
@@ -81,24 +82,24 @@ std::unique_ptr<Dict> 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<unsigned char, DHTBucket::K * 38> 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<unsigned char, COMPACT_LEN_IPV6> 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<Dict> 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<unsigned char, COMPACT_LEN_IPV6> 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));
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;
- }
- 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<int64_t>((*i)->goff + celloff)) <
- std::min(fent->getLastOffset(),
- static_cast<int64_t>((*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<unsigned long>(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<int64_t>(lstart + buflen) < loff) {
- A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu",
- fent->getPath().c_str(), lstart,
- static_cast<unsigned long>(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<int64_t>((*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<unsigned long>(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<unsigned long>(buflen - buffoffset)));
- (*dent)->getDiskWriter()->writeData(buf + buffoffset, buflen - buffoffset,
- lstart);
- break;
- }
+ 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);
}
- assert(i == eoi);
}
bool MultiDiskAdaptor::fileExists()
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<Cookie> 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<int64_t>(expiryTimeDouble);
}
if (std::numeric_limits<time_t>::max() < expiryTime) {
expiryTime = std::numeric_limits<time_t>::max();
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/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<int> parseIntSegments(const std::string& src)
{
SegList<int> 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<int> 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/chromium_cookies.sqlite b/test/chromium_cookies.sqlite
index c3e98fc8..e653715b 100644
--- a/test/chromium_cookies.sqlite
+++ b/test/chromium_cookies.sqlite
Binary files differ
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