Browse Source

Merge branch 'master' into random-webseeding

Tatsuhiro Tsujikawa 9 years ago
parent
commit
d64089632e
100 changed files with 2614 additions and 2296 deletions
  1. 65 0
      .clang-format
  2. 38 1
      AUTHORS
  3. 14 11
      Dockerfile.mingw
  4. 8 7
      Dockerfile.raspberrypi
  5. 10 0
      Makefile.am
  6. 19 149
      NEWS
  7. 4 4
      README.android
  8. 13 9
      README.mingw
  9. 31 11
      README.rst
  10. 285 153
      configure.ac
  11. 1 1
      deps/wslay/COPYING
  12. 0 5
      deps/wslay/Makefile.am
  13. 31 25
      deps/wslay/NEWS
  14. 29 1
      deps/wslay/README.rst
  15. 21 5
      deps/wslay/configure.ac
  16. 0 46
      deps/wslay/examples/Makefile
  17. 1 1
      deps/wslay/examples/echoserv.cc
  18. 80 5
      deps/wslay/examples/fork-echoserv.c
  19. 1 1
      deps/wslay/examples/testclient.cc
  20. 9 1
      deps/wslay/lib/includes/wslay/wslay.h
  21. 4 0
      deps/wslay/lib/wslay_event.c
  22. 1 1
      deps/wslay/lib/wslay_frame.c
  23. 2 1
      deps/wslay/lib/wslay_stack.c
  24. 0 0
      doc/bash_completion/aria2c
  25. 116 18
      doc/manual-src/en/aria2c.rst
  26. 15 18
      doc/manual-src/pt/README.rst
  27. 1 3
      doc/manual-src/pt/aria2c.rst
  28. 116 18
      doc/manual-src/ru/aria2c.rst
  29. 1 1
      doc/sphinx_themes/sphinx_rtd_theme/__init__.py
  30. 21 13
      doc/sphinx_themes/sphinx_rtd_theme/breadcrumbs.html
  31. 17 1
      doc/sphinx_themes/sphinx_rtd_theme/footer.html
  32. 43 28
      doc/sphinx_themes/sphinx_rtd_theme/layout.html
  33. 0 0
      doc/sphinx_themes/sphinx_rtd_theme/static/css/badge_only.css.map
  34. 0 0
      doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css
  35. 0 0
      doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css.map
  36. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
  37. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf
  38. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Regular.ttf
  39. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf
  40. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf
  41. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf
  42. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf
  43. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf
  44. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
  45. 22 21
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
  46. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
  47. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
  48. 150 107
      doc/sphinx_themes/sphinx_rtd_theme/static/js/theme.js
  49. 2 0
      doc/sphinx_themes/sphinx_rtd_theme/theme.conf
  50. 1 1
      doc/xmlrpc/README.txt
  51. 27 26
      examples/libaria2ex.cc
  52. 77 101
      examples/libaria2wx.cc
  53. 74 0
      m4/ax_check_compile_flag.m4
  54. 2 0
      m4/libexpat.m4
  55. 54 104
      makerelease-osx.mk
  56. 1 1
      po/Makevars
  57. 4 4
      src/ARC4Encryptor.h
  58. 4 4
      src/AbstractAuthResolver.cc
  59. 1 0
      src/AbstractAuthResolver.h
  60. 16 16
      src/AbstractBtMessage.cc
  61. 25 58
      src/AbstractBtMessage.h
  62. 104 125
      src/AbstractCommand.cc
  63. 17 49
      src/AbstractCommand.h
  64. 212 201
      src/AbstractDiskWriter.cc
  65. 9 7
      src/AbstractDiskWriter.h
  66. 32 30
      src/AbstractHttpServerResponseCommand.cc
  67. 6 8
      src/AbstractHttpServerResponseCommand.h
  68. 25 36
      src/AbstractOptionHandler.cc
  69. 9 15
      src/AbstractOptionHandler.h
  70. 18 20
      src/AbstractProxyRequestCommand.cc
  71. 4 4
      src/AbstractProxyRequestCommand.h
  72. 15 14
      src/AbstractProxyResponseCommand.cc
  73. 7 8
      src/AbstractProxyResponseCommand.h
  74. 44 50
      src/AbstractSingleDiskAdaptor.cc
  75. 7 10
      src/AbstractSingleDiskAdaptor.h
  76. 49 48
      src/ActivePeerConnectionCommand.cc
  77. 2 4
      src/ActivePeerConnectionCommand.h
  78. 25 22
      src/AdaptiveFileAllocationIterator.cc
  79. 4 4
      src/AdaptiveFileAllocationIterator.h
  80. 85 85
      src/AdaptiveURISelector.cc
  81. 7 7
      src/AdaptiveURISelector.h
  82. 7 15
      src/Adler32MessageDigestImpl.cc
  83. 6 2
      src/Adler32MessageDigestImpl.h
  84. 76 60
      src/AnnounceList.cc
  85. 2 2
      src/AnnounceList.h
  86. 5 4
      src/AnnounceTier.cc
  87. 4 4
      src/AnonDiskWriterFactory.h
  88. 7 10
      src/ApiCallbackDownloadEventListener.cc
  89. 3 2
      src/ApiCallbackDownloadEventListener.h
  90. 35 63
      src/AppleMessageDigestImpl.cc
  91. 20 53
      src/AppleTLSContext.cc
  92. 9 24
      src/AppleTLSContext.h
  93. 209 202
      src/AppleTLSSession.cc
  94. 6 6
      src/AppleTLSSession.h
  95. 16 19
      src/AsyncNameResolver.cc
  96. 13 24
      src/AsyncNameResolver.h
  97. 40 47
      src/AsyncNameResolverMan.cc
  98. 5 14
      src/AsyncNameResolverMan.h
  99. 8 7
      src/AuthConfig.cc
  100. 5 10
      src/AuthConfig.h

+ 65 - 0
.clang-format

@@ -0,0 +1,65 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: true
+AlignEscapedNewlinesLeft: false
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AlwaysBreakAfterDefinitionReturnType: false
+AlwaysBreakTemplateDeclarations: false
+AlwaysBreakBeforeMultilineStrings: false
+BreakBeforeBinaryOperators: None
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BinPackParameters: true
+BinPackArguments: true
+ColumnLimit:     80
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+DerivePointerAlignment: false
+ExperimentalAutoDetectBinPacking: false
+IndentCaseLabels: false
+IndentWrappedFunctionNames: false
+IndentFunctionDeclarationAfterType: false
+MaxEmptyLinesToKeep: 1
+KeepEmptyLinesAtTheStartOfBlocks: true
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakString: 1000
+PenaltyBreakFirstLessLess: 120
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+SpacesBeforeTrailingComments: 1
+Cpp11BracedListStyle: true
+Standard:        Cpp11
+IndentWidth:     2
+TabWidth:        8
+UseTab:          Never
+BreakBeforeBraces: Stroustrup
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpacesInAngles:  false
+SpaceInEmptyParentheses: false
+SpacesInCStyleCastParentheses: false
+SpaceAfterCStyleCast: false
+SpacesInContainerLiterals: true
+SpaceBeforeAssignmentOperators: true
+ContinuationIndentWidth: 4
+CommentPragmas:  '^ IWYU pragma:'
+ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
+SpaceBeforeParens: ControlStatements
+DisableFormat:   false
+...
+

+ 38 - 1
AUTHORS

@@ -1,3 +1,40 @@
-Tatsuhiro Tsujikawa <t-tujikawa at users dot sourceforge dot net>
+These are people who made lots of contributions:
+
+Tatsuhiro Tsujikawa <tatsuhiro.t at gmail dot com>
 Ross Smith II <aria2spam at netebb dot com> (Windows port)
 Nils Maier <maierman at web dot Germany>
+
+The aria2 contributor's list extracted from commit logs [1]:
+
+Alexander Amanuel
+Anthony Bryan
+Athmane Madjoudj
+Cristian Rodríguez
+Dan Fandrich
+David Macek
+ITriskTI
+Igor Khomyakov
+Jarda Snajdr
+Kcchouette
+Nils Maier
+ORiON-
+Ross Smith II
+Ryan Steinmetz
+Ryo ONODERA
+Sarim Khan
+Sergey Zolotarev
+Tatsuhiro Tsujikawa
+Vasilij Schneidermann
+Zoltan Toth-Czifra
+amtlib-dot-dll
+c3mb0
+diadistis
+gilberto dos santos alves
+gt
+kwkam
+luokar
+mozillazg
+multisnow
+oliviercommelarbre
+
+[1] https://gist.github.com/tatsuhiro-t/deaffeb064652104ad11

+ 14 - 11
Dockerfile.mingw

@@ -4,9 +4,12 @@
 # $ sudo docker build -t aria2-mingw - < Dockerfile.mingw
 #
 # After successful build, windows binary is located at
-# /aria2/src/aria2c.exe.  You can copy the binary using
+# /aria2/src/aria2c.exe.  You can copy the binary using following
+# commands:
 #
-# $ sudo docker cp <containerId>:/aria2/src/aria2c.exe <dest>
+# $ id=$(sudo docker create aria2-mingw)
+# $ sudo docker cp $id:/aria2/src/aria2c.exe <dest>
+# $ sudo docker rm -v $id
 
 FROM ubuntu
 
@@ -24,15 +27,15 @@ RUN apt-get install -y make binutils autoconf automake autotools-dev libtool \
     pkg-config git curl dpkg-dev gcc-mingw-w64 \
     autopoint libcppunit-dev libxml2-dev libgcrypt11-dev lzip
 
-RUN curl -L -O https://gmplib.org/download/gmp/gmp-6.0.0a.tar.lz
+RUN curl -L -O https://gmplib.org/download/gmp/gmp-6.1.0.tar.lz
 RUN curl -L -O http://downloads.sourceforge.net/project/expat/expat/2.1.0/expat-2.1.0.tar.gz
-RUN curl -L -O http://www.sqlite.org/2015/sqlite-autoconf-3080803.tar.gz
+RUN curl -L -O http://www.sqlite.org/2016/sqlite-autoconf-3100200.tar.gz
 RUN curl -L -O http://zlib.net/zlib-1.2.8.tar.xz
 RUN curl -L -O http://c-ares.haxx.se/download/c-ares-1.10.0.tar.gz
-RUN curl -L -O http://libssh2.org/download/libssh2-1.5.0.tar.gz
+RUN curl -L -O http://libssh2.org/download/libssh2-1.6.0.tar.gz
 
-RUN tar xf gmp-6.0.0a.tar.lz
-RUN cd gmp-6.0.0 && \
+RUN tar xf gmp-6.1.0.tar.lz
+RUN cd gmp-6.1.0 && \
     ./configure \
     --disable-shared \
     --enable-static \
@@ -53,8 +56,8 @@ RUN cd expat-2.1.0 && \
     --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` && \
     make install
 
-RUN tar xf sqlite-autoconf-3080803.tar.gz
-RUN cd sqlite-autoconf-3080803 && \
+RUN tar xf sqlite-autoconf-3100200.tar.gz
+RUN cd sqlite-autoconf-3100200 && \
     ./configure \
     --disable-shared \
     --enable-static \
@@ -89,8 +92,8 @@ RUN cd c-ares-1.10.0 && \
     LIBS="-lws2_32" && \
     make install
 
-RUN tar xf libssh2-1.5.0.tar.gz
-RUN cd libssh2-1.5.0 && \
+RUN tar xf libssh2-1.6.0.tar.gz
+RUN cd libssh2-1.6.0 && \
     ./configure \
     --disable-shared \
     --enable-static \

+ 8 - 7
Dockerfile.raspberrypi

@@ -17,7 +17,7 @@ ENV TOOL_BIN_DIR /tools/arm-bcm2708/gcc-linaro-$HOST-raspbian-x64/bin
 ENV PATH ${TOOL_BIN_DIR}:$PATH
 
 RUN mkdir $LOCAL_DIR && mkdir zlib && cd zlib && \
-   curl -Ls -o - 'http://prdownloads.sourceforge.net/libpng/zlib-1.2.8.tar.gz?download'  | \
+   curl -Ls -o - 'http://zlib.net/zlib-1.2.8.tar.gz'  | \
         tar xzf - --strip-components=1 && \
    prefix=${LOCAL_DIR} \
    CC=$HOST-gcc \
@@ -43,7 +43,7 @@ RUN mkdir -p expat && cd expat && \
     make -s install
 
 RUN mkdir c-ares && cd c-ares && \
-    curl -Ls -o -  http://c-ares.haxx.se/download/c-ares-1.10.0.tar.gz | \
+    curl -Ls -o - 'http://c-ares.haxx.se/download/c-ares-1.10.0.tar.gz' | \
         tar xzf - --strip-components=1 && \
     ./configure \
         --host=$HOST \
@@ -55,7 +55,7 @@ RUN mkdir c-ares && cd c-ares && \
     make -s install
 
 RUN mkdir gmp && cd gmp && \
-    curl -Ls -o - 'https://gmplib.org/download/gmp/gmp-6.0.0a.tar.lz' | \
+    curl -Ls -o - 'https://gmplib.org/download/gmp/gmp-6.1.0.tar.lz' | \
         lzip -d | tar xf - --strip-components=1 && \
     ./configure \
         --disable-shared \
@@ -68,7 +68,7 @@ RUN mkdir gmp && cd gmp && \
     make -s install
 
 RUN mkdir sqlite && cd sqlite && \
-    curl -Ls -o - https://www.sqlite.org/2015/sqlite-autoconf-3080900.tar.gz | \
+    curl -Ls -o - 'https://www.sqlite.org/2016/sqlite-autoconf-3100100.tar.gz' | \
         tar xzf - --strip-components=1 && \
     ./configure \
         --disable-shared \
@@ -78,10 +78,11 @@ RUN mkdir sqlite && cd sqlite && \
         --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` && \
     make -s && \
     make -s install
-   
+
 RUN mkdir aria && cd aria && \
-    curl -Ls -o - http://sourceforge.net/projects/aria2/files/latest/download | \
-        tar xjf - --strip-components=1 && \
+    curl -s 'https://api.github.com/repos/tatsuhiro-t/aria2/releases/latest' | \
+        grep 'browser_download_url.*[0-9]\.tar\.bz2' | sed -e 's/^[[:space:]]*//' | \
+        cut -d ' ' -f 2 | xargs -I % curl -Ls -o - '%' | tar xjf - --strip-components=1 && \
     ./configure \
         --host=$HOST \
         --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \

+ 10 - 0
Makefile.am

@@ -15,6 +15,8 @@ EXTRA_DIST = config.rpath \
 
 dist_doc_DATA = README README.rst README.html
 
+.PHONY: clang-format
+
 if HAVE_RST2HTML
 README.html: README.rst
 	$(RST2HTML)  $< > $@
@@ -27,3 +29,11 @@ endif # !HAVE_RST2HTML
 
 dist_noinst_DATA = LICENSE.OpenSSL
 
+# Format source files using clang-format.  Don't format source files
+# under deps directory since we are not responsible for thier coding
+# style.
+clang-format:
+	CLANGFORMAT=`git config --get clangformat.binary`; \
+	test -z $${CLANGFORMAT} && CLANGFORMAT="clang-format"; \
+	$${CLANGFORMAT} -i $(top_srcdir)/src/*.{c,cc,h} $(top_srcdir)/src/includes/aria2/*.h \
+	$(top_srcdir)/examples/*.cc $(top_srcdir)/test/*.{cc,h}

+ 19 - 149
NEWS

@@ -1,170 +1,40 @@
-aria2 1.19.1
+aria2 1.21.0
 ============
 
 Release Note
 ------------
 
-This release fixes TLS handshake error with servers which only support
-RSA-SHA1 signature algorithm.  We removed RSA-SHA1 for enchanced
-security, but many users reported there were servers which could not
-talk aria2 1.19.0, so added it again for compatibility reasons.  For
-Windows build, we fixed potential infinite loop bug when TLS is used.
-
-We changed the location where dht.dat and aria2.conf are looked up.
-The aria2 manual page described details.  Basically we now follow XDG
-specification (http://standards.freedesktop.org/basedir-spec/latest/).
-For dht.dat, the default location is $XDG_CACHE_HOME/aria2/ directory.
-For aria2.conf, the default location is $XDG_CONFIG_HOME/aria2/
-directory.  To keep the current user configuration working, if aria2
-detects dht.dat under $HOME/.aria2/ directory, it is used instead.
-Similarly, if aria2.conf exists under $HOME/.aria2/ directory, it is
-used instead.
-
-Previously, we return 500 HTTP status if RPC method execution
-encountered error.  Now it returns with 400 HTTP status with error
-code.  This is more natural because server processed request and found
-an error, and returned error reply correctly.  This is not something
-server crashed or something.  Also, there is RPC libraries which
-throws exception if it sees 5XX status code, where 400 is better
-because we can examine the error.
+This release fixes several bugs, see the Changes for details.  We
+added "following" key to the response of aria2.tellStatus RPC method
+as reverse link for followedBy.
 
 Changes
 -------
 
-* Update README.android
+* SessionSerializer: Fix bug that pause=true is added to wrong item
 
-  Providing some workarounds about CA certificates and standard output
+  This change also defers writing metadata download to the location
+  where first its follower download is written.
 
-  Patch from amtlib-dot-dll
+* Add "following" to aria2.tellStatus response key as reverse link for
+  followedBy
 
-* Return 400 HTTP status code if exception was caught while executing
-  RPC method
+* mingw: Add warning for falloc
 
-  Previously, we returned 500 HTTP status code.  I think the found in
-  RPC level, not in HTTP protocol, so 500 is not appropriate.
+* Update ciphers in AppleTLS
 
-* WinTLS: Fix potential infinite loop
+  Also enable fast start while at it
 
-* Fix on-download-error is executed even if download succeeded
+* OSX: Enable libssh2 and sftp
 
-* Update Dockerfile.mingw
+  Closes GH-468
 
-  Patch from Adam Baxter
+* Update OSX dependencies
 
-* Increase --select-file upper bound to 1m for torrent containing lots
-  of files
+  Closes GH-466
 
-* Fix busy loop with --dry-run and 4xx response for URI listed in
-  metalink
+* Fix compile error without TLS support
 
-  See GH-430
+* Add support for using gnutls system wide crypto policy
 
-* Update sqlite in OSX build to 3.8.10.2
-
-* Make LibuvEventPoll compatible with the latest libuv again
-
-* gnutls: Allow SIGN-RSA-SHA1 for compatibility reason
-
-* Make script compatible with both Python 2 and 3
-
-  Patch from Vasilij Schneidermann
-
-* Make config and cache files conform to XDG
-
-  See http://standards.freedesktop.org/basedir-spec/latest/ for
-  further details.  This implementation decides the default based on
-  whether a file exists at the legacy location, if it doesn't, it
-  picks the XDG-conforming location instead.
-
-  Patch from Vasilij Schneidermann
-
-* ftp, sftp: Fix heap-after-free bug on exception
-
-* ftp: Fix timeout when reusing FTP connection
-
-* Various MinGW-w64 build improvements
-
-  - Fix detection of localtime_r and asctime_r on MinGW-w64
-  - Fix linking with libintl on MinGW-w64
-
-  Patch from David Macek
-
-
-
-aria2 1.19.0
-============
-
-Release Note
-------------
-
-This releases adds SFTP support, and fixes several bugs.  SFTP support
-has been implemented using libssh2.  We added several new options.
---multiple-interface option is like --interface option, but can take
-several interfaces.  They are used in round-robin manner, and it works
-like link aggregation.  Previously, .netrc search path is fixed under
-$HOME directory, and cannot be changed.  In this release, --netrc-path
-option has been added to override the search path.  The runtime bug
-concerning getrandom has been fixed in this release.  Previously if
-download failed because checksum error, aria2 exited with error code 1
-(unknown error).  Now it exits with dedicated error code 32.  We fixed
-long outstanding bug that aria2 crashes when downloading multi-file
-torrent.
-
-Changes
--------
-
-* android: Build and link with zlib
-
-  Previously, we linked with zlib shipped with NDK, but it seems this
-  is not part of NDK API, and thus could break our app.
-
-* Allow netrc-path to be specified in the config file
-
-  Adds --netrc-path to override default .netrc search path.  Patch
-  from Ryan Steinmetz
-
-* Exit with 32 status code if checksum verification failed
-
-* Add SFTP support using libssh2
-
-  aria2 can now download files via sftp protocol: aria2c sftp://....
-  --ssh-host-key-md option is added to specify expected server's
-  fingerprint.
-
-* Added Dockerfile to cross complile aria2 for RaspberryPI (armhf)
-
-  Patch from Igor Khomyakov
-
-* multiple interface support for link aggregation
-
-  Adds --multiple-interface option.  Patch from Sarim Khan
-
-* Run on-bt-download-complete command when -V reports download finished
-
-  Fixes GH-355
-
-* Use dedicated DiskWriter in MultiDiskFileAllocationIterator
-
-  We have to use dedicated DiskWriter instead of
-  (*entryItr_)->getDiskWriter().  This is because
-  SingleFileAllocationIterator cannot reopen file if file is closed by
-  OpenedFileCounter.  Fixes GH-350
-
-* Fix getrandom for system with libc not including errno or systems
-
-  not supporting ENOSYS in the first place.  Fixes GH-347
-
-* Don't send back rpc-secret option value in aria2.getGlobalOption RPC
-  method
-
-* Make libuv default off
-
-  See GH-241 for discussion
-
-* Fixed slow RPC response
-
-  Fxies GH-345
-
-* Fix getrandom interface detection
-
-  Fixes GH-346
+  Patch from Athmane Madjoudj

+ 4 - 4
README.android

@@ -33,7 +33,7 @@ How to use
 ----------
 
 See `the online manual
-<http://aria2.sourceforge.net/manual/en/html/>`_.
+<https://aria2.github.io/manual/en/html/>`_.
 
 Notes
 -----
@@ -42,10 +42,10 @@ aria2c executable was generated using android-ndk-r10d.
 
 The following libraries were statically linked.
 
-* openssl 1.0.2d
+* openssl 1.0.2g
 * expat 2.1.0
-* c-ares 1.10.0
-* libssh2 1.6.0
+* c-ares 1.11.0
+* libssh2 1.7.0
 
 Since Android does not have ``/etc/resolv.conf``, c-ares (asynchronous
 DNS resolver) is disabled by default. But name resolution is sometimes

+ 13 - 9
README.mingw

@@ -5,21 +5,19 @@ aria2 Windows build is provided in 2 flavors: 32bit version and 64bit
 version. The executable was compiled using mingw-w64 cross compiler on
 Debian Linux.
 
-* gcc-mingw-w64               4.9.2-21+15.4
-* binutils-mingw-w64-i686     2.25-8+6.2
-* binutils-mingw-w64-x86-64   2.25-8+6.2
+* gcc-mingw-w64               5.2.1-26+16
+* binutils-mingw-w64-i686     2.25.90.20151209-1+6.5+b1
+* binutils-mingw-w64-x86-64   2.25.90.20151209-1+6.5+b1
 
 The executable is statically linked, so no extra DLLs are
 necessary. The linked libraries are:
 
-* gmp 6.0.0
+* gmp 6.1.0
 * expat 2.1.0
-* sqlite 3.8.11.1
+* sqlite 3.10.2
 * zlib 1.2.8
-* c-ares 1.10.0 with the dns.patch [1] applied
-* libssh2 1.6.0
-
-[1] http://c-ares.haxx.se/mail/c-ares-archive-2014-05/0008.shtml
+* c-ares 1.11.0
+* libssh2 1.7.0
 
 This build has the following difference from the original release:
 
@@ -29,6 +27,12 @@ This build has the following difference from the original release:
 Known Issues
 ------------
 
+* --file-allocation=falloc uses SetFileValidData function to allocate
+    disk space without filling zero.  But it has security
+    implications.  Refer to
+    https://msdn.microsoft.com/en-us/library/windows/desktop/aa365544%28v=vs.85%29.aspx
+    for more details.
+
 * When Ctrl-C is pressed, aria2 shows "Shutdown sequence
   commencing... Press Ctrl-C again for emergency shutdown." But
   mingw32 build cannot handle second Ctrl-C properly. The second

+ 31 - 11
README.rst

@@ -1,7 +1,7 @@
 aria2 - The ultra fast download utility
 =======================================
 :Author:    Tatsuhiro Tsujikawa
-:Email:     t-tujikawa_at_users_dot_sourceforge_dot_net
+:Email:     tatsuhiro.t_at_gmail_dot_com
 
 Disclaimer
 ----------
@@ -20,12 +20,12 @@ downloaded from HTTP(S)/FTP/SFTP is uploaded to the BitTorrent
 swarm. Using Metalink's chunk checksums, aria2 automatically validates
 chunks of data while downloading a file like BitTorrent.
 
-The project page is located at http://aria2.sourceforge.net/.
+The project page is located at https://aria2.github.io/.
 
 See `aria2 Online Manual
-<http://aria2.sourceforge.net/manual/en/html/>`_ (`Russian translation
-<http://aria2.sourceforge.net/manual/ru/html/>`_, `Portuguese
-translation <http://aria2.sourceforge.net/manual/pt/html/>`_) to learn
+<https://aria2.github.io/manual/en/html/>`_ (`Russian translation
+<https://aria2.github.io/manual/ru/html/>`_, `Portuguese
+translation <https://aria2.github.io/manual/pt/html/>`_) to learn
 how to use aria2.
 
 Features
@@ -78,6 +78,22 @@ Here is a list of features:
 * IPv6 support with Happy Eyeballs
 * Disk cache to reduce disk activity
 
+
+Versioning and release schedule
+-------------------------------
+
+We use 3 numbers for aria2 version: MAJOR.MINOR.PATCH.  We will ship
+MINOR update on 15th of every month.  We may skip a release if we have
+no changes since the last release.  The feature and documentation
+freeze happens 10 days before the release day (5th day of the month)
+for translation teams.  We will raise an issue about the upcoming
+release around that day.
+
+We may release PATCH releases between regular releases if we have
+security issues.
+
+MAJOR version will stay at 1 for the time being.
+
 How to get source code
 ----------------------
 
@@ -214,6 +230,11 @@ following packages to get autoconf macros:
 
 * libxml2-dev
 * libcppunit-dev
+* autoconf
+* automake
+* autotools-dev
+* autopoint
+* libtool
 
 And run following command to generate configure script and other files
 necessary to build the program::
@@ -395,10 +416,10 @@ Building documentation
 documentation. aria2 man pages will be build when you run ``make`` if
 they are not up-to-date.  You can also build HTML version of aria2 man
 page by ``make html``. The HTML version manual is also available at
-`online <http://aria2.sourceforge.net/manual/en/html/>`_ (`Russian
-translation <http://aria2.sourceforge.net/manual/ru/html/>`_,
+`online <https://aria2.github.io/manual/en/html/>`_ (`Russian
+translation <https://aria2.github.io/manual/ru/html/>`_,
 `Portuguese translation
-<http://aria2.sourceforge.net/manual/pt/html/>`_).
+<https://aria2.github.io/manual/pt/html/>`_).
 
 BitTorrent
 -----------
@@ -534,9 +555,8 @@ documentation to know how to use API.
 References
 ----------
 
-* `aria2 Online Manual <http://aria2.sourceforge.net/manual/en/html/>`_
-* http://aria2.sourceforge.net/
-* https://github.com/tatsuhiro-t/aria2
+* `aria2 Online Manual <https://aria2.github.io/manual/en/html/>`_
+* https://aria2.github.io/
 * `RFC 959 FILE TRANSFER PROTOCOL (FTP) <http://tools.ietf.org/html/rfc959>`_
 * `RFC 1738 Uniform Resource Locators (URL) <http://tools.ietf.org/html/rfc1738>`_
 * `RFC 2428 FTP Extensions for IPv6 and NATs <http://tools.ietf.org/html/rfc2428>`_

+ 285 - 153
configure.ac

@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 #
 AC_PREREQ([2.67])
-AC_INIT([aria2],[1.19.1],[https://github.com/tatsuhiro-t/aria2/issues],[aria2],[http://aria2.sourceforge.net/])
+AC_INIT([aria2],[1.21.0],[https://github.com/tatsuhiro-t/aria2/issues],[aria2],[https://aria2.github.io/])
 
 AC_CANONICAL_HOST
 AC_CANONICAL_TARGET
@@ -21,21 +21,29 @@ AC_SUBST(LT_REVISION, 0)
 AC_SUBST(LT_AGE, 0)
 
 AC_CONFIG_MACRO_DIR([m4])
-AM_PATH_CPPUNIT(1.10.2)
+m4_ifdef([AM_PATH_CPPUNIT], [AM_PATH_CPPUNIT(1.10.2)])
 AC_CONFIG_SRCDIR([src/a2io.h])
 AC_CONFIG_HEADERS([config.h])
 
+# extra flags
+EXTRACFLAGS=
+EXTRACXXFLAGS=
+EXTRACPPFLAGS=
+EXTRALDFLAGS=
+EXTRALIBS=
+
 case "$host" in
   *mingw*)
     win_build=yes
-    LIBS="$LIBS -lws2_32 -lwsock32 -lgdi32 -lwinmm -liphlpapi -lpsapi"
-    # Define _POSIX_C_SOURCE to 1. This makes {asc,local}time_r available
-    # from <time.h> even without (un)helpful interference from <pthread.h>,
-    # and also defines __USE_MINGW_ANSI_STDIO.
-    CPPFLAGS="-D_POSIX_C_SOURCE=1 $CPPFLAGS"
+    EXTRALIBS="-lws2_32 -lwsock32 -lgdi32 -lwinmm -liphlpapi -lpsapi $EXTRALIBS"
+    # Define _POSIX_C_SOURCE to 1. This makes {asc,local}time_r
+    # available from <time.h> even without (un)helpful interference
+    # from <pthread.h>, and also defines __USE_MINGW_ANSI_STDIO.
+    EXTRACPPFLAGS="$EXTRACPPFLAGS -D_POSIX_C_SOURCE=1"
     # Build with ASLR (dynamicbase) and NX compatiblity (nxcompat)
-    # Enable pie once upstream/binutils gets fixed to produce correct binaries with it.
-    LDFLAGS="$LDFLAGS -Wl,--dynamicbase -Wl,--nxcompat"
+    # Enable pie once upstream/binutils gets fixed to produce correct
+    # binaries with it.
+    EXTRALDFLAGS="$EXTRALDFLAGS -Wl,--dynamicbase -Wl,--nxcompat"
     ;;
 esac
 
@@ -67,6 +75,7 @@ ARIA2_ARG_DISABLE([metalink])
 ARIA2_ARG_DISABLE([websocket])
 ARIA2_ARG_DISABLE([epoll])
 ARIA2_ARG_ENABLE([libaria2])
+ARIA2_ARG_ENABLE([werror])
 
 AC_ARG_WITH([ca-bundle],
   AS_HELP_STRING([--with-ca-bundle=FILE],[Use FILE as default CA bundle.]),
@@ -86,6 +95,13 @@ AC_ARG_WITH([bashcompletiondir],
 
 AC_ARG_VAR([ARIA2_STATIC], [Set 'yes' to build a statically linked aria2])
 
+AC_ARG_ENABLE([gnutls-system-crypto-policy],
+    AS_HELP_STRING([--enable-gnutls-system-crypto-policy], [Enable gnutls system wide crypto policy]))
+
+AS_IF([test "x$enable_gnutls_system_crypto_policy" = "xyes"], [
+  AC_DEFINE([USE_GNUTLS_SYSTEM_CRYPTO_POLICY], [1], [Define to 1 if using gnutls system wide crypto policy .])
+])
+
 # Checks for programs.
 AC_PROG_CXX
 AC_PROG_CC
@@ -96,10 +112,10 @@ AM_PROG_AS
 
 # Speed GCC compilation up.
 if test "$GCC" = yes; then
-  CFLAGS="$CFLAGS -pipe"
+  EXTRACFLAGS="$EXTRACFLAGS -pipe"
 fi
 if test "$GXX" = yes; then
-  CXXFLAGS="$CXXFLAGS -pipe"
+  EXTRACXXFLAGS="$EXTRACXXFLAGS -pipe"
 fi
 
 AC_CHECK_TOOL([AR], [ar], [:])
@@ -123,9 +139,19 @@ AC_LANG([C++])
 PKG_PROG_PKG_CONFIG([0.20])
 
 # Check C++ compiler supports C++0x/C++11 feature
+save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+
 AX_CXX_COMPILE_STDCXX_11([noext], [mandatory])
 
+CXX1XCXXFLAGS="$CXXFLAGS"
+CXXFLAGS="$save_CXXFLAGS"
+AC_SUBST([CXX1XCXXFLAGS])
+
 # Check C++ compiler actually supports nullptr
+save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $CXX1XCXXFLAGS"
+
 AC_MSG_CHECKING([whether the c++ compiler supports nullptr])
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 ]],
@@ -156,20 +182,22 @@ Derived x;
 AC_DEFINE_UNQUOTED([CXX11_OVERRIDE], [$cxx11_override],
                    [Define `override` keyword if the compiler supports it])
 
+CXXFLAGS=$save_CXXFLAGS
+
 # Check static build is requested
 if test "x$ARIA2_STATIC" = "xyes"; then
   case "$host" in
     i686*mingw*)
       dnl Define _USE_32BIT_TIME_T because 32bit library of MinGW-w64
       dnl does not implement many 64bit version functions.
-      CPPFLAGS="-D_USE_32BIT_TIME_T $CPPFLAGS"
+      EXTRACPPFLAGS="$EXTRACPPFLAGS -D_USE_32BIT_TIME_T"
     ;;
   esac
   # Make pkg-config produce static linking variables
   PKG_CONFIG="$PKG_CONFIG --static"
 else
   dnl Make variable empty to avoid confusion
-  ARIA2_STATIC=
+  ARIA2_STATIC=no
 fi
 
 # Checks for libraries.
@@ -177,14 +205,15 @@ fi
 # Check availability of libz
 if test "x$with_libz" = "xyes"; then
   PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
-  if test "x$have_zlib" = "xyes"; then
-    LIBS="$ZLIB_LIBS $LIBS"
-    CPPFLAGS="$ZLIB_CFLAGS $CPPFLAGS"
-  else
+  if test "x$have_zlib" != "xyes"; then
     AC_MSG_WARN([$ZLIB_PKG_ERRORS])
     AC_CHECK_LIB([z], [zlibVersion], [have_zlib=yes], [have_zlib=no])
+
     if test "x$have_zlib" = "xyes"; then
-      LIBS="-lz $LIBS"
+      ZLIB_CFLAGS=
+      ZLIB_LIBS="-lz"
+      AC_SUBST([ZLIB_CFLAGS])
+      AC_SUBST([ZLIB_LIBS])
     elif test "x$with_libz_requested" = "xyes"; then
       ARIA2_DEP_NOT_MET([libz])
     fi
@@ -193,64 +222,82 @@ if test "x$with_libz" = "xyes"; then
     AC_DEFINE([HAVE_ZLIB], [1], [Define to 1 if you have zlib.])
     # Android NDK arch-mips contains gzbuffer symbol but it is missing
     # in zlib.h
+    save_CFLAGS=$CFLAGS
+    save_LIBS=$LIBS
+    CFLAGS="$CFLAGS $ZLIB_CFLAGS"
+    LIBS="$ZLIB_LIBS $LIBS"
     AC_CHECK_DECL([gzbuffer], [have_decl_gzbuffer=yes], [],
                   [[#include <zlib.h>]])
     if test "x$have_decl_gzbuffer" = "xyes"; then
       AC_CHECK_FUNC([gzbuffer])
     fi
     AC_CHECK_FUNCS([gzsetparams])
+    CFLAGS=$save_CFLAGS
+    LIBS=$save_LIBS
   fi
 fi
 
+have_libuv=no
 if test "x$with_libuv" = "xyes"; then
   case "$host" in
     *mingw*|*msvc*)
-      old_CPPFLAGS=$CPPFLAGS
-      CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600"
+      libuv_cflags="-D_WIN32_WINNT=0x0600"
+      save_CPPFLAGS=$CPPFLAGS
+      save_LIBS=$LIBS
+      CPPFLAGS="$CPPFLAGS $libuv_cflags"
       AC_SEARCH_LIBS([uv_poll_init_socket], [uv], [
                       AC_CHECK_HEADER([uv.h], [have_libuv=yes], [have_libuv=no])
-                      break;
                       ], [have_libuv=no])
-      if test "x$have_libuv" != "xyes"; then
-        CPPFLAGS=$old_CPPFLAGS
+      if test "x$have_libuv" = "xyes"; then
+        LIBUV_CFLAGS=$libuv_cflags
+        LIBUV_LIBS=-luv
+        AC_SUBST([LIBUV_CFLAGS])
+        AC_SUBST([LIBUV_LIBS])
       fi
+      CPPFLAGS=$save_CPPFLAGS
+      CPPLIBS=$save_LIBS
     ;;
 
     *darwin*)
-      old_LDFLAGS=$LDFLAGS
-      LDFLAGS="$LDFLAGS -framework Foundation -framework CoreServices -framework ApplicationServices"
-      old_LIBS=$LIBS
-      LIBS="$LIBS -lm"
+      libuv_ldflags="-framework Foundation -framework CoreServices -framework ApplicationServices"
+      save_LDFLAGS=$LDFLAGS
+      save_LIBS=$LIBS
+      LDFLAGS="$LDFLAGS $libuv_ldflags"
       AC_SEARCH_LIBS([uv_poll_init_socket], [uv], [
                       AC_CHECK_HEADER([uv.h], [have_libuv=yes], [have_libuv=no])
-                      break;
-                      ], [have_libuv=no])
-      if test "x$have_libuv" != "xyes"; then
-        LDFLAGS=$old_LDFLAGS
-        LIBS=$old_LIBS
+                      ], [have_libuv=no], [-lm])
+      if test "x$have_libuv" = "xyes"; then
+        LIBUV_CFLAGS=
+        LIBUV_LIBS="$libuv_ldflags -luv -lm"
+        AC_SUBST([LIBUV_CFLAGS])
+        AC_SUBST([LIBUV_LIBS])
       fi
+      LDFLAGS=$save_LDFLAGS
+      LIBS=$save_LIBS
       ;;
 
     *)
       dnl Yeah, sucks that luv does not bring a pkg-config or config-tool
       AC_MSG_CHECKING([for libuv])
+      save_LIBS=$LIBS
       for combo in "" "-lrt" "-ldl -lrt" "-ldl -lrt -lpthread" "-lkvm"; do
-        old_LIBS=$LIBS
-        LIBS="-luv $combo $LIBS -lm"
+        LIBS="-luv $combo $save_LIBS -lm"
         AC_LINK_IFELSE([AC_LANG_SOURCE([
 extern "C" int uv_poll_init_socket(void);
 int main() { return uv_poll_init_socket(); }
                        ])], [
                         AC_MSG_RESULT(-luv $combo -lm)
                         AC_CHECK_HEADER([uv.h], [have_libuv=yes], [have_libuv=no])
-                        break;
                         ], [have_libuv=no])
         if test "x$have_libuv" = "xyes"; then
+          LIBUV_CFLAGS=
+          LIBUV_LIBS="-luv $combo -lm"
+          AC_SUBST([LIBUV_CFLAGS])
+          AC_SUBST([LIBUV_LIBS])
           break;
-        else
-          LIBS=$old_LIBS
         fi
       done
+      LIBS=$save_LIBS
       if test "x$have_libuv" != "xyes"; then
         AC_MSG_RESULT("no")
       fi
@@ -259,41 +306,56 @@ int main() { return uv_poll_init_socket(); }
 
   if test "x$have_libuv" = "xyes"; then
     AC_DEFINE([HAVE_LIBUV], [1], [Define to 1 if you have libuv.])
+    save_LIBS=$LIBS
+    LIBS="$LIBUV_LIBS $LIBS"
     AC_CHECK_FUNCS([uv_last_error])
+    LIBS=$save_LIBS
   elif test "x$with_libuv_requested" = "xyes"; then
     ARIA2_DEP_NOT_MET([libuv])
   fi
 fi
 AM_CONDITIONAL([HAVE_LIBUV], [test "x$have_libuv" = "xyes"])
 
+have_libxml2=no
 if test "x$with_libxml2" = "xyes"; then
-  AM_PATH_XML2([2.6.24], [have_libxml2=yes])
+  m4_ifdef([AM_PATH_XML2], [AM_PATH_XML2([2.6.24], [have_libxml2=yes])], [
+    AC_MSG_WARN([configure was generated without libxml2 detection.  libxml2 detection is disabled])
+    XML_CPPFLAGS=
+    XML_LIBS=
+    AC_SUBST([XML_CPPFLAGS])
+    AC_SUBST([XML_LIBS])
+  ])
   if test "x$have_libxml2" = "xyes"; then
     AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have libxml2.])
-    LIBS="$XML_LIBS $LIBS"
-    CPPFLAGS="$XML_CPPFLAGS $CPPFLAGS"
   elif test "x$with_libxml2_requested" = "xyes"; then
     ARIA2_DEP_NOT_MET([libxml2])
   fi
 fi
 
+have_libexpat=no
 if test "x$with_libexpat" = "xyes" && test "x$have_libxml2" != "xyes"; then
-  AM_PATH_LIBEXPAT
-  if test "x$have_libexpat" = "xyes"; then
-    LIBS="$EXPAT_LIBS $LIBS"
-    CPPFLAGS="$EXPAT_CFLAGS $CPPFLAGS"
-  elif test "x$with_libexpat_requested" = "xyes"; then
+  m4_ifdef([AM_PATH_LIBEXPAT], [AM_PATH_LIBEXPAT], [
+    AC_MSG_WARN([configure was generated without libexpat detection.  libexpat detection is disabled])
+    EXPAT_CFLAGS=
+    EXPAT_LIBS=
+    AC_SUBST([EXPAT_CFLAGS])
+    AC_SUBST([EXPAT_LIBS])
+  ])
+  if test "x$have_libexpat" != "xyes" &&
+     test "x$with_libexpat_requested" = "xyes"; then
     ARIA2_DEP_NOT_MET([libexpat])
   fi
 fi
 
+have_sqlite3=no
 if test "x$with_sqlite3" = "xyes"; then
   PKG_CHECK_MODULES([SQLITE3],[sqlite3],[have_sqlite3=yes],[have_sqlite3=no])
   if test "x$have_sqlite3" = "xyes"; then
     AC_DEFINE([HAVE_SQLITE3], [1], [Define to 1 if you have sqlite3.])
+    save_LIBS=$LIBS
     LIBS="$SQLITE3_LIBS $LIBS"
-    CPPFLAGS="$SQLITE3_CFLAGS $CPPFLAGS"
     AC_CHECK_FUNCS([sqlite3_open_v2])
+    LIBS=$save_LIBS
   else
     AC_MSG_WARN([$SQLITE3_PKG_ERRORS])
     if test "x$with_sqlite3_requested" = "xyes"; then
@@ -339,11 +401,13 @@ if test "x$enable_ssl" != "xyes"; then
   with_openssl=no
 fi
 
+have_appletls=no
 if test "x$with_appletls" = "xyes"; then
   AC_MSG_CHECKING([whether to enable Mac OS X native SSL/TLS])
   if test "x$have_osx" = "xyes"; then
     AC_DEFINE([HAVE_APPLETLS], [1], [Define to 1 if you have Apple TLS])
-    LDFLAGS="$LDFLAGS -framework CoreFoundation -framework Security"
+    APPLETLS_LDFLAGS="-framework CoreFoundation -framework Security"
+    AC_SUBST([APPLETLS_LDFLAGS])
     have_appletls="yes"
     have_ssl=yes
     have_nativetls=yes
@@ -356,6 +420,7 @@ if test "x$with_appletls" = "xyes"; then
   fi
 fi
 
+have_wintls=no
 if test "x$with_wintls" = "xyes"; then
   AC_HAVE_LIBRARY([crypt32],[have_wintls_libs=yes],[have_wintls_libs=no])
   AC_HAVE_LIBRARY([secur32],[have_wintls_libs=$have_wintls_libs],[have_wintls_libs=no])
@@ -377,7 +442,8 @@ if test "x$with_wintls" = "xyes"; then
   if test "x$have_wintls_libs" = "xyes" &&
      test "x$have_wintls_headers" = "xyes"; then
     AC_DEFINE([SECURITY_WIN32], [1], [Use security.h in WIN32 mode])
-    LIBS="$LIBS -lcrypt32 -lsecur32 -ladvapi32"
+    WINTLS_LIBS="-lcrypt32 -lsecur32 -ladvapi32"
+    AC_SUBST([WINTLS_LIBS])
     have_wintls=yes
     have_ssl=yes
     have_nativetls=yes
@@ -391,6 +457,7 @@ if test "x$with_wintls" = "xyes"; then
   fi
 fi
 
+have_libgnutls=no
 if test "x$with_gnutls" = "xyes" && test "x$have_ssl" != "xyes"; then
   # gnutls >= 2.8 doesn't have libgnutls-config anymore. We require
   # 2.2.0 because we use gnutls_priority_set_direct()
@@ -399,9 +466,10 @@ if test "x$with_gnutls" = "xyes" && test "x$have_ssl" != "xyes"; then
   if test "x$have_libgnutls" = "xyes"; then
     have_ssl=yes
     AC_DEFINE([HAVE_LIBGNUTLS], [1], [Define to 1 if you have libgnutls.])
+    save_LIBS=$LIBS
     LIBS="$LIBGNUTLS_LIBS $LIBS"
-    CPPFLAGS="$LIBGNUTLS_CFLAGS $CPPFLAGS"
     AC_CHECK_FUNCS([gnutls_certificate_set_x509_system_trust])
+    LIBS=$save_LIBS
   else
     AC_MSG_WARN([$LIBGNUTLS_PKG_ERRORS])
     if test "x$with_gnutls_requested" = "xyes"; then
@@ -410,15 +478,16 @@ if test "x$with_gnutls" = "xyes" && test "x$have_ssl" != "xyes"; then
   fi
 fi
 
+have_openssl=no
 if test "x$with_openssl" = "xyes" && test "x$have_ssl" != "xyes"; then
   PKG_CHECK_MODULES([OPENSSL], [openssl >= 0.9.8],
                     [have_openssl=yes], [have_openssl=no])
   if test "x$have_openssl" = "xyes"; then
     have_ssl=yes
     AC_DEFINE([HAVE_OPENSSL], [1], [Define to 1 if you have openssl.])
-    LIBS="$OPENSSL_LIBS $LIBS"
-    CPPFLAGS="$OPENSSL_CFLAGS $CPPFLAGS"
 
+    save_LIBS=$LIBS
+    LIBS="$OPENSSL_LIBS $LIBS"
     AC_CHECK_FUNCS([EVP_DigestInit_ex], [have_digestinit_ex=yes])
     if test "x$have_digestinit_ex" = "x"; then
       AC_DEFINE([HAVE_OLD_OPENSSL], [1], [Define to 1 if you have old openssl.])
@@ -427,6 +496,7 @@ if test "x$with_openssl" = "xyes" && test "x$have_ssl" != "xyes"; then
     AC_CHECK_FUNCS([EVP_sha256])
     AC_CHECK_FUNCS([EVP_sha384])
     AC_CHECK_FUNCS([EVP_sha512])
+    LIBS=$save_LIBS
   else
     AC_MSG_WARN([$OPENSSL_PKG_ERRORS])
     if test "x$with_openssl_requested" = "xyes"; then
@@ -435,12 +505,19 @@ if test "x$with_openssl" = "xyes" && test "x$have_ssl" != "xyes"; then
   fi
 fi
 
+have_libnettle=no
+have_libgmp=no
+have_libgcrypt=no
 if test "x$have_openssl" != "xyes"; then
   if test "x$with_libnettle" = "xyes" &&
      test "x$have_nativetls" != "xyes"; then
-    AC_SEARCH_LIBS([nettle_sha1_init], [nettle],
-                   [have_libnettle=yes], [have_libnettle=no])
+    AC_CHECK_LIB([nettle], [nettle_sha1_init],
+                 [have_libnettle=yes], [have_libnettle=no])
     if test "x$have_libnettle" = "xyes"; then
+      LIBNETTLE_CFLAGS=
+      LIBNETTLE_LIBS="-lnettle"
+      AC_SUBST([LIBNETTLE_CFLAGS])
+      AC_SUBST([LIBNETTLE_LIBS])
       AC_DEFINE([HAVE_LIBNETTLE], [1], [Define to 1 if you have libnettle.])
     fi
   fi
@@ -448,10 +525,17 @@ if test "x$have_openssl" != "xyes"; then
      (test "x$have_libnettle" = "xyes" ||
       test "x$have_nativetls" = "xyes") &&
      test "x$enable_bittorrent" = "xyes"; then
-    AC_SEARCH_LIBS([__gmpz_init], [gmp], [have_libgmp=yes], [have_libgmp=no])
+    AC_CHECK_LIB([gmp], [__gmpz_init], [have_libgmp=yes], [have_libgmp=no])
     if test "x$have_libgmp" = "xyes"; then
+      LIBGMP_CFLAGS=
+      LIBGMP_LIBS=-lgmp
+      AC_SUBST([LIBGMP_CFLAGS])
+      AC_SUBST([LIBGMP_LIBS])
       AC_DEFINE([HAVE_LIBGMP], [1], [Define to 1 if you have libgmp.])
+      save_LIBS=$LIBS
+      LIBS="$LIBGMP_LIBS $LIBS"
       AC_CHECK_FUNCS([__gmpz_powm_sec], [have_mpz_powm_sec=yes])
+      LIBS=$save_LIBS
       if test "x$have_mpz_powm_sec" = "xyes"; then
         AC_DEFINE([HAVE_GMP_SEC], [1], [Define to 1 if you have a GMP with sec functions.])
       fi
@@ -465,21 +549,24 @@ if test "x$have_openssl" != "xyes"; then
   if test "x$with_libgcrypt" = "xyes" &&
      test "x$have_nativetls" != "xyes" &&
      test "x$have_libnettle" != "xyes"; then
-    AM_PATH_LIBGCRYPT([1.2.4], [have_libgcrypt=yes])
+    m4_ifdef([AM_PATH_LIBGCRYPT], [AM_PATH_LIBGCRYPT([1.2.4], [have_libgcrypt=yes])], [
+    AC_MSG_WARN([configure was generated without libgcrypt detection.  libgcrypt detection is disabled])
+      LIBGCRYPT_CFLAGS=
+      LIBGCRYPT_LIBS=
+      AC_SUBST([LIBGCRYPT_CFLAGS])
+      AC_SUBST([LIBGCRYPT_LIBS])
+    ])
     if test "x$have_libgcrypt" = "xyes"; then
       AC_DEFINE([HAVE_LIBGCRYPT], [1], [Define to 1 if you have libgcrypt.])
-      LIBS="$LIBGCRYPT_LIBS $LIBS"
-      CPPFLAGS="$LIBGCRYPT_CFLAGS $CPPFLAGS"
     fi
   fi
 fi
 
+have_libssh2=no
 if test "x$with_libssh2" = "xyes"; then
   PKG_CHECK_MODULES([LIBSSH2], [libssh2], [have_libssh2=yes], [have_libssh2=no])
   if test "x$have_libssh2" = "xyes"; then
     AC_DEFINE([HAVE_LIBSSH2], [1], [Define to 1 if you have libssh2.])
-    LIBS="$LIBSSH2_LIBS $LIBS"
-    CPPFLAGS="$LIBSSH2_CFLAGS $CPPFLAGS"
   else
     AC_MSG_WARN([$LIBSSH2_PKG_ERRORS])
     if test "x$with_libssh2_requested" = "xyes"; then
@@ -488,19 +575,22 @@ if test "x$with_libssh2" = "xyes"; then
   fi
 fi
 
+have_libcares=no
 if test "x$with_libcares" = "xyes"; then
   PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.0], [have_libcares=yes],
                     [have_libcares=no])
   if test "x$have_libcares" = "xyes"; then
     AC_DEFINE([HAVE_LIBCARES], [1], [Define to 1 if you have libcares.])
+    save_LIBS=$LIBS
+    save_CPPFLAGS=$CPPFLAGS
     LIBS="$LIBCARES_LIBS $LIBS"
     CPPFLAGS="$LIBCARES_CFLAGS $CPPFLAGS"
     AC_CHECK_TYPES([ares_addr_node], [], [], [[#include <ares.h>]])
     AC_CHECK_FUNCS([ares_set_servers])
+    LIBS=$save_LIBS
+    CPPFLAGS=$save_CPPFLAGS
 
-    if test "x$ARIA2_STATIC" = "xyes"; then
-      CPPFLAGS="-DCARES_STATICLIB $CPPFLAGS"
-    fi
+    # -DCARES_STATICLIB is appended by pkg-config file libcares.pc
   else
     AC_MSG_WARN([$LIBCARES_PKG_ERRORS])
     if test "x$with_libcares_requested" = "xyes"; then
@@ -606,6 +696,8 @@ AM_CONDITIONAL([HAVE_SOME_XMLLIB],
 
 if test "x$have_libxml2" = "xyes" || test "x$have_libexpat" = "xyes"; then
   enable_xml_rpc=yes
+else
+  enable_xml_rpc=no
 fi
 
 if test "x$enable_xml_rpc" = "xyes"; then
@@ -634,11 +726,13 @@ AM_CONDITIONAL([HAVE_SQLITE3], [test "x$have_sqlite3" = "xyes"])
 # Set conditional for libssh2
 AM_CONDITIONAL([HAVE_LIBSSH2], [test "x$have_libssh2" = "xyes"])
 
-AC_SEARCH_LIBS([clock_gettime], [rt])
-
 case "$host" in
   *solaris*)
-    AC_SEARCH_LIBS([getaddrinfo], [nsl socket])
+    save_LIBS=$LIBS
+    LIBS=
+    AC_SEARCH_LIBS([getaddrinfo], [nsl socket], [], [$save_LIBS])
+    EXTRALIBS="$LIBS $EXTRALIBS"
+    LIBS=$save_LIBS
     ;;
 esac
 
@@ -739,7 +833,7 @@ AC_CHECK_FUNCS([__argz_count \
                 getcwd \
                 gethostbyaddr \
                 gethostbyname \
-		getifaddrs \
+                getifaddrs \
                 getpagesize \
                 getrandom \
                 memchr \
@@ -750,9 +844,9 @@ AC_CHECK_FUNCS([__argz_count \
                 mmap \
                 munmap \
                 nl_langinfo \
-		posix_fadvise \
+                posix_fadvise \
                 posix_memalign \
-		pow \
+                pow \
                 putenv \
                 rmdir \
                 select \
@@ -774,8 +868,8 @@ AC_CHECK_FUNCS([__argz_count \
                 tzset \
                 unsetenv \
                 usleep \
-		utime \
-		utimes])
+                utime \
+                utimes])
 
 AC_MSG_CHECKING([for getrandom linux syscall interface])
 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@@ -801,17 +895,18 @@ if test "x$with_tcmalloc_requested" = "xyes" &&
   AC_MSG_FAILURE([Cannot use both, tcmalloc and jemalloc!])
 fi
 
+have_tcmalloc=no
 if test "x$with_tcmalloc" = "xyes"; then
   dnl Important: put malloc libs at the very end.
   dnl Only newish versions have a .pc, thus try CHECK_LIB as well.
   PKG_CHECK_MODULES([TCMALLOC], [libtcmalloc_minimal], [have_tcmalloc=yes], [have_tcmalloc=no])
-  if test "x$have_tcmalloc" = "xyes"; then
-    CPPFLAGS="$TCMALLOC_CFLAGS $CPPFLAGS"
-    LIBS="$LIBS $TCMALLOC_LIBS"
-  else
+  if test "x$have_tcmalloc" != "xyes"; then
     AC_CHECK_LIB([tcmalloc_minimal], [malloc], [have_tcmalloc=yes], [have_tcmalloc=no])
     if test "x$have_tcmalloc" = "xyes"; then
-      LIBS="$LIBS -ltcmalloc_minimal"
+      TCMALLOC_CFLAGS=
+      TCMALLOC_LIBS="-ltcmalloc_minimal"
+      AC_SUBST([TCMALLOC_CFLAGS])
+      AC_SUBST([TCMALLOC_LIBS])
     else
       if test "x$with_tcmalloc_requested" = "xyes"; then
         ARIA2_DEP_NOT_MET([tcmalloc_minimal])
@@ -820,18 +915,19 @@ if test "x$with_tcmalloc" = "xyes"; then
   fi
 fi
 
-if test "x$have_tcmalloc" != "xyes" && test "x$with_jemalloc" = "xyes"; then
+have_jemalloc=no
+if test "x$with_jemalloc" = "xyes"; then
   dnl Important: put malloc libs at the very end.
   dnl Usually jemalloc does not come with a .pc, as the official source does not
   dnl generate one.
   PKG_CHECK_MODULES([JEMALLOC], [jemalloc], [have_jemalloc=yes], [have_jemalloc=no])
-  if test "x$have_jemalloc" = "xyes"; then
-    CPPFLAGS="$JEMALLOC_CFLAGS $CPPFLAGS"
-    LIBS="$LIBS $JEMALLOC_LIBS"
-  else
+  if test "x$have_jemalloc" != "xyes"; then
     AC_CHECK_LIB([jemalloc], [malloc], [have_jemalloc=yes], [have_jemalloc=no])
     if test "x$have_jemalloc" = "xyes"; then
-      LIBS="$LIBS -ljemalloc"
+      JEMALLOC_CFLAGS=
+      JEMALLOC_LIBS="-ljemalloc"
+      AC_SUBST([JEMALLOC_CFLAGS])
+      AC_SUBST([JEMALLOC_LIBS])
     else
       if test "x$with_jemalloc_requested" = "xyes"; then
         ARIA2_DEP_NOT_MET([jemalloc (unprefixed)])
@@ -840,7 +936,7 @@ if test "x$have_tcmalloc" != "xyes" && test "x$with_jemalloc" = "xyes"; then
   fi
 fi
 
-
+have_epoll=no
 if test "x$enable_epoll" = "xyes"; then
   AC_CHECK_FUNCS([epoll_create], [have_epoll=yes])
   if test "x$have_epoll" = "xyes"; then
@@ -862,6 +958,9 @@ AM_CONDITIONAL([HAVE_SOME_FALLOCATE],
   [test "x$have_posix_fallocate" = "xyes" || test "x$have_fallocate" = "xyes" \
   || test "x$have_osx" = "xyes" || test "x$win_build" = "xyes"])
 
+# mingw needs this
+save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $EXTRACPPFLAGS"
 AC_MSG_CHECKING([for asctime_r])
 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
     #include <time.h>
@@ -887,25 +986,26 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
    AC_DEFINE([HAVE_LOCALTIME_R], [1], [Define to 1 if you have the `localtime_r' function or macro.])],
   [AC_MSG_RESULT([no])
    AM_CONDITIONAL([HAVE_LOCALTIME_R], false)])
+CPPFLAGS=$save_CPPFLAGS
 
 AC_CHECK_FUNCS([basename],
-	[AM_CONDITIONAL([HAVE_BASENAME], true)],
-	[AM_CONDITIONAL([HAVE_BASENAME], false)])
+        [AM_CONDITIONAL([HAVE_BASENAME], true)],
+        [AM_CONDITIONAL([HAVE_BASENAME], false)])
 AC_CHECK_FUNCS([gai_strerror],
-	[AM_CONDITIONAL([HAVE_GAI_STRERROR], true)],
- 	[AM_CONDITIONAL([HAVE_GAI_STRERROR], false)])
+        [AM_CONDITIONAL([HAVE_GAI_STRERROR], true)],
+        [AM_CONDITIONAL([HAVE_GAI_STRERROR], false)])
 AC_CHECK_FUNCS([getaddrinfo],
-	[AM_CONDITIONAL([HAVE_GETADDRINFO], true)],
-	[AM_CONDITIONAL([HAVE_GETADDRINFO], false)])
+        [AM_CONDITIONAL([HAVE_GETADDRINFO], true)],
+        [AM_CONDITIONAL([HAVE_GETADDRINFO], false)])
 AC_CHECK_FUNCS([gettimeofday],
-	[AM_CONDITIONAL([HAVE_GETTIMEOFDAY], true)],
-	[AM_CONDITIONAL([HAVE_GETTIMEOFDAY], false)])
+        [AM_CONDITIONAL([HAVE_GETTIMEOFDAY], true)],
+        [AM_CONDITIONAL([HAVE_GETTIMEOFDAY], false)])
 AC_CHECK_FUNCS([strptime],
-	[AM_CONDITIONAL([HAVE_STRPTIME], true)],
-	[AM_CONDITIONAL([HAVE_STRPTIME], false)])
+        [AM_CONDITIONAL([HAVE_STRPTIME], true)],
+        [AM_CONDITIONAL([HAVE_STRPTIME], false)])
 AC_CHECK_FUNCS([timegm],
-	[AM_CONDITIONAL([HAVE_TIMEGM], true)],
-	[AM_CONDITIONAL([HAVE_TIMEGM], false)])
+        [AM_CONDITIONAL([HAVE_TIMEGM], true)],
+        [AM_CONDITIONAL([HAVE_TIMEGM], false)])
 AC_CHECK_FUNCS([daemon], [have_daemon=yes])
 AM_CONDITIONAL([HAVE_DAEMON], [test "x$have_daemon" = "xyes"])
 
@@ -992,10 +1092,11 @@ if test "x$enable_websocket" = "xyes"; then
   enable_websocket=yes
   AC_DEFINE([ENABLE_WEBSOCKET], [1],
             [Define 1 if WebSocket support is enabled.])
+  # $(top_srcdir) for `make distcheck`
+  WSLAY_CFLAGS="-I\$(top_builddir)/deps/wslay/lib/includes -I\$(top_srcdir)/deps/wslay/lib/includes"
   WSLAY_LIBS="\$(top_builddir)/deps/wslay/lib/libwslay.la"
+  AC_SUBST([WSLAY_CFLAGS])
   AC_SUBST([WSLAY_LIBS])
-  # $(top_srcdir) for `make distcheck`
-  CPPFLAGS="-I\$(top_builddir)/deps/wslay/lib/includes -I\$(top_srcdir)/deps/wslay/lib/includes $CPPFLAGS"
 fi
 AM_CONDITIONAL([ENABLE_WEBSOCKET], [test "x$enable_websocket" = "xyes"])
 
@@ -1031,77 +1132,108 @@ AM_CONDITIONAL([ANDROID_X86], [test "x$android_x86" = "xyes"])
 if test "x$ARIA2_STATIC" = "xyes"; then
   # -static-libgcc and -static-libstdc++ are linker flags and not for
   # libtool.
-  LDFLAGS="$LDFLAGS -all-static"
+  EXTRALDFLAGS="$EXTRALDFLAGS -all-static"
   dnl For non-MinGW build, we need additional libs for static build.
   case "$host" in
     *mingw*|*msvc*|*darwin*)
     ;;
 
     *)
-      LIBS="$LIBS -lpthread -ldl -lrt"
+      EXTRALIBS="$EXTRALIBS -lpthread -ldl -lrt"
     ;;
   esac
 fi
 
 if test "x$win_build" = "xyes" && test "x$enable_libaria2" = "xyes"; then
   # Creating dll needs this
-  LDFLAGS="$LDFLAGS -no-undefined"
+  EXTRALDFLAGS="$EXTRALDFLAGS -no-undefined"
+fi
+
+AC_SUBST([EXTRACFLAGS])
+AC_SUBST([EXTRACXXFLAGS])
+AC_SUBST([EXTRACPPFLAGS])
+AC_SUBST([EXTRALDFLAGS])
+AC_SUBST([EXTRALIBS])
+
+save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS=
+
+if test "x$enable_werror" = "xyes"; then
+  AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
+  AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
+  AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
 fi
 
+WARNCXXFLAGS=$CXXFLAGS
+CXXFLAGS=$save_CXXFLAGS
+
+AC_SUBST([WARNCXXFLAGS])
+
 AC_CONFIG_FILES([Makefile
-		src/Makefile
-		src/libaria2.pc
-		src/includes/Makefile
-		test/Makefile
-		po/Makefile.in
-		lib/Makefile
-		doc/Makefile
-		doc/manual-src/Makefile
-		doc/manual-src/en/Makefile
-		doc/manual-src/en/conf.py
-		doc/manual-src/ru/Makefile
-		doc/manual-src/ru/conf.py
-		doc/manual-src/pt/Makefile
-		doc/manual-src/pt/conf.py
-		deps/Makefile])
+                src/Makefile
+                src/libaria2.pc
+                src/includes/Makefile
+                test/Makefile
+                po/Makefile.in
+                lib/Makefile
+                doc/Makefile
+                doc/manual-src/Makefile
+                doc/manual-src/en/Makefile
+                doc/manual-src/en/conf.py
+                doc/manual-src/ru/Makefile
+                doc/manual-src/ru/conf.py
+                doc/manual-src/pt/Makefile
+                doc/manual-src/pt/conf.py
+                deps/Makefile])
 AC_OUTPUT
 
-echo " "
-echo "Build:          $build"
-echo "Host:           $host"
-echo "Target:         $target"
-echo "Install prefix: $prefix"
-echo "CC:             $CC"
-echo "CXX:            $CXX"
-echo "CPP:            $CPP"
-echo "CXXFLAGS:       $CXXFLAGS"
-echo "CFLAGS:         $CFLAGS"
-echo "CPPFLAGS:       $CPPFLAGS"
-echo "LDFLAGS:        $LDFLAGS"
-echo "LIBS:           $LIBS"
-echo "DEFS:           $DEFS"
-echo "LibUV:          $have_libuv"
-echo "SQLite3:        $have_sqlite3"
-echo "SSL Support:    $have_ssl"
-echo "AppleTLS:       $have_appletls"
-echo "WinTLS:         $have_wintls"
-echo "GnuTLS:         $have_libgnutls"
-echo "OpenSSL:        $have_openssl"
-echo "CA Bundle:      $ca_bundle"
-echo "LibXML2:        $have_libxml2"
-echo "LibExpat:       $have_libexpat"
-echo "LibCares:       $have_libcares"
-echo "Zlib:           $have_zlib"
-echo "Libssh2:        $have_libssh2"
-echo "Epoll:          $have_epoll"
-echo "Bittorrent:     $enable_bittorrent"
-echo "Metalink:       $enable_metalink"
-echo "XML-RPC:        $enable_xml_rpc"
-echo "Message Digest: $use_md"
-echo "WebSocket:      $enable_websocket"
-echo "Libaria2:       $enable_libaria2"
-if test "x$enable_libaria2" = "xyes"; then
-  echo "Library types:  Shared=${enable_shared}, Static=${enable_static}"
-fi
-echo "bash_completion dir: $bashcompletiondir"
-echo "Static build:   $ARIA2_STATIC"
+AC_MSG_NOTICE([summary of build options:
+
+Build:          $build
+Host:           $host
+Target:         $target
+Install prefix: $prefix
+CC:             $CC
+CXX:            $CXX
+CPP:            $CPP
+CXXFLAGS:       $CXXFLAGS
+CFLAGS:         $CFLAGS
+CPPFLAGS:       $CPPFLAGS
+LDFLAGS:        $LDFLAGS
+LIBS:           $LIBS
+DEFS:           $DEFS
+CXX1XCXXFLAGS:  $CXX1XCXXFLAGS
+EXTRACXXFLAGS:  $EXTRACXXFLAGS
+EXTRACFLAGS:    $EXTRACFLAGS
+EXTRACPPFLAGS:  $EXTRACPPFLAGS
+EXTRALDFLAGS:   $EXTRALDFLAGS
+EXTRALIBS:      $EXTRALIBS
+WARNCXXFLAGS:   $WARNCXXFLAGS
+LibUV:          $have_libuv (CFLAGS='$LIBUV_CFLAGS' LIBS='$LIBUV_LIBS')
+SQLite3:        $have_sqlite3 (CFLAGS='$SQLITE3_CFLAGS' LIBS='$SQLITE3_LIBS')
+SSL Support:    $have_ssl
+AppleTLS:       $have_appletls (LDFLAGS='$APPLETLS_LDFLAGS')
+WinTLS:         $have_wintls (LIBS='$WINTLS_LIBS')
+GnuTLS:         $have_libgnutls (CFLAGS='$LIBGNUTLS_CFLAGS' LIBS='$LIBGNUTLS_LIBS')
+OpenSSL:        $have_openssl (CFLAGS='$OPENSSL_CFLAGS' LIBS='$OPENSSL_LIBS')
+CA Bundle:      $ca_bundle
+LibNettle:      $have_libnettle (CFLAGS='$LIBNETTLE_CFLAGS' LIBS='$LIBNETTLE_LIBS')
+LibGmp:         $have_libgmp (CFLAGS='$LIBGMP_CFLAGS' LIBS='$LIBGMP_LIBS')
+LibGcrypt:      $have_libgcrypt (CFLAGS='$LIBGCRYPT_CFLAGS' LIBS='$LIBGCRYPT_LIBS')
+LibXML2:        $have_libxml2 (CFLAGS='$XML_CPPFLAGS' LIBS='$XML_LIBS')
+LibExpat:       $have_libexpat (CFLAGS='$EXPAT_CFLAGS' LIBS='$EXPAT_LIBS')
+LibCares:       $have_libcares (CFLAGS='$LIBCARES_CFLAGS' LIBS='$LIBCARES_LIBS')
+Zlib:           $have_zlib (CFLAGS='$ZLIB_CFLAGS' LIBS='$ZLIB_LIBS')
+Libssh2:        $have_libssh2 (CFLAGS='$LIBSSH2_CFLAGS' LIBS='$LIBSSH2_LIBS')
+Tcmalloc:       $have_tcmalloc (CFLAGS='$TCMALLOC_CFLAGS' LIBS='$TCMALLOC_LIBS')
+Jemalloc:       $have_jemalloc (CFLAGS='$JEMALLOC_CFLAGS' LIBS='$JEMALLOC_LIBS')
+Epoll:          $have_epoll
+Bittorrent:     $enable_bittorrent
+Metalink:       $enable_metalink
+XML-RPC:        $enable_xml_rpc
+Message Digest: $use_md
+WebSocket:      $enable_websocket (CFLAGS='$WSLAY_CFLAGS' LIBS='$WSLAY_LIBS')
+Libaria2:       $enable_libaria2 (shared=${enable_shared} static=${enable_static})
+bash_completion dir: $bashcompletiondir
+Static build:   $ARIA2_STATIC
+])

+ 1 - 1
deps/wslay/COPYING

@@ -1,6 +1,6 @@
 The MIT License
 
-Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa
+Copyright (c) 2011, 2012, 2015 Tatsuhiro Tsujikawa
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the

+ 0 - 5
deps/wslay/Makefile.am

@@ -23,8 +23,3 @@
 SUBDIRS = lib tests
 
 ACLOCAL_AMFLAGS = -I m4
-
-EXTRA_DIST = examples/Makefile \
-	examples/fork-echoserv.c \
-	examples/echoserv.cc \
-	examples/testclient.cc

+ 31 - 25
deps/wslay/NEWS

@@ -1,41 +1,47 @@
-wslay 0.1.1
+wslay 1.0.0
 ===========
 
 Release Note
 ------------
 
-This release fixes the example programs and tutorial.  It does not
-change library code at all, so the library version has not been
-changed.
+This release fixes several build issues.  Most changes were introduced
+by contributors.  Thank you for all the contributions in this project.
+Because wslay is very stable since the previous release (more than 2
+years ago), we mark this release 1.0.0.
 
 Changes
 -------
 
-* Fixed example source code and tutorial.
+* Fix NULL check in wslay_frame_context_init.
 
-
+  Patch from Witchakorn Kamolpornwijit
 
-wslay 0.1.0
-===========
+* the examples uses epoll and thus only be built on linux
 
-Release Note
-------------
+  Patch from Kazuho Oku
+
+* build: allow one to build out-of-tree documentation
+
+  Patch from Vincent Bernat
+
+* build: fix `./configure` when nettle is not present
+
+  `PKG_CHECK_MODULES` will fail unless we give it an action to execute
+  on failure. When nettle is not available, we set `have_nettle` to
+  `no`.
+
+  Patch from Vincent Bernat
+
+* Adds the ability to override the version header include with a
+  define.  This enables projects to set the build version from the
+  compile environment and avoid the need to generate the version
+  header.
 
-This is the initial release of wslay WebSocket C library.
+  Patch from Ben Vanik
 
-Wslay is a WebSocket library written in C. It implements the protocol
-version 13 described in RFC 6455. This library offers 2 levels of API:
-event-based API and frame-based low-level API. For event-based API, it
-is suitable for non-blocking reactor pattern style. You can set
-callbacks in various events. For frame-based API, you can send
-WebSocket frame directly. Wslay only supports data transfer part of
-WebSocket protocol and does not perform opening handshake in HTTP.
+* Improve http_handshake in fork-echoserver.
 
-Wslay does not perform any I/O operations for its own. Instead, it
-offers callbacks for them. This makes Wslay independent on any I/O
-frameworks, SSL, sockets, etc. This makes Wslay protable across
-various platforms and the application authors can choose freely IO
-frameworks.
+  Patch from Gurjeet Singh
 
-Visit http://wslay.sourceforge.net/ for the API reference and
-tutorial.
+* Don't send any pending control frame other than Close control frame
+  after Close is queued.

+ 29 - 1
deps/wslay/README.rst

@@ -22,7 +22,7 @@ Wslay supports:
 
 Wslay does not perform any I/O operations for its own. Instead, it
 offers callbacks for them. This makes Wslay independent on any I/O
-frameworks, SSL, sockets, etc.  This makes Wslay protable across
+frameworks, SSL, sockets, etc.  This makes Wslay portable across
 various platforms and the application authors can choose freely I/O
 frameworks.
 
@@ -30,3 +30,31 @@ See Autobahn test reports:
 `server <http://wslay.sourceforge.net/autobahn/reports/servers/index.html>`_
 and
 `client <http://wslay.sourceforge.net/autobahn/reports/clients/index.html>`_.
+
+Requirements
+------------
+
+`Sphinx <http://sphinx.pocoo.org/>`_ is used to generate man pages.
+
+To build and run the unit test programs, the following packages are
+needed:
+
+* cunit >= 2.1
+
+To build and run the example programs, the following packages are
+needed:
+
+* nettle >= 2.4
+
+
+Build from git
+--------------
+
+Building from git is easy, but please be sure that at least autoconf 2.68 is
+used.::
+
+    $ autoreconf -i
+    $ automake
+    $ autoconf
+    $ ./configure
+    $ make

+ 21 - 5
deps/wslay/configure.ac

@@ -21,14 +21,14 @@ dnl LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 dnl OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 dnl WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 AC_PREREQ(2.61)
-AC_INIT([wslay], [0.1.1], [[email protected]])
+AC_INIT([wslay], [1.0.1-DEV], [[email protected]])
 LT_PREREQ([2.2.6])
 LT_INIT()
 AC_CONFIG_AUX_DIR([.])
 dnl See versioning rule:
 dnl  http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
 AC_SUBST(LT_CURRENT, 0)
-AC_SUBST(LT_REVISION, 0)
+AC_SUBST(LT_REVISION, 1)
 AC_SUBST(LT_AGE, 0)
 
 AC_CANONICAL_BUILD
@@ -42,15 +42,21 @@ AC_CONFIG_HEADERS([config.h])
 
 dnl Checks for programs
 AC_PROG_CC
+AC_PROG_CXX
 AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG([0.20])
 
 AC_PATH_PROG([SPHINX_BUILD], [sphinx-build])
 AC_SUBST([SPHINX_BUILD])
 AM_CONDITIONAL([HAVE_SPHINX_BUILD], [ test "x$SPHINX_BUILD" != "x" ])
 
 # Checks for libraries.
+
+# Nettle used in examples
+PKG_CHECK_MODULES([NETTLE], [nettle >= 2.4], [have_nettle=yes], [have_nettle=no])
+
 AC_CHECK_LIB([cunit], [CU_initialize_registry],
              [have_cunit=yes], [have_cunit=no])
 AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
@@ -91,9 +97,6 @@ AC_CHECK_TYPES([ptrdiff_t])
 AC_C_BIGENDIAN
 
 # Checks for library functions.
-if test "x$cross_compiling" != "xyes"; then
-  AC_FUNC_MALLOC
-fi
 AC_CHECK_FUNCS([ \
   memmove \
   memset \
@@ -102,6 +105,17 @@ AC_CHECK_FUNCS([ \
   htons
 ])
 
+build_examples=no
+if test "x${have_nettle}" = "xyes"; then
+  case $host_os in
+    linux*)
+      # the examples uses epoll
+      build_examples=yes
+      ;;
+  esac
+fi
+AM_CONDITIONAL([ENABLE_EXAMPLES], [ test "x${build_examples}" = "xyes" ])
+
 AC_CONFIG_FILES([
   Makefile
   lib/Makefile
@@ -121,4 +135,6 @@ AC_MSG_NOTICE([summary of build options:
     CFlags:         ${CFLAGS}
     Library types:  Shared=${enable_shared}, Static=${enable_static}
     CUnit:          ${have_cunit}
+    Nettle:         ${have_nettle}
+    Build examples: ${build_examples}
 ])

+ 0 - 46
deps/wslay/examples/Makefile

@@ -1,46 +0,0 @@
-# Wslay - The WebSocket Library
-
-# Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa
-
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-CC = gcc
-CXX = g++
-CFLAGS = -g -O2 -I../lib/includes
-CXXFLAGS = $(CFLAGS)
-LDFLAGS = -L../lib/.libs
-LIBS = -lwslay -lnettle
-
-PROGRAMS = fork-echoserv echoserv testclient
-
-.PHONY: all
-all: $(PROGRAMS)
-
-fork-echoserv: fork-echoserv.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ fork-echoserv.c $(LIBS)
-
-echoserv: echoserv.cc
-	$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ echoserv.cc $(LIBS)
-
-testclient: testclient.cc
-	$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ testclient.cc $(LIBS)
-
-.PHONY: clean
-clean:
-	rm -f *.o $(PROGRAMS)

+ 1 - 1
deps/wslay/examples/echoserv.cc

@@ -570,7 +570,7 @@ void reactor(int sfd)
             } else {
               perror("epoll_ctl");
               delete next;
-            }              
+            }
           }
         }
         if(eh->finish()) {

+ 80 - 5
deps/wslay/examples/fork-echoserv.c

@@ -50,6 +50,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 #include <nettle/base64.h>
 #include <nettle/sha.h>
@@ -159,6 +160,80 @@ void create_accept_key(char *dst, const char *client_key)
   dst[BASE64_ENCODE_RAW_LENGTH(20)] = '\0';
 }
 
+/* We parse HTTP header lines of the format
+ *   \r\nfield_name: value1, value2, ... \r\n
+ *
+ * If the caller is looking for a specific value, we return a pointer to the
+ * start of that value, else we simply return the start of values list.
+ */
+static char*
+http_header_find_field_value(char *header, char *field_name, char *value)
+{
+  char *header_end,
+       *field_start,
+       *field_end,
+       *next_crlf,
+       *value_start;
+  int field_name_len;
+
+  /* Pointer to the last character in the header */
+  header_end = header + strlen(header) - 1;
+
+  field_name_len = strlen(field_name);
+
+  field_start = header;
+
+  do{
+    field_start = strstr(field_start+1, field_name);
+
+    field_end = field_start + field_name_len - 1;
+
+    if(field_start != NULL
+       && field_start - header >= 2
+       && field_start[-2] == '\r'
+       && field_start[-1] == '\n'
+       && header_end - field_end >= 1
+       && field_end[1] == ':')
+    {
+      break; /* Found the field */
+    }
+    else
+    {
+      continue; /* This is not the one; keep looking. */
+    }
+  } while(field_start != NULL);
+
+  if(field_start == NULL)
+    return NULL;
+
+  /* Find the field terminator */
+  next_crlf = strstr(field_start, "\r\n");
+
+  /* A field is expected to end with \r\n */
+  if(next_crlf == NULL)
+    return NULL; /* Malformed HTTP header! */
+
+  /* If not looking for a value, then return a pointer to the start of values string */
+  if(value == NULL)
+    return field_end+2;
+
+  value_start = strstr(field_start, value);
+
+  /* Value not found */
+  if(value_start == NULL)
+    return NULL;
+
+  /* Found the value we're looking for */
+  if(value_start > next_crlf)
+    return NULL; /* ... but after the CRLF terminator of the field. */
+
+  /* The value we found should be properly delineated from the other tokens */
+  if(isalnum(value_start[-1]) || isalnum(value_start[strlen(value)]))
+    return NULL;
+
+  return value_start;
+}
+
 /*
  * Performs HTTP handshake. *fd* is the file descriptor of the
  * connection to the client. This function returns 0 if it succeeds,
@@ -195,13 +270,13 @@ int http_handshake(int fd)
       }
     }
   }
-  if(strstr(header, "\r\nUpgrade: websocket\r\n") == NULL ||
-     strstr(header, "\r\nConnection: Upgrade\r\n") == NULL ||
-     (keyhdstart = strstr(header, "\r\nSec-WebSocket-Key:")) == NULL) {
+
+  if(http_header_find_field_value(header, "Upgrade", "websocket") == NULL ||
+     http_header_find_field_value(header, "Connection", "Upgrade") == NULL ||
+     (keyhdstart = http_header_find_field_value(header, "Sec-WebSocket-Key", NULL)) == NULL) {
     fprintf(stderr, "HTTP Handshake: Missing required header fields");
     return -1;
   }
-  keyhdstart += 20;
   for(; *keyhdstart == ' '; ++keyhdstart);
   keyhdend = keyhdstart;
   for(; *keyhdend != '\r' && *keyhdend != ' '; ++keyhdend);
@@ -281,7 +356,7 @@ ssize_t recv_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len,
     r = -1;
   }
   return r;
-}    
+}
 
 void on_msg_recv_callback(wslay_event_context_ptr ctx,
                           const struct wslay_event_on_msg_recv_arg *arg,

+ 1 - 1
deps/wslay/examples/testclient.cc

@@ -496,7 +496,7 @@ int update_reports(const char *host, const char *service)
 
 int main(int argc, char **argv)
 {
-  if(argc < 2) {
+  if(argc < 3) {
     std::cerr << "Usage: " << argv[0] << " HOST SERV" << std::endl;
     exit(EXIT_FAILURE);
   }

+ 9 - 1
deps/wslay/lib/includes/wslay/wslay.h

@@ -33,7 +33,15 @@ extern "C" {
 #include <stdlib.h>
 #include <sys/types.h>
 
-#include <wslay/wslayver.h>
+
+/*
+ * wslay/wslayver.h is generated from wslay/wslayver.h.in by
+ * configure. The projects which do not use autotools can set
+ * WSLAY_VERSION macro from outside to avoid to generating wslayver.h
+ */
+#ifndef WSLAY_VERSION
+#  include <wslay/wslayver.h>
+#endif /* WSLAY_VERSION */
 
 enum wslay_error {
   WSLAY_ERR_WANT_READ = -100,

+ 4 - 0
deps/wslay/lib/wslay_event.c

@@ -135,6 +135,10 @@ static int wslay_event_byte_chunk_init
   memset(*chunk, 0, sizeof(struct wslay_event_byte_chunk));
   if(len) {
     (*chunk)->data = (uint8_t*)malloc(len);
+    if((*chunk)->data == NULL) {
+      free(*chunk);
+      return WSLAY_ERR_NOMEM;
+    }
     (*chunk)->data_length = len;
   }
   return 0;

+ 1 - 1
deps/wslay/lib/wslay_frame.c

@@ -37,7 +37,7 @@ int wslay_frame_context_init(wslay_frame_context_ptr *ctx,
                              void *user_data)
 {
   *ctx = (wslay_frame_context_ptr)malloc(sizeof(struct wslay_frame_context));
-  if(ctx == NULL) {
+  if(*ctx == NULL) {
     return -1;
   }
   memset(*ctx, 0, sizeof(struct wslay_frame_context));

+ 2 - 1
deps/wslay/lib/wslay_stack.c

@@ -40,10 +40,11 @@ struct wslay_stack* wslay_stack_new()
 
 void wslay_stack_free(struct wslay_stack *stack)
 {
+  struct wslay_stack_cell *p;
   if(!stack) {
     return;
   }
-  struct wslay_stack_cell *p = stack->top;
+  p = stack->top;
   while(p) {
     struct wslay_stack_cell *next = p->next;
     free(p);

File diff suppressed because it is too large
+ 0 - 0
doc/bash_completion/aria2c


+ 116 - 18
doc/manual-src/en/aria2c.rst

@@ -43,7 +43,7 @@ Basic Options
   When ``FILE`` is specified as ``-``, aria2 will read the input from ``stdin``.
   See the `Input File`_ subsection for details.
   See also the :option:`--deferred-input` option.
-  See also the :option:`--save-session-file` option.
+  See also the :option:`--save-session` option.
 
 .. option:: -l, --log=<LOG>
 
@@ -170,8 +170,11 @@ HTTP/FTP/SFTP Options
 
   If aria2 receives "file not found" status from the remote HTTP/FTP
   servers NUM times without getting a single byte, then force the
-  download to fail. Specify ``0`` to disable this option. This options is
-  effective only when using HTTP/FTP servers.
+  download to fail. Specify ``0`` to disable this option. This options
+  is effective only when using HTTP/FTP servers.  The number of retry
+  attempt is counted toward :option:`--max-tries`, so it should be
+  configured too.
+
   Default: ``0``
 
 .. option:: -m, --max-tries=<N>
@@ -639,6 +642,14 @@ BitTorrent Specific Options
   queue gets started. But be aware that seeding item is still
   recognized as active download in RPC method.  Default: ``false``
 
+.. option:: --bt-enable-hook-after-hash-check[=true|false]
+
+  Allow hook command invocation after hash check (see :option:`-V`
+  option) in BitTorrent download. By default, when hash check
+  succeeds, the command given by :option:`--on-bt-download-complete`
+  is executed. To disable this action, give ``false`` to this option.
+  Default: ``true``
+
 .. option:: --bt-enable-lpd[=true|false]
 
   Enable Local Peer Discovery.  If a private flag is set in a torrent,
@@ -1207,6 +1218,11 @@ Advanced Options
   and options at startup.
   Default: ``false``
 
+  .. Warning::
+
+    :option:`--deferred-input` option will be disabled when
+    :option:`--save-session` is used together.
+
 .. option:: --disable-ipv6[=true|false]
 
   Disable IPv6. This is useful if you have to use broken DNS and want
@@ -1359,6 +1375,16 @@ Advanced Options
   downloads. Specifying 0 means no download result is kept. Default:
   ``1000``
 
+.. option:: --max-mmap-limit=<SIZE>
+
+  Set the maximum file size to enable mmap (see
+  :option:`--enable-mmap` option). The file size is determined by the
+  sum of all files contained in one download. For example, if a
+  download contains 5 files, then file size is the total size of those
+  files. If file size is strictly greater than the size specified in
+  this option, mmap will be disabled.
+  Default: ``9223372036854775807``
+
 .. option:: --max-resume-failure-tries=<N>
 
   When used with :option:`--always-resume=false, <--always-resume>` aria2 downloads file from
@@ -1431,6 +1457,21 @@ Advanced Options
   See `Event Hook`_ for more details about COMMAND.
   Possible Values: ``/path/to/command``
 
+
+.. option:: --optimize-concurrent-downloads[=true|false|<A>:<B>]
+
+  Optimizes the number of concurrent downloads according to the
+  bandwidth available. aria2 uses the download speed observed in the
+  previous downloads to adapt the number of downloads launched in
+  parallel according to the rule N = A + B Log10(speed in Mbps). The
+  coefficients A and B can be customized in the option arguments with
+  A and B separated by a colon. The default values (A=5, B=25) lead to
+  using typically 5 parallel downloads on 1Mbps networks and above 50
+  on 100Mbps networks. The number of parallel downloads remains
+  constrained under the maximum defined by the
+  :option:`--max-concurrent-downloads` parameter.
+  Default: ``false``
+
 .. option:: --piece-length=<LENGTH>
 
   Set a piece length for HTTP/FTP downloads. This is the boundary when
@@ -1540,16 +1581,16 @@ Advanced Options
     use meta data (e.g., BitTorrent and Metalink). In this case, there
     are some restrictions.
 
-    1. magnet URI, and followed by torrent download
-        GID of BitTorrent meta data download is saved.
-    2. URI to torrent file, and followed by torrent download
-        GID of torrent file download is saved.
-    3. URI to metalink file, and followed by file downloads described in metalink file
-        GID of metalink file download is saved.
-    4. local torrent file
-        GID of torrent download is saved.
-    5. local metalink file
-        Any meaningful GID is not saved.
+    magnet URI, and followed by torrent download
+       GID of BitTorrent meta data download is saved.
+    URI to torrent file, and followed by torrent download
+       GID of torrent file download is saved.
+    URI to metalink file, and followed by file downloads described in metalink file
+       GID of metalink file download is saved.
+    local torrent file
+       GID of torrent download is saved.
+    local metalink file
+       Any meaningful GID is not saved.
 
 .. option:: --save-session-interval=<SEC>
 
@@ -1557,6 +1598,14 @@ Advanced Options
   :option:`--save-session` option every SEC seconds. If ``0`` is
   given, file will be saved only when aria2 exits. Default: ``0``
 
+
+.. option:: --socket-recv-buffer-size=<SIZE>
+
+  Set the maximum socket receive buffer in bytes.  Specifing ``0``
+  will disable this option. This value will be set to socket file
+  descriptor using ``SO_RCVBUF`` socket option with ``setsockopt()``
+  call.  Default: ``0``
+
 .. option:: --stop=<SEC>
 
   Stop application after SEC seconds has passed.
@@ -1954,6 +2003,7 @@ of URIs. These optional lines must start with white space(s).
   * :option:`always-resume <--always-resume>`
   * :option:`async-dns <--async-dns>`
   * :option:`auto-file-renaming <--auto-file-renaming>`
+  * :option:`bt-enable-hook-after-hash-check <--bt-enable-hook-after-hash-check>`
   * :option:`bt-enable-lpd <--bt-enable-lpd>`
   * :option:`bt-exclude-tracker <--bt-exclude-tracker>`
   * :option:`bt-external-ip <--bt-external-ip>`
@@ -2015,6 +2065,7 @@ of URIs. These optional lines must start with white space(s).
   * :option:`max-connection-per-server <-x>`
   * :option:`max-download-limit <--max-download-limit>`
   * :option:`max-file-not-found <--max-file-not-found>`
+  * :option:`max-mmap-limit <--max-mmap-limit>`
   * :option:`max-resume-failure-tries <--max-resume-failure-tries>`
   * :option:`max-tries <-m>`
   * :option:`max-upload-limit <-u>`
@@ -2203,6 +2254,10 @@ to provide the token as the first parameter as described above.
   interface. Therefore it is recommended to prefer Batch or `system.multicall`
   requests when appropriate.
 
+  `system.listMethods` can be executed without token.  Since it just
+  returns the all available methods, and does not alter anything, it
+  is safe without secret token.
+
 Methods
 ~~~~~~~
 
@@ -2305,7 +2360,7 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
 
     >>> import xmlrpclib
     >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
-    >>> s.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent').read()))
+    >>> s.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent', mode='rb').read()))
     '2089b05ecca3d829'
 
 .. function:: aria2.addMetalink([secret], metalink[, options[, position]])
@@ -2351,7 +2406,7 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
 
     >>> import xmlrpclib
     >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
-    >>> s.aria2.addMetalink(xmlrpclib.Binary(open('file.meta4').read()))
+    >>> s.aria2.addMetalink(xmlrpclib.Binary(open('file.meta4', mode='rb').read()))
     ['2089b05ecca3d829']
 
 .. function:: aria2.remove([secret], gid)
@@ -2478,6 +2533,10 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
   ``numSeeders``
     The number of seeders aria2 has connected to. BitTorrent only.
 
+  ``seeder``
+    ``true`` if the local endpoint is a seeder. Otherwise ``false``.
+    BitTorrent only.
+
   ``pieceLength``
     Piece length in bytes.
 
@@ -2492,6 +2551,10 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
     is a string. The error codes are defined in the `EXIT STATUS`_ section.
     This value is only available for stopped/completed downloads.
 
+  ``errorMessage``
+    The (hopefully) human readable error message associated to
+    ``errorCode``.
+
   ``followedBy``
     List of GIDs which are generated as the result of this
     download. For example, when aria2 downloads a Metalink file, it
@@ -2500,6 +2563,10 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
     auto-generated downloads. If there are no such downloads, this key will not
     be included in the response.
 
+  ``following``
+    The reverse link for ``followedBy``.  A download included in
+    ``followedBy`` has this object's GID in its ``following`` value.
+
   ``belongsTo``
     GID of a parent download. Some downloads are a part of another
     download.  For example, if a file in a Metalink has BitTorrent
@@ -2768,7 +2835,7 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
     Upload speed(byte/sec) that this client uploads to the peer.
 
   ``seeder``
-    ``true`` is this peer is a seeder. Otherwise ``false``.
+    ``true`` if this peer is a seeder. Otherwise ``false``.
 
   **JSON-RPC Example**
   ::
@@ -3139,6 +3206,7 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
   * :option:`max-download-result <--max-download-result>`
   * :option:`max-overall-download-limit <--max-overall-download-limit>`
   * :option:`max-overall-upload-limit <--max-overall-upload-limit>`
+  * :option:`optimize-concurrent-downloads <--optimize-concurrent-downloads>`
   * :option:`save-cookies <--save-cookies>`
   * :option:`save-session <--save-session>`
   * :option:`server-stat-of <--server-stat-of>`
@@ -3395,11 +3463,41 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
     >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
     >>> mc = xmlrpclib.MultiCall(s)
     >>> mc.aria2.addUri(['http://example.org/file'])
-    >>> mc.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent').read()))
+    >>> mc.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent', mode='rb').read()))
     >>> r = mc()
     >>> tuple(r)
     ('2089b05ecca3d829', 'd2703803b52216d1')
 
+.. function:: system.listMethods()
+
+  This method returns the all available RPC methods in an array of
+  string.  Unlike other methods, this method does not require secret
+  token.  This is safe because this method jsut returns the available
+  method names.
+
+  **JSON-RPC Example**
+  ::
+
+    >>> import urllib2, json
+    >>> from pprint import pprint
+    >>> jsonreq = json.dumps({'jsonrpc':'2.0', 'id':'qwer',
+    ...                       'method':'system.listMethods'})
+    >>> c = urllib2.urlopen('http://localhost:6800/jsonrpc', jsonreq)
+    >>> pprint(json.loads(c.read()))
+    {u'id': u'qwer',
+     u'jsonrpc': u'2.0',
+     u'result': [u'aria2.addUri',
+                 u'aria2.addTorrent',
+    ...
+
+  **XML-RPC Example**
+  ::
+
+    >>> import xmlrpclib
+    >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
+    >>> s.system.listMethods()
+    ['aria2.addUri', 'aria2.addTorrent', ...
+
 Error Handling
 ~~~~~~~~~~~~~~
 
@@ -4154,7 +4252,7 @@ Encrypt the whole payload using ARC4 (obfuscation):
 
 SEE ALSO
 --------
-Project Web Site: http://aria2.sourceforge.net/
+Project Web Site: https://aria2.github.io/
 
 Metalink Homepage: http://www.metalinker.org/
 

+ 15 - 18
doc/manual-src/pt/README.rst

@@ -8,17 +8,17 @@
               windows, linux, manual download aria2, torrent, download stream,
               como compilar programa no android, como executar download no
               android
-   :author: t-tujikawa_at_users_dot_sourceforge_dot_net english version
+   :author: tatsuhiro.t_at_gmail_dot_com english version
    :author: [email protected] tradução para português do brasil
 
 
 aria2 - Utilitário para Download Super Ultra Rápido
 ===================================================
 :Author:     Tatsuhiro Tsujikawa
-:Email:      t-tujikawa_at_users_dot_sourceforge_dot_net
+:Email:      tatsuhiro.t_at_gmail_dot_com
 :translator: pt_BR Portuguese, tradutor: [email protected]
 
-.. index:: double: author; t-tujikawa_at_users_dot_sourceforge_dot_net
+.. index:: double: author; tatsuhiro.t_at_gmail_dot_com
 .. index:: triple: tradutor; tradução; [email protected];
 
 Renúncia
@@ -39,10 +39,9 @@ para você ir assistindo um filme enquanto o download prossegue.  Através da
 verificação (checksum) de partes dos dados dos Metalink's, aria2
 automaticamente valida partes (chunks) do BitTorrent.
 
-A página do projeto está em http://aria2.sourceforge.net/.
+A página do projeto está em https://aria2.github.io/.
 
-Veja `aria2 Manual Online <http://aria2.sourceforge.net/manual/pt/html/>`_
-e `Exemplos de Uso <http://sourceforge.net/apps/trac/aria2/wiki/UsageExample>`_ 
+Veja `aria2 Manual Online <https://aria2.github.io/manual/pt/html/>`_
 para aprender como a usar aria2.
 
 Funcionalidades
@@ -396,9 +395,9 @@ Como usar comandos do aria2 no Android
 --------------------------------------
 
 Ver o manual do aria2 online nos seguintes idiomas:
-`Tradução em Português <http://aria2.sourceforge.net/manual/pt/html/>`_.
-`Original em Inglês    <http://aria2.sourceforge.net/manual/en/html/>`_.
-`Tradução em Russo     <http://aria2.sourceforge.net/manual/ru/html/>`_.
+`Tradução em Português <https://aria2.github.io/manual/pt/html/>`_.
+`Original em Inglês    <https://aria2.github.io/manual/en/html/>`_.
+`Tradução em Russo     <https://aria2.github.io/manual/ru/html/>`_.
 
 Notas sobre uso do aria2 no Android
 -----------------------------------
@@ -463,10 +462,10 @@ certifique-se de que os pré-requisitos de fontes usados pelo latex
 estejam presentes.
 
 A versão online HTML também está disponível em:
-`Original em Inglês <http://aria2.sourceforge.net/manual/en/html/>`_ 
+`Original em Inglês <https://aria2.github.io/manual/en/html/>`_ 
 e nas traduções em:
-(`Português <http://aria2.sourceforge.net/manual/pt/html/>`_ e
-`Russo <http://aria2.sourceforge.net/manual/ru/html/>`_).
+(`Português <https://aria2.github.io/manual/pt/html/>`_ e
+`Russo <https://aria2.github.io/manual/ru/html/>`_).
 
 BitTorrrent
 ===========
@@ -597,17 +596,15 @@ Referências
 ===========
 
 * `aria2 Manual Inglês 
-  <http://aria2.sourceforge.net/manual/en/html/>`_ original inglês
+  <https://aria2.github.io/manual/en/html/>`_ original inglês
   
 * `aria2 Manual Russo 
-  <http://aria2.sourceforge.net/manual/ru/html/>`_ versão russo
+  <https://aria2.github.io/manual/ru/html/>`_ versão russo
   
 * `aria2 Manual Português 
-  <http://aria2.sourceforce.net/manual/pt/html/>`_ versão português
+  <https://aria2.github.io/manual/pt/html/>`_ versão português
   
-* http://aria2.sourceforge.net/
-* http://sourceforge.net/apps/trac/aria2/wiki
-* https://github.com/tatsuhiro-t/aria2
+* https://aria2.github.io/
 * `RFC 959 FILE TRANSFER PROTOCOL (FTP) 
   <http://tools.ietf.org/html/rfc959>`_
 * `RFC 1738 Uniform Resource Locators (URL) 

+ 1 - 3
doc/manual-src/pt/aria2c.rst

@@ -3959,9 +3959,7 @@ Criptografar todo conjunto usando ARC4:
 Ver Também
 ----------
 
-Site do Projeto aria2: http://aria2.sourceforge.net/
-
-Wiki aria2: http://sourceforge.net/apps/trac/aria2/wiki
+Site do Projeto aria2: https://aria2.github.io/
 
 Site do Projeto Metalink: http://www.metalinker.org/
 

+ 116 - 18
doc/manual-src/ru/aria2c.rst

@@ -44,7 +44,7 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
   Входной файл может использовать gzip-сжатие.
   Смотрите подраздел `Входной файл`_ для детальных пояснений.
   Также смотрите параметр :option:`--deferred-input`.
-  Также смотрите параметр :option:`--save-session-file`.
+  Также смотрите параметр :option:`--save-session`.
 
 .. option:: -l, --log=<LOG>
 
@@ -181,7 +181,10 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
   удаленных HTTP/FTP-серверов NUM раз без получения, хотя бы одного байта,
   тогда принудительно отказывается от загрузки. Укажите ``0``, чтобы
   отключить этот параметр. Этот параметр действенен только, когда
-  используются HTTP/FTP-серверы.
+  используются HTTP/FTP-серверы. Количество повторных попыток засчитывается в
+  :option:`--max-tries`, таким образом, этот параметр также должен быть
+  сконфигурирован.
+
   По умолчанию: ``0``
 
 .. option:: -m, --max-tries=<N>
@@ -665,6 +668,15 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
   загрузка стартует. Но знайте, что в RPC-методе сидирующий элемент всё
   ещё признаётся как активная загрузка. По умолчанию: ``false``
 
+.. option:: --bt-enable-hook-after-hash-check[=true|false]
+
+  Позволяет перехватить команду вызова (управление) после проверки хэша
+  (см. параметр :option:`-V`) в BitTorrent-загрузке. По умолчанию, когда
+  проверка хэша завершилась удачно, выполняется команда заданная в
+  :option:`--on-bt-download-complete`.
+  Укажите для этого параметра ``false``, чтобы отключить это действие.
+  По умолчанию: ``true``
+
 .. option:: --bt-enable-lpd[=true|false]
 
   Включить поиск локальных пиров. Если в torrent-файле установлен
@@ -1283,6 +1295,11 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
   и параметры.
   По умолчанию: ``false``
 
+  .. Warning::
+
+    параметр :option:`--deferred-input` будет заблокирован, если
+    используется вместе с :option:`--save-session`.
+
 .. option:: --disable-ipv6[=true|false]
 
   Отключить IPv6. Это полезно, если вы используете поврежденный DNS
@@ -1443,6 +1460,15 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
   загрузок. Значение 0 отключит сохранение результата загрузки.
   По умолчанию: ``1000``
 
+.. option:: --max-mmap-limit=<SIZE>
+
+  Задать максимальный размер файла для включения mmap (см. параметр
+  :option:`--enable-mmap`). Размер файла определяется по сумме всех файлов,
+  содержащихся в одной загрузке. Например, если загрузка содержит 5 файлов, то
+  размер файла - это суммарный размер этих файлов. Если размер файла строго больше
+  чем размер, указанный в этом параметре, то mmap будет отключён.
+  По умолчанию: ``9223372036854775807``
+
 .. option:: --max-resume-failure-tries=<N>
 
   Если параметр :option:`--always-resume=false, <--always-resume>` aria2
@@ -1523,6 +1549,21 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
   для более подробной информации о COMMAND. Возможные
   значения: ``/путь/к/команде``
 
+
+.. option:: --optimize-concurrent-downloads[=true|false|<A>:<B>]
+
+  Оптимизирует количество одновременных загрузок в соответствии с
+  доступной полосой пропускания. aria2 использует скорость загрузки,
+  наблюдаемую в предыдущих загрузках, чтобы адаптировать количество
+  загрузок, запущенных параллельно согласно правилу N = A + B Log10
+  (скорость в Мбит/c). Коэффициенты А и В могут быть настроены в
+  аргументах А и В, разделённых двоеточием. Значения по умолчанию
+  (A=5, B=25) приводят к использованию обычно 5 параллельных загрузок
+  в сетях с 1Мбит/с и более 50 в сетях с 100 Мбит/с. Число параллельных
+  загрузок остаётся ограниченно максимумом, определяемом в параметре
+  :option:`--max-concurrent-downloads`.
+  По умолчанию: ``false``
+
 .. option:: --piece-length=<LENGTH>
 
   Задать длину блока для HTTP/FTP-загрузок. Это является границей, когда
@@ -1634,16 +1675,16 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
     используют метаданные (например, BitTorrent и Metalink). В этом
     случае есть некоторые ограничения.
 
-    1. magnet-ссылка, и последующая torrent-загрузка
-        Сохранится GID из метаданных BitTorrent-загрузки.
-    2. URI к torrent-файл, и последующая torrent-загрузка
-        Сохранится GID из torrent-файла загрузки.
-    3. URI к metalink-файл, и последующая загрузка файлов, описанных metalink-файле
-        Сохранится GID из metalink-файла загрузки.
-    4. Локальный torrent-файл
-        Сохранится GID из torrent-загрузки.
-    5. Локальный metalink-файл
-        Никакой значимый GID не сохранится.
+    magnet-ссылка, и последующая torrent-загрузка
+       Сохранится GID из метаданных BitTorrent-загрузки.
+    URI к torrent-файл, и последующая torrent-загрузка
+       Сохранится GID из torrent-файла загрузки.
+    URI к metalink-файл, и последующая загрузка файлов, описанных metalink-файле
+       Сохранится GID из metalink-файла загрузки.
+    Локальный torrent-файл
+       Сохранится GID из torrent-загрузки.
+    Локальный metalink-файл
+       Никакой значимый GID не сохранится.
 
 .. option:: --save-session-interval=<SEC>
 
@@ -1652,6 +1693,14 @@ HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-
   Если указан ``0``, то файл будет сохранён только тогда, когда
   aria2 завершит работу. По умолчанию: ``0``
 
+
+.. option:: --socket-recv-buffer-size=<SIZE>
+
+  Задать максимальный приёмный буфер сокета в байтах. Указание ``0``
+  отключит этот параметр. Это значение будет установлено для дескриптора
+  файла сокета с помощью ``SO_RCVBUF``, параметра сокета в вызове ``setsockopt()``.
+  По умолчанию: ``0``
+
 .. option:: --stop=<SEC>
 
   Останавливать программу после того как пройдет
@@ -2063,6 +2112,7 @@ URI. Эти дополнительные строки должны начина
   * :option:`always-resume <--always-resume>`
   * :option:`async-dns <--async-dns>`
   * :option:`auto-file-renaming <--auto-file-renaming>`
+  * :option:`bt-enable-hook-after-hash-check <--bt-enable-hook-after-hash-check>`
   * :option:`bt-enable-lpd <--bt-enable-lpd>`
   * :option:`bt-exclude-tracker <--bt-exclude-tracker>`
   * :option:`bt-external-ip <--bt-external-ip>`
@@ -2124,6 +2174,7 @@ URI. Эти дополнительные строки должны начина
   * :option:`max-connection-per-server <-x>`
   * :option:`max-download-limit <--max-download-limit>`
   * :option:`max-file-not-found <--max-file-not-found>`
+  * :option:`max-mmap-limit <--max-mmap-limit>`
   * :option:`max-resume-failure-tries <--max-resume-failure-tries>`
   * :option:`max-tries <-m>`
   * :option:`max-upload-limit <-u>`
@@ -2313,6 +2364,10 @@ RPC-метод `system.multicall` обрабатывается особым об
   против RPC-интерфейса. Поэтому рекомендуется отдавать предпочтение пакетным
   или `system.multicall` запросам, когда это необходимо.
 
+  `system.listMethods` может выполняться без секретного маркера. Так он
+  просто возвращает все доступные методы, и ничего не изменяет, это
+  безопасно без секретного маркера.
+
 Методы
 ~~~~~~
 
@@ -2416,7 +2471,7 @@ RPC-метод `system.multicall` обрабатывается особым об
 
     >>> import xmlrpclib
     >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
-    >>> s.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent').read()))
+    >>> s.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent', mode='rb').read()))
     '2089b05ecca3d829'
 
 .. function:: aria2.addMetalink([secret], metalink[, options[, position]])
@@ -2461,7 +2516,7 @@ RPC-метод `system.multicall` обрабатывается особым об
 
     >>> import xmlrpclib
     >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
-    >>> s.aria2.addMetalink(xmlrpclib.Binary(open('file.meta4').read()))
+    >>> s.aria2.addMetalink(xmlrpclib.Binary(open('file.meta4', mode='rb').read()))
     ['2089b05ecca3d829']
 
 .. function:: aria2.remove([secret], gid)
@@ -2588,6 +2643,10 @@ RPC-метод `system.multicall` обрабатывается особым об
   ``numSeeders``
     Количество сидов, к которым подключена aria2. Только для BitTorrent.
 
+  ``seeder``
+    ``true`` - если локальная конечная точка является сидом. Иначе ``false``.
+    Только для BitTorrent.
+
   ``pieceLength``
     Размер блока в байтах.
 
@@ -2602,6 +2661,10 @@ RPC-метод `system.multicall` обрабатывается особым об
     является строкой. Коды ошибок определены в разделе `КОДЫ ЗАВЕРШЕНИЯ`_.
     Это значение доступно только для остановленных/завершённых загрузок.
 
+  ``errorMessage``
+    Сообщение об ошибке, удобное (надеюсь) для восприятия,
+    связанной с ``errorCode``.
+
   ``followedBy``
     Список с GID, которые сгенерируются в результате этой
     загрузки. Например, когда aria2 загружает Metalink-файл, то это генерирует
@@ -2610,6 +2673,10 @@ RPC-метод `system.multicall` обрабатывается особым об
     сгенерированных загрузок. Если таких загрузок нет, то ключ не будет
     включён в ответ.
 
+  ``following``
+    Обратная ссылка для ``followedBy``. У загрузки, включённой в
+    ``followedBy``, есть GID этого объекта в этом значении ``following``.
+
   ``belongsTo``
     GID родительской загрузки. Некоторые загрузки являются частью другой
     загрузки. Например, если файл в Metalink содержит BitTorrent ресурсы,
@@ -2774,7 +2841,7 @@ RPC-метод `system.multicall` обрабатывается особым об
 .. function:: aria2.getFiles([secret], gid)
 
   Этот метод возвращает список файлов загрузки, которая обозначена *gid* (строка).
-  Ответ - это массив и содержит следующие ключи.
+  Ответ - это массив структур, которые содержат следующие ключи.
   Значения являются строками.
 
   ``index``
@@ -3241,6 +3308,7 @@ RPC-метод `system.multicall` обрабатывается особым об
   * :option:`max-download-result <--max-download-result>`
   * :option:`max-overall-download-limit <--max-overall-download-limit>`
   * :option:`max-overall-upload-limit <--max-overall-upload-limit>`
+  * :option:`optimize-concurrent-downloads <--optimize-concurrent-downloads>`
   * :option:`save-cookies <--save-cookies>`
   * :option:`save-session <--save-session>`
   * :option:`server-stat-of <--server-stat-of>`
@@ -3497,11 +3565,41 @@ RPC-метод `system.multicall` обрабатывается особым об
     >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
     >>> mc = xmlrpclib.MultiCall(s)
     >>> mc.aria2.addUri(['http://example.org/file'])
-    >>> mc.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent').read()))
+    >>> mc.aria2.addTorrent(xmlrpclib.Binary(open('file.torrent', mode='rb').read()))
     >>> r = mc()
     >>> tuple(r)
     ('2089b05ecca3d829', 'd2703803b52216d1')
 
+.. function:: system.listMethods()
+
+  Этот метод возвращает все доступные RPC-методы в массиве строк.
+  В отличие от других методов, этот метод не требует секретный маркер.
+  Это безопасно, потому что этот метод просто возвращает названия доступных
+  методов.
+
+  **Пример JSON-RPC**
+  ::
+
+    >>> import urllib2, json
+    >>> from pprint import pprint
+    >>> jsonreq = json.dumps({'jsonrpc':'2.0', 'id':'qwer',
+    ...                       'method':'system.listMethods'})
+    >>> c = urllib2.urlopen('http://localhost:6800/jsonrpc', jsonreq)
+    >>> pprint(json.loads(c.read()))
+    {u'id': u'qwer',
+     u'jsonrpc': u'2.0',
+     u'result': [u'aria2.addUri',
+                 u'aria2.addTorrent',
+    ...
+
+  **Пример XML-RPC**
+  ::
+
+    >>> import xmlrpclib
+    >>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
+    >>> s.system.listMethods()
+    ['aria2.addUri', 'aria2.addTorrent', ...
+
 Обработка ошибок
 ~~~~~~~~~~~~~~~~
 
@@ -4265,7 +4363,7 @@ RPC
 
 СМОТРИТЕ ТАКЖЕ
 --------------
-Веб-сайт проекта: http://aria2.sourceforge.net/
+Веб-сайт проекта: https://aria2.github.io/
 
 Домашняя страница Metalink: http://www.metalinker.org/
 
@@ -4273,7 +4371,7 @@ RPC
 
 АВТОРСКОЕ ПРАВО
 ---------------
-Авторское право (C) 2006, 2014 Tatsuhiro Tsujikawa
+Авторское право (C) 2006, 2015 Tatsuhiro Tsujikawa
 
 Эта программа является свободным программным обеспечением; вы можете
 распространять его и/или изменять его в соответствии с условиями лицензии

+ 1 - 1
doc/sphinx_themes/sphinx_rtd_theme/__init__.py

@@ -5,7 +5,7 @@ From https://github.com/ryan-roemer/sphinx-bootstrap-theme.
 """
 import os
 
-VERSION = (0, 1, 8)
+VERSION = (0, 1, 9)
 
 __version__ = ".".join(str(v) for v in VERSION)
 __version_full__ = __version__

+ 21 - 13
doc/sphinx_themes/sphinx_rtd_theme/breadcrumbs.html

@@ -1,23 +1,31 @@
+{# Support for Sphinx 1.3+ page_source_suffix, but don't break old builds. #}
+
+{% if page_source_suffix %} 
+{% set suffix = page_source_suffix %}
+{% else %}
+{% set suffix = source_suffix %}
+{% endif %}
+
 <div role="navigation" aria-label="breadcrumbs navigation">
   <ul class="wy-breadcrumbs">
     <li><a href="{{ pathto(master_doc) }}">Docs</a> &raquo;</li>
       {% for doc in parents %}
-          <li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
+        <li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
       {% endfor %}
     <li>{{ title }}</li>
-      <li class="wy-breadcrumbs-aside">
-        {% if pagename != "search" %}
-          {% if display_github %}
-            <a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ source_suffix }}" class="fa fa-github"> Edit on GitHub</a>
-          {% elif display_bitbucket %}
-            <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ source_suffix }}" class="fa fa-bitbucket"> Edit on Bitbucket</a>
-          {% elif show_source and source_url_prefix %}
-            <a href="{{ source_url_prefix }}{{ pagename }}{{ source_suffix }}">View page source</a>
-          {% elif show_source and has_source and sourcename %}
-            <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
-          {% endif %}
+    <li class="wy-breadcrumbs-aside">
+      {% if pagename != "search" %}
+        {% if display_github %}
+          <a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-github"> Edit on GitHub</a>
+        {% elif display_bitbucket %}
+          <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ suffix }}" class="fa fa-bitbucket"> Edit on Bitbucket</a>
+        {% elif show_source and source_url_prefix %}
+          <a href="{{ source_url_prefix }}{{ pagename }}{{ suffix }}">View page source</a>
+        {% elif show_source and has_source and sourcename %}
+          <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
         {% endif %}
-      </li>
+      {% endif %}
+    </li>
   </ul>
   <hr/>
 </div>

+ 17 - 1
doc/sphinx_themes/sphinx_rtd_theme/footer.html

@@ -22,9 +22,23 @@
       {%- endif %}
     {%- endif %}
 
-    {%- if last_updated %}
+    {%- if build_id and build_url %}
+      {% trans build_url=build_url, build_id=build_id %}
+        <span class="build">
+          Build
+          <a href="{{ build_url }}">{{ build_id }}</a>.
+        </span>
+      {% endtrans %}
+    {%- elif commit %}
+      {% trans commit=commit %}
+        <span class="commit">
+          Revision <code>{{ commit }}</code>.
+        </span>
+      {% endtrans %}
+    {%- elif last_updated %}
       {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
     {%- endif %}
+
     </p>
   </div>
 
@@ -32,5 +46,7 @@
   {% trans %}Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}.
   {%- endif %}
 
+  {%- block extrafooter %} {% endblock %}
+
 </footer>
 

+ 43 - 28
doc/sphinx_themes/sphinx_rtd_theme/layout.html

@@ -75,7 +75,7 @@
   {%- block extrahead %} {% endblock %}
 
   {# Keep modernizr in head - http://modernizr.com/docs/#installing #}
-  <script src="_static/js/modernizr.min.js"></script>
+  <script src="{{ pathto('_static/js/modernizr.min.js', 1) }}"></script>
 
 </head>
 
@@ -85,38 +85,51 @@
 
     {# SIDE NAV, TOGGLES ON MOBILE #}
     <nav data-toggle="wy-nav-shift" class="wy-nav-side">
-      <div class="wy-side-nav-search">
-        {% block sidebartitle %}
+      <div class="wy-side-scroll">
+        <div class="wy-side-nav-search">
+          {% block sidebartitle %}
 
-        {% if logo and theme_logo_only %}
-          <a href="{{ pathto(master_doc) }}">
-        {% else %}
-          <a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}
-        {% endif %}
+          {% if logo and theme_logo_only %}
+            <a href="{{ pathto(master_doc) }}">
+          {% else %}
+            <a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}
+          {% endif %}
 
-        {% if logo %}
-          {# Not strictly valid HTML, but it's the only way to display/scale it properly, without weird scripting or heaps of work #}
-          <img src="{{ pathto('_static/' + logo, 1) }}" class="logo" />
-        {% endif %}
-        </a>
+          {% if logo %}
+            {# Not strictly valid HTML, but it's the only way to display/scale it properly, without weird scripting or heaps of work #}
+            <img src="{{ pathto('_static/' + logo, 1) }}" class="logo" />
+          {% endif %}
+          </a>
+
+          {% if theme_display_version %}
+            {%- set nav_version = version %}
+            {% if READTHEDOCS and current_version %}
+              {%- set nav_version = current_version %}
+            {% endif %}
+            {% if nav_version %}
+              <div class="version">
+                {{ nav_version }}
+              </div>
+            {% endif %}
+          {% endif %}
 
-        {% include "searchbox.html" %}
+          {% include "searchbox.html" %}
 
-        {% endblock %}
-      </div>
+          {% endblock %}
+        </div>
 
-      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
-        {% block menu %}
-          {% set toctree = toctree(maxdepth=4, collapse=False, includehidden=True) %}
-          {% if toctree %}
-              {{ toctree }}
-          {% else %}
-              <!-- Local TOC -->
-              <div class="local-toc">{{ toc }}</div>
-          {% endif %}
-        {% endblock %}
+        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+          {% block menu %}
+            {% set toctree = toctree(maxdepth=4, collapse=theme_collapse_navigation, includehidden=True) %}
+            {% if toctree %}
+                {{ toctree }}
+            {% else %}
+                <!-- Local TOC -->
+                <div class="local-toc">{{ toc }}</div>
+            {% endif %}
+          {% endblock %}
+        </div>
       </div>
-      &nbsp;
     </nav>
 
     <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
@@ -132,8 +145,10 @@
       <div class="wy-nav-content">
         <div class="rst-content">
           {% include "breadcrumbs.html" %}
-          <div role="main" class="document">
+          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
+           <div itemprop="articleBody">
             {% block body %}{% endblock %}
+           </div>
           </div>
           {% include "footer.html" %}
         </div>

File diff suppressed because it is too large
+ 0 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/css/badge_only.css.map


File diff suppressed because it is too large
+ 0 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css


File diff suppressed because it is too large
+ 0 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css.map


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Regular.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot


File diff suppressed because it is too large
+ 22 - 21
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff


+ 150 - 107
doc/sphinx_themes/sphinx_rtd_theme/static/js/theme.js

@@ -1,113 +1,156 @@
-function toggleCurrent (elem) {
-    var parent_li = elem.closest('li');
-    parent_li.siblings('li.current').removeClass('current');
-    parent_li.siblings().find('li.current').removeClass('current');
-    parent_li.find('> ul li.current').removeClass('current');
-    parent_li.toggleClass('current');
-}
+require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"sphinx-rtd-theme":[function(require,module,exports){
+var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');
 
-$(document).ready(function() {
-    // Shift nav in mobile when clicking the menu.
-    $(document).on('click', "[data-toggle='wy-nav-top']", function() {
-        $("[data-toggle='wy-nav-shift']").toggleClass("shift");
-        $("[data-toggle='rst-versions']").toggleClass("shift");
-    });
-    // Nav menu link click operations
-    $(document).on('click', ".wy-menu-vertical .current ul li a", function() {
-        var target = $(this);
-        // Close menu when you click a link.
-        $("[data-toggle='wy-nav-shift']").removeClass("shift");
-        $("[data-toggle='rst-versions']").toggleClass("shift");
-        // Handle dynamic display of l3 and l4 nav lists
-        toggleCurrent(target);
-        if (typeof(window.SphinxRtdTheme) != 'undefined') {
-            window.SphinxRtdTheme.StickyNav.hashChange();
-        }
-    });
-    $(document).on('click', "[data-toggle='rst-current-version']", function() {
-        $("[data-toggle='rst-versions']").toggleClass("shift-up");
-    });
-    // Make tables responsive
-    $("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
-
-    // Add expand links to all parents of nested ul
-    $('.wy-menu-vertical ul').siblings('a').each(function () {
-        var link = $(this);
-            expand = $('<span class="toctree-expand"></span>');
-        expand.on('click', function (ev) {
-            toggleCurrent(link);
-            ev.stopPropagation();
-            return false;
-        });
-        link.prepend(expand);
-    });
-});
-
-// Sphinx theme state
-window.SphinxRtdTheme = (function (jquery) {
-    var stickyNav = (function () {
-        var navBar,
-            win,
-            winScroll = false,
-            linkScroll = false,
-            winPosition = 0,
-            enable = function () {
-                init();
-                reset();
-                win.on('hashchange', reset);
-
-                // Set scrolling
-                win.on('scroll', function () {
-                    if (!linkScroll) {
-                        winScroll = true;
+// Sphinx theme nav state
+function ThemeNav () {
+
+    var nav = {
+        navBar: null,
+        win: null,
+        winScroll: false,
+        winResize: false,
+        linkScroll: false,
+        winPosition: 0,
+        winHeight: null,
+        docHeight: null,
+        isRunning: false
+    };
+
+    nav.enable = function () {
+        var self = this;
+
+        if (!self.isRunning) {
+            self.isRunning = true;
+            jQuery(function ($) {
+                self.init($);
+
+                self.reset();
+                self.win.on('hashchange', self.reset);
+
+                // Set scroll monitor
+                self.win.on('scroll', function () {
+                    if (!self.linkScroll) {
+                        self.winScroll = true;
                     }
                 });
-                setInterval(function () {
-                    if (winScroll) {
-                        winScroll = false;
-                        var newWinPosition = win.scrollTop(),
-                            navPosition = navBar.scrollTop(),
-                            newNavPosition = navPosition + (newWinPosition - winPosition);
-                        navBar.scrollTop(newNavPosition);
-                        winPosition = newWinPosition;
-                    }
-                }, 25);
-            },
-            init = function () {
-                navBar = jquery('nav.wy-nav-side:first');
-                win = jquery(window);
-            },
-            reset = function () {
-                // Get anchor from URL and open up nested nav
-                var anchor = encodeURI(window.location.hash);
-                if (anchor) {
-                    try {
-                        var link = $('.wy-menu-vertical')
-                            .find('[href="' + anchor + '"]');
-                        $('.wy-menu-vertical li.toctree-l1 li.current')
-                            .removeClass('current');
-                        link.closest('li.toctree-l2').addClass('current');
-                        link.closest('li.toctree-l3').addClass('current');
-                        link.closest('li.toctree-l4').addClass('current');
-                    }
-                    catch (err) {
-                        console.log("Error expanding nav for anchor", err);
-                    }
-                }
-            },
-            hashChange = function () {
-                linkScroll = true;
-                win.one('hashchange', function () {
-                    linkScroll = false;
+                setInterval(function () { if (self.winScroll) self.onScroll(); }, 25);
+
+                // Set resize monitor
+                self.win.on('resize', function () {
+                    self.winResize = true;
                 });
-            };
-        jquery(init);
-        return {
-            enable: enable,
-            hashChange: hashChange
+                setInterval(function () { if (self.winResize) self.onResize(); }, 25);
+                self.onResize();
+            });
         };
-    }());
-    return {
-        StickyNav: stickyNav
     };
-}($));
+
+    nav.init = function ($) {
+        var doc = $(document),
+            self = this;
+
+        this.navBar = $('div.wy-side-scroll:first');
+        this.win = $(window);
+
+        // Set up javascript UX bits
+        $(document)
+            // Shift nav in mobile when clicking the menu.
+            .on('click', "[data-toggle='wy-nav-top']", function() {
+                $("[data-toggle='wy-nav-shift']").toggleClass("shift");
+                $("[data-toggle='rst-versions']").toggleClass("shift");
+            })
+
+            // Nav menu link click operations
+            .on('click', ".wy-menu-vertical .current ul li a", function() {
+                var target = $(this);
+                // Close menu when you click a link.
+                $("[data-toggle='wy-nav-shift']").removeClass("shift");
+                $("[data-toggle='rst-versions']").toggleClass("shift");
+                // Handle dynamic display of l3 and l4 nav lists
+                self.toggleCurrent(target);
+                self.hashChange();
+            })
+            .on('click', "[data-toggle='rst-current-version']", function() {
+                $("[data-toggle='rst-versions']").toggleClass("shift-up");
+            })
+
+        // Make tables responsive
+        $("table.docutils:not(.field-list)")
+            .wrap("<div class='wy-table-responsive'></div>");
+
+        // Add expand links to all parents of nested ul
+        $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
+            var link = $(this);
+                expand = $('<span class="toctree-expand"></span>');
+            expand.on('click', function (ev) {
+                self.toggleCurrent(link);
+                ev.stopPropagation();
+                return false;
+            });
+            link.prepend(expand);
+        });
+    };
+
+    nav.reset = function () {
+        // Get anchor from URL and open up nested nav
+        var anchor = encodeURI(window.location.hash);
+        if (anchor) {
+            try {
+                var link = $('.wy-menu-vertical')
+                    .find('[href="' + anchor + '"]');
+                $('.wy-menu-vertical li.toctree-l1 li.current')
+                    .removeClass('current');
+                link.closest('li.toctree-l2').addClass('current');
+                link.closest('li.toctree-l3').addClass('current');
+                link.closest('li.toctree-l4').addClass('current');
+            }
+            catch (err) {
+                console.log("Error expanding nav for anchor", err);
+            }
+        }
+    };
+
+    nav.onScroll = function () {
+        this.winScroll = false;
+        var newWinPosition = this.win.scrollTop(),
+            winBottom = newWinPosition + this.winHeight,
+            navPosition = this.navBar.scrollTop(),
+            newNavPosition = navPosition + (newWinPosition - this.winPosition);
+        if (newWinPosition < 0 || winBottom > this.docHeight) {
+            return;
+        }
+        this.navBar.scrollTop(newNavPosition);
+        this.winPosition = newWinPosition;
+    };
+
+    nav.onResize = function () {
+        this.winResize = false;
+        this.winHeight = this.win.height();
+        this.docHeight = $(document).height();
+    };
+
+    nav.hashChange = function () {
+        this.linkScroll = true;
+        this.win.one('hashchange', function () {
+            this.linkScroll = false;
+        });
+    };
+
+    nav.toggleCurrent = function (elem) {
+        var parent_li = elem.closest('li');
+        parent_li.siblings('li.current').removeClass('current');
+        parent_li.siblings().find('li.current').removeClass('current');
+        parent_li.find('> ul li.current').removeClass('current');
+        parent_li.toggleClass('current');
+    }
+
+    return nav;
+};
+
+module.exports.ThemeNav = ThemeNav();
+
+if (typeof(window) != 'undefined') {
+    window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };
+}
+
+},{"jquery":"jquery"}]},{},["sphinx-rtd-theme"]);

+ 2 - 0
doc/sphinx_themes/sphinx_rtd_theme/theme.conf

@@ -7,3 +7,5 @@ typekit_id = hiw1hhg
 analytics_id = 
 sticky_navigation = False
 logo_only =
+collapse_navigation = False
+display_version = True

+ 1 - 1
doc/xmlrpc/README.txt

@@ -1,3 +1,3 @@
 This directory contains sample scripts to interact with aria2 via
 XML-RPC. For more information, see
-http://sourceforge.net/apps/trac/aria2/wiki/XmlrpcInterface
+https://aria2.github.io/manual/en/html/aria2c.html#rpc-interface

+ 27 - 26
examples/libaria2ex.cc

@@ -43,7 +43,7 @@
 int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
                           aria2::A2Gid gid, void* userData)
 {
-  switch(event) {
+  switch (event) {
   case aria2::EVENT_ON_DOWNLOAD_COMPLETE:
     std::cerr << "COMPLETE";
     break;
@@ -55,15 +55,17 @@ int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
   }
   std::cerr << " [" << aria2::gidToHex(gid) << "] ";
   aria2::DownloadHandle* dh = aria2::getDownloadHandle(session, gid);
-  if(!dh) return 0;
-  if(dh->getNumFiles() > 0) {
+  if (!dh)
+    return 0;
+  if (dh->getNumFiles() > 0) {
     aria2::FileData f = dh->getFile(1);
     // Path may be empty if the file name has not been determined yet.
-    if(f.path.empty()) {
-      if(!f.uris.empty()) {
+    if (f.path.empty()) {
+      if (!f.uris.empty()) {
         std::cerr << f.uris[0].uri;
       }
-    } else {
+    }
+    else {
       std::cerr << f.path;
     }
   }
@@ -75,7 +77,7 @@ int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
 int main(int argc, char** argv)
 {
   int rv;
-  if(argc < 2) {
+  if (argc < 2) {
     std::cerr << "Usage: libaria2ex URI [URI...]\n"
               << "\n"
               << "  Download given URIs in parallel in the current directory."
@@ -92,46 +94,45 @@ int main(int argc, char** argv)
   config.downloadEventCallback = downloadEventCallback;
   session = aria2::sessionNew(aria2::KeyVals(), config);
   // Add download item to session
-  for(int i = 1; i < argc; ++i) {
+  for (int i = 1; i < argc; ++i) {
     std::vector<std::string> uris = {argv[i]};
     aria2::KeyVals options;
     rv = aria2::addUri(session, nullptr, uris, options);
-    if(rv < 0) {
+    if (rv < 0) {
       std::cerr << "Failed to add download " << uris[0] << std::endl;
     }
   }
   auto start = std::chrono::steady_clock::now();
-  for(;;) {
+  for (;;) {
     rv = aria2::run(session, aria2::RUN_ONCE);
-    if(rv != 1) {
+    if (rv != 1) {
       break;
     }
     // the application can call aria2 API to add URI or query progress
     // here
     auto now = std::chrono::steady_clock::now();
-    auto count = std::chrono::duration_cast<std::chrono::milliseconds>
-      (now - start).count();
+    auto count = std::chrono::duration_cast<std::chrono::milliseconds>(
+                     now - start).count();
     // Print progress information once per 500ms
-    if(count >= 500) {
+    if (count >= 500) {
       start = now;
       aria2::GlobalStat gstat = aria2::getGlobalStat(session);
       std::cerr << "Overall #Active:" << gstat.numActive
                 << " #waiting:" << gstat.numWaiting
-                << " D:" << gstat.downloadSpeed/1024 << "KiB/s"
-                << " U:"<< gstat.uploadSpeed/1024 << "KiB/s " << std::endl;
+                << " D:" << gstat.downloadSpeed / 1024 << "KiB/s"
+                << " U:" << gstat.uploadSpeed / 1024 << "KiB/s " << std::endl;
       std::vector<aria2::A2Gid> gids = aria2::getActiveDownload(session);
-      for(const auto& gid : gids) {
+      for (const auto& gid : gids) {
         aria2::DownloadHandle* dh = aria2::getDownloadHandle(session, gid);
-        if(dh) {
+        if (dh) {
           std::cerr << "    [" << aria2::gidToHex(gid) << "] "
-                    << dh->getCompletedLength() << "/"
-                    << dh->getTotalLength() << "("
-                    << (dh->getTotalLength() > 0 ?
-                        (100*dh->getCompletedLength()/dh->getTotalLength())
-                        : 0) << "%)"
-                    << " D:"
-                    << dh->getDownloadSpeed()/1024 << "KiB/s, U:"
-                    << dh->getUploadSpeed()/1024 << "KiB/s"
+                    << dh->getCompletedLength() << "/" << dh->getTotalLength()
+                    << "(" << (dh->getTotalLength() > 0
+                                   ? (100 * dh->getCompletedLength() /
+                                      dh->getTotalLength())
+                                   : 0) << "%)"
+                    << " D:" << dh->getDownloadSpeed() / 1024
+                    << "KiB/s, U:" << dh->getUploadSpeed() / 1024 << "KiB/s"
                     << std::endl;
           aria2::deleteDownloadHandle(dh);
         }

+ 77 - 101
examples/libaria2wx.cc

@@ -38,7 +38,8 @@
 // the main window.
 //
 // Compile and link like this:
-// $ g++ -O2 -Wall -g -std=c++11 `wx-config --cflags` -o libaria2wx libaria2wx.cc `wx-config --libs` -laria2 -pthread
+// $ g++ -O2 -Wall -g -std=c++11 `wx-config --cflags` -o libaria2wx
+// libaria2wx.cc `wx-config --libs` -laria2 -pthread
 #include <iostream>
 #include <chrono>
 #include <thread>
@@ -51,7 +52,7 @@
 
 // Interface to send message to downloader thread from UI thread
 struct Job {
-  virtual ~Job() {};
+  virtual ~Job(){};
   virtual void execute(aria2::Session* session) = 0;
 };
 
@@ -59,15 +60,14 @@ class MainFrame;
 
 // Interface to report back to UI thread from downloader thread
 struct Notification {
-  virtual ~Notification() {};
+  virtual ~Notification(){};
   virtual void notify(MainFrame* frame) = 0;
 };
 
 // std::queue<T> wrapper synchronized by mutex. In this example
 // program, only one thread consumes from the queue, so separating
 // empty() and pop() is not a problem.
-template<typename T>
-class SynchronizedQueue {
+template <typename T> class SynchronizedQueue {
 public:
   SynchronizedQueue() {}
   ~SynchronizedQueue() {}
@@ -88,8 +88,9 @@ public:
     std::lock_guard<std::mutex> l(m_);
     return q_.empty();
   }
+
 private:
-  std::queue<std::unique_ptr<T> > q_;
+  std::queue<std::unique_ptr<T>> q_;
   std::mutex m_;
 };
 
@@ -109,8 +110,9 @@ struct ShutdownJob : public Job {
 // Job to send URI to download and options to downloader thread
 struct AddUriJob : public Job {
   AddUriJob(std::vector<std::string>&& uris, aria2::KeyVals&& options)
-    : uris(uris), options(options)
-  {}
+      : uris(uris), options(options)
+  {
+  }
   virtual void execute(aria2::Session* session)
   {
     // TODO check return value
@@ -148,6 +150,7 @@ public:
   void OnTimer(wxTimerEvent& event);
   void OnAddUri(wxCommandEvent& event);
   void UpdateActiveStatus(const std::vector<DownloadStatus>& v);
+
 private:
   wxTextCtrl* text_;
   wxTimer timer_;
@@ -157,13 +160,9 @@ private:
   DECLARE_EVENT_TABLE()
 };
 
-enum {
-  TIMER_ID = 1
-};
+enum { TIMER_ID = 1 };
 
-enum {
-  MI_ADD_URI = 1
-};
+enum { MI_ADD_URI = 1 };
 
 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
 EVT_CLOSE(MainFrame::OnCloseWindow)
@@ -177,6 +176,7 @@ public:
   void OnButton(wxCommandEvent& event);
   wxString GetUri();
   wxString GetOption();
+
 private:
   wxTextCtrl* uriText_;
   wxTextCtrl* optionText_;
@@ -193,7 +193,8 @@ IMPLEMENT_APP(Aria2App)
 
 bool Aria2App::OnInit()
 {
-  if(!wxApp::OnInit()) return false;
+  if (!wxApp::OnInit())
+    return false;
   aria2::libraryInit();
   MainFrame* frame = new MainFrame(wxT("libaria2 GUI example"));
   frame->Show(true);
@@ -207,14 +208,12 @@ int Aria2App::OnExit()
 }
 
 MainFrame::MainFrame(const wxString& title)
-  : wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition,
-            wxSize(640, 400)),
-    timer_(this, TIMER_ID),
-    downloaderThread_(downloaderJob, std::ref(jobq_), std::ref(notifyq_))
+    : wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxSize(640, 400)),
+      timer_(this, TIMER_ID),
+      downloaderThread_(downloaderJob, std::ref(jobq_), std::ref(notifyq_))
 {
   wxMenu* downloadMenu = new wxMenu;
-  downloadMenu->Append(MI_ADD_URI, wxT("&Add URI"),
-                       wxT("Add URI to download"));
+  downloadMenu->Append(MI_ADD_URI, wxT("&Add URI"), wxT("Add URI to download"));
 
   wxMenuBar* menuBar = new wxMenuBar();
   menuBar->Append(downloadMenu, wxT("&Download"));
@@ -237,35 +236,36 @@ void MainFrame::OnAddUri(wxCommandEvent& WXUNUSED(event))
 {
   AddUriDialog dlg(this);
   int ret = dlg.ShowModal();
-  if(ret == 0) {
-    if(dlg.GetUri().IsEmpty()) {
+  if (ret == 0) {
+    if (dlg.GetUri().IsEmpty()) {
       return;
     }
-    std::vector<std::string> uris = { std::string(dlg.GetUri().mb_str()) };
+    std::vector<std::string> uris = {std::string(dlg.GetUri().mb_str())};
     std::string optstr(dlg.GetOption().mb_str());
     aria2::KeyVals options;
     int keyfirst = 0;
-    for(int i = 0; i < (int)optstr.size(); ++i) {
-      if(optstr[i] == '\n') {
-        keyfirst = i+1;
-      } else if(optstr[i] == '=') {
+    for (int i = 0; i < (int)optstr.size(); ++i) {
+      if (optstr[i] == '\n') {
+        keyfirst = i + 1;
+      }
+      else if (optstr[i] == '=') {
         int j;
-        for(j = i+1; j < (int)optstr.size(); ++j) {
-          if(optstr[j] == '\n') {
+        for (j = i + 1; j < (int)optstr.size(); ++j) {
+          if (optstr[j] == '\n') {
             break;
           }
         }
-        if(i - keyfirst > 0) {
-          options.push_back
-            (std::make_pair(optstr.substr(keyfirst, i - keyfirst),
-                            optstr.substr(i + 1, j - i - 1)));
+        if (i - keyfirst > 0) {
+          options.push_back(
+              std::make_pair(optstr.substr(keyfirst, i - keyfirst),
+                             optstr.substr(i + 1, j - i - 1)));
         }
         keyfirst = j + 1;
         i = j;
       }
     }
-    jobq_.push(std::unique_ptr<Job>(new AddUriJob(std::move(uris),
-                                                  std::move(options))));
+    jobq_.push(std::unique_ptr<Job>(
+        new AddUriJob(std::move(uris), std::move(options))));
   }
 }
 
@@ -281,56 +281,47 @@ void MainFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
 
 void MainFrame::OnTimer(wxTimerEvent& event)
 {
-  while(!notifyq_.empty()) {
+  while (!notifyq_.empty()) {
     std::unique_ptr<Notification> nt = notifyq_.pop();
     nt->notify(this);
   }
 }
 
-template<typename T>
-std::string abbrevsize(T size)
+template <typename T> std::string abbrevsize(T size)
 {
-  if(size >= 1024*1024*1024) {
-    return std::to_string(size/1024/1024/1024)+"G";
-  } else if(size >= 1024*1024) {
-    return std::to_string(size/1024/1024)+"M";
-  } else if(size >= 1024) {
-    return std::to_string(size/1024)+"K";
-  } else {
+  if (size >= 1024 * 1024 * 1024) {
+    return std::to_string(size / 1024 / 1024 / 1024) + "G";
+  }
+  else if (size >= 1024 * 1024) {
+    return std::to_string(size / 1024 / 1024) + "M";
+  }
+  else if (size >= 1024) {
+    return std::to_string(size / 1024) + "K";
+  }
+  else {
     return std::to_string(size);
   }
 }
 
-wxString towxs(const std::string& s)
-{
-  return wxString(s.c_str(), wxConvUTF8);
-}
+wxString towxs(const std::string& s) { return wxString(s.c_str(), wxConvUTF8); }
 
 void MainFrame::UpdateActiveStatus(const std::vector<DownloadStatus>& v)
 {
   text_->Clear();
-  for(auto& a : v) {
-    *text_ << wxT("[")
-           << towxs(aria2::gidToHex(a.gid))
-           << wxT("] ")
-           << towxs(abbrevsize(a.completedLength))
-           << wxT("/")
-           << towxs(abbrevsize(a.totalLength))
-           << wxT("(")
-           << (a.totalLength != 0 ? a.completedLength*100/a.totalLength : 0)
-           << wxT("%)")
-           << wxT(" D:")
-           << towxs(abbrevsize(a.downloadSpeed))
-           << wxT(" U:")
-           << towxs(abbrevsize(a.uploadSpeed))
-           << wxT("\n")
+  for (auto& a : v) {
+    *text_ << wxT("[") << towxs(aria2::gidToHex(a.gid)) << wxT("] ")
+           << towxs(abbrevsize(a.completedLength)) << wxT("/")
+           << towxs(abbrevsize(a.totalLength)) << wxT("(")
+           << (a.totalLength != 0 ? a.completedLength * 100 / a.totalLength : 0)
+           << wxT("%)") << wxT(" D:") << towxs(abbrevsize(a.downloadSpeed))
+           << wxT(" U:") << towxs(abbrevsize(a.uploadSpeed)) << wxT("\n")
            << wxT("File:") << towxs(a.filename) << wxT("\n");
   }
 }
 
 AddUriDialog::AddUriDialog(wxWindow* parent)
-  : wxDialog(parent, wxID_ANY, wxT("Add URI"), wxDefaultPosition,
-             wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
+    : wxDialog(parent, wxID_ANY, wxT("Add URI"), wxDefaultPosition,
+               wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
 {
   wxPanel* panel = new wxPanel(this, wxID_ANY);
   wxBoxSizer* box = new wxBoxSizer(wxVERTICAL);
@@ -339,9 +330,8 @@ AddUriDialog::AddUriDialog(wxWindow* parent)
   uriText_ = new wxTextCtrl(panel, wxID_ANY);
   box->Add(uriText_, wxSizerFlags().Align(wxGROW));
   // Option multi text input
-  box->Add(new wxStaticText
-           (panel, wxID_ANY,
-            wxT("Options (key=value pair per line, e.g. dir=/tmp")));
+  box->Add(new wxStaticText(
+      panel, wxID_ANY, wxT("Options (key=value pair per line, e.g. dir=/tmp")));
   optionText_ = new wxTextCtrl(panel, wxID_ANY, wxT(""), wxDefaultPosition,
                                wxDefaultSize, wxTE_MULTILINE);
   box->Add(optionText_, wxSizerFlags().Align(wxGROW));
@@ -363,38 +353,25 @@ AddUriDialog::AddUriDialog(wxWindow* parent)
 void AddUriDialog::OnButton(wxCommandEvent& event)
 {
   int ret = -1;
-  if(event.GetEventObject() == okBtn_) {
+  if (event.GetEventObject() == okBtn_) {
     ret = 0;
   }
   EndModal(ret);
 }
 
-wxString AddUriDialog::GetUri()
-{
-  return uriText_->GetValue();
-}
+wxString AddUriDialog::GetUri() { return uriText_->GetValue(); }
 
-wxString AddUriDialog::GetOption()
-{
-  return optionText_->GetValue();
-}
+wxString AddUriDialog::GetOption() { return optionText_->GetValue(); }
 
 struct DownloadStatusNotification : public Notification {
-  DownloadStatusNotification(std::vector<DownloadStatus>&& v)
-    : v(v) {}
-  virtual void notify(MainFrame* frame)
-  {
-    frame->UpdateActiveStatus(v);
-  }
+  DownloadStatusNotification(std::vector<DownloadStatus>&& v) : v(v) {}
+  virtual void notify(MainFrame* frame) { frame->UpdateActiveStatus(v); }
   std::vector<DownloadStatus> v;
 };
 
 struct ShutdownNotification : public Notification {
   ShutdownNotification() {}
-  virtual void notify(MainFrame* frame)
-  {
-    frame->Close();
-  }
+  virtual void notify(MainFrame* frame) { frame->Close(); }
 };
 
 int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
@@ -406,32 +383,32 @@ int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
   config.keepRunning = true;
   session = aria2::sessionNew(aria2::KeyVals(), config);
   auto start = std::chrono::steady_clock::now();
-  for(;;) {
+  for (;;) {
     int rv = aria2::run(session, aria2::RUN_ONCE);
-    if(rv != 1) {
+    if (rv != 1) {
       break;
     }
     auto now = std::chrono::steady_clock::now();
-    auto count = std::chrono::duration_cast<std::chrono::milliseconds>
-      (now - start).count();
-    while(!jobq.empty()) {
+    auto count = std::chrono::duration_cast<std::chrono::milliseconds>(
+                     now - start).count();
+    while (!jobq.empty()) {
       std::unique_ptr<Job> job = jobq.pop();
       job->execute(session);
     }
-    if(count >= 900) {
+    if (count >= 900) {
       start = now;
       std::vector<aria2::A2Gid> gids = aria2::getActiveDownload(session);
       std::vector<DownloadStatus> v;
-      for(auto gid : gids) {
+      for (auto gid : gids) {
         aria2::DownloadHandle* dh = aria2::getDownloadHandle(session, gid);
-        if(dh) {
+        if (dh) {
           DownloadStatus st;
           st.gid = gid;
           st.totalLength = dh->getTotalLength();
           st.completedLength = dh->getCompletedLength();
           st.downloadSpeed = dh->getDownloadSpeed();
           st.uploadSpeed = dh->getUploadSpeed();
-          if(dh->getNumFiles() > 0) {
+          if (dh->getNumFiles() > 0) {
             aria2::FileData file = dh->getFile(1);
             st.filename = file.path;
           }
@@ -439,8 +416,8 @@ int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
           aria2::deleteDownloadHandle(dh);
         }
       }
-      notifyq.push(std::unique_ptr<Notification>
-                   (new DownloadStatusNotification(std::move(v))));
+      notifyq.push(std::unique_ptr<Notification>(
+          new DownloadStatusNotification(std::move(v))));
     }
   }
   int rv = aria2::sessionFinal(session);
@@ -449,4 +426,3 @@ int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
   notifyq.push(std::unique_ptr<Notification>(new ShutdownNotification()));
   return rv;
 }
-

+ 74 - 0
m4/ax_check_compile_flag.m4

@@ -0,0 +1,74 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's compiler
+#   or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <[email protected]>
+#   Copyright (c) 2011 Maarten Bosmans <[email protected]>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 4
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS

+ 2 - 0
m4/libexpat.m4

@@ -9,6 +9,8 @@ if test "x$have_libexpat" = "xyes"; then
     AC_DEFINE([HAVE_LIBEXPAT], [1], [Define to 1 if you have libexpat.])
     EXPAT_LIBS=-lexpat
     EXPAT_CFLAGS=
+    AC_SUBST([EXPAT_LIBS])
+    AC_SUBST([EXPAT_CFLAGS])
 fi
 
 LIBS=$LIBS_save

+ 54 - 104
makerelease-osx.mk

@@ -32,9 +32,6 @@
 #  - $ ln -s ../makerelease-os.mk Makefile
 #  - $ make
 #
-# To make an universal build (x86_64, i686) use instead:
-#  - $ make universal
-#
 # To make an both builds use instead:
 #  - $ make multi
 #
@@ -91,14 +88,14 @@ endif
 # Set up compiler.
 CC = cc
 export CC
-CXX = c++
+CXX = c++ -stdlib=libc++
 export CXX
 
 # Set up compiler/linker flags.
 OPTFLAGS ?= -Os
-CFLAGS ?= -mmacosx-version-min=10.7 $(OPTFLAGS)
+CFLAGS ?= -mmacosx-version-min=10.10 $(OPTFLAGS)
 export CFLAGS
-CXXFLAGS ?= -mmacosx-version-min=10.7 $(OPTFLAGS)
+CXXFLAGS ?= -mmacosx-version-min=10.10 $(OPTFLAGS)
 export CXXFLAGS
 LDFLAGS ?= -Wl,-dead_strip
 export LDFLAGS
@@ -116,32 +113,51 @@ expat_url = http://sourceforge.net/projects/expat/files/expat/$(expat_version)/e
 expat_cflags=$(LTO_FLAGS)
 expat_ldflags=$(CFLAGS) $(LTO_FLAGS)
 
-cares_version = 1.10.0
-cares_hash = e44e6575d5af99cb3a38461486e1ee8b49810eb5
+cares_version = 1.11.0
+cares_hash = 8c20b2680099ac73861a780c731edd59e010383a
 cares_url = http://c-ares.haxx.se/download/c-ares-$(cares_version).tar.gz
 cares_confflags = "--enable-optimize=$(OPTFLAGS)"
 cares_cflags=$(LTO_FLAGS)
 cares_ldflags=$(CFLAGS) $(LTO_FLAGS)
 
-sqlite_version = autoconf-3081002
-sqlite_hash = c2f2c17d3dc4c4e179d35cc04e4420636d48a152
-sqlite_url = http://sqlite.org/2015/sqlite-$(sqlite_version).tar.gz
+sqlite_version = autoconf-3110000
+sqlite_hash = e2d300e4b24af5ecd67a1396488893fa44864e36
+sqlite_url = http://sqlite.org/2016/sqlite-$(sqlite_version).tar.gz
 sqlite_cflags=$(LTO_FLAGS)
 sqlite_ldflags=$(CFLAGS) $(LTO_FLAGS)
 
-gmp_version = 5.1.3
-gmp_hash = b35928e2927b272711fdfbf71b7cfd5f86a6b165
+gmp_version = 6.1.0
+gmp_hash = db38c7b67f8eea9f2e5b8a48d219165b2fdab11f
 gmp_url = https://ftp.gnu.org/gnu/gmp/gmp-$(gmp_version).tar.bz2
 gmp_confflags = --disable-cxx --enable-assembly --with-pic
 gmp_confflags_x86_64 = --enable-fat
 
+libgpgerror_version = 1.21
+libgpgerror_hash = ef1dfb2f8761f019091180596e9e638d8cc37513
+libgpgerror_url = https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-$(libgpgerror_version).tar.bz2
+libgpgerror_cflags=$(LTO_FLAGS)
+libgpgerror_ldflags=$(CFLAGS) $(LTO_FLAGS)
+libgpgerror_confflags = --with-pic --disable-languages --disable-doc --disable-nls
+
+libgcrypt_version = 1.6.5
+libgcrypt_hash = c3a5a13e717f7b3e3895650afc1b6e0d3fe9c726
+libgcrypt_url = https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-$(libgcrypt_version).tar.bz2
+libgcrypt_confflags=--with-gpg-error-prefix=$(PWD)/arch
+
+libssh2_version = 1.7.0
+libssh2_hash = 02fef9bdafce3da466b36581a4ff53d519637aca
+libssh2_url = https://www.libssh2.org/download/libssh2-$(libssh2_version).tar.gz
+libssh2_cflags=$(LTO_FLAGS)
+libssh2_ldflags=$(CFLAGS) $(LTO_FLAGS)
+libssh2_confflags = --with-pic --with-libgcrypt --with-libgcrypt-prefix=$(PWD)/arch
+
 cppunit_version = 1.12.1
 cppunit_hash = f1ab8986af7a1ffa6760f4bacf5622924639bf4a
 cppunit_url = http://sourceforge.net/projects/cppunit/files/cppunit/$(cppunit_version)/cppunit-$(cppunit_version).tar.gz
 
 
 # ARCHLIBS that can be template build
-ARCHLIBS = expat cares sqlite gmp cppunit
+ARCHLIBS = expat cares sqlite gmp libgpgerror libgcrypt libssh2 cppunit
 # NONARCHLIBS that cannot be template build
 NONARCHLIBS = zlib
 
@@ -167,11 +183,12 @@ ARIA2_CONFFLAGS = \
         --with-libz \
         --with-libexpat \
         --with-libcares \
+        --with-libgcrypt \
+        --with-libssh2 \
         --without-libuv \
         --without-gnutls \
         --without-openssl \
         --without-libnettle \
-        --without-libgcrypt \
         --without-libxml2 \
         ARIA2_STATIC=yes
 ARIA2_DOCDIR = $(ARIA2_PREFIX)/share/doc/aria2
@@ -223,14 +240,14 @@ CPUS = $(shell sysctl hw.ncpu | cut -d" " -f2)
 # default target
 all::
 
-universal all::
+all::
 	@if test "x$(NON_RELEASE)" = "x" && !(git describe --tags --exact); then \
 		echo 'Not on a release tag; override by defining NON_RELEASE!'; \
 		exit 1; \
 	fi
 
 # No dice without sphinx
-universal all::
+all::
 	@if test "x$$(which sphinx-build)" = "x"; then \
 		echo "sphinx-build not present"; \
 		exit 1; \
@@ -263,20 +280,23 @@ deps::
 
 .PRECIOUS: cares.stamp
 cares.stamp: cares.tar.gz cares.check
-	tar xzf $<
+	tar xf $<
 	mv c-ares-$($(basename $@)_version) $(basename $@)
 	touch $@
 
+.PRECIOUS: libgpgerror.stamp
+libgpgerror.stamp: libgpgerror.tar.gz libgpgerror.check
+	tar xf $<
+	mv libgpg-error-$($(basename $@)_version) $(basename $@)
+	touch $@
+
 # Using (NON)ARCH_template kinda stinks, but real multi-target pattern rules
 # only exist in feverish dreams.
 define NONARCH_template
 $(1).build: $(1).x86_64.build
 
-$(1).universal.build: $(1).x86_64.build $(1).i686.build
-
 deps:: $(1).build
 
-deps.universal:: $(1).universal.build
 endef
 
 .PRECIOUS: zlib.%.build
@@ -286,7 +306,7 @@ zlib.%.build: zlib.stamp
 	$(eval ARCH := $(subst .,,$(suffix $(DEST))))
 	rsync -a $(BASE)/ $(DEST)
 	( cd $(DEST) && ./configure \
-		--static --prefix=$(PWD)/$(ARCH) \
+		--static --prefix=$(PWD)/arch \
 		)
 	$(MAKE) -C $(DEST) -sj$(CPUS) CFLAGS="$(CFLAGS) $(LTO_FLAGS) -arch $(ARCH)"
 	$(MAKE) -C $(DEST) -sj$(CPUS) CFLAGS="$(CFLAGS) $(LTO_FLAGS) -arch $(ARCH)" check
@@ -302,14 +322,13 @@ $(1).%.build: $(1).stamp
 	$$(eval ARCH := $$(subst .,,$$(suffix $$(DEST))))
 	mkdir -p $$(DEST)
 	( cd $$(DEST) && ../$(1)/configure \
-		--host=$$(ARCH)-apple-darwin11.4.2 \
-		--build=$$(ARCH)-apple-darwin11.4.2 \
 		--enable-static --disable-shared \
-		--prefix=$$(PWD)/$$(ARCH) \
-		$$($(1)_confflags) $$($(1)_confflags_$$(ARCH)) \
+		--prefix=$(PWD)/arch \
+		$$($(1)_confflags) \
 		CFLAGS="$$(CFLAGS) $$($(1)_cflags) -arch $$(ARCH)" \
-		CXXFLAGS="$$(CXXFLAGS) $$($(1)_cxxflags) -arch $$(ARCH) -stdlib=libc++ -std=c++11" \
+		CXXFLAGS="$$(CXXFLAGS) $$($(1)_cxxflags) -arch $$(ARCH) -std=c++11" \
 		LDFLAGS="$(LDFLAGS) $$($(1)_ldflags)" \
+		PKG_CONFIG_PATH=$$(PWD)/arch/lib/pkgconfig \
 		)
 	$$(MAKE) -C $$(DEST) -sj$(CPUS)
 	$$(MAKE) -C $$(DEST) -sj$(CPUS) check
@@ -318,17 +337,14 @@ $(1).%.build: $(1).stamp
 
 $(1).build: $(1).x86_64.build
 
-$(1).universal.build: $(1).x86_64.build $(1).i686.build
-
 deps:: $(1).build
 
-deps.universal:: $(1).universal.build
 endef
 
 $(foreach lib,$(ARCHLIBS),$(eval $(call ARCH_template,$(lib))))
 
 .PRECIOUS: aria2.%.build
-aria2.%.build: zlib.%.build expat.%.build gmp.%.build cares.%.build sqlite.%.build cppunit.%.build
+aria2.%.build: zlib.%.build expat.%.build gmp.%.build cares.%.build sqlite.%.build libgpgerror.%.build libgcrypt.%.build libssh2.%.build cppunit.%.build
 	$(eval DEST := $$(basename $$@))
 	$(eval ARCH := $$(subst .,,$$(suffix $$(DEST))))
 	mkdir -p $(DEST)
@@ -336,12 +352,12 @@ aria2.%.build: zlib.%.build expat.%.build gmp.%.build cares.%.build sqlite.%.bui
 		--prefix=$(ARIA2_PREFIX) \
 		--bindir=$(PWD)/$(DEST) \
 		--sysconfdir=/etc \
-		--with-cppunit-prefix=$(PWD)/$(ARCH) \
+		--with-cppunit-prefix=$(PWD)/arch \
 		$(ARIA2_CONFFLAGS) \
-		CFLAGS="$(CFLAGS) $(LTO_FLAGS) -arch $(ARCH) -I$(PWD)/$(ARCH)/include" \
-		CXXFLAGS="$(CXXFLAGS) $(LTO_FLAGS) -arch $(ARCH) -I$(PWD)/$(ARCH)/include" \
-		LDFLAGS="$(LDFLAGS) $(CXXFLAGS) $(LTO_FLAGS) -L$(PWD)/$(ARCH)/lib" \
-		PKG_CONFIG_PATH=$(PWD)/$(ARCH)/lib/pkgconfig \
+		CFLAGS="$(CFLAGS) $(LTO_FLAGS) -arch $(ARCH) -I$(PWD)/arch/include" \
+		CXXFLAGS="$(CXXFLAGS) $(LTO_FLAGS) -arch $(ARCH) -I$(PWD)/arch/include" \
+		LDFLAGS="$(LDFLAGS) $(CXXFLAGS) $(LTO_FLAGS) -L$(PWD)/arch/lib" \
+		PKG_CONFIG_PATH=$(PWD)/arch/lib/pkgconfig \
 		)
 	$(MAKE) -C $(DEST) -sj$(CPUS)
 	$(MAKE) -C $(DEST) -sj$(CPUS) check
@@ -356,19 +372,6 @@ aria2.build: aria2.x86_64.build
 	arch -64 $(ARIA2_PREFIX)/bin/aria2c -v
 	touch $@
 
-aria2.universal.build: aria2.x86_64.build aria2.i686.build
-	mkdir -p $(ARIA2_PREFIX)/bin
-	# Got two binaries now. Merge them into one universal binary and remove
-	# the old ones.
-	lipo \
-		-arch x86_64 aria2.x86_64/aria2c \
-		-arch i686 aria2.i686/aria2c \
-		-create -output $(ARIA2_PREFIX)/bin/aria2c
-	# Basic sanity check
-	arch -64 $(ARIA2_PREFIX)/bin/aria2c -v
-	arch -32 $(ARIA2_PREFIX)/bin/aria2c -v
-	touch $@
-
 $(ARIA2_CHANGELOG): aria2.x86_64.build
 	git log --pretty=fuller --date=short $(PREV_TAG)..HEAD > $@
 
@@ -382,13 +385,6 @@ $(ARIA2_DIST).tar.bz2: aria2.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
 		--options='compression-level=9' \
 		$(ARIA2)
 
-$(ARIA2_DIST).universal.tar.bz2: aria2.universal.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
-	find $(ARIA2_PREFIX) -exec touch "{}" \;
-	tar -cf $@ \
-		--use-compress-program=bzip2 \
-		--options='compression-level=9' \
-		$(ARIA2)
-
 $(ARIA2_DIST).pkg: aria2.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
 	find $(ARIA2_PREFIX) -exec touch "{}" \;
 	pkgbuild \
@@ -412,29 +408,6 @@ $(ARIA2_DIST).pkg: aria2.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
 		$@
 	rm -rf out.pkg paths.pkg dist.xml
 
-$(ARIA2_DIST).universal.pkg: aria2.universal.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
-	find $(ARIA2_PREFIX) -exec touch "{}" \;
-	pkgbuild \
-		--root $(ARIA2) \
-		--identifier aria2 \
-		--version $(VERSION) \
-		--install-location /usr/local/aria2 \
-		--ownership recommended \
-		out.pkg
-	pkgbuild \
-		--root $(SRCDIR)/osx-package/etc \
-		--identifier aria2.paths \
-		--version $(VERSION) \
-		--install-location /etc \
-		--ownership recommended \
-		paths.pkg
-	echo "$$ARIA2_DISTXML" > dist.xml
-	productbuild \
-		--distribution dist.xml \
-		--resources $(ARIA2_PREFIX)/share/doc/aria2 \
-		$@
-	rm -rf out.pkg paths.pkg dist.xml
-
 $(ARIA2_DIST).dmg: $(ARIA2_DIST).pkg
 	-rm -rf dmg
 	mkdir -p dmg/Docs
@@ -450,35 +423,12 @@ $(ARIA2_DIST).dmg: $(ARIA2_DIST).pkg
 	hdiutil flatten $@
 	rm -rf [email protected] dmg
 
-$(ARIA2_DIST).universal.dmg: $(ARIA2_DIST).universal.pkg
-	-rm -rf dmg
-	mkdir -p dmg/Docs
-	cp -av $(ARIA2_DIST).universal.pkg dmg/aria2.pkg
-	find $(ARIA2_PREFIX)/share/doc/aria2 -type f -depth 1 -exec cp -av "{}" dmg/Docs \;
-	rm -rf dmg/Docs/README dmg/Docs/README.rst
-	cp $(SRCDIR)/osx-package/DS_Store dmg/.DS_Store
-	hdiutil create [email protected] \
-		-srcfolder dmg \
-		-volname "aria2 $(VERSION) Intel Universal" \
-		-ov
-	hdiutil convert -format UDBZ -o $@ [email protected]
-	hdiutil flatten $@
-	rm -rf [email protected] dmg
-
 dist.build: $(ARIA2_DIST).tar.bz2 $(ARIA2_DIST).pkg $(ARIA2_DIST).dmg
 	echo 'Build success: $(ARIA2_DIST)'
 	touch $@
 
-dist.universal.build: $(ARIA2_DIST).universal.tar.bz2 $(ARIA2_DIST).universal.pkg $(ARIA2_DIST).universal.dmg
-	echo 'Build success: $(ARIA2_DIST)'
-	touch $@
-
 all:: dist.build
 
-universal:: dist.universal.build
-
-multi: all universal
-
 clean-dist:
 	rm -rf $(ARIA2_DIST).tar.bz2 $(ARIA2_DIST).pkg $(ARIA2_DIST).dmg
 
@@ -486,10 +436,10 @@ clean: clean-dist
 	rm -rf *aria2*
 
 cleaner: clean
-	rm -rf *.build *.check *.stamp $(ARCHLIBS) $(NONARCHLIBS) *x86_64* *i686*
+	rm -rf *.build *.check *.stamp $(ARCHLIBS) $(NONARCHLIBS) arch
 
 really-clean: cleaner
 	rm -rf *.tar.*
 
 
-.PHONY: all universal multi clean-dist clean cleaner really-clean
+.PHONY: all multi clean-dist clean cleaner really-clean

+ 1 - 1
po/Makevars

@@ -34,7 +34,7 @@ COPYRIGHT_HOLDER = Tatsuhiro Tsujikawa
 # It can be your email address, or a mailing list address where translators
 # can write to without being subscribed, or the URL of a web page through
 # which the translators can contact you.
-MSGID_BUGS_ADDRESS = http://aria2.sourceforge.net/
+MSGID_BUGS_ADDRESS = https://aria2.github.io/
 
 # This is the list of locale categories, beyond LC_MESSAGES, for which the
 # message catalogs shall be used.  It is usually empty.

+ 4 - 4
src/ARC4Encryptor.h

@@ -38,13 +38,13 @@
 #include "common.h"
 
 #ifdef USE_INTERNAL_ARC4
-# include "InternalARC4Encryptor.h"
+#include "InternalARC4Encryptor.h"
 #elif HAVE_LIBNETTLE
-# include "LibnettleARC4Encryptor.h"
+#include "LibnettleARC4Encryptor.h"
 #elif HAVE_LIBGCRYPT
-# include "LibgcryptARC4Encryptor.h"
+#include "LibgcryptARC4Encryptor.h"
 #elif HAVE_OPENSSL
-# include "LibsslARC4Encryptor.h"
+#include "LibsslARC4Encryptor.h"
 #endif
 
 #endif // D_ARC4_ENCRYPTOR_H

+ 4 - 4
src/AbstractAuthResolver.cc

@@ -42,8 +42,8 @@ AbstractAuthResolver::AbstractAuthResolver() {}
 
 AbstractAuthResolver::~AbstractAuthResolver() {}
 
-void AbstractAuthResolver::setUserDefinedCred
-(std::string user, std::string password)
+void AbstractAuthResolver::setUserDefinedCred(std::string user,
+                                              std::string password)
 {
   userDefinedUser_ = std::move(user);
   userDefinedPassword_ = std::move(password);
@@ -55,8 +55,8 @@ AbstractAuthResolver::getUserDefinedAuthConfig() const
   return AuthConfig::create(userDefinedUser_, userDefinedPassword_);
 }
 
-void AbstractAuthResolver::setDefaultCred
-(std::string user, std::string password)
+void AbstractAuthResolver::setDefaultCred(std::string user,
+                                          std::string password)
 {
   defaultUser_ = std::move(user);
   defaultPassword_ = std::move(password);

+ 1 - 0
src/AbstractAuthResolver.h

@@ -52,6 +52,7 @@ public:
   void setDefaultCred(std::string user, std::string password);
 
   std::unique_ptr<AuthConfig> getDefaultAuthConfig() const;
+
 private:
   std::string userDefinedUser_;
   std::string userDefinedPassword_;

+ 16 - 16
src/AbstractBtMessage.cc

@@ -40,18 +40,19 @@
 namespace aria2 {
 
 AbstractBtMessage::AbstractBtMessage(uint8_t id, const char* name)
-  : BtMessage(id),
-    invalidate_(false),
-    uploading_(false),
-    cuid_(0),
-    name_(name),
-    pieceStorage_(nullptr),
-    dispatcher_(nullptr),
-    messageFactory_(nullptr),
-    requestFactory_(nullptr),
-    peerConnection_(nullptr),
-    metadataGetMode_(false)
-{}
+    : BtMessage(id),
+      invalidate_(false),
+      uploading_(false),
+      cuid_(0),
+      name_(name),
+      pieceStorage_(nullptr),
+      dispatcher_(nullptr),
+      messageFactory_(nullptr),
+      requestFactory_(nullptr),
+      peerConnection_(nullptr),
+      metadataGetMode_(false)
+{
+}
 
 AbstractBtMessage::~AbstractBtMessage() {}
 
@@ -62,14 +63,13 @@ void AbstractBtMessage::setPeer(const std::shared_ptr<Peer>& peer)
 
 void AbstractBtMessage::validate()
 {
-  if(validator_) {
+  if (validator_) {
     validator_->validate();
   }
 }
 
-void
-AbstractBtMessage::setBtMessageValidator
-(std::unique_ptr<BtMessageValidator> validator)
+void AbstractBtMessage::setBtMessageValidator(
+    std::unique_ptr<BtMessageValidator> validator)
 {
   validator_ = std::move(validator);
 }

+ 25 - 58
src/AbstractBtMessage.h

@@ -71,69 +71,38 @@ private:
   std::unique_ptr<BtMessageValidator> validator_;
 
   bool metadataGetMode_;
+
 protected:
-  PieceStorage* getPieceStorage() const
-  {
-    return pieceStorage_;
-  }
+  PieceStorage* getPieceStorage() const { return pieceStorage_; }
 
-  PeerConnection* getPeerConnection() const
-  {
-    return peerConnection_;
-  }
+  PeerConnection* getPeerConnection() const { return peerConnection_; }
 
-  BtMessageDispatcher* getBtMessageDispatcher() const
-  {
-    return dispatcher_;
-  }
+  BtMessageDispatcher* getBtMessageDispatcher() const { return dispatcher_; }
 
-  BtRequestFactory* getBtRequestFactory() const
-  {
-    return requestFactory_;
-  }
+  BtRequestFactory* getBtRequestFactory() const { return requestFactory_; }
 
-  BtMessageFactory* getBtMessageFactory() const
-  {
-    return messageFactory_;
-  }
+  BtMessageFactory* getBtMessageFactory() const { return messageFactory_; }
+
+  bool isMetadataGetMode() const { return metadataGetMode_; }
 
-  bool isMetadataGetMode() const
-  {
-    return metadataGetMode_;
-  }
 public:
   AbstractBtMessage(uint8_t id, const char* name);
 
   virtual ~AbstractBtMessage();
 
-  virtual bool isInvalidate() CXX11_OVERRIDE {
-    return invalidate_;
-  }
+  virtual bool isInvalidate() CXX11_OVERRIDE { return invalidate_; }
 
-  void setInvalidate(bool invalidate) {
-    invalidate_ = invalidate;
-  }
+  void setInvalidate(bool invalidate) { invalidate_ = invalidate; }
 
-  virtual bool isUploading() CXX11_OVERRIDE {
-    return uploading_;
-  }
+  virtual bool isUploading() CXX11_OVERRIDE { return uploading_; }
 
-  void setUploading(bool uploading) {
-    uploading_ = uploading;
-  }
+  void setUploading(bool uploading) { uploading_ = uploading; }
 
-  cuid_t getCuid() const {
-    return cuid_;
-  }
+  cuid_t getCuid() const { return cuid_; }
 
-  void setCuid(cuid_t cuid) {
-    cuid_ = cuid;
-  }
+  void setCuid(cuid_t cuid) { cuid_ = cuid; }
 
-  const std::shared_ptr<Peer>& getPeer() const
-  {
-    return peer_;
-  }
+  const std::shared_ptr<Peer>& getPeer() const { return peer_; }
 
   void setPeer(const std::shared_ptr<Peer>& peer);
 
@@ -143,11 +112,15 @@ public:
 
   virtual void onQueued() CXX11_OVERRIDE {}
 
-  virtual void onAbortOutstandingRequestEvent
-  (const BtAbortOutstandingRequestEvent& event) CXX11_OVERRIDE {}
+  virtual void onAbortOutstandingRequestEvent(
+      const BtAbortOutstandingRequestEvent& event) CXX11_OVERRIDE
+  {
+  }
 
-  virtual void onCancelSendingPieceEvent
-  (const BtCancelSendingPieceEvent& event) CXX11_OVERRIDE {}
+  virtual void onCancelSendingPieceEvent(const BtCancelSendingPieceEvent& event)
+      CXX11_OVERRIDE
+  {
+  }
 
   virtual void onChokingEvent(const BtChokingEvent& event) CXX11_OVERRIDE {}
 
@@ -163,15 +136,9 @@ public:
 
   void setBtRequestFactory(BtRequestFactory* factory);
 
-  const char* getName() const
-  {
-    return name_;
-  }
+  const char* getName() const { return name_; }
 
-  void enableMetadataGetMode()
-  {
-    metadataGetMode_ = true;
-  }
+  void enableMetadataGetMode() { metadataGetMode_ = true; }
 };
 
 } // namespace aria2

+ 104 - 125
src/AbstractCommand.cc

@@ -74,31 +74,28 @@
 
 namespace aria2 {
 
-AbstractCommand::AbstractCommand
-(cuid_t cuid,
- const std::shared_ptr<Request>& req,
- const std::shared_ptr<FileEntry>& fileEntry,
- RequestGroup* requestGroup,
- DownloadEngine* e,
- const std::shared_ptr<SocketCore>& s,
- const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer,
- bool incNumConnection)
-  : Command(cuid),
-    req_(req),
-    fileEntry_(fileEntry),
-    socket_(s),
-    socketRecvBuffer_(socketRecvBuffer),
+AbstractCommand::AbstractCommand(
+    cuid_t cuid, const std::shared_ptr<Request>& req,
+    const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
+    DownloadEngine* e, const std::shared_ptr<SocketCore>& s,
+    const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer,
+    bool incNumConnection)
+    : Command(cuid),
+      req_(req),
+      fileEntry_(fileEntry),
+      socket_(s),
+      socketRecvBuffer_(socketRecvBuffer),
 #ifdef ENABLE_ASYNC_DNS
-    asyncNameResolverMan_(make_unique<AsyncNameResolverMan>()),
+      asyncNameResolverMan_(make_unique<AsyncNameResolverMan>()),
 #endif // ENABLE_ASYNC_DNS
-    requestGroup_(requestGroup),
-    e_(e),
-    checkPoint_(global::wallclock()),
-    serverStatTimer_(global::wallclock()),
-    timeout_(requestGroup->getTimeout()),
-    checkSocketIsReadable_(false),
-    checkSocketIsWritable_(false),
-    incNumConnection_(incNumConnection)
+      requestGroup_(requestGroup),
+      e_(e),
+      checkPoint_(global::wallclock()),
+      serverStatTimer_(global::wallclock()),
+      timeout_(requestGroup->getTimeout()),
+      checkSocketIsReadable_(false),
+      checkSocketIsWritable_(false),
+      incNumConnection_(incNumConnection)
 {
   if (socket_ && socket_->isOpen()) {
     setReadCheckSocket(socket_);
@@ -127,19 +124,18 @@ AbstractCommand::~AbstractCommand()
   }
 }
 
-void
-AbstractCommand::useFasterRequest(const std::shared_ptr<Request>& fasterRequest)
+void AbstractCommand::useFasterRequest(
+    const std::shared_ptr<Request>& fasterRequest)
 {
   A2_LOG_INFO(fmt("CUID#%" PRId64 " - Use faster Request hostname=%s, port=%u",
-                  getCuid(),
-                  fasterRequest->getHost().c_str(),
+                  getCuid(), fasterRequest->getHost().c_str(),
                   fasterRequest->getPort()));
   // Cancel current Request object and use faster one.
   fileEntry_->removeRequest(req_);
   e_->setNoWait(true);
-  e_->addCommand
-    (InitiateConnectionCommandFactory::createInitiateConnectionCommand
-     (getCuid(), fasterRequest, fileEntry_, requestGroup_, e_));
+  e_->addCommand(
+      InitiateConnectionCommandFactory::createInitiateConnectionCommand(
+          getCuid(), fasterRequest, fileEntry_, requestGroup_, e_));
 }
 
 bool AbstractCommand::shouldProcess() const
@@ -152,6 +148,10 @@ bool AbstractCommand::shouldProcess() const
     if (socketRecvBuffer_ && !socketRecvBuffer_->bufferEmpty()) {
       return true;
     }
+
+    if (socket_ && socket_->getRecvBufferedLength()) {
+      return true;
+    }
   }
 
   if (checkSocketIsWritable_ && writeEventEnabled()) {
@@ -167,7 +167,7 @@ bool AbstractCommand::shouldProcess() const
   if (!checkSocketIsReadable_ && !checkSocketIsWritable_ && !resolverChecked) {
     return true;
   }
-#else // ENABLE_ASYNC_DNS
+#else  // ENABLE_ASYNC_DNS
   if (!checkSocketIsReadable_ && !checkSocketIsWritable_) {
     return true;
   }
@@ -180,11 +180,8 @@ bool AbstractCommand::execute()
 {
   A2_LOG_DEBUG(fmt("CUID#%" PRId64
                    " - socket: read:%d, write:%d, hup:%d, err:%d",
-                   getCuid(),
-                   readEventEnabled(),
-                   writeEventEnabled(),
-                   hupEventEnabled(),
-                   errorEventEnabled()));
+                   getCuid(), readEventEnabled(), writeEventEnabled(),
+                   hupEventEnabled(), errorEventEnabled()));
   try {
     if (requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
       return true;
@@ -194,8 +191,7 @@ bool AbstractCommand::execute()
       A2_LOG_DEBUG(fmt("CUID#%" PRId64
                        " - Discard original URI=%s because it is"
                        " requested.",
-                       getCuid(),
-                       req_->getUri().c_str()));
+                       getCuid(), req_->getUri().c_str()));
       return prepareForRetry(0);
     }
 
@@ -243,8 +239,8 @@ bool AbstractCommand::execute()
         if (getOption()->getAsBool(PREF_SELECT_LEAST_USED_HOST)) {
           getDownloadEngine()->getRequestGroupMan()->getUsedHosts(usedHosts);
         }
-        auto fasterRequest = fileEntry_->findFasterRequest
-          (req_, usedHosts, e_->getRequestGroupMan()->getServerStatMan());
+        auto fasterRequest = fileEntry_->findFasterRequest(
+            req_, usedHosts, e_->getRequestGroupMan()->getServerStatMan());
         if (fasterRequest) {
           useFasterRequest(fasterRequest);
           return true;
@@ -296,8 +292,8 @@ bool AbstractCommand::execute()
         size_t minSplitSize = calculateMinSplitSize();
         size_t maxSegments = req_->getMaxPipelinedRequest();
         if (segments_.size() < maxSegments) {
-          sm->getSegment
-            (segments_, getCuid(), minSplitSize, fileEntry_, maxSegments);
+          sm->getSegment(segments_, getCuid(), minSplitSize, fileEntry_,
+                         maxSegments);
         }
         if (segments_.empty()) {
           return prepareForRetry(0);
@@ -308,22 +304,21 @@ bool AbstractCommand::execute()
     }
 
     if (errorEventEnabled()) {
-      throw DL_RETRY_EX
-        (fmt(MSG_NETWORK_PROBLEM, socket_->getSocketError().c_str()));
+      throw DL_RETRY_EX(
+          fmt(MSG_NETWORK_PROBLEM, socket_->getSocketError().c_str()));
     }
 
     if (checkPoint_.difference(global::wallclock()) >= timeout_) {
       // timeout triggers ServerStat error state.
-      auto ss = e_->getRequestGroupMan()->getOrCreateServerStat
-        (req_->getHost(), req_->getProtocol());
+      auto ss = e_->getRequestGroupMan()->getOrCreateServerStat(
+          req_->getHost(), req_->getProtocol());
       ss->setError();
       // When DNS query was timeout, req_->getConnectedAddr() is
       // empty.
       if (!req_->getConnectedAddr().empty()) {
         // Purging IP address cache to renew IP address.
         A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Marking IP address %s as bad",
-                         getCuid(),
-                         req_->getConnectedAddr().c_str()));
+                         getCuid(), req_->getConnectedAddr().c_str()));
         e_->markBadIPAddress(req_->getConnectedHostname(),
                              req_->getConnectedAddr(),
                              req_->getConnectedPort());
@@ -343,11 +338,11 @@ bool AbstractCommand::execute()
     return false;
   }
   catch (DlAbortEx& err) {
-    requestGroup_->setLastErrorCode(err.getErrorCode());
+    requestGroup_->setLastErrorCode(err.getErrorCode(), err.what());
     if (req_) {
-      A2_LOG_ERROR_EX
-        (fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
-         DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
+      A2_LOG_ERROR_EX(
+          fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
+          DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
       fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
       if (err.getErrorCode() == error_code::CANNOT_RESUME) {
         requestGroup_->increaseResumeFailureCount();
@@ -362,9 +357,9 @@ bool AbstractCommand::execute()
   }
   catch (DlRetryEx& err) {
     assert(req_);
-    A2_LOG_INFO_EX
-      (fmt(MSG_RESTARTING_DOWNLOAD, getCuid(), req_->getUri().c_str()),
-       DL_RETRY_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
+    A2_LOG_INFO_EX(
+        fmt(MSG_RESTARTING_DOWNLOAD, getCuid(), req_->getUri().c_str()),
+        DL_RETRY_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
     req_->addTryCount();
     req_->resetRedirectCount();
     req_->resetUri();
@@ -373,10 +368,10 @@ bool AbstractCommand::execute()
     bool isAbort = maxTries != 0 && req_->getTryCount() >= maxTries;
     if (isAbort) {
       A2_LOG_INFO(fmt(MSG_MAX_TRY, getCuid(), req_->getTryCount()));
-      A2_LOG_ERROR_EX
-        (fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), err);
+      A2_LOG_ERROR_EX(
+          fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), err);
       fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
-      requestGroup_->setLastErrorCode(err.getErrorCode());
+      requestGroup_->setLastErrorCode(err.getErrorCode(), err.what());
       if (err.getErrorCode() == error_code::CANNOT_RESUME) {
         requestGroup_->increaseResumeFailureCount();
       }
@@ -392,13 +387,14 @@ bool AbstractCommand::execute()
     return prepareForRetry(0);
   }
   catch (DownloadFailureException& err) {
-    requestGroup_->setLastErrorCode(err.getErrorCode());
+    requestGroup_->setLastErrorCode(err.getErrorCode(), err.what());
     if (req_) {
-      A2_LOG_ERROR_EX
-        (fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
-         DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
+      A2_LOG_ERROR_EX(
+          fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
+          DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
       fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
-    } else {
+    }
+    else {
       A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, err);
     }
     requestGroup_->setHaltRequested(true);
@@ -422,8 +418,8 @@ void AbstractCommand::tryReserved()
       return;
     }
   }
-  A2_LOG_DEBUG
-    (fmt("CUID#%" PRId64 " - Trying reserved/pooled request.", getCuid()));
+  A2_LOG_DEBUG(
+      fmt("CUID#%" PRId64 " - Trying reserved/pooled request.", getCuid()));
   std::vector<std::unique_ptr<Command>> commands;
   requestGroup_->createNextCommand(commands, e_, 1);
   e_->setNoWait(true);
@@ -443,8 +439,7 @@ bool AbstractCommand::prepareForRetry(time_t wait)
     req_->setMaxPipelinedRequest(1);
 
     fileEntry_->poolRequest(req_);
-    A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Pooling request URI=%s",
-                     getCuid(),
+    A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Pooling request URI=%s", getCuid(),
                      req_->getUri().c_str()));
     if (getSegmentMan()) {
       getSegmentMan()->recognizeSegmentFor(fileEntry_);
@@ -518,8 +513,7 @@ void AbstractCommand::onAbort()
   uris.reserve(res.size());
   std::transform(std::begin(res), std::end(res), std::back_inserter(uris),
                  std::mem_fn(&URIResult::getURI));
-  A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - %lu URIs found.",
-                   getCuid(),
+  A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - %lu URIs found.", getCuid(),
                    static_cast<unsigned long int>(uris.size())));
   fileEntry_->addUris(std::begin(uris), std::end(uris));
   getSegmentMan()->recognizeSegmentFor(fileEntry_);
@@ -536,8 +530,8 @@ void AbstractCommand::disableReadCheckSocket()
   readCheckTarget_.reset();
 }
 
-void
-AbstractCommand::setReadCheckSocket(const std::shared_ptr<SocketCore>& socket)
+void AbstractCommand::setReadCheckSocket(
+    const std::shared_ptr<SocketCore>& socket)
 {
   if (!socket->isOpen()) {
     disableReadCheckSocket();
@@ -558,9 +552,8 @@ AbstractCommand::setReadCheckSocket(const std::shared_ptr<SocketCore>& socket)
   readCheckTarget_ = socket;
 }
 
-void
-AbstractCommand::setReadCheckSocketIf(const std::shared_ptr<SocketCore>& socket,
-                                      bool pred)
+void AbstractCommand::setReadCheckSocketIf(
+    const std::shared_ptr<SocketCore>& socket, bool pred)
 {
   if (pred) {
     setReadCheckSocket(socket);
@@ -580,8 +573,8 @@ void AbstractCommand::disableWriteCheckSocket()
   writeCheckTarget_.reset();
 }
 
-void
-AbstractCommand::setWriteCheckSocket(const std::shared_ptr<SocketCore>& socket)
+void AbstractCommand::setWriteCheckSocket(
+    const std::shared_ptr<SocketCore>& socket)
 {
   if (!socket->isOpen()) {
     disableWriteCheckSocket();
@@ -602,8 +595,8 @@ AbstractCommand::setWriteCheckSocket(const std::shared_ptr<SocketCore>& socket)
   writeCheckTarget_ = socket;
 }
 
-void AbstractCommand::setWriteCheckSocketIf
-(const std::shared_ptr<SocketCore>& socket, bool pred)
+void AbstractCommand::setWriteCheckSocketIf(
+    const std::shared_ptr<SocketCore>& socket, bool pred)
 {
   if (pred) {
     setWriteCheckSocket(socket);
@@ -623,10 +616,8 @@ void AbstractCommand::swapSocket(std::shared_ptr<SocketCore>& socket)
 namespace {
 // Constructs proxy URI, merging username and password if they are
 // defined.
-std::string makeProxyUri(PrefPtr proxyPref,
-                         PrefPtr proxyUser,
-                         PrefPtr proxyPasswd,
-                         const Option* option)
+std::string makeProxyUri(PrefPtr proxyPref, PrefPtr proxyUser,
+                         PrefPtr proxyPasswd, const Option* option)
 {
   uri::UriStruct us;
   if (!uri::parse(us, option->get(proxyPref))) {
@@ -645,15 +636,13 @@ std::string makeProxyUri(PrefPtr proxyPref,
 
 namespace {
 // Returns proxy option value for the given protocol.
-std::string getProxyOptionFor(PrefPtr proxyPref,
-                              PrefPtr proxyUser,
-                              PrefPtr proxyPasswd,
-                              const Option* option)
+std::string getProxyOptionFor(PrefPtr proxyPref, PrefPtr proxyUser,
+                              PrefPtr proxyPasswd, const Option* option)
 {
   std::string uri = makeProxyUri(proxyPref, proxyUser, proxyPasswd, option);
   if (uri.empty()) {
-    return makeProxyUri
-      (PREF_ALL_PROXY, PREF_ALL_PROXY_USER, PREF_ALL_PROXY_PASSWD, option);
+    return makeProxyUri(PREF_ALL_PROXY, PREF_ALL_PROXY_USER,
+                        PREF_ALL_PROXY_PASSWD, option);
   }
 
   return uri;
@@ -665,20 +654,18 @@ std::string getProxyOptionFor(PrefPtr proxyPref,
 std::string getProxyUri(const std::string& protocol, const Option* option)
 {
   if (protocol == "http") {
-    return getProxyOptionFor
-      (PREF_HTTP_PROXY, PREF_HTTP_PROXY_USER, PREF_HTTP_PROXY_PASSWD, option);
+    return getProxyOptionFor(PREF_HTTP_PROXY, PREF_HTTP_PROXY_USER,
+                             PREF_HTTP_PROXY_PASSWD, option);
   }
 
   if (protocol == "https") {
-    return getProxyOptionFor(PREF_HTTPS_PROXY,
-                             PREF_HTTPS_PROXY_USER,
-                             PREF_HTTPS_PROXY_PASSWD,
-                             option);
+    return getProxyOptionFor(PREF_HTTPS_PROXY, PREF_HTTPS_PROXY_USER,
+                             PREF_HTTPS_PROXY_PASSWD, option);
   }
 
   if (protocol == "ftp" || protocol == "sftp") {
-    return getProxyOptionFor
-      (PREF_FTP_PROXY, PREF_FTP_PROXY_USER, PREF_FTP_PROXY_PASSWD, option);
+    return getProxyOptionFor(PREF_FTP_PROXY, PREF_FTP_PROXY_USER,
+                             PREF_FTP_PROXY_PASSWD, option);
   }
 
   return A2STR::NIL;
@@ -752,8 +739,8 @@ std::shared_ptr<Request> AbstractCommand::createProxyRequest() const
       A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Using proxy", getCuid()));
     }
     else {
-      A2_LOG_DEBUG
-        (fmt("CUID#%" PRId64 " - Failed to parse proxy string", getCuid()));
+      A2_LOG_DEBUG(
+          fmt("CUID#%" PRId64 " - Failed to parse proxy string", getCuid()));
       proxyRequest.reset();
     }
   }
@@ -790,8 +777,7 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
             ->getOrCreateServerStat(req_->getHost(), req_->getProtocol())
             ->setError();
       }
-      throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED,
-                             getCuid(),
+      throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(),
                              hostname.c_str(),
                              asyncNameResolverMan_->getLastError().c_str()),
                          error_code::NAME_RESOLVE_ERROR);
@@ -801,10 +787,8 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
     case 1:
       asyncNameResolverMan_->getResolvedAddress(addrs);
       if (addrs.empty()) {
-        throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED,
-                               getCuid(),
-                               hostname.c_str(),
-                               "No address returned"),
+        throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(),
+                               hostname.c_str(), "No address returned"),
                            error_code::NAME_RESOLVE_ERROR);
       }
       break;
@@ -829,21 +813,20 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
   return ipaddr;
 }
 
-void AbstractCommand::prepareForNextAction
-(std::unique_ptr<CheckIntegrityEntry> checkEntry)
+void AbstractCommand::prepareForNextAction(
+    std::unique_ptr<CheckIntegrityEntry> checkEntry)
 {
   std::vector<std::unique_ptr<Command>> commands;
-  requestGroup_->processCheckIntegrityEntry
-    (commands, std::move(checkEntry), e_);
+  requestGroup_->processCheckIntegrityEntry(commands, std::move(checkEntry),
+                                            e_);
   e_->addCommand(std::move(commands));
   e_->setNoWait(true);
 }
 
-bool AbstractCommand::checkIfConnectionEstablished
-(const std::shared_ptr<SocketCore>& socket,
- const std::string& connectedHostname,
- const std::string& connectedAddr,
- uint16_t connectedPort)
+bool AbstractCommand::checkIfConnectionEstablished(
+    const std::shared_ptr<SocketCore>& socket,
+    const std::string& connectedHostname, const std::string& connectedAddr,
+    uint16_t connectedPort)
 {
   std::string error = socket->getSocketError();
   if (error.empty()) {
@@ -864,14 +847,12 @@ bool AbstractCommand::checkIfConnectionEstablished
     throw DL_RETRY_EX(fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()));
   }
 
-  A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY,
-                  getCuid(),
-                  connectedAddr.c_str(),
-                  connectedPort));
+  A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY, getCuid(),
+                  connectedAddr.c_str(), connectedPort));
   e_->setNoWait(true);
-  e_->addCommand
-    (InitiateConnectionCommandFactory::createInitiateConnectionCommand
-     (getCuid(), req_, fileEntry_, requestGroup_, e_));
+  e_->addCommand(
+      InitiateConnectionCommandFactory::createInitiateConnectionCommand(
+          getCuid(), req_, fileEntry_, requestGroup_, e_));
   return false;
 }
 
@@ -909,10 +890,7 @@ void AbstractCommand::setRequest(const std::shared_ptr<Request>& request)
   req_ = request;
 }
 
-void AbstractCommand::resetRequest()
-{
-  req_.reset();
-}
+void AbstractCommand::resetRequest() { req_.reset(); }
 
 void AbstractCommand::setFileEntry(const std::shared_ptr<FileEntry>& fileEntry)
 {
@@ -942,7 +920,8 @@ const std::shared_ptr<PieceStorage>& AbstractCommand::getPieceStorage() const
 
 void AbstractCommand::checkSocketRecvBuffer()
 {
-  if (socketRecvBuffer_->bufferEmpty()) {
+  if (socketRecvBuffer_->bufferEmpty() &&
+      socket_->getRecvBufferedLength() == 0) {
     return;
   }
 

+ 17 - 49
src/AbstractCommand.h

@@ -62,8 +62,7 @@ class AsyncNameResolver;
 class AsyncNameResolverMan;
 #endif // ENABLE_ASYNC_DNS
 
-class AbstractCommand : public Command
-{
+class AbstractCommand : public Command {
 private:
   std::shared_ptr<Request> req_;
   std::shared_ptr<FileEntry> fileEntry_;
@@ -97,15 +96,9 @@ private:
   bool shouldProcess() const;
 
 public:
-  RequestGroup* getRequestGroup() const
-  {
-    return requestGroup_;
-  }
+  RequestGroup* getRequestGroup() const { return requestGroup_; }
 
-  const std::shared_ptr<Request>& getRequest() const
-  {
-    return req_;
-  }
+  const std::shared_ptr<Request>& getRequest() const { return req_; }
 
   void setRequest(const std::shared_ptr<Request>& request);
 
@@ -113,27 +106,15 @@ public:
   // setRequest(std::shared_ptr<Request>());
   void resetRequest();
 
-  const std::shared_ptr<FileEntry>& getFileEntry() const
-  {
-    return fileEntry_;
-  }
+  const std::shared_ptr<FileEntry>& getFileEntry() const { return fileEntry_; }
 
   void setFileEntry(const std::shared_ptr<FileEntry>& fileEntry);
 
-  DownloadEngine* getDownloadEngine() const
-  {
-    return e_;
-  }
+  DownloadEngine* getDownloadEngine() const { return e_; }
 
-  const std::shared_ptr<SocketCore>& getSocket() const
-  {
-    return socket_;
-  }
+  const std::shared_ptr<SocketCore>& getSocket() const { return socket_; }
 
-  std::shared_ptr<SocketCore>& getSocket()
-  {
-    return socket_;
-  }
+  std::shared_ptr<SocketCore>& getSocket() { return socket_; }
 
   void setSocket(const std::shared_ptr<SocketCore>& s);
 
@@ -155,8 +136,7 @@ public:
   // arguments until resolved address is returned.  Exception is
   // thrown on error. port is used for retrieving cached addresses.
   std::string resolveHostname(std::vector<std::string>& addrs,
-                              const std::string& hostname,
-                              uint16_t port);
+                              const std::string& hostname, uint16_t port);
 
   void tryReserved();
 
@@ -185,10 +165,7 @@ public:
   // check.
   void swapSocket(std::shared_ptr<SocketCore>& socket);
 
-  std::chrono::seconds getTimeout() const
-  {
-    return timeout_;
-  }
+  std::chrono::seconds getTimeout() const { return timeout_; }
 
   void setTimeout(std::chrono::seconds timeout)
   {
@@ -229,10 +206,7 @@ public:
   const std::shared_ptr<SegmentMan>& getSegmentMan() const;
   const std::shared_ptr<PieceStorage>& getPieceStorage() const;
 
-  Timer& getCheckPoint()
-  {
-    return checkPoint_;
-  }
+  Timer& getCheckPoint() { return checkPoint_; }
 
   void checkSocketRecvBuffer();
 
@@ -247,21 +221,15 @@ protected:
 
   // Returns true if the derived class wants to execute
   // executeInternal() unconditionally
-  virtual bool noCheck() const
-  {
-    return false;
-  }
+  virtual bool noCheck() const { return false; }
 
 public:
-  AbstractCommand(cuid_t cuid,
-                  const std::shared_ptr<Request>& req,
-                  const std::shared_ptr<FileEntry>& fileEntry,
-                  RequestGroup* requestGroup,
-                  DownloadEngine* e,
-                  const std::shared_ptr<SocketCore>& s = nullptr,
-                  const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer =
-                      nullptr,
-                  bool incNumConnection = true);
+  AbstractCommand(
+      cuid_t cuid, const std::shared_ptr<Request>& req,
+      const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
+      DownloadEngine* e, const std::shared_ptr<SocketCore>& s = nullptr,
+      const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer = nullptr,
+      bool incNumConnection = true);
 
   virtual ~AbstractCommand();
 

+ 212 - 201
src/AbstractDiskWriter.cc

@@ -36,7 +36,7 @@
 
 #include <unistd.h>
 #ifdef HAVE_MMAP
-#  include <sys/mman.h>
+#include <sys/mman.h>
 #endif // HAVE_MMAP
 #include <fcntl.h>
 
@@ -57,24 +57,22 @@
 namespace aria2 {
 
 AbstractDiskWriter::AbstractDiskWriter(const std::string& filename)
-  : filename_(filename),
-    fd_(A2_BAD_FD),
+    : filename_(filename),
+      fd_(A2_BAD_FD),
 #ifdef __MINGW32__
-    mapView_(0),
-#else // !__MINGW32__
+      mapView_(0),
+#else  // !__MINGW32__
 #endif // !__MINGW32__
-    readOnly_(false),
-    enableMmap_(false),
-    mapaddr_(nullptr),
-    maplen_(0)
-
-{}
+      readOnly_(false),
+      enableMmap_(false),
+      mapaddr_(nullptr),
+      maplen_(0)
 
-AbstractDiskWriter::~AbstractDiskWriter()
 {
-  closeFile();
 }
 
+AbstractDiskWriter::~AbstractDiskWriter() { closeFile(); }
+
 namespace {
 // Returns error code depending on the platform. For MinGW32, return
 // the value of GetLastError(). Otherwise, return errno.
@@ -82,7 +80,7 @@ int fileError()
 {
 #ifdef __MINGW32__
   return GetLastError();
-#else // !__MINGW32__
+#else  // !__MINGW32__
   return errno;
 #endif // !__MINGW32__
 }
@@ -95,19 +93,14 @@ namespace {
 std::string fileStrerror(int errNum)
 {
 #ifdef __MINGW32__
-  static char buf[256];
-  if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
-                   0,
-                   errNum,
-                   // Default language
-                   MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
-                   (LPTSTR) &buf,
-                   sizeof(buf),
-                   0) == 0) {
+  auto msg = util::formatLastError(errNum);
+  if (msg.empty()) {
+    char buf[256];
     snprintf(buf, sizeof(buf), "File I/O error %x", errNum);
+    return buf;
   }
-  return buf;
-#else // !__MINGW32__
+  return msg;
+#else  // !__MINGW32__
   return util::safeStrerror(errNum);
 #endif // !__MINGW32__
 }
@@ -117,17 +110,19 @@ void AbstractDiskWriter::openFile(int64_t totalLength)
 {
   try {
     openExistingFile(totalLength);
-  } catch(RecoverableException& e) {
-    if(
+  }
+  catch (RecoverableException& e) {
+    if (
 #ifdef __MINGW32__
-       e.getErrNum() == ERROR_FILE_NOT_FOUND ||
-       e.getErrNum() == ERROR_PATH_NOT_FOUND
-#else // !__MINGW32__
-       e.getErrNum() == ENOENT
+        e.getErrNum() == ERROR_FILE_NOT_FOUND ||
+        e.getErrNum() == ERROR_PATH_NOT_FOUND
+#else  // !__MINGW32__
+        e.getErrNum() == ENOENT
 #endif // !__MINGW32__
-       ) {
+        ) {
       initAndOpenFile(totalLength);
-    } else {
+    }
+    else {
       throw;
     }
   }
@@ -136,34 +131,35 @@ void AbstractDiskWriter::openFile(int64_t totalLength)
 void AbstractDiskWriter::closeFile()
 {
 #if defined(HAVE_MMAP) || defined(__MINGW32__)
-  if(mapaddr_) {
+  if (mapaddr_) {
     int errNum = 0;
 #ifdef __MINGW32__
-    if(!UnmapViewOfFile(mapaddr_)) {
+    if (!UnmapViewOfFile(mapaddr_)) {
       errNum = GetLastError();
     }
     CloseHandle(mapView_);
     mapView_ = INVALID_HANDLE_VALUE;
-#else // !__MINGW32__
-    if(munmap(mapaddr_, maplen_) == -1) {
+#else  // !__MINGW32__
+    if (munmap(mapaddr_, maplen_) == -1) {
       errNum = errno;
     }
 #endif // !__MINGW32__
-    if(errNum != 0) {
+    if (errNum != 0) {
       int errNum = fileError();
-      A2_LOG_ERROR(fmt("Unmapping file %s failed: %s",
-                       filename_.c_str(), fileStrerror(errNum).c_str()));
-    } else {
+      A2_LOG_ERROR(fmt("Unmapping file %s failed: %s", filename_.c_str(),
+                       fileStrerror(errNum).c_str()));
+    }
+    else {
       A2_LOG_INFO(fmt("Unmapping file %s succeeded", filename_.c_str()));
     }
     mapaddr_ = nullptr;
     maplen_ = 0;
   }
 #endif // HAVE_MMAP || defined __MINGW32__
-  if(fd_ != A2_BAD_FD) {
+  if (fd_ != A2_BAD_FD) {
 #ifdef __MINGW32__
     CloseHandle(fd_);
-#else // !__MINGW32__
+#else  // !__MINGW32__
     close(fd_);
 #endif // !__MINGW32__
     fd_ = A2_BAD_FD;
@@ -180,29 +176,32 @@ HANDLE openFileWithFlags(const std::string& filename, int flags,
   DWORD sharedMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
   DWORD creationDisp = 0;
 
-  if(flags & O_RDWR) {
+  if (flags & O_RDWR) {
     desiredAccess = GENERIC_READ | GENERIC_WRITE;
-  } else if(flags & O_WRONLY) {
+  }
+  else if (flags & O_WRONLY) {
     desiredAccess = GENERIC_WRITE;
-  } else {
+  }
+  else {
     desiredAccess = GENERIC_READ;
   }
-  if(flags & O_CREAT) {
-    if(flags & O_TRUNC) {
+  if (flags & O_CREAT) {
+    if (flags & O_TRUNC) {
       creationDisp |= CREATE_ALWAYS;
-    } else {
+    }
+    else {
       creationDisp |= CREATE_NEW;
     }
-  } else {
+  }
+  else {
     creationDisp |= OPEN_EXISTING;
   }
   hn = CreateFileW(utf8ToWChar(filename).c_str(), desiredAccess, sharedMode,
                    /* lpSecurityAttributes */ 0, creationDisp,
                    FILE_ATTRIBUTE_NORMAL, /* hTemplateFile */ 0);
-  if(hn == INVALID_HANDLE_VALUE) {
+  if (hn == INVALID_HANDLE_VALUE) {
     int errNum = GetLastError();
-    throw DL_ABORT_EX3(errNum, fmt(EX_FILE_OPEN,
-                                   filename.c_str(),
+    throw DL_ABORT_EX3(errNum, fmt(EX_FILE_OPEN, filename.c_str(),
                                    fileStrerror(errNum).c_str()),
                        errCode);
   }
@@ -213,14 +212,16 @@ int openFileWithFlags(const std::string& filename, int flags,
                       error_code::Value errCode)
 {
   int fd;
-  while((fd = a2open(utf8ToWChar(filename).c_str(), flags, OPEN_MODE)) == -1
-        && errno == EINTR);
-  if(fd < 0) {
+  while ((fd = a2open(utf8ToWChar(filename).c_str(), flags, OPEN_MODE)) == -1 &&
+         errno == EINTR)
+    ;
+  if (fd < 0) {
     int errNum = errno;
     throw DL_ABORT_EX3(errNum, fmt(EX_FILE_OPEN, filename.c_str(),
                                    util::safeStrerror(errNum).c_str()),
                        errCode);
   }
+  util::make_fd_cloexec(fd);
 #if defined(__APPLE__) && defined(__MACH__)
   // This may reduce memory consumption on Mac OS X.
   fcntl(fd, F_NOCACHE, 1);
@@ -233,9 +234,10 @@ int openFileWithFlags(const std::string& filename, int flags,
 void AbstractDiskWriter::openExistingFile(int64_t totalLength)
 {
   int flags = O_BINARY;
-  if(readOnly_) {
+  if (readOnly_) {
     flags |= O_RDONLY;
-  } else {
+  }
+  else {
     flags |= O_RDWR;
   }
   fd_ = openFileWithFlags(filename_, flags, error_code::FILE_OPEN_ERROR);
@@ -245,32 +247,38 @@ void AbstractDiskWriter::createFile(int addFlags)
 {
   assert(!filename_.empty());
   util::mkdirs(File(filename_).getDirname());
-  fd_ = openFileWithFlags(filename_, O_CREAT|O_RDWR|O_TRUNC|O_BINARY|addFlags,
+  fd_ = openFileWithFlags(filename_,
+                          O_CREAT | O_RDWR | O_TRUNC | O_BINARY | addFlags,
                           error_code::FILE_CREATE_ERROR);
 }
 
 ssize_t AbstractDiskWriter::writeDataInternal(const unsigned char* data,
                                               size_t len, int64_t offset)
 {
-  if(mapaddr_) {
+  if (mapaddr_) {
     memcpy(mapaddr_ + offset, data, len);
     return len;
-  } else {
+  }
+  else {
     ssize_t writtenLength = 0;
     seek(offset);
-    while((size_t)writtenLength < len) {
+    while ((size_t)writtenLength < len) {
 #ifdef __MINGW32__
       DWORD nwrite;
-      if(WriteFile(fd_, data+writtenLength, len-writtenLength, &nwrite, 0)) {
+      if (WriteFile(fd_, data + writtenLength, len - writtenLength, &nwrite,
+                    0)) {
         writtenLength += nwrite;
-      } else {
+      }
+      else {
         return -1;
       }
-#else // !__MINGW32__
+#else  // !__MINGW32__
       ssize_t ret = 0;
-      while((ret = write(fd_, data+writtenLength, len-writtenLength)) == -1 &&
-            errno == EINTR);
-      if(ret == -1) {
+      while ((ret = write(fd_, data + writtenLength, len - writtenLength)) ==
+                 -1 &&
+             errno == EINTR)
+        ;
+      if (ret == -1) {
         return -1;
       }
       writtenLength += ret;
@@ -283,27 +291,28 @@ ssize_t AbstractDiskWriter::writeDataInternal(const unsigned char* data,
 ssize_t AbstractDiskWriter::readDataInternal(unsigned char* data, size_t len,
                                              int64_t offset)
 {
-  if(mapaddr_) {
-    ssize_t readlen;
-    if(offset > maplen_) {
-      readlen = 0;
-    } else {
-      readlen = std::min(static_cast<size_t>(maplen_ - offset), len);
+  if (mapaddr_) {
+    if (offset >= maplen_) {
+      return 0;
     }
+    auto readlen = std::min(maplen_ - offset, static_cast<int64_t>(len));
     memcpy(data, mapaddr_ + offset, readlen);
     return readlen;
-  } else {
+  }
+  else {
     seek(offset);
 #ifdef __MINGW32__
     DWORD nread;
-    if(ReadFile(fd_, data, len, &nread, 0)) {
+    if (ReadFile(fd_, data, len, &nread, 0)) {
       return nread;
-    } else {
+    }
+    else {
       return -1;
     }
-#else // !__MINGW32__
+#else  // !__MINGW32__
     ssize_t ret = 0;
-    while((ret = read(fd_, data, len)) == -1 && errno == EINTR);
+    while ((ret = read(fd_, data, len)) == -1 && errno == EINTR)
+      ;
     return ret;
 #endif // !__MINGW32__
   }
@@ -315,78 +324,87 @@ void AbstractDiskWriter::seek(int64_t offset)
 #ifdef __MINGW32__
   LARGE_INTEGER fileLength;
   fileLength.QuadPart = offset;
-  if(SetFilePointerEx(fd_, fileLength, 0, FILE_BEGIN) == 0)
-#else // !__MINGW32__
-  if(a2lseek(fd_, offset, SEEK_SET) == (a2_off_t)-1)
+  if (SetFilePointerEx(fd_, fileLength, 0, FILE_BEGIN) == 0)
+#else  // !__MINGW32__
+  if (a2lseek(fd_, offset, SEEK_SET) == (a2_off_t)-1)
 #endif // !__MINGW32__
-    {
-      int errNum = fileError();
-      throw DL_ABORT_EX2(fmt(EX_FILE_SEEK, filename_.c_str(),
-                             fileStrerror(errNum).c_str()),
-                         error_code::FILE_IO_ERROR);
-    }
+  {
+    int errNum = fileError();
+    throw DL_ABORT_EX2(
+        fmt(EX_FILE_SEEK, filename_.c_str(), fileStrerror(errNum).c_str()),
+        error_code::FILE_IO_ERROR);
+  }
 }
 
 void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
 {
 #if defined(HAVE_MMAP) || defined(__MINGW32__)
-  if(enableMmap_) {
-    if(mapaddr_) {
-      if(static_cast<int64_t>(len + offset) > maplen_) {
+  if (enableMmap_) {
+    if (mapaddr_) {
+      if (static_cast<int64_t>(len + offset) > maplen_) {
         int errNum = 0;
 #ifdef __MINGW32__
-        if(!UnmapViewOfFile(mapaddr_)) {
+        if (!UnmapViewOfFile(mapaddr_)) {
           errNum = GetLastError();
         }
         CloseHandle(mapView_);
         mapView_ = INVALID_HANDLE_VALUE;
-#else // !__MINGW32__
-        if(munmap(mapaddr_, maplen_) == -1) {
+#else  // !__MINGW32__
+        if (munmap(mapaddr_, maplen_) == -1) {
           errNum = errno;
         }
 #endif // !__MINGW32__
-        if(errNum != 0) {
-          A2_LOG_ERROR(fmt("Unmapping file %s failed: %s",
-                           filename_.c_str(), fileStrerror(errNum).c_str()));
+        if (errNum != 0) {
+          A2_LOG_ERROR(fmt("Unmapping file %s failed: %s", filename_.c_str(),
+                           fileStrerror(errNum).c_str()));
         }
         mapaddr_ = nullptr;
         maplen_ = 0;
         enableMmap_ = false;
       }
-    } else {
+    }
+    else {
       int64_t filesize = size();
+
+      if (filesize == 0) {
+        // mapping 0 length file is useless.  Also munmap with size ==
+        // 0 will fail with EINVAL.
+        enableMmap_ = false;
+        return;
+      }
+
       int errNum = 0;
-      if(static_cast<int64_t>(len + offset) <= filesize) {
+      if (static_cast<int64_t>(len + offset) <= filesize) {
 #ifdef __MINGW32__
-        mapView_ = CreateFileMapping(fd_, 0, PAGE_READWRITE,
-                                     filesize >> 32, filesize & 0xffffffffu,
-                                     0);
-        if(mapView_) {
-          mapaddr_ = reinterpret_cast<unsigned char*>
-            (MapViewOfFile(mapView_, FILE_MAP_WRITE, 0, 0, 0));
-          if(!mapaddr_) {
+        mapView_ = CreateFileMapping(fd_, 0, PAGE_READWRITE, filesize >> 32,
+                                     filesize & 0xffffffffu, 0);
+        if (mapView_) {
+          mapaddr_ = reinterpret_cast<unsigned char*>(
+              MapViewOfFile(mapView_, FILE_MAP_WRITE, 0, 0, 0));
+          if (!mapaddr_) {
             errNum = GetLastError();
             CloseHandle(mapView_);
             mapView_ = INVALID_HANDLE_VALUE;
           }
-        } else {
+        }
+        else {
           errNum = GetLastError();
         }
-#else // !__MINGW32__
-        mapaddr_ = reinterpret_cast<unsigned char*>
-          (mmap(nullptr, size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
-        if(!mapaddr_) {
+#else  // !__MINGW32__
+        mapaddr_ = reinterpret_cast<unsigned char*>(mmap(
+            nullptr, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
+        if (!mapaddr_) {
           errNum = errno;
         }
 #endif // !__MINGW32__
-        if(mapaddr_) {
+        if (mapaddr_) {
           A2_LOG_DEBUG(fmt("Mapping file %s succeeded, length=%" PRId64 "",
-                           filename_.c_str(),
-                           static_cast<uint64_t>(filesize)));
+                           filename_.c_str(), static_cast<uint64_t>(filesize)));
           maplen_ = filesize;
-        } else {
-          A2_LOG_WARN(fmt("Mapping file %s failed: %s",
-                          filename_.c_str(), fileStrerror(errNum).c_str()));
+        }
+        else {
+          A2_LOG_WARN(fmt("Mapping file %s failed: %s", filename_.c_str(),
+                          fileStrerror(errNum).c_str()));
           enableMmap_ = false;
         }
       }
@@ -395,158 +413,151 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
 #endif // HAVE_MMAP || __MINGW32__
 }
 
-void AbstractDiskWriter::writeData(const unsigned char* data, size_t len, int64_t offset)
+void AbstractDiskWriter::writeData(const unsigned char* data, size_t len,
+                                   int64_t offset)
 {
   ensureMmapWrite(len, offset);
-  if(writeDataInternal(data, len, offset) < 0) {
+  if (writeDataInternal(data, len, offset) < 0) {
     int errNum = fileError();
-    if(
-       // If the error indicates disk full situation, throw
-       // DownloadFailureException and abort download instantly.
+    if (
+// If the error indicates disk full situation, throw
+// DownloadFailureException and abort download instantly.
 #ifdef __MINGW32__
-       errNum == ERROR_DISK_FULL || errNum == ERROR_HANDLE_DISK_FULL
-#else // !__MINGW32__
-       errNum == ENOSPC
+        errNum == ERROR_DISK_FULL || errNum == ERROR_HANDLE_DISK_FULL
+#else  // !__MINGW32__
+        errNum == ENOSPC
 #endif // !__MINGW32__
-       ) {
-      throw DOWNLOAD_FAILURE_EXCEPTION3
-        (errNum, fmt(EX_FILE_WRITE, filename_.c_str(),
-                     fileStrerror(errNum).c_str()),
-         error_code::NOT_ENOUGH_DISK_SPACE);
-    } else {
-      throw DL_ABORT_EX3
-        (errNum, fmt(EX_FILE_WRITE, filename_.c_str(),
-                     fileStrerror(errNum).c_str()),
-         error_code::FILE_IO_ERROR);
+        ) {
+      throw DOWNLOAD_FAILURE_EXCEPTION3(
+          errNum,
+          fmt(EX_FILE_WRITE, filename_.c_str(), fileStrerror(errNum).c_str()),
+          error_code::NOT_ENOUGH_DISK_SPACE);
+    }
+    else {
+      throw DL_ABORT_EX3(errNum, fmt(EX_FILE_WRITE, filename_.c_str(),
+                                     fileStrerror(errNum).c_str()),
+                         error_code::FILE_IO_ERROR);
     }
   }
 }
 
-ssize_t AbstractDiskWriter::readData(unsigned char* data, size_t len, int64_t offset)
+ssize_t AbstractDiskWriter::readData(unsigned char* data, size_t len,
+                                     int64_t offset)
 {
   ssize_t ret;
-  if((ret = readDataInternal(data, len, offset)) < 0) {
+  if ((ret = readDataInternal(data, len, offset)) < 0) {
     int errNum = fileError();
-    throw DL_ABORT_EX3
-      (errNum, fmt(EX_FILE_READ, filename_.c_str(),
-                   fileStrerror(errNum).c_str()),
-       error_code::FILE_IO_ERROR);
+    throw DL_ABORT_EX3(errNum, fmt(EX_FILE_READ, filename_.c_str(),
+                                   fileStrerror(errNum).c_str()),
+                       error_code::FILE_IO_ERROR);
   }
   return ret;
 }
 
 void AbstractDiskWriter::truncate(int64_t length)
 {
-  if(fd_ == A2_BAD_FD) {
+  if (fd_ == A2_BAD_FD) {
     throw DL_ABORT_EX("File not yet opened.");
   }
 #ifdef __MINGW32__
   // Since mingw32's ftruncate cannot handle over 2GB files, we use
   // SetEndOfFile instead.
   seek(length);
-  if(SetEndOfFile(fd_) == 0)
-#else // !__MINGW32__
-  if(a2ftruncate(fd_, length) == -1)
+  if (SetEndOfFile(fd_) == 0)
+#else  // !__MINGW32__
+  if (a2ftruncate(fd_, length) == -1)
 #endif // !__MINGW32__
-    {
-      int errNum = fileError();
-      throw DL_ABORT_EX2(fmt("File truncation failed. cause: %s",
-                             fileStrerror(errNum).c_str()),
-                         error_code::FILE_IO_ERROR);
-    }
+  {
+    int errNum = fileError();
+    throw DL_ABORT_EX2(
+        fmt("File truncation failed. cause: %s", fileStrerror(errNum).c_str()),
+        error_code::FILE_IO_ERROR);
+  }
 }
 
 void AbstractDiskWriter::allocate(int64_t offset, int64_t length, bool sparse)
 {
-  if(fd_ == A2_BAD_FD) {
+  if (fd_ == A2_BAD_FD) {
     throw DL_ABORT_EX("File not yet opened.");
   }
-  if(sparse) {
+  if (sparse) {
 #ifdef __MINGW32__
     DWORD bytesReturned;
-    if(!DeviceIoControl(fd_, FSCTL_SET_SPARSE, 0, 0, 0, 0,
-                        &bytesReturned, 0)) {
+    if (!DeviceIoControl(fd_, FSCTL_SET_SPARSE, 0, 0, 0, 0, &bytesReturned,
+                         0)) {
       A2_LOG_WARN(fmt("Making file sparse failed or pending: %s",
                       fileStrerror(GetLastError()).c_str()));
     }
 #endif // __MINGW32__
-    truncate(offset+length);
+    truncate(offset + length);
     return;
   }
-#ifdef  HAVE_SOME_FALLOCATE
-# ifdef __MINGW32__
-  truncate(offset+length);
-# elif defined(__APPLE__) && defined(__MACH__)
+#ifdef HAVE_SOME_FALLOCATE
+#ifdef __MINGW32__
+  truncate(offset + length);
+  if (!SetFileValidData(fd_, offset + length)) {
+    auto errNum = fileError();
+    A2_LOG_WARN(fmt(
+        "File allocation (SetFileValidData) failed (cause: %s). File will be "
+        "allocated by filling zero, which blocks whole aria2 execution. Run "
+        "aria2 as an administrator or use a different file allocation method "
+        "(see --file-allocation).",
+        fileStrerror(errNum).c_str()));
+  }
+#elif defined(__APPLE__) && defined(__MACH__)
   auto toalloc = offset + length - size();
   while (toalloc > 0) {
     fstore_t fstore = {
-      F_ALLOCATECONTIG | F_ALLOCATEALL,
-      F_PEOFPOSMODE,
-      0,
-      // Allocate in 1GB chunks or else some OSX versions may choke.
-      std::min(toalloc, (int64_t)1<<30),
-      0
-    };
+        F_ALLOCATECONTIG | F_ALLOCATEALL, F_PEOFPOSMODE, 0,
+        // Allocate in 1GB chunks or else some OSX versions may choke.
+        std::min(toalloc, (int64_t)1 << 30), 0};
     if (fcntl(fd_, F_PREALLOCATE, &fstore) == -1) {
       // Retry non-contig.
       fstore.fst_flags = F_ALLOCATEALL;
       if (fcntl(fd_, F_PREALLOCATE, &fstore) == -1) {
         int err = errno;
-        throw DL_ABORT_EX3(err,
-                          fmt("fcntl(F_PREALLOCATE) of %" PRId64 " failed. cause: %s",
-                              fstore.fst_length, util::safeStrerror(err).c_str()),
-                          error_code::FILE_IO_ERROR);
+        throw DL_ABORT_EX3(
+            err, fmt("fcntl(F_PREALLOCATE) of %" PRId64 " failed. cause: %s",
+                     fstore.fst_length, util::safeStrerror(err).c_str()),
+            error_code::FILE_IO_ERROR);
       }
     }
     toalloc -= fstore.fst_bytesalloc;
   }
   // This forces the allocation on disk.
   ftruncate(fd_, offset + length);
-# elif HAVE_FALLOCATE
+#elif HAVE_FALLOCATE
   // For linux, we use fallocate to detect file system supports
   // fallocate or not.
   int r;
-  while((r = fallocate(fd_, 0, offset, length)) == -1 && errno == EINTR);
+  while ((r = fallocate(fd_, 0, offset, length)) == -1 && errno == EINTR)
+    ;
   int errNum = errno;
-  if(r == -1) {
-    throw DL_ABORT_EX3(errNum,
-                       fmt("fallocate failed. cause: %s",
-                           util::safeStrerror(errNum).c_str()),
+  if (r == -1) {
+    throw DL_ABORT_EX3(errNum, fmt("fallocate failed. cause: %s",
+                                   util::safeStrerror(errNum).c_str()),
                        error_code::FILE_IO_ERROR);
   }
-# elif HAVE_POSIX_FALLOCATE
+#elif HAVE_POSIX_FALLOCATE
   int r = posix_fallocate(fd_, offset, length);
-  if(r != 0) {
-    throw DL_ABORT_EX3(r,
-                       fmt("posix_fallocate failed. cause: %s",
-                           util::safeStrerror(r).c_str()),
+  if (r != 0) {
+    throw DL_ABORT_EX3(r, fmt("posix_fallocate failed. cause: %s",
+                              util::safeStrerror(r).c_str()),
                        error_code::FILE_IO_ERROR);
   }
-# else
-#  error "no *_fallocate function available."
-# endif
+#else
+#error "no *_fallocate function available."
+#endif
 #endif // HAVE_SOME_FALLOCATE
 }
 
-int64_t AbstractDiskWriter::size()
-{
-  return File(filename_).size();
-}
+int64_t AbstractDiskWriter::size() { return File(filename_).size(); }
 
-void AbstractDiskWriter::enableReadOnly()
-{
-  readOnly_ = true;
-}
+void AbstractDiskWriter::enableReadOnly() { readOnly_ = true; }
 
-void AbstractDiskWriter::disableReadOnly()
-{
-  readOnly_ = false;
-}
+void AbstractDiskWriter::disableReadOnly() { readOnly_ = false; }
 
-void AbstractDiskWriter::enableMmap()
-{
-  enableMmap_ = true;
-}
+void AbstractDiskWriter::enableMmap() { enableMmap_ = true; }
 
 void AbstractDiskWriter::dropCache(int64_t len, int64_t offset)
 {

+ 9 - 7
src/AbstractDiskWriter.h

@@ -48,7 +48,7 @@ private:
   HANDLE fd_;
   // The handle for memory mapped file. mmap equivalent in Windows.
   HANDLE mapView_;
-#else // !__MINGW32__
+#else  // !__MINGW32__
   int fd_;
 #endif // !__MINGW32__
 
@@ -65,8 +65,10 @@ private:
   void seek(int64_t offset);
 
   void ensureMmapWrite(size_t len, int64_t offset);
+
 protected:
   void createFile(int addFlags = 0);
+
 public:
   AbstractDiskWriter(const std::string& filename);
   virtual ~AbstractDiskWriter();
@@ -77,17 +79,17 @@ public:
 
   virtual void openExistingFile(int64_t totalLength = 0) CXX11_OVERRIDE;
 
-  virtual void writeData(const unsigned char* data, size_t len, int64_t offset)
-    CXX11_OVERRIDE;
+  virtual void writeData(const unsigned char* data, size_t len,
+                         int64_t offset) CXX11_OVERRIDE;
 
-  virtual ssize_t readData(unsigned char* data, size_t len, int64_t offset)
-    CXX11_OVERRIDE;
+  virtual ssize_t readData(unsigned char* data, size_t len,
+                           int64_t offset) CXX11_OVERRIDE;
 
   virtual void truncate(int64_t length) CXX11_OVERRIDE;
 
   // File must be opened before calling this function.
-  virtual void allocate(int64_t offset, int64_t length, bool sparse)
-     CXX11_OVERRIDE;
+  virtual void allocate(int64_t offset, int64_t length,
+                        bool sparse) CXX11_OVERRIDE;
 
   virtual int64_t size() CXX11_OVERRIDE;
 

+ 32 - 30
src/AbstractHttpServerResponseCommand.cc

@@ -47,17 +47,15 @@
 
 namespace aria2 {
 
-AbstractHttpServerResponseCommand::AbstractHttpServerResponseCommand
-(cuid_t cuid,
- const std::shared_ptr<HttpServer>& httpServer,
- DownloadEngine* e,
- const std::shared_ptr<SocketCore>& socket)
- : Command(cuid),
-   e_(e),
-   socket_(socket),
-   httpServer_(httpServer),
-   readCheck_(false),
-   writeCheck_(true)
+AbstractHttpServerResponseCommand::AbstractHttpServerResponseCommand(
+    cuid_t cuid, const std::shared_ptr<HttpServer>& httpServer,
+    DownloadEngine* e, const std::shared_ptr<SocketCore>& socket)
+    : Command(cuid),
+      e_(e),
+      socket_(socket),
+      httpServer_(httpServer),
+      readCheck_(false),
+      writeCheck_(true)
 {
   setStatus(Command::STATUS_ONESHOT_REALTIME);
   e_->addSocketForWriteCheck(socket_, this);
@@ -65,31 +63,33 @@ AbstractHttpServerResponseCommand::AbstractHttpServerResponseCommand
 
 AbstractHttpServerResponseCommand::~AbstractHttpServerResponseCommand()
 {
-  if(readCheck_) {
+  if (readCheck_) {
     e_->deleteSocketForReadCheck(socket_, this);
   }
-  if(writeCheck_) {
+  if (writeCheck_) {
     e_->deleteSocketForWriteCheck(socket_, this);
   }
 }
 
 void AbstractHttpServerResponseCommand::updateReadWriteCheck()
 {
-  if(httpServer_->wantRead()) {
-    if(!readCheck_) {
+  if (httpServer_->wantRead()) {
+    if (!readCheck_) {
       readCheck_ = true;
       e_->addSocketForReadCheck(socket_, this);
     }
-  } else if(readCheck_) {
+  }
+  else if (readCheck_) {
     readCheck_ = false;
     e_->deleteSocketForReadCheck(socket_, this);
   }
-  if(httpServer_->wantWrite()) {
-    if(!writeCheck_) {
+  if (httpServer_->wantWrite()) {
+    if (!writeCheck_) {
       writeCheck_ = true;
       e_->addSocketForWriteCheck(socket_, this);
     }
-  } else if(writeCheck_) {
+  }
+  else if (writeCheck_) {
     writeCheck_ = false;
     e_->deleteSocketForWriteCheck(socket_, this);
   }
@@ -97,34 +97,36 @@ void AbstractHttpServerResponseCommand::updateReadWriteCheck()
 
 bool AbstractHttpServerResponseCommand::execute()
 {
-  if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) {
+  if (e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) {
     return true;
   }
   try {
     ssize_t len = httpServer_->sendResponse();
-    if(len > 0) {
+    if (len > 0) {
       timeoutTimer_ = global::wallclock();
     }
-  } catch(RecoverableException& e) {
-    A2_LOG_INFO_EX
-      (fmt("CUID#%" PRId64
-           " - Error occurred while transmitting response body.",
-           getCuid()),
-       e);
+  }
+  catch (RecoverableException& e) {
+    A2_LOG_INFO_EX(fmt("CUID#%" PRId64
+                       " - Error occurred while transmitting response body.",
+                       getCuid()),
+                   e);
     return true;
   }
-  if(httpServer_->sendBufferIsEmpty()) {
+  if (httpServer_->sendBufferIsEmpty()) {
     A2_LOG_INFO(fmt("CUID#%" PRId64 " - HttpServer: all response transmitted.",
                     getCuid()));
     afterSend(httpServer_, e_);
     return true;
-  } else {
+  }
+  else {
     if (timeoutTimer_.difference(global::wallclock()) >= 30_s) {
       A2_LOG_INFO(fmt("CUID#%" PRId64
                       " - HttpServer: Timeout while trasmitting response.",
                       getCuid()));
       return true;
-    } else {
+    }
+    else {
       updateReadWriteCheck();
       e_->addCommand(std::unique_ptr<Command>(this));
       return false;

+ 6 - 8
src/AbstractHttpServerResponseCommand.h

@@ -57,19 +57,17 @@ private:
   bool writeCheck_;
 
   void updateReadWriteCheck();
+
 protected:
-  DownloadEngine* getDownloadEngine()
-  {
-    return e_;
-  }
+  DownloadEngine* getDownloadEngine() { return e_; }
   // Called after content body is completely sent.
   virtual void afterSend(const std::shared_ptr<HttpServer>& httpServer,
                          DownloadEngine* e) = 0;
+
 public:
-  AbstractHttpServerResponseCommand(cuid_t cuid,
-                                    const std::shared_ptr<HttpServer>& httpServer,
-                                    DownloadEngine* e,
-                                    const std::shared_ptr<SocketCore>& socket);
+  AbstractHttpServerResponseCommand(
+      cuid_t cuid, const std::shared_ptr<HttpServer>& httpServer,
+      DownloadEngine* e, const std::shared_ptr<SocketCore>& socket);
 
   virtual ~AbstractHttpServerResponseCommand();
 

+ 25 - 36
src/AbstractOptionHandler.cc

@@ -44,20 +44,19 @@
 
 namespace aria2 {
 
-AbstractOptionHandler::AbstractOptionHandler
-(PrefPtr pref,
- const char* description,
- const std::string& defaultValue,
- ARG_TYPE argType,
- char shortName)
-  : pref_(pref),
-    description_(description),
-    defaultValue_(defaultValue),
-    argType_(argType),
-    shortName_(shortName),
-    tags_(0),
-    flags_(0)
-{}
+AbstractOptionHandler::AbstractOptionHandler(PrefPtr pref,
+                                             const char* description,
+                                             const std::string& defaultValue,
+                                             ARG_TYPE argType, char shortName)
+    : pref_(pref),
+      description_(description),
+      defaultValue_(defaultValue),
+      argType_(argType),
+      shortName_(shortName),
+      tags_(0),
+      flags_(0)
+{
+}
 
 AbstractOptionHandler::~AbstractOptionHandler() {}
 
@@ -65,7 +64,8 @@ void AbstractOptionHandler::parse(Option& option, const std::string& arg) const
 {
   try {
     parseArg(option, arg);
-  } catch(Exception& e) {
+  }
+  catch (Exception& e) {
     throw OPTION_HANDLER_EXCEPTION2(pref_, e);
   }
 }
@@ -75,49 +75,38 @@ bool AbstractOptionHandler::hasTag(uint32_t tag) const
   return (tags_ & (1 << tag));
 }
 
-void AbstractOptionHandler::addTag(uint32_t tag)
-{
-  tags_ |= (1 << tag);
-}
+void AbstractOptionHandler::addTag(uint32_t tag) { tags_ |= (1 << tag); }
 
 std::string AbstractOptionHandler::toTagString() const
 {
   std::string s;
-  for(int i = 0; i < MAX_HELP_TAG; ++i) {
-    if(tags_ & (1 << i)) {
+  for (int i = 0; i < MAX_HELP_TAG; ++i) {
+    if (tags_ & (1 << i)) {
       s += strHelpTag(i);
       s += ", ";
     }
   }
-  if(!s.empty()) {
+  if (!s.empty()) {
     s.resize(s.size() - 2);
   }
   return s;
 }
 
-const char* AbstractOptionHandler::getName() const
-{
-  return pref_->k;
-}
+const char* AbstractOptionHandler::getName() const { return pref_->k; }
 
 void AbstractOptionHandler::updateFlags(int flag, bool val)
 {
-  if(val) {
+  if (val) {
     flags_ |= flag;
-  } else {
+  }
+  else {
     flags_ &= ~flag;
   }
 }
 
-bool AbstractOptionHandler::isHidden() const
-{
-  return flags_ & FLAG_HIDDEN;
-}
+bool AbstractOptionHandler::isHidden() const { return flags_ & FLAG_HIDDEN; }
 
-void AbstractOptionHandler::hide()
-{
-  updateFlags(FLAG_HIDDEN, true);
-}
+void AbstractOptionHandler::hide() { updateFlags(FLAG_HIDDEN, true); }
 
 bool AbstractOptionHandler::getEraseAfterParse() const
 {

+ 9 - 15
src/AbstractOptionHandler.h

@@ -55,17 +55,16 @@ protected:
   char shortName_;
 
   virtual void parseArg(Option& option, const std::string& arg) const = 0;
+
 public:
-  AbstractOptionHandler(PrefPtr pref,
-                         const char* description = NO_DESCRIPTION,
-                         const std::string& defaultValue = NO_DEFAULT_VALUE,
-                         ARG_TYPE argType = REQ_ARG,
-                         char shortName = 0);
+  AbstractOptionHandler(PrefPtr pref, const char* description = NO_DESCRIPTION,
+                        const std::string& defaultValue = NO_DEFAULT_VALUE,
+                        ARG_TYPE argType = REQ_ARG, char shortName = 0);
 
   virtual ~AbstractOptionHandler();
 
-  virtual void parse(Option& option, const std::string& arg) const
-    CXX11_OVERRIDE;
+  virtual void parse(Option& option,
+                     const std::string& arg) const CXX11_OVERRIDE;
 
   virtual bool hasTag(uint32_t tag) const CXX11_OVERRIDE;
 
@@ -85,15 +84,9 @@ public:
     return defaultValue_;
   }
 
-  virtual PrefPtr getPref() const CXX11_OVERRIDE
-  {
-    return pref_;
-  }
+  virtual PrefPtr getPref() const CXX11_OVERRIDE { return pref_; }
 
-  virtual char getShortName() const CXX11_OVERRIDE
-  {
-    return shortName_;
-  }
+  virtual char getShortName() const CXX11_OVERRIDE { return shortName_; }
 
   virtual OptionHandler::ARG_TYPE getArgType() const CXX11_OVERRIDE
   {
@@ -137,6 +130,7 @@ public:
     FLAG_CHANGE_GLOBAL_OPTION = 1 << 5,
     FLAG_CUMULATIVE = 1 << 6
   };
+
 private:
   // bitwise OR of (1 << HelpTag value) defined in help_tags.h.
   uint32_t tags_;

+ 18 - 20
src/AbstractProxyRequestCommand.cc

@@ -49,20 +49,15 @@
 
 namespace aria2 {
 
-AbstractProxyRequestCommand::AbstractProxyRequestCommand
-(cuid_t cuid,
- const std::shared_ptr<Request>& req,
- const std::shared_ptr<FileEntry>& fileEntry,
- RequestGroup* requestGroup,
- DownloadEngine* e,
- const std::shared_ptr<Request>& proxyRequest,
- const std::shared_ptr<SocketCore>& s)
-  :
-  AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
-  proxyRequest_(proxyRequest),
-  httpConnection_
-  (std::make_shared<HttpConnection>
-   (cuid, s, std::make_shared<SocketRecvBuffer>(s)))
+AbstractProxyRequestCommand::AbstractProxyRequestCommand(
+    cuid_t cuid, const std::shared_ptr<Request>& req,
+    const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
+    DownloadEngine* e, const std::shared_ptr<Request>& proxyRequest,
+    const std::shared_ptr<SocketCore>& s)
+    : AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
+      proxyRequest_(proxyRequest),
+      httpConnection_(std::make_shared<HttpConnection>(
+          cuid, s, std::make_shared<SocketRecvBuffer>(s)))
 {
   setTimeout(std::chrono::seconds(getOption()->getAsInt(PREF_CONNECT_TIMEOUT)));
   disableReadCheckSocket();
@@ -71,22 +66,25 @@ AbstractProxyRequestCommand::AbstractProxyRequestCommand
 
 AbstractProxyRequestCommand::~AbstractProxyRequestCommand() {}
 
-bool AbstractProxyRequestCommand::executeInternal() {
-  //socket->setBlockingMode();
-  if(httpConnection_->sendBufferIsEmpty()) {
+bool AbstractProxyRequestCommand::executeInternal()
+{
+  // socket->setBlockingMode();
+  if (httpConnection_->sendBufferIsEmpty()) {
     auto httpRequest = make_unique<HttpRequest>();
     httpRequest->setUserAgent(getOption()->get(PREF_USER_AGENT));
     httpRequest->setRequest(getRequest());
     httpRequest->setProxyRequest(proxyRequest_);
 
     httpConnection_->sendProxyRequest(std::move(httpRequest));
-  } else {
+  }
+  else {
     httpConnection_->sendPendingData();
   }
-  if(httpConnection_->sendBufferIsEmpty()) {
+  if (httpConnection_->sendBufferIsEmpty()) {
     getDownloadEngine()->addCommand(getNextCommand());
     return true;
-  } else {
+  }
+  else {
     setWriteCheckSocket(getSocket());
     addCommandSelf();
     return false;

+ 4 - 4
src/AbstractProxyRequestCommand.h

@@ -47,6 +47,7 @@ private:
   std::shared_ptr<Request> proxyRequest_;
 
   std::shared_ptr<HttpConnection> httpConnection_;
+
 protected:
   virtual bool executeInternal() CXX11_OVERRIDE;
 
@@ -59,12 +60,11 @@ protected:
   {
     return proxyRequest_;
   }
+
 public:
-  AbstractProxyRequestCommand(cuid_t cuid,
-                              const std::shared_ptr<Request>& req,
+  AbstractProxyRequestCommand(cuid_t cuid, const std::shared_ptr<Request>& req,
                               const std::shared_ptr<FileEntry>& fileEntry,
-                              RequestGroup* requestGroup,
-                              DownloadEngine* e,
+                              RequestGroup* requestGroup, DownloadEngine* e,
                               const std::shared_ptr<Request>& proxyRequest,
                               const std::shared_ptr<SocketCore>& s);
 

+ 15 - 14
src/AbstractProxyResponseCommand.cc

@@ -50,27 +50,28 @@
 
 namespace aria2 {
 
-AbstractProxyResponseCommand::AbstractProxyResponseCommand
-(cuid_t cuid,
- const std::shared_ptr<Request>& req,
- const std::shared_ptr<FileEntry>& fileEntry,
- RequestGroup* requestGroup,
- const std::shared_ptr<HttpConnection>& httpConnection,
- DownloadEngine* e,
- const std::shared_ptr<SocketCore>& s)
-  :AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
-   httpConnection_(httpConnection) {}
+AbstractProxyResponseCommand::AbstractProxyResponseCommand(
+    cuid_t cuid, const std::shared_ptr<Request>& req,
+    const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
+    const std::shared_ptr<HttpConnection>& httpConnection, DownloadEngine* e,
+    const std::shared_ptr<SocketCore>& s)
+    : AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
+      httpConnection_(httpConnection)
+{
+}
 
 AbstractProxyResponseCommand::~AbstractProxyResponseCommand() {}
 
-bool AbstractProxyResponseCommand::executeInternal() {
-  std::shared_ptr<HttpResponse> httpResponse = httpConnection_->receiveResponse();
-  if(!httpResponse) {
+bool AbstractProxyResponseCommand::executeInternal()
+{
+  std::shared_ptr<HttpResponse> httpResponse =
+      httpConnection_->receiveResponse();
+  if (!httpResponse) {
     // the server has not responded our request yet.
     addCommandSelf();
     return false;
   }
-  if(httpResponse->getStatusCode() != 200) {
+  if (httpResponse->getStatusCode() != 200) {
     throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED);
   }
   getDownloadEngine()->addCommand(getNextCommand());

+ 7 - 8
src/AbstractProxyResponseCommand.h

@@ -45,6 +45,7 @@ class SocketCore;
 class AbstractProxyResponseCommand : public AbstractCommand {
 private:
   std::shared_ptr<HttpConnection> httpConnection_;
+
 protected:
   virtual bool executeInternal() CXX11_OVERRIDE;
 
@@ -52,15 +53,13 @@ protected:
   {
     return httpConnection_;
   }
+
 public:
-  AbstractProxyResponseCommand
-  (cuid_t cuid,
-   const std::shared_ptr<Request>& req,
-   const std::shared_ptr<FileEntry>& fileEntry,
-   RequestGroup* requestGroup,
-   const std::shared_ptr<HttpConnection>& httpConnection,
-   DownloadEngine* e,
-   const std::shared_ptr<SocketCore>& s);
+  AbstractProxyResponseCommand(
+      cuid_t cuid, const std::shared_ptr<Request>& req,
+      const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
+      const std::shared_ptr<HttpConnection>& httpConnection, DownloadEngine* e,
+      const std::shared_ptr<SocketCore>& s);
 
   virtual ~AbstractProxyResponseCommand();
 

+ 44 - 50
src/AbstractSingleDiskAdaptor.cc

@@ -41,13 +41,15 @@
 #include "WrDiskCacheEntry.h"
 #include "LogFactory.h"
 #ifdef HAVE_SOME_FALLOCATE
-# include "FallocFileAllocationIterator.h"
+#include "FallocFileAllocationIterator.h"
 #endif // HAVE_SOME_FALLOCATE
 
 namespace aria2 {
 
-AbstractSingleDiskAdaptor::AbstractSingleDiskAdaptor():
-  totalLength_(0), readOnly_(false) {}
+AbstractSingleDiskAdaptor::AbstractSingleDiskAdaptor()
+    : totalLength_(0), readOnly_(false)
+{
+}
 
 AbstractSingleDiskAdaptor::~AbstractSingleDiskAdaptor() {}
 
@@ -61,34 +63,31 @@ void AbstractSingleDiskAdaptor::openFile()
   diskWriter_->openFile(totalLength_);
 }
 
-void AbstractSingleDiskAdaptor::closeFile()
-{
-  diskWriter_->closeFile();
-}
+void AbstractSingleDiskAdaptor::closeFile() { diskWriter_->closeFile(); }
 
 void AbstractSingleDiskAdaptor::openExistingFile()
 {
   diskWriter_->openExistingFile(totalLength_);
 }
 
-void AbstractSingleDiskAdaptor::writeData
-(const unsigned char* data, size_t len, int64_t offset)
+void AbstractSingleDiskAdaptor::writeData(const unsigned char* data, size_t len,
+                                          int64_t offset)
 {
   diskWriter_->writeData(data, len, offset);
 }
 
-ssize_t AbstractSingleDiskAdaptor::readData
-(unsigned char* data, size_t len, int64_t offset)
+ssize_t AbstractSingleDiskAdaptor::readData(unsigned char* data, size_t len,
+                                            int64_t offset)
 {
   return diskWriter_->readData(data, len, offset);
 }
 
-ssize_t AbstractSingleDiskAdaptor::readDataDropCache
-(unsigned char* data, size_t len, int64_t offset)
+ssize_t AbstractSingleDiskAdaptor::readDataDropCache(unsigned char* data,
+                                                     size_t len, int64_t offset)
 {
   auto rv = readData(data, len, offset);
 
-  if(rv > 0) {
+  if (rv > 0) {
     diskWriter_->dropCache(len, offset);
   }
 
@@ -106,31 +105,32 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
   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);
+  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) {
+    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)));
+      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) {
+    }
+    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);
+      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);
+      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;
@@ -138,7 +138,7 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
       }
     }
   }
-  writeData(buf+buffoffset, buflen-buffoffset, start);
+  writeData(buf + buffoffset, buflen - buffoffset, start);
 }
 
 bool AbstractSingleDiskAdaptor::fileExists()
@@ -146,10 +146,7 @@ bool AbstractSingleDiskAdaptor::fileExists()
   return File(getFilePath()).exists();
 }
 
-int64_t AbstractSingleDiskAdaptor::size()
-{
-  return File(getFilePath()).size();
-}
+int64_t AbstractSingleDiskAdaptor::size() { return File(getFilePath()).size(); }
 
 void AbstractSingleDiskAdaptor::truncate(int64_t length)
 {
@@ -159,18 +156,18 @@ void AbstractSingleDiskAdaptor::truncate(int64_t length)
 std::unique_ptr<FileAllocationIterator>
 AbstractSingleDiskAdaptor::fileAllocationIterator()
 {
-  switch(getFileAllocationMethod()) {
+  switch (getFileAllocationMethod()) {
 #ifdef HAVE_SOME_FALLOCATE
-  case(DiskAdaptor::FILE_ALLOC_FALLOC):
-    return make_unique<FallocFileAllocationIterator>
-      (diskWriter_.get(), size() ,totalLength_);
+  case (DiskAdaptor::FILE_ALLOC_FALLOC):
+    return make_unique<FallocFileAllocationIterator>(diskWriter_.get(), size(),
+                                                     totalLength_);
 #endif // HAVE_SOME_FALLOCATE
-  case(DiskAdaptor::FILE_ALLOC_TRUNC):
-    return make_unique<TruncFileAllocationIterator>
-      (diskWriter_.get(), size(), totalLength_);
+  case (DiskAdaptor::FILE_ALLOC_TRUNC):
+    return make_unique<TruncFileAllocationIterator>(diskWriter_.get(), size(),
+                                                    totalLength_);
   default:
-    return make_unique<AdaptiveFileAllocationIterator>
-      (diskWriter_.get(), size(), totalLength_);
+    return make_unique<AdaptiveFileAllocationIterator>(diskWriter_.get(),
+                                                       size(), totalLength_);
   }
 }
 
@@ -186,20 +183,17 @@ void AbstractSingleDiskAdaptor::disableReadOnly()
   readOnly_ = false;
 }
 
-void AbstractSingleDiskAdaptor::enableMmap()
-{
-  diskWriter_->enableMmap();
-}
+void AbstractSingleDiskAdaptor::enableMmap() { diskWriter_->enableMmap(); }
 
 void AbstractSingleDiskAdaptor::cutTrailingGarbage()
 {
-  if(File(getFilePath()).size() > totalLength_) {
+  if (File(getFilePath()).size() > totalLength_) {
     diskWriter_->truncate(totalLength_);
   }
 }
 
-void AbstractSingleDiskAdaptor::setDiskWriter
-(std::unique_ptr<DiskWriter> diskWriter)
+void AbstractSingleDiskAdaptor::setDiskWriter(
+    std::unique_ptr<DiskWriter> diskWriter)
 {
   diskWriter_ = std::move(diskWriter);
 }

+ 7 - 10
src/AbstractSingleDiskAdaptor.h

@@ -47,6 +47,7 @@ private:
   std::unique_ptr<DiskWriter> diskWriter_;
   int64_t totalLength_;
   bool readOnly_;
+
 public:
   AbstractSingleDiskAdaptor();
 
@@ -63,12 +64,11 @@ public:
   virtual void writeData(const unsigned char* data, size_t len,
                          int64_t offset) CXX11_OVERRIDE;
 
-  virtual ssize_t readData(unsigned char* data, size_t len, int64_t offset)
-    CXX11_OVERRIDE;
+  virtual ssize_t readData(unsigned char* data, size_t len,
+                           int64_t offset) CXX11_OVERRIDE;
 
   virtual ssize_t readDataDropCache(unsigned char* data, size_t len,
-                                    int64_t offset)
-    CXX11_OVERRIDE;
+                                    int64_t offset) CXX11_OVERRIDE;
 
   virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
 
@@ -78,8 +78,8 @@ public:
 
   virtual void truncate(int64_t length) CXX11_OVERRIDE;
 
-  virtual std::unique_ptr<FileAllocationIterator> fileAllocationIterator()
-    CXX11_OVERRIDE;
+  virtual std::unique_ptr<FileAllocationIterator>
+  fileAllocationIterator() CXX11_OVERRIDE;
 
   // Make sure that DiskWriter is set before calling this function.
   virtual void enableReadOnly() CXX11_OVERRIDE;
@@ -104,10 +104,7 @@ public:
 
   void setTotalLength(int64_t totalLength);
 
-  int64_t getTotalLength() const
-  {
-    return totalLength_;
-  }
+  int64_t getTotalLength() const { return totalLength_; }
 };
 
 } // namespace aria2

+ 49 - 48
src/ActivePeerConnectionCommand.cc

@@ -56,16 +56,14 @@
 
 namespace aria2 {
 
-ActivePeerConnectionCommand::ActivePeerConnectionCommand
-(cuid_t cuid,
- RequestGroup* requestGroup,
- DownloadEngine* e,
- std::chrono::seconds interval)
-  : Command(cuid),
-    requestGroup_(requestGroup),
-    interval_(std::move(interval)),
-    e_(e),
-    numNewConnection_(5)
+ActivePeerConnectionCommand::ActivePeerConnectionCommand(
+    cuid_t cuid, RequestGroup* requestGroup, DownloadEngine* e,
+    std::chrono::seconds interval)
+    : Command(cuid),
+      requestGroup_(requestGroup),
+      interval_(std::move(interval)),
+      e_(e),
+      numNewConnection_(5)
 {
   requestGroup_->increaseNumCommand();
 }
@@ -75,50 +73,53 @@ ActivePeerConnectionCommand::~ActivePeerConnectionCommand()
   requestGroup_->decreaseNumCommand();
 }
 
-bool ActivePeerConnectionCommand::execute() {
-  if(btRuntime_->isHalt()) {
+bool ActivePeerConnectionCommand::execute()
+{
+  if (btRuntime_->isHalt()) {
     return true;
   }
-  if(checkPoint_.difference(global::wallclock()) >= interval_) {
+  if (checkPoint_.difference(global::wallclock()) >= interval_) {
     checkPoint_ = global::wallclock();
     NetStat& stat = requestGroup_->getDownloadContext()->getNetStat();
     const int maxDownloadLimit = requestGroup_->getMaxDownloadSpeedLimit();
     const int maxUploadLimit = requestGroup_->getMaxUploadSpeedLimit();
     int thresholdSpeed;
-    if(!bittorrent::getTorrentAttrs
-       (requestGroup_->getDownloadContext())->metadata.empty()) {
-      thresholdSpeed =
-        requestGroup_->getOption()->getAsInt(PREF_BT_REQUEST_PEER_SPEED_LIMIT);
-    } else {
+    if (!bittorrent::getTorrentAttrs(requestGroup_->getDownloadContext())
+             ->metadata.empty()) {
+      thresholdSpeed = requestGroup_->getOption()->getAsInt(
+          PREF_BT_REQUEST_PEER_SPEED_LIMIT);
+    }
+    else {
       thresholdSpeed = 0;
     }
-    if(maxDownloadLimit > 0) {
+    if (maxDownloadLimit > 0) {
       thresholdSpeed = std::min(maxDownloadLimit, thresholdSpeed);
     }
-    if(// for seeder state
-       (pieceStorage_->downloadFinished() && btRuntime_->lessThanMaxPeers() &&
-        (maxUploadLimit == 0 ||
-         stat.calculateUploadSpeed() < maxUploadLimit*0.8)) ||
-       // for leecher state
-       (!pieceStorage_->downloadFinished() &&
-        (stat.calculateDownloadSpeed() < thresholdSpeed ||
-         btRuntime_->lessThanMinPeers()))) {
+    if ( // for seeder state
+        (pieceStorage_->downloadFinished() && btRuntime_->lessThanMaxPeers() &&
+         (maxUploadLimit == 0 ||
+          stat.calculateUploadSpeed() < maxUploadLimit * 0.8)) ||
+        // for leecher state
+        (!pieceStorage_->downloadFinished() &&
+         (stat.calculateDownloadSpeed() < thresholdSpeed ||
+          btRuntime_->lessThanMinPeers()))) {
 
       int numConnection = 0;
-      if(pieceStorage_->downloadFinished()) {
-        if(btRuntime_->getMaxPeers() > btRuntime_->getConnections()) {
+      if (pieceStorage_->downloadFinished()) {
+        if (btRuntime_->getMaxPeers() > btRuntime_->getConnections()) {
           numConnection =
-            std::min(numNewConnection_,
-                     btRuntime_->getMaxPeers()-btRuntime_->getConnections());
+              std::min(numNewConnection_, btRuntime_->getMaxPeers() -
+                                              btRuntime_->getConnections());
         }
-      } else {
+      }
+      else {
         numConnection = numNewConnection_;
       }
 
       makeNewConnections(numConnection);
 
-      if(btRuntime_->getConnections() == 0 &&
-         !pieceStorage_->downloadFinished()) {
+      if (btRuntime_->getConnections() == 0 &&
+          !pieceStorage_->downloadFinished()) {
         btAnnounce_->overrideMinInterval(BtAnnounce::DEFAULT_ANNOUNCE_INTERVAL);
       }
     }
@@ -129,43 +130,43 @@ bool ActivePeerConnectionCommand::execute() {
 
 void ActivePeerConnectionCommand::makeNewConnections(int num)
 {
-  for(; num && peerStorage_->isPeerAvailable(); --num) {
+  for (; num && peerStorage_->isPeerAvailable(); --num) {
     cuid_t ncuid = e_->newCUID();
     std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid);
     // sanity check
-    if(!peer) {
+    if (!peer) {
       break;
     }
-    auto command = make_unique<PeerInitiateConnectionCommand>
-      (ncuid, requestGroup_, peer, e_, btRuntime_);
+    auto command = make_unique<PeerInitiateConnectionCommand>(
+        ncuid, requestGroup_, peer, e_, btRuntime_);
     command->setPeerStorage(peerStorage_);
     command->setPieceStorage(pieceStorage_);
     e_->addCommand(std::move(command));
-    A2_LOG_INFO(fmt(MSG_CONNECTING_TO_PEER, getCuid(),
-                    peer->getIPAddress().c_str()));
+    A2_LOG_INFO(
+        fmt(MSG_CONNECTING_TO_PEER, getCuid(), peer->getIPAddress().c_str()));
   }
 }
 
-void ActivePeerConnectionCommand::setBtRuntime
-(const std::shared_ptr<BtRuntime>& btRuntime)
+void ActivePeerConnectionCommand::setBtRuntime(
+    const std::shared_ptr<BtRuntime>& btRuntime)
 {
   btRuntime_ = btRuntime;
 }
 
-void ActivePeerConnectionCommand::setPieceStorage
-(const std::shared_ptr<PieceStorage>& pieceStorage)
+void ActivePeerConnectionCommand::setPieceStorage(
+    const std::shared_ptr<PieceStorage>& pieceStorage)
 {
   pieceStorage_ = pieceStorage;
 }
 
-void ActivePeerConnectionCommand::setPeerStorage
-(const std::shared_ptr<PeerStorage>& peerStorage)
+void ActivePeerConnectionCommand::setPeerStorage(
+    const std::shared_ptr<PeerStorage>& peerStorage)
 {
   peerStorage_ = peerStorage;
 }
 
-void ActivePeerConnectionCommand::setBtAnnounce
-(const std::shared_ptr<BtAnnounce>& btAnnounce)
+void ActivePeerConnectionCommand::setBtAnnounce(
+    const std::shared_ptr<BtAnnounce>& btAnnounce)
 {
   btAnnounce_ = btAnnounce;
 }

+ 2 - 4
src/ActivePeerConnectionCommand.h

@@ -64,10 +64,8 @@ private:
   Timer checkPoint_;
   int numNewConnection_; // the number of the connection to establish.
 public:
-  ActivePeerConnectionCommand(cuid_t cuid,
-                              RequestGroup* requestGroup,
-                              DownloadEngine* e,
-                              std::chrono::seconds interval);
+  ActivePeerConnectionCommand(cuid_t cuid, RequestGroup* requestGroup,
+                              DownloadEngine* e, std::chrono::seconds interval);
 
   virtual ~ActivePeerConnectionCommand();
 

+ 25 - 22
src/AdaptiveFileAllocationIterator.cc

@@ -40,68 +40,71 @@
 #include "Logger.h"
 #include "a2functional.h"
 #ifdef HAVE_FALLOCATE
-# include "FallocFileAllocationIterator.h"
+#include "FallocFileAllocationIterator.h"
 #endif // HAVE_FALLOCATE
 
 namespace aria2 {
 
-AdaptiveFileAllocationIterator::AdaptiveFileAllocationIterator
-(BinaryStream* stream, int64_t offset, int64_t totalLength)
- : stream_(stream),
-   offset_(offset),
-   totalLength_(totalLength)
-{}
+AdaptiveFileAllocationIterator::AdaptiveFileAllocationIterator(
+    BinaryStream* stream, int64_t offset, int64_t totalLength)
+    : stream_(stream), offset_(offset), totalLength_(totalLength)
+{
+}
 
 AdaptiveFileAllocationIterator::~AdaptiveFileAllocationIterator() {}
 
 void AdaptiveFileAllocationIterator::allocateChunk()
 {
-  if(!allocator_) {
+  if (!allocator_) {
 #ifdef HAVE_FALLOCATE
     try {
       A2_LOG_DEBUG("Testing file system supports fallocate.");
-      if(offset_ < totalLength_) {
+      if (offset_ < totalLength_) {
         int64_t len =
             std::min(totalLength_ - offset_, static_cast<int64_t>(4_k));
         stream_->allocate(offset_, len, false);
         offset_ += len;
       }
       A2_LOG_DEBUG("File system supports fallocate.");
-      allocator_ = make_unique<FallocFileAllocationIterator>
-        (stream_, offset_, totalLength_);
-    } catch(RecoverableException& e) {
+      allocator_ = make_unique<FallocFileAllocationIterator>(stream_, offset_,
+                                                             totalLength_);
+    }
+    catch (RecoverableException& e) {
       A2_LOG_DEBUG("File system does not support fallocate.");
-      auto salloc = make_unique<SingleFileAllocationIterator>
-        (stream_, offset_, totalLength_);
+      auto salloc = make_unique<SingleFileAllocationIterator>(stream_, offset_,
+                                                              totalLength_);
       salloc->init();
       allocator_ = std::move(salloc);
     }
-#else // !HAVE_FALLOCATE
-    auto salloc = make_unique<SingleFileAllocationIterator>
-      (stream_, offset_, totalLength_);
+#else  // !HAVE_FALLOCATE
+    auto salloc = make_unique<SingleFileAllocationIterator>(stream_, offset_,
+                                                            totalLength_);
     salloc->init();
     allocator_ = std::move(salloc);
 #endif // !HAVE_FALLOCATE
     allocator_->allocateChunk();
-  } else {
+  }
+  else {
     allocator_->allocateChunk();
   }
 }
 
 bool AdaptiveFileAllocationIterator::finished()
 {
-  if(!allocator_) {
+  if (!allocator_) {
     return offset_ == totalLength_;
-  } else {
+  }
+  else {
     return allocator_->finished();
   }
 }
 
 int64_t AdaptiveFileAllocationIterator::getCurrentLength()
 {
-  if(!allocator_) {
+  if (!allocator_) {
     return offset_;
-  } else {
+  }
+  else {
     return allocator_->getCurrentLength();
   }
 }

+ 4 - 4
src/AdaptiveFileAllocationIterator.h

@@ -43,8 +43,7 @@ namespace aria2 {
 
 class BinaryStream;
 
-class AdaptiveFileAllocationIterator:public FileAllocationIterator
-{
+class AdaptiveFileAllocationIterator : public FileAllocationIterator {
 private:
   std::unique_ptr<FileAllocationIterator> allocator_;
 
@@ -53,9 +52,10 @@ private:
   int64_t offset_;
 
   int64_t totalLength_;
+
 public:
-  AdaptiveFileAllocationIterator
-  (BinaryStream* stream, int64_t offset, int64_t totalLength);
+  AdaptiveFileAllocationIterator(BinaryStream* stream, int64_t offset,
+                                 int64_t totalLength);
 
   virtual ~AdaptiveFileAllocationIterator();
 

+ 85 - 85
src/AdaptiveURISelector.cc

@@ -65,22 +65,21 @@ namespace aria2 {
  * be tested again. Otherwise, it doesn't return anymore mirrors.
  */
 
-AdaptiveURISelector::AdaptiveURISelector
-(std::shared_ptr<ServerStatMan> serverStatMan, RequestGroup* requestGroup)
-  : serverStatMan_(std::move(serverStatMan)),
-    requestGroup_(requestGroup)
+AdaptiveURISelector::AdaptiveURISelector(
+    std::shared_ptr<ServerStatMan> serverStatMan, RequestGroup* requestGroup)
+    : serverStatMan_(std::move(serverStatMan)), requestGroup_(requestGroup)
 {
   resetCounters();
 }
 
 AdaptiveURISelector::~AdaptiveURISelector() {}
 
-std::string AdaptiveURISelector::select
-(FileEntry* fileEntry,
- const std::vector<std::pair<size_t, std::string> >& usedHosts)
+std::string AdaptiveURISelector::select(
+    FileEntry* fileEntry,
+    const std::vector<std::pair<size_t, std::string>>& usedHosts)
 {
-  A2_LOG_DEBUG(fmt("AdaptiveURISelector: called %d",
-                   requestGroup_->getNumConnection()));
+  A2_LOG_DEBUG(
+      fmt("AdaptiveURISelector: called %d", requestGroup_->getNumConnection()));
   std::deque<std::string>& uris = fileEntry->getRemainingUris();
   if (uris.empty() && requestGroup_->getNumConnection() <= 1) {
     // here we know the download will fail, trying to find previously
@@ -90,7 +89,7 @@ std::string AdaptiveURISelector::select
 
   std::string selected = selectOne(uris);
 
-  if(selected != A2STR::NIL) {
+  if (selected != A2STR::NIL) {
     uris.erase(std::find(std::begin(uris), std::end(uris), selected));
   }
   return selected;
@@ -102,8 +101,9 @@ constexpr auto MAX_TIMEOUT = 60_s;
 
 void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
 {
-  if (requestGroup_->getTimeout()*2 >= MAX_TIMEOUT) return;
-  requestGroup_->setTimeout(requestGroup_->getTimeout()*2);
+  if (requestGroup_->getTimeout() * 2 >= MAX_TIMEOUT)
+    return;
+  requestGroup_->setTimeout(requestGroup_->getTimeout() * 2);
 
   std::deque<std::string>& uris = fileEntry->getRemainingUris();
   // looking for retries
@@ -112,7 +112,7 @@ void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
   std::transform(std::begin(timeouts), std::end(timeouts),
                  std::back_inserter(uris), std::mem_fn(&URIResult::getURI));
 
-  if(A2_LOG_DEBUG_ENABLED) {
+  if (A2_LOG_DEBUG_ENABLED) {
     for (const auto& uri : uris) {
       A2_LOG_DEBUG(
           fmt("AdaptiveURISelector: will retry server with increased"
@@ -126,25 +126,27 @@ void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
 std::string AdaptiveURISelector::selectOne(const std::deque<std::string>& uris)
 {
 
-  if(uris.empty()) {
+  if (uris.empty()) {
     return A2STR::NIL;
-  } else {
+  }
+  else {
     const size_t numPieces =
-      requestGroup_->getDownloadContext()->getNumPieces();
+        requestGroup_->getDownloadContext()->getNumPieces();
 
-    bool reservedContext = numPieces > 0 &&
-      static_cast<size_t>(nbConnections_) > std::min
-      (numPieces,
-       static_cast<size_t>(requestGroup_->getNumConcurrentCommand()));
+    bool reservedContext =
+        numPieces > 0 &&
+        static_cast<size_t>(nbConnections_) >
+            std::min(numPieces, static_cast<size_t>(
+                                    requestGroup_->getNumConcurrentCommand()));
     bool selectBest = numPieces == 0 || reservedContext;
 
-    if(numPieces > 0)
+    if (numPieces > 0)
       ++nbConnections_;
 
     /* At least, 3 mirrors must be tested */
-    if(getNbTestedServers(uris) < 3) {
+    if (getNbTestedServers(uris) < 3) {
       std::string notTested = getFirstNotTestedUri(uris);
-      if(notTested != A2STR::NIL) {
+      if (notTested != A2STR::NIL) {
         A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing the first non tested"
                          " mirror: %s",
                          notTested.c_str()));
@@ -153,24 +155,26 @@ std::string AdaptiveURISelector::selectOne(const std::deque<std::string>& uris)
       }
     }
 
-    if(!selectBest && nbConnections_ > 1 && nbServerToEvaluate_ > 0) {
+    if (!selectBest && nbConnections_ > 1 && nbServerToEvaluate_ > 0) {
       nbServerToEvaluate_--;
       std::string notTested = getFirstNotTestedUri(uris);
-      if(notTested != A2STR::NIL) {
+      if (notTested != A2STR::NIL) {
         /* Here we return the first untested mirror */
         A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing non tested mirror %s"
                          " for connection #%d",
                          notTested.c_str(), nbConnections_));
         return notTested;
-      } else {
+      }
+      else {
         /* Here we return a mirror which need to be tested again */
         std::string toReTest = getFirstToTestUri(uris);
-        if(toReTest != A2STR::NIL) {
+        if (toReTest != A2STR::NIL) {
           A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing mirror %s which has"
                            " not been tested recently for connection #%d",
                            toReTest.c_str(), nbConnections_));
           return toReTest;
-        } else {
+        }
+        else {
           return getBestMirror(uris);
         }
       }
@@ -181,28 +185,26 @@ std::string AdaptiveURISelector::selectOne(const std::deque<std::string>& uris)
   }
 }
 
-std::string AdaptiveURISelector::getBestMirror
-(const std::deque<std::string>& uris) const
+std::string
+AdaptiveURISelector::getBestMirror(const std::deque<std::string>& uris) const
 {
   /* Here we return one of the bests mirrors */
   int max = getMaxDownloadSpeed(uris);
-  int min = max-(int)(max*0.25);
+  int min = max - (int)(max * 0.25);
   std::deque<std::string> bests = getUrisBySpeed(uris, min);
 
   if (bests.size() < 2) {
     std::string uri = getMaxDownloadSpeedUri(uris);
     A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing the best mirror :"
                      " %.2fKB/s %s (other mirrors are at least 25%% slower)",
-                     (float) max/1024,
-                     uri.c_str()));
+                     (float)max / 1024, uri.c_str()));
     return uri;
-  } else {
+  }
+  else {
     std::string uri = selectRandomUri(bests);
     A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing randomly one of the best"
                      " mirrors (range [%.2fKB/s, %.2fKB/s]): %s",
-                     (float) min/1024,
-                     (float) max/1024,
-                     uri.c_str()));
+                     (float)min / 1024, (float)max / 1024, uri.c_str()));
     return uri;
   }
 }
@@ -210,36 +212,32 @@ std::string AdaptiveURISelector::getBestMirror
 void AdaptiveURISelector::resetCounters()
 {
   nbConnections_ = 1;
-  nbServerToEvaluate_ =
-    requestGroup_->getOption()->getAsInt(PREF_SPLIT) - 1;
+  nbServerToEvaluate_ = requestGroup_->getOption()->getAsInt(PREF_SPLIT) - 1;
 }
 
-void AdaptiveURISelector::tuneDownloadCommand
-(const std::deque<std::string>& uris, DownloadCommand* command)
+void AdaptiveURISelector::tuneDownloadCommand(
+    const std::deque<std::string>& uris, DownloadCommand* command)
 {
   adjustLowestSpeedLimit(uris, command);
 }
 
-void AdaptiveURISelector::adjustLowestSpeedLimit
-(const std::deque<std::string>& uris, DownloadCommand* command) const
+void AdaptiveURISelector::adjustLowestSpeedLimit(
+    const std::deque<std::string>& uris, DownloadCommand* command) const
 {
-  int lowest =
-    requestGroup_->getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT);
+  int lowest = requestGroup_->getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT);
   if (lowest > 0) {
     int low_lowest = 4_k;
     int max = getMaxDownloadSpeed(uris);
     if (max > 0 && lowest > max / 4) {
       A2_LOG_NOTICE(fmt(_("Lowering lowest-speed-limit since known max speed is"
                           " too near (new:%d was:%d max:%d)"),
-                        max / 4,
-                        lowest,
-                        max));
+                        max / 4, lowest, max));
       command->setLowestDownloadSpeedLimit(max / 4);
-    } else if (max == 0 && lowest > low_lowest) {
+    }
+    else if (max == 0 && lowest > low_lowest) {
       A2_LOG_NOTICE(fmt(_("Lowering lowest-speed-limit since we have no clue"
                           " about available speed (now:%d was:%d)"),
-                        low_lowest,
-                        lowest));
+                        low_lowest, lowest));
       command->setLowestDownloadSpeedLimit(low_lowest);
     }
   }
@@ -253,30 +251,30 @@ int getUriMaxSpeed(std::shared_ptr<ServerStat> ss)
 }
 } // namespace
 
-int AdaptiveURISelector::getMaxDownloadSpeed
-(const std::deque<std::string>& uris) const
+int AdaptiveURISelector::getMaxDownloadSpeed(
+    const std::deque<std::string>& uris) const
 {
   std::string uri = getMaxDownloadSpeedUri(uris);
-  if(uri == A2STR::NIL)
+  if (uri == A2STR::NIL)
     return 0;
   return getUriMaxSpeed(getServerStats(uri));
 }
 
-std::string AdaptiveURISelector::getMaxDownloadSpeedUri
-(const std::deque<std::string>& uris) const
+std::string AdaptiveURISelector::getMaxDownloadSpeedUri(
+    const std::deque<std::string>& uris) const
 {
   int max = -1;
   std::string uri = A2STR::NIL;
-  for(auto& u : uris) {
+  for (auto& u : uris) {
     std::shared_ptr<ServerStat> ss = getServerStats(u);
-    if(!ss)
+    if (!ss)
       continue;
 
-    if((int)ss->getSingleConnectionAvgSpeed() > max) {
+    if ((int)ss->getSingleConnectionAvgSpeed() > max) {
       max = ss->getSingleConnectionAvgSpeed();
       uri = u;
     }
-    if((int)ss->getMultiConnectionAvgSpeed() > max) {
+    if ((int)ss->getMultiConnectionAvgSpeed() > max) {
       max = ss->getMultiConnectionAvgSpeed();
       uri = u;
     }
@@ -284,84 +282,86 @@ std::string AdaptiveURISelector::getMaxDownloadSpeedUri
   return uri;
 }
 
-std::deque<std::string> AdaptiveURISelector::getUrisBySpeed
-(const std::deque<std::string>& uris, int min) const
+std::deque<std::string>
+AdaptiveURISelector::getUrisBySpeed(const std::deque<std::string>& uris,
+                                    int min) const
 {
   std::deque<std::string> bests;
-  for(auto& uri : uris) {
+  for (auto& uri : uris) {
     std::shared_ptr<ServerStat> ss = getServerStats(uri);
-    if(!ss)
+    if (!ss)
       continue;
-    if(ss->getSingleConnectionAvgSpeed() > min ||
-       ss->getMultiConnectionAvgSpeed() > min) {
+    if (ss->getSingleConnectionAvgSpeed() > min ||
+        ss->getMultiConnectionAvgSpeed() > min) {
       bests.push_back(uri);
     }
   }
   return bests;
 }
 
-std::string AdaptiveURISelector::selectRandomUri
-(const std::deque<std::string>& uris) const
+std::string
+AdaptiveURISelector::selectRandomUri(const std::deque<std::string>& uris) const
 {
   int pos = SimpleRandomizer::getInstance()->getRandomNumber(uris.size());
   auto i = std::begin(uris);
-  i = i+pos;
+  i = i + pos;
   return *i;
 }
 
-std::string AdaptiveURISelector::getFirstNotTestedUri
-(const std::deque<std::string>& uris) const
+std::string AdaptiveURISelector::getFirstNotTestedUri(
+    const std::deque<std::string>& uris) const
 {
   for (const auto& i : uris) {
     std::shared_ptr<ServerStat> ss = getServerStats(i);
-    if(!ss)
+    if (!ss)
       return i;
   }
   return A2STR::NIL;
 }
 
-std::string AdaptiveURISelector::getFirstToTestUri
-(const std::deque<std::string>& uris) const
+std::string AdaptiveURISelector::getFirstToTestUri(
+    const std::deque<std::string>& uris) const
 {
   int counter;
   int power;
   for (const auto& u : uris) {
     std::shared_ptr<ServerStat> ss = getServerStats(u);
-    if(!ss)
+    if (!ss)
       continue;
     counter = ss->getCounter();
-    if(counter > 8)
+    if (counter > 8)
       continue;
     power = (int)pow(2.0, (float)counter);
     /* We test the mirror another time if it has not been
      * tested since 2^counter days */
-    if(ss->getLastUpdated().difference() > std::chrono::hours(power * 24)) {
+    if (ss->getLastUpdated().difference() > std::chrono::hours(power * 24)) {
       return u;
     }
   }
   return A2STR::NIL;
 }
 
-std::shared_ptr<ServerStat> AdaptiveURISelector::getServerStats
-(const std::string& uri) const
+std::shared_ptr<ServerStat>
+AdaptiveURISelector::getServerStats(const std::string& uri) const
 {
   uri_split_result us;
-  if(uri_split(&us, uri.c_str()) == 0) {
+  if (uri_split(&us, uri.c_str()) == 0) {
     std::string host = uri::getFieldString(us, USR_HOST, uri.c_str());
     std::string protocol = uri::getFieldString(us, USR_SCHEME, uri.c_str());
     return serverStatMan_->find(host, protocol);
-  } else {
+  }
+  else {
     return nullptr;
   }
 }
 
-int AdaptiveURISelector::getNbTestedServers
-(const std::deque<std::string>& uris) const
+int AdaptiveURISelector::getNbTestedServers(
+    const std::deque<std::string>& uris) const
 {
   int counter = 0;
-  for(const auto& u : uris) {
+  for (const auto& u : uris) {
     std::shared_ptr<ServerStat> ss = getServerStats(u);
-    if(!ss)
+    if (!ss)
       ++counter;
   }
   return uris.size() - counter;

+ 7 - 7
src/AdaptiveURISelector.h

@@ -46,7 +46,7 @@ class ServerStatMan;
 class RequestGroup;
 class ServerStat;
 
-class AdaptiveURISelector:public URISelector {
+class AdaptiveURISelector : public URISelector {
 private:
   std::shared_ptr<ServerStatMan> serverStatMan_;
   // No need to delete requestGroup_
@@ -69,20 +69,20 @@ private:
   std::shared_ptr<ServerStat> getServerStats(const std::string& uri) const;
   int getNbTestedServers(const std::deque<std::string>& uris) const;
   std::string getBestMirror(const std::deque<std::string>& uris) const;
+
 public:
   AdaptiveURISelector(std::shared_ptr<ServerStatMan> serverStatMan,
                       RequestGroup* requestGroup);
 
   virtual ~AdaptiveURISelector();
 
-  virtual std::string select
-  (FileEntry* fileEntry,
-   const std::vector<std::pair<size_t, std::string> >& usedHosts)
-    CXX11_OVERRIDE;
+  virtual std::string
+  select(FileEntry* fileEntry,
+         const std::vector<std::pair<size_t, std::string>>& usedHosts)
+      CXX11_OVERRIDE;
 
   virtual void tuneDownloadCommand(const std::deque<std::string>& uris,
-                                   DownloadCommand* command)
-    CXX11_OVERRIDE;
+                                   DownloadCommand* command) CXX11_OVERRIDE;
 
   virtual void resetCounters() CXX11_OVERRIDE;
 };

+ 7 - 15
src/Adler32MessageDigestImpl.cc

@@ -43,23 +43,18 @@
 namespace aria2 {
 
 Adler32MessageDigestImpl::Adler32MessageDigestImpl()
-  : adler_(adler32(0, Z_NULL, 0))
-{}
-
-size_t Adler32MessageDigestImpl::getDigestLength() const
+    : adler_(adler32(0, Z_NULL, 0))
 {
-  return length();
 }
 
-void Adler32MessageDigestImpl::reset()
-{
-  adler_ = adler32(0, Z_NULL, 0);
-}
+size_t Adler32MessageDigestImpl::getDigestLength() const { return length(); }
+
+void Adler32MessageDigestImpl::reset() { adler_ = adler32(0, Z_NULL, 0); }
 
 void Adler32MessageDigestImpl::update(const void* data, size_t length)
 {
-  adler_ = adler32(adler_, reinterpret_cast<const unsigned char*>(data),
-                   length);
+  adler_ =
+      adler32(adler_, reinterpret_cast<const unsigned char*>(data), length);
 }
 
 void Adler32MessageDigestImpl::digest(unsigned char* md)
@@ -68,9 +63,6 @@ void Adler32MessageDigestImpl::digest(unsigned char* md)
   memcpy(md, &adler, getDigestLength());
 }
 
-size_t Adler32MessageDigestImpl::length()
-{
-  return 4;
-}
+size_t Adler32MessageDigestImpl::length() { return 4; }
 
 } // namespace aria2

+ 6 - 2
src/Adler32MessageDigestImpl.h

@@ -41,8 +41,11 @@ namespace aria2 {
 
 #ifdef HAVE_ZLIB
 
-#define ADLER32_MESSAGE_DIGEST                          \
-  { "adler32", make_hi<Adler32MessageDigestImpl>() },
+#define ADLER32_MESSAGE_DIGEST                                                 \
+  {                                                                            \
+    "adler32", make_hi<Adler32MessageDigestImpl>()                             \
+  }                                                                            \
+  ,
 
 class Adler32MessageDigestImpl : public MessageDigestImpl {
 public:
@@ -52,6 +55,7 @@ public:
   virtual void update(const void* data, size_t length) CXX11_OVERRIDE;
   virtual void digest(unsigned char* md) CXX11_OVERRIDE;
   static size_t length();
+
 private:
   unsigned long adler_;
 };

+ 76 - 60
src/AnnounceList.cc

@@ -42,64 +42,71 @@
 
 namespace aria2 {
 
-AnnounceList::AnnounceList():currentTrackerInitialized_(false) {}
+AnnounceList::AnnounceList() : currentTrackerInitialized_(false) {}
 
-AnnounceList::AnnounceList
-(const std::vector<std::vector<std::string>>& announceList):
-  currentTrackerInitialized_(false) {
+AnnounceList::AnnounceList(
+    const std::vector<std::vector<std::string>>& announceList)
+    : currentTrackerInitialized_(false)
+{
   reconfigure(announceList);
 }
 
-AnnounceList::AnnounceList
-(const std::deque<std::shared_ptr<AnnounceTier>>& announceTiers):
-  tiers_(announceTiers), currentTrackerInitialized_(false)  {
+AnnounceList::AnnounceList(
+    const std::deque<std::shared_ptr<AnnounceTier>>& announceTiers)
+    : tiers_(announceTiers), currentTrackerInitialized_(false)
+{
   resetIterator();
 }
 
 AnnounceList::~AnnounceList() {}
 
-void AnnounceList::reconfigure
-(const std::vector<std::vector<std::string>>& announceList)
+void AnnounceList::reconfigure(
+    const std::vector<std::vector<std::string>>& announceList)
 {
-  for (const auto& vec: announceList) {
-    if(vec.empty()) {
+  for (const auto& vec : announceList) {
+    if (vec.empty()) {
       continue;
     }
 
     std::deque<std::string> uris(std::begin(vec), std::end(vec));
-    auto tier =
-      std::make_shared<AnnounceTier>(std::move(uris));
+    auto tier = std::make_shared<AnnounceTier>(std::move(uris));
     tiers_.push_back(std::move(tier));
   }
   resetIterator();
 }
 
-void AnnounceList::reconfigure(const std::string& url) {
-  std::deque<std::string> urls{ url };
+void AnnounceList::reconfigure(const std::string& url)
+{
+  std::deque<std::string> urls{url};
   tiers_.push_back(std::make_shared<AnnounceTier>(std::move(urls)));
   resetIterator();
 }
 
-void AnnounceList::resetIterator() {
+void AnnounceList::resetIterator()
+{
   currentTier_ = std::begin(tiers_);
-  if(currentTier_ != std::end(tiers_) && (*currentTier_)->urls.size()) {
+  if (currentTier_ != std::end(tiers_) && (*currentTier_)->urls.size()) {
     currentTracker_ = std::begin((*currentTier_)->urls);
     currentTrackerInitialized_ = true;
-  } else {
+  }
+  else {
     currentTrackerInitialized_ = false;
   }
 }
 
-std::string AnnounceList::getAnnounce() const {
-  if(currentTrackerInitialized_) {
+std::string AnnounceList::getAnnounce() const
+{
+  if (currentTrackerInitialized_) {
     return *currentTracker_;
-  } else {
+  }
+  else {
     return A2STR::NIL;
   }
 }
 
-void AnnounceList::announceSuccess() {
-  if(currentTrackerInitialized_) {
+void AnnounceList::announceSuccess()
+{
+  if (currentTrackerInitialized_) {
     (*currentTier_)->nextEvent();
     auto url = *currentTracker_;
     (*currentTier_)->urls.erase(currentTracker_);
@@ -109,39 +116,45 @@ void AnnounceList::announceSuccess() {
   }
 }
 
-void AnnounceList::announceFailure() {
-  if(currentTrackerInitialized_) {
+void AnnounceList::announceFailure()
+{
+  if (currentTrackerInitialized_) {
     ++currentTracker_;
-    if(currentTracker_ == std::end((*currentTier_)->urls)) {
+    if (currentTracker_ == std::end((*currentTier_)->urls)) {
       // force next event
       (*currentTier_)->nextEventIfAfterStarted();
       ++currentTier_;
-      if(currentTier_ == std::end(tiers_)) {
+      if (currentTier_ == std::end(tiers_)) {
         currentTrackerInitialized_ = false;
-      } else {
+      }
+      else {
         currentTracker_ = std::begin((*currentTier_)->urls);
       }
     }
   }
 }
 
-AnnounceTier::AnnounceEvent AnnounceList::getEvent() const {
-  if(currentTrackerInitialized_) {
+AnnounceTier::AnnounceEvent AnnounceList::getEvent() const
+{
+  if (currentTrackerInitialized_) {
     return (*currentTier_)->event;
-  } else {
+  }
+  else {
     return AnnounceTier::STARTED;
   }
 }
 
-void AnnounceList::setEvent(AnnounceTier::AnnounceEvent event) {
-  if(currentTrackerInitialized_) {
+void AnnounceList::setEvent(AnnounceTier::AnnounceEvent event)
+{
+  if (currentTrackerInitialized_) {
     (*currentTier_)->event = event;
   }
 }
 
-const char* AnnounceList::getEventString() const {
-  if(currentTrackerInitialized_) {
-    switch((*currentTier_)->event) {
+const char* AnnounceList::getEventString() const
+{
+  if (currentTrackerInitialized_) {
+    switch ((*currentTier_)->event) {
     case AnnounceTier::STARTED:
     case AnnounceTier::STARTED_AFTER_COMPLETION:
       return "started";
@@ -152,7 +165,8 @@ const char* AnnounceList::getEventString() const {
     default:
       return "";
     }
-  } else {
+  }
+  else {
     return "";
   }
 }
@@ -160,8 +174,9 @@ const char* AnnounceList::getEventString() const {
 namespace {
 class FindStoppedAllowedTier {
 public:
-  bool operator()(const std::shared_ptr<AnnounceTier>& tier) const {
-    switch(tier->event) {
+  bool operator()(const std::shared_ptr<AnnounceTier>& tier) const
+  {
+    switch (tier->event) {
     case AnnounceTier::DOWNLOADING:
     case AnnounceTier::STOPPED:
     case AnnounceTier::COMPLETED:
@@ -177,8 +192,9 @@ public:
 namespace {
 class FindCompletedAllowedTier {
 public:
-  bool operator()(const std::shared_ptr<AnnounceTier>& tier) const {
-    switch(tier->event) {
+  bool operator()(const std::shared_ptr<AnnounceTier>& tier) const
+  {
+    switch (tier->event) {
     case AnnounceTier::DOWNLOADING:
     case AnnounceTier::COMPLETED:
       return true;
@@ -189,38 +205,44 @@ public:
 };
 } // namespace
 
-size_t AnnounceList::countStoppedAllowedTier() const {
+size_t AnnounceList::countStoppedAllowedTier() const
+{
   return count_if(std::begin(tiers_), std::end(tiers_),
                   FindStoppedAllowedTier());
 }
 
-size_t AnnounceList::countCompletedAllowedTier() const {
+size_t AnnounceList::countCompletedAllowedTier() const
+{
   return count_if(std::begin(tiers_), std::end(tiers_),
                   FindCompletedAllowedTier());
 }
 
-void AnnounceList::setCurrentTier
-(std::deque<std::shared_ptr<AnnounceTier>>::iterator itr) {
-  if(itr != std::end(tiers_)) {
+void AnnounceList::setCurrentTier(
+    std::deque<std::shared_ptr<AnnounceTier>>::iterator itr)
+{
+  if (itr != std::end(tiers_)) {
     currentTier_ = std::move(itr);
     currentTracker_ = std::begin((*currentTier_)->urls);
   }
 }
 
-void AnnounceList::moveToStoppedAllowedTier() {
+void AnnounceList::moveToStoppedAllowedTier()
+{
   auto itr = find_wrap_if(std::begin(tiers_), std::end(tiers_), currentTier_,
                           FindStoppedAllowedTier());
   setCurrentTier(std::move(itr));
 }
 
-void AnnounceList::moveToCompletedAllowedTier() {
+void AnnounceList::moveToCompletedAllowedTier()
+{
   auto itr = find_wrap_if(std::begin(tiers_), std::end(tiers_), currentTier_,
                           FindCompletedAllowedTier());
   setCurrentTier(std::move(itr));
 }
 
-void AnnounceList::shuffle() {
-  for (const auto& tier: tiers_) {
+void AnnounceList::shuffle()
+{
+  for (const auto& tier : tiers_) {
     auto& urls = tier->urls;
     std::shuffle(std::begin(urls), std::end(urls),
                  *SimpleRandomizer::getInstance());
@@ -232,14 +254,11 @@ bool AnnounceList::allTiersFailed() const
   return currentTier_ == std::end(tiers_);
 }
 
-void AnnounceList::resetTier()
-{
-  resetIterator();
-}
+void AnnounceList::resetTier() { resetIterator(); }
 
 bool AnnounceList::currentTierAcceptsStoppedEvent() const
 {
-  if(currentTrackerInitialized_) {
+  if (currentTrackerInitialized_) {
     return FindStoppedAllowedTier()(*currentTier_);
   }
 
@@ -248,16 +267,13 @@ bool AnnounceList::currentTierAcceptsStoppedEvent() const
 
 bool AnnounceList::currentTierAcceptsCompletedEvent() const
 {
-  if(currentTrackerInitialized_) {
+  if (currentTrackerInitialized_) {
     return FindCompletedAllowedTier()(*currentTier_);
   }
 
   return false;
 }
 
-size_t AnnounceList::countTier() const
-{
-  return tiers_.size();
-}
+size_t AnnounceList::countTier() const { return tiers_.size(); }
 
 } // namespace aria2

+ 2 - 2
src/AnnounceList.h

@@ -56,8 +56,8 @@ private:
   bool currentTrackerInitialized_;
 
   void resetIterator();
-  void setCurrentTier
-  (std::deque<std::shared_ptr<AnnounceTier>>::iterator itr);
+  void setCurrentTier(std::deque<std::shared_ptr<AnnounceTier>>::iterator itr);
+
 public:
   AnnounceList();
   AnnounceList(const std::vector<std::vector<std::string>>& announceList);

+ 5 - 4
src/AnnounceTier.cc

@@ -37,14 +37,15 @@
 namespace aria2 {
 
 AnnounceTier::AnnounceTier(std::deque<std::string> urls)
-  : event(STARTED), urls(std::move(urls))
-{}
+    : event(STARTED), urls(std::move(urls))
+{
+}
 
 AnnounceTier::~AnnounceTier() {}
 
 void AnnounceTier::nextEvent()
 {
-  switch(event) {
+  switch (event) {
   case STARTED:
     event = DOWNLOADING;
     break;
@@ -64,7 +65,7 @@ void AnnounceTier::nextEvent()
 
 void AnnounceTier::nextEventIfAfterStarted()
 {
-  switch(event) {
+  switch (event) {
   case STOPPED:
     event = HALTED;
     break;

+ 4 - 4
src/AnonDiskWriterFactory.h

@@ -42,14 +42,14 @@ namespace aria2 {
 
 // DiskwriterFactory class template to create DiskWriter derived
 // object, ignoring filename.
-template<class DiskWriterType>
-class AnonDiskWriterFactory:public DiskWriterFactory {
+template <class DiskWriterType>
+class AnonDiskWriterFactory : public DiskWriterFactory {
 public:
   AnonDiskWriterFactory() {}
   virtual ~AnonDiskWriterFactory() {}
 
-  virtual std::unique_ptr<DiskWriter> newDiskWriter(const std::string& filename)
-    CXX11_OVERRIDE
+  virtual std::unique_ptr<DiskWriter>
+  newDiskWriter(const std::string& filename) CXX11_OVERRIDE
   {
     return make_unique<DiskWriterType>();
   }

+ 7 - 10
src/ApiCallbackDownloadEventListener.cc

@@ -37,19 +37,16 @@
 
 namespace aria2 {
 
-ApiCallbackDownloadEventListener::ApiCallbackDownloadEventListener
-(Session* session,
- DownloadEventCallback callback,
- void* userData)
-  : session_(session),
-    callback_(callback),
-    userData_(userData)
-{}
+ApiCallbackDownloadEventListener::ApiCallbackDownloadEventListener(
+    Session* session, DownloadEventCallback callback, void* userData)
+    : session_(session), callback_(callback), userData_(userData)
+{
+}
 
 ApiCallbackDownloadEventListener::~ApiCallbackDownloadEventListener() {}
 
-void ApiCallbackDownloadEventListener::onEvent
-(DownloadEvent event, const RequestGroup* group)
+void ApiCallbackDownloadEventListener::onEvent(DownloadEvent event,
+                                               const RequestGroup* group)
 {
   callback_(session_, event, group->getGID(), userData_);
 }

+ 3 - 2
src/ApiCallbackDownloadEventListener.h

@@ -45,8 +45,9 @@ public:
                                    DownloadEventCallback callback,
                                    void* userData);
   virtual ~ApiCallbackDownloadEventListener();
-  virtual void onEvent(DownloadEvent event, const RequestGroup* group)
-    CXX11_OVERRIDE;
+  virtual void onEvent(DownloadEvent event,
+                       const RequestGroup* group) CXX11_OVERRIDE;
+
 private:
   Session* session_;
   DownloadEventCallback callback_;

+ 35 - 63
src/AppleMessageDigestImpl.cc

@@ -42,77 +42,50 @@
 namespace aria2 {
 namespace {
 
-template<size_t dlen,
-         typename ctx_t,
-         int (*init_fn)(ctx_t*),
-         int (*update_fn)(ctx_t*, const void*, CC_LONG),
-         int(*final_fn)(unsigned char*, ctx_t*)>
+template <size_t dlen, typename ctx_t, int (*init_fn)(ctx_t*),
+          int (*update_fn)(ctx_t*, const void*, CC_LONG),
+          int (*final_fn)(unsigned char*, ctx_t*)>
 class MessageDigestBase : public MessageDigestImpl {
 public:
   MessageDigestBase() { reset(); }
   virtual ~MessageDigestBase() {}
 
-  static  size_t length() {
-    return dlen;
-  }
-  virtual size_t getDigestLength() const CXX11_OVERRIDE {
-    return dlen;
-  }
-  virtual void reset() CXX11_OVERRIDE {
-    init_fn(&ctx_);
-  }
-  virtual void update(const void* data, size_t length) CXX11_OVERRIDE {
+  static size_t length() { return dlen; }
+  virtual size_t getDigestLength() const CXX11_OVERRIDE { return dlen; }
+  virtual void reset() CXX11_OVERRIDE { init_fn(&ctx_); }
+  virtual void update(const void* data, size_t length) CXX11_OVERRIDE
+  {
     auto bytes = reinterpret_cast<const char*>(data);
     while (length) {
-      CC_LONG l = std::min(length, (size_t)std::numeric_limits<uint32_t>::max());
+      CC_LONG l =
+          std::min(length, (size_t)std::numeric_limits<uint32_t>::max());
       update_fn(&ctx_, bytes, l);
       length -= l;
       bytes += l;
     }
   }
-  virtual void digest(unsigned char* md) CXX11_OVERRIDE {
-    final_fn(md, &ctx_);
-  }
+  virtual void digest(unsigned char* md) CXX11_OVERRIDE { final_fn(md, &ctx_); }
+
 private:
   ctx_t ctx_;
 };
 
-typedef MessageDigestBase<CC_MD5_DIGEST_LENGTH,
-                          CC_MD5_CTX,
-                          CC_MD5_Init,
-                          CC_MD5_Update,
-                          CC_MD5_Final>
-MessageDigestMD5;
-typedef MessageDigestBase<CC_SHA1_DIGEST_LENGTH,
-                          CC_SHA1_CTX,
-                          CC_SHA1_Init,
-                          CC_SHA1_Update,
-                          CC_SHA1_Final>
-MessageDigestSHA1;
-typedef MessageDigestBase<CC_SHA224_DIGEST_LENGTH,
-                          CC_SHA256_CTX,
-                          CC_SHA224_Init,
-                          CC_SHA224_Update,
-                          CC_SHA224_Final>
-MessageDigestSHA224;
-typedef MessageDigestBase<CC_SHA256_DIGEST_LENGTH,
-                          CC_SHA256_CTX,
-                          CC_SHA256_Init,
-                          CC_SHA256_Update,
-                          CC_SHA256_Final>
-MessageDigestSHA256;
-typedef MessageDigestBase<CC_SHA384_DIGEST_LENGTH,
-                          CC_SHA512_CTX,
-                          CC_SHA384_Init,
-                          CC_SHA384_Update,
-                          CC_SHA384_Final>
-MessageDigestSHA384;
-typedef MessageDigestBase<CC_SHA512_DIGEST_LENGTH,
-                          CC_SHA512_CTX,
-                          CC_SHA512_Init,
-                          CC_SHA512_Update,
-                          CC_SHA512_Final>
-MessageDigestSHA512;
+typedef MessageDigestBase<CC_MD5_DIGEST_LENGTH, CC_MD5_CTX, CC_MD5_Init,
+                          CC_MD5_Update, CC_MD5_Final> MessageDigestMD5;
+typedef MessageDigestBase<CC_SHA1_DIGEST_LENGTH, CC_SHA1_CTX, CC_SHA1_Init,
+                          CC_SHA1_Update, CC_SHA1_Final> MessageDigestSHA1;
+typedef MessageDigestBase<CC_SHA224_DIGEST_LENGTH, CC_SHA256_CTX,
+                          CC_SHA224_Init, CC_SHA224_Update,
+                          CC_SHA224_Final> MessageDigestSHA224;
+typedef MessageDigestBase<CC_SHA256_DIGEST_LENGTH, CC_SHA256_CTX,
+                          CC_SHA256_Init, CC_SHA256_Update,
+                          CC_SHA256_Final> MessageDigestSHA256;
+typedef MessageDigestBase<CC_SHA384_DIGEST_LENGTH, CC_SHA512_CTX,
+                          CC_SHA384_Init, CC_SHA384_Update,
+                          CC_SHA384_Final> MessageDigestSHA384;
+typedef MessageDigestBase<CC_SHA512_DIGEST_LENGTH, CC_SHA512_CTX,
+                          CC_SHA512_Init, CC_SHA512_Update,
+                          CC_SHA512_Final> MessageDigestSHA512;
 
 } // namespace
 
@@ -122,13 +95,12 @@ std::unique_ptr<MessageDigestImpl> MessageDigestImpl::sha1()
 }
 
 MessageDigestImpl::hashes_t MessageDigestImpl::hashes = {
-  { "sha-1", make_hi<MessageDigestSHA1>() },
-  { "sha-224", make_hi<MessageDigestSHA224>() },
-  { "sha-256", make_hi<MessageDigestSHA256>() },
-  { "sha-384", make_hi<MessageDigestSHA384>() },
-  { "sha-512", make_hi<MessageDigestSHA512>() },
-  { "md5", make_hi<MessageDigestMD5>() },
-  ADLER32_MESSAGE_DIGEST
-};
+    {"sha-1", make_hi<MessageDigestSHA1>()},
+    {"sha-224", make_hi<MessageDigestSHA224>()},
+    {"sha-256", make_hi<MessageDigestSHA256>()},
+    {"sha-384", make_hi<MessageDigestSHA384>()},
+    {"sha-512", make_hi<MessageDigestSHA512>()},
+    {"md5", make_hi<MessageDigestMD5>()},
+    ADLER32_MESSAGE_DIGEST};
 
 } // namespace aria2

+ 20 - 53
src/AppleTLSContext.cc

@@ -56,17 +56,11 @@ using namespace aria2;
 #if defined(__MAC_10_6)
 
 #if defined(__MAC_10_7)
-static const void* query_keys[] = {
-  kSecClass,
-  kSecReturnRef,
-  kSecMatchPolicy,
-  kSecMatchLimit
-};
+static const void* query_keys[] = {kSecClass, kSecReturnRef, kSecMatchPolicy,
+                                   kSecMatchLimit};
 #endif // defined(__MAC_10_7)
 
-template <typename T>
-class CFRef
-{
+template <typename T> class CFRef {
   T ref_;
 
 public:
@@ -74,10 +68,7 @@ public:
 
   CFRef(T ref) : ref_(ref) {}
 
-  ~CFRef()
-  {
-    reset(nullptr);
-  }
+  ~CFRef() { reset(nullptr); }
 
   void reset(T ref)
   {
@@ -87,20 +78,11 @@ public:
     ref_ = ref;
   }
 
-  T get()
-  {
-    return ref_;
-  }
+  T get() { return ref_; }
 
-  const T get() const
-  {
-    return ref_;
-  }
+  const T get() const { return ref_; }
 
-  operator bool() const
-  {
-    return !!ref_;
-  }
+  operator bool() const { return !!ref_; }
 };
 
 static inline bool isWhitespace(char c)
@@ -116,8 +98,7 @@ static inline std::string stripWhitespace(std::string str)
   return str;
 }
 
-struct hash_validator
-{
+struct hash_validator {
   const std::string& hash_;
 
   hash_validator(const std::string& hash) : hash_(hash) {}
@@ -128,14 +109,14 @@ struct hash_validator
   }
 };
 
-struct hash_finder
-{
+struct hash_finder {
   CFDataRef data_;
   const std::string& hash_;
 
   hash_finder(CFDataRef data, const std::string& hash)
-    : data_(data), hash_(hash)
-  {}
+      : data_(data), hash_(hash)
+  {
+  }
 
   inline bool operator()(std::string type) const
   {
@@ -163,8 +144,7 @@ std::string errToString(OSStatus err)
   return rv;
 }
 
-bool checkIdentity(const SecIdentityRef id,
-                   const std::string& fingerPrint,
+bool checkIdentity(const SecIdentityRef id, const std::string& fingerPrint,
                    const std::vector<std::string> supported)
 {
   CFRef<SecCertificateRef> ref;
@@ -235,10 +215,7 @@ bool AppleTLSContext::addTrustedCACertFile(const std::string& certfile)
   return false;
 }
 
-SecIdentityRef AppleTLSContext::getCredentials()
-{
-  return credentials_;
-}
+SecIdentityRef AppleTLSContext::getCredentials() { return credentials_; }
 
 bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
 {
@@ -264,12 +241,8 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
     A2_LOG_ERROR("Failed to create SecPolicy");
     return false;
   }
-  const void* query_values[] = {
-    kSecClassIdentity,
-    kCFBooleanTrue,
-    policy.get(),
-    kSecMatchLimitAll
-  };
+  const void* query_values[] = {kSecClassIdentity, kCFBooleanTrue, policy.get(),
+                                kSecMatchLimitAll};
   CFRef<CFDictionaryRef> query(CFDictionaryCreate(
       nullptr, query_keys, query_values, 4, nullptr, nullptr));
   if (!query) {
@@ -372,18 +345,12 @@ bool AppleTLSContext::tryAsPKCS12(CFDataRef data, const char* password)
 #if defined(__MAC_10_6)
   CFRef<CFStringRef> passwordRef;
   if (password) {
-    passwordRef.reset(CFStringCreateWithBytes(nullptr,
-                                              (const UInt8*)password,
+    passwordRef.reset(CFStringCreateWithBytes(nullptr, (const UInt8*)password,
                                               strlen(password),
-                                              kCFStringEncodingUTF8,
-                                              false));
+                                              kCFStringEncodingUTF8, false));
   }
-  const void* keys[] = {
-    kSecImportExportPassphrase
-  };
-  const void* values[] = {
-    passwordRef.get()
-  };
+  const void* keys[] = {kSecImportExportPassphrase};
+  const void* values[] = {passwordRef.get()};
   CFRef<CFDictionaryRef> options(
       CFDictionaryCreate(nullptr, keys, values, 1, nullptr, nullptr));
   if (!options) {

+ 9 - 24
src/AppleTLSContext.h

@@ -46,12 +46,12 @@
 
 namespace aria2 {
 
-class AppleTLSContext : public TLSContext
-{
+class AppleTLSContext : public TLSContext {
 public:
   AppleTLSContext(TLSSessionSide side, TLSVersion ver)
-    : side_(side), minTLSVer_(ver), verifyPeer_(true), credentials_(nullptr)
-  {}
+      : side_(side), minTLSVer_(ver), verifyPeer_(true), credentials_(nullptr)
+  {
+  }
 
   virtual ~AppleTLSContext();
 
@@ -59,28 +59,16 @@ public:
   virtual bool addCredentialFile(const std::string& certfile,
                                  const std::string& keyfile) CXX11_OVERRIDE;
 
-  virtual bool addSystemTrustedCACerts() CXX11_OVERRIDE
-  {
-    return true;
-  }
+  virtual bool addSystemTrustedCACerts() CXX11_OVERRIDE { return true; }
 
   // certfile can contain multiple certificates.
   virtual bool addTrustedCACertFile(const std::string& certfile) CXX11_OVERRIDE;
 
-  virtual bool good() const CXX11_OVERRIDE
-  {
-    return true;
-  }
+  virtual bool good() const CXX11_OVERRIDE { return true; }
 
-  virtual TLSSessionSide getSide() const CXX11_OVERRIDE
-  {
-    return side_;
-  }
+  virtual TLSSessionSide getSide() const CXX11_OVERRIDE { return side_; }
 
-  virtual bool getVerifyPeer() const CXX11_OVERRIDE
-  {
-    return verifyPeer_;
-  }
+  virtual bool getVerifyPeer() const CXX11_OVERRIDE { return verifyPeer_; }
 
   virtual void setVerifyPeer(bool verify) CXX11_OVERRIDE
   {
@@ -89,10 +77,7 @@ public:
 
   SecIdentityRef getCredentials();
 
-  TLSVersion getMinTLSVersion() const
-  {
-    return minTLSVer_;
-  }
+  TLSVersion getMinTLSVersion() const { return minTLSVer_; }
 
 private:
   TLSSessionSide side_;

+ 209 - 202
src/AppleTLSSession.cc

@@ -101,172 +101,180 @@ static inline const char* protoToString(SSLProtocol proto)
   {                                                                            \
     n, #s                                                                      \
   }
-static struct
-{
+static struct {
   SSLCipherSuite suite;
   const char* name;
 } kSuites[] = {
-      // From CipherSuite.h (10.9)
-      SUITE(SSL_NULL_WITH_NULL_NULL, 0x0000),
-      SUITE(SSL_RSA_WITH_NULL_MD5, 0x0001),
-      SUITE(SSL_RSA_WITH_NULL_SHA, 0x0002),
-      SUITE(SSL_RSA_EXPORT_WITH_RC4_40_MD5, 0x0003),
-      SUITE(SSL_RSA_WITH_RC4_128_MD5, 0x0004),
-      SUITE(SSL_RSA_WITH_RC4_128_SHA, 0x0005),
-      SUITE(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0x0006),
-      SUITE(SSL_RSA_WITH_IDEA_CBC_SHA, 0x0007),
-      SUITE(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0008),
-      SUITE(SSL_RSA_WITH_DES_CBC_SHA, 0x0009),
-      SUITE(SSL_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
-      SUITE(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x000B),
-      SUITE(SSL_DH_DSS_WITH_DES_CBC_SHA, 0x000C),
-      SUITE(SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
-      SUITE(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x000E),
-      SUITE(SSL_DH_RSA_WITH_DES_CBC_SHA, 0x000F),
-      SUITE(SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
-      SUITE(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x0011),
-      SUITE(SSL_DHE_DSS_WITH_DES_CBC_SHA, 0x0012),
-      SUITE(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
-      SUITE(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0014),
-      SUITE(SSL_DHE_RSA_WITH_DES_CBC_SHA, 0x0015),
-      SUITE(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
-      SUITE(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 0x0017),
-      SUITE(SSL_DH_anon_WITH_RC4_128_MD5, 0x0018),
-      SUITE(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 0x0019),
-      SUITE(SSL_DH_anon_WITH_DES_CBC_SHA, 0x001A),
-      SUITE(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
-      SUITE(SSL_FORTEZZA_DMS_WITH_NULL_SHA, 0x001C),
-      SUITE(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, 0x001D),
-      SUITE(TLS_RSA_WITH_AES_128_CBC_SHA, 0x002F),
-      SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA, 0x0030),
-      SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA, 0x0031),
-      SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 0x0032),
-      SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 0x0033),
-      SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA, 0x0034),
-      SUITE(TLS_RSA_WITH_AES_256_CBC_SHA, 0x0035),
-      SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA, 0x0036),
-      SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA, 0x0037),
-      SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 0x0038),
-      SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 0x0039),
-      SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA, 0x003A),
-      SUITE(TLS_ECDH_ECDSA_WITH_NULL_SHA, 0xC001),
-      SUITE(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, 0xC002),
-      SUITE(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC003),
-      SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, 0xC004),
-      SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, 0xC005),
-      SUITE(TLS_ECDHE_ECDSA_WITH_NULL_SHA, 0xC006),
-      SUITE(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 0xC007),
-      SUITE(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC008),
-      SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 0xC009),
-      SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 0xC00A),
-      SUITE(TLS_ECDH_RSA_WITH_NULL_SHA, 0xC00B),
-      SUITE(TLS_ECDH_RSA_WITH_RC4_128_SHA, 0xC00C),
-      SUITE(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, 0xC00D),
-      SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, 0xC00E),
-      SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, 0xC00F),
-      SUITE(TLS_ECDHE_RSA_WITH_NULL_SHA, 0xC010),
-      SUITE(TLS_ECDHE_RSA_WITH_RC4_128_SHA, 0xC011),
-      SUITE(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 0xC012),
-      SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0xC013),
-      SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0xC014),
-      SUITE(TLS_ECDH_anon_WITH_NULL_SHA, 0xC015),
-      SUITE(TLS_ECDH_anon_WITH_RC4_128_SHA, 0xC016),
-      SUITE(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, 0xC017),
-      SUITE(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, 0xC018),
-      SUITE(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, 0xC019),
-      SUITE(TLS_NULL_WITH_NULL_NULL, 0x0000),
-      SUITE(TLS_RSA_WITH_NULL_MD5, 0x0001),
-      SUITE(TLS_RSA_WITH_NULL_SHA, 0x0002),
-      SUITE(TLS_RSA_WITH_RC4_128_MD5, 0x0004),
-      SUITE(TLS_RSA_WITH_RC4_128_SHA, 0x0005),
-      SUITE(TLS_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
-      SUITE(TLS_RSA_WITH_NULL_SHA256, 0x003B),
-      SUITE(TLS_RSA_WITH_AES_128_CBC_SHA256, 0x003C),
-      SUITE(TLS_RSA_WITH_AES_256_CBC_SHA256, 0x003D),
-      SUITE(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
-      SUITE(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
-      SUITE(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
-      SUITE(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
-      SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, 0x003E),
-      SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, 0x003F),
-      SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, 0x0040),
-      SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 0x0067),
-      SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, 0x0068),
-      SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, 0x0069),
-      SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 0x006A),
-      SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 0x006B),
-      SUITE(TLS_DH_anon_WITH_RC4_128_MD5, 0x0018),
-      SUITE(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
-      SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA256, 0x006C),
-      SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA256, 0x006D),
-      SUITE(TLS_PSK_WITH_RC4_128_SHA, 0x008A),
-      SUITE(TLS_PSK_WITH_3DES_EDE_CBC_SHA, 0x008B),
-      SUITE(TLS_PSK_WITH_AES_128_CBC_SHA, 0x008C),
-      SUITE(TLS_PSK_WITH_AES_256_CBC_SHA, 0x008D),
-      SUITE(TLS_DHE_PSK_WITH_RC4_128_SHA, 0x008E),
-      SUITE(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, 0x008F),
-      SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, 0x0090),
-      SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, 0x0091),
-      SUITE(TLS_RSA_PSK_WITH_RC4_128_SHA, 0x0092),
-      SUITE(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, 0x0093),
-      SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, 0x0094),
-      SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, 0x0095),
-      SUITE(TLS_PSK_WITH_NULL_SHA, 0x002C),
-      SUITE(TLS_DHE_PSK_WITH_NULL_SHA, 0x002D),
-      SUITE(TLS_RSA_PSK_WITH_NULL_SHA, 0x002E),
-      SUITE(TLS_RSA_WITH_AES_128_GCM_SHA256, 0x009C),
-      SUITE(TLS_RSA_WITH_AES_256_GCM_SHA384, 0x009D),
-      SUITE(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0x009E),
-      SUITE(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 0x009F),
-      SUITE(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, 0x00A0),
-      SUITE(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, 0x00A1),
-      SUITE(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, 0x00A2),
-      SUITE(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, 0x00A3),
-      SUITE(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, 0x00A4),
-      SUITE(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, 0x00A5),
-      SUITE(TLS_DH_anon_WITH_AES_128_GCM_SHA256, 0x00A6),
-      SUITE(TLS_DH_anon_WITH_AES_256_GCM_SHA384, 0x00A7),
-      SUITE(TLS_PSK_WITH_AES_128_GCM_SHA256, 0x00A8),
-      SUITE(TLS_PSK_WITH_AES_256_GCM_SHA384, 0x00A9),
-      SUITE(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, 0x00AA),
-      SUITE(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, 0x00AB),
-      SUITE(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, 0x00AC),
-      SUITE(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, 0x00AD),
-      SUITE(TLS_PSK_WITH_AES_128_CBC_SHA256, 0x00AE),
-      SUITE(TLS_PSK_WITH_AES_256_CBC_SHA384, 0x00AF),
-      SUITE(TLS_PSK_WITH_NULL_SHA256, 0x00B0),
-      SUITE(TLS_PSK_WITH_NULL_SHA384, 0x00B1),
-      SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, 0x00B2),
-      SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, 0x00B3),
-      SUITE(TLS_DHE_PSK_WITH_NULL_SHA256, 0x00B4),
-      SUITE(TLS_DHE_PSK_WITH_NULL_SHA384, 0x00B5),
-      SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, 0x00B6),
-      SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, 0x00B7),
-      SUITE(TLS_RSA_PSK_WITH_NULL_SHA256, 0x00B8),
-      SUITE(TLS_RSA_PSK_WITH_NULL_SHA384, 0x00B9),
-      SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 0xC023),
-      SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 0xC024),
-      SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, 0xC025),
-      SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, 0xC026),
-      SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0xC027),
-      SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 0xC028),
-      SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, 0xC029),
-      SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, 0xC02A),
-      SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02B),
-      SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02C),
-      SUITE(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02D),
-      SUITE(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02E),
-      SUITE(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0xC02F),
-      SUITE(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0xC030),
-      SUITE(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, 0xC031),
-      SUITE(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, 0xC032),
-      SUITE(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, 0x00FF),
-      SUITE(SSL_RSA_WITH_RC2_CBC_MD5, 0xFF80),
-      SUITE(SSL_RSA_WITH_IDEA_CBC_MD5, 0xFF81),
-      SUITE(SSL_RSA_WITH_DES_CBC_MD5, 0xFF82),
-      SUITE(SSL_RSA_WITH_3DES_EDE_CBC_MD5, 0xFF83),
-      SUITE(SSL_NO_SUCH_CIPHERSUITE, 0xFFFF)
-};
+    // From CipherSuite.h (10.11)
+    SUITE(SSL_NULL_WITH_NULL_NULL, 0x0000),
+    SUITE(SSL_RSA_WITH_NULL_MD5, 0x0001), SUITE(SSL_RSA_WITH_NULL_SHA, 0x0002),
+    SUITE(SSL_RSA_EXPORT_WITH_RC4_40_MD5, 0x0003),
+    SUITE(SSL_RSA_WITH_RC4_128_MD5, 0x0004),
+    SUITE(SSL_RSA_WITH_RC4_128_SHA, 0x0005),
+    SUITE(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0x0006),
+    SUITE(SSL_RSA_WITH_IDEA_CBC_SHA, 0x0007),
+    SUITE(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0008),
+    SUITE(SSL_RSA_WITH_DES_CBC_SHA, 0x0009),
+    SUITE(SSL_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
+    SUITE(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x000B),
+    SUITE(SSL_DH_DSS_WITH_DES_CBC_SHA, 0x000C),
+    SUITE(SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
+    SUITE(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x000E),
+    SUITE(SSL_DH_RSA_WITH_DES_CBC_SHA, 0x000F),
+    SUITE(SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
+    SUITE(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x0011),
+    SUITE(SSL_DHE_DSS_WITH_DES_CBC_SHA, 0x0012),
+    SUITE(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
+    SUITE(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0014),
+    SUITE(SSL_DHE_RSA_WITH_DES_CBC_SHA, 0x0015),
+    SUITE(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
+    SUITE(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 0x0017),
+    SUITE(SSL_DH_anon_WITH_RC4_128_MD5, 0x0018),
+    SUITE(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 0x0019),
+    SUITE(SSL_DH_anon_WITH_DES_CBC_SHA, 0x001A),
+    SUITE(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
+    SUITE(SSL_FORTEZZA_DMS_WITH_NULL_SHA, 0x001C),
+    SUITE(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, 0x001D),
+    SUITE(TLS_RSA_WITH_AES_128_CBC_SHA, 0x002F),
+    SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA, 0x0030),
+    SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA, 0x0031),
+    SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 0x0032),
+    SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 0x0033),
+    SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA, 0x0034),
+    SUITE(TLS_RSA_WITH_AES_256_CBC_SHA, 0x0035),
+    SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA, 0x0036),
+    SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA, 0x0037),
+    SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 0x0038),
+    SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 0x0039),
+    SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA, 0x003A),
+    SUITE(TLS_ECDH_ECDSA_WITH_NULL_SHA, 0xC001),
+    SUITE(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, 0xC002),
+    SUITE(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC003),
+    SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, 0xC004),
+    SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, 0xC005),
+    SUITE(TLS_ECDHE_ECDSA_WITH_NULL_SHA, 0xC006),
+    SUITE(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 0xC007),
+    SUITE(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC008),
+    SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 0xC009),
+    SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 0xC00A),
+    SUITE(TLS_ECDH_RSA_WITH_NULL_SHA, 0xC00B),
+    SUITE(TLS_ECDH_RSA_WITH_RC4_128_SHA, 0xC00C),
+    SUITE(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, 0xC00D),
+    SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, 0xC00E),
+    SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, 0xC00F),
+    SUITE(TLS_ECDHE_RSA_WITH_NULL_SHA, 0xC010),
+    SUITE(TLS_ECDHE_RSA_WITH_RC4_128_SHA, 0xC011),
+    SUITE(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 0xC012),
+    SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0xC013),
+    SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0xC014),
+    SUITE(TLS_ECDH_anon_WITH_NULL_SHA, 0xC015),
+    SUITE(TLS_ECDH_anon_WITH_RC4_128_SHA, 0xC016),
+    SUITE(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, 0xC017),
+    SUITE(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, 0xC018),
+    SUITE(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, 0xC019),
+    SUITE(TLS_NULL_WITH_NULL_NULL, 0x0000),
+    SUITE(TLS_RSA_WITH_NULL_MD5, 0x0001), SUITE(TLS_RSA_WITH_NULL_SHA, 0x0002),
+    SUITE(TLS_RSA_WITH_RC4_128_MD5, 0x0004),
+    SUITE(TLS_RSA_WITH_RC4_128_SHA, 0x0005),
+    SUITE(TLS_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
+    SUITE(TLS_RSA_WITH_AES_128_CBC_SHA, 0x002F),
+    SUITE(TLS_RSA_WITH_AES_256_CBC_SHA, 0x0035),
+    SUITE(TLS_RSA_WITH_NULL_SHA256, 0x003B),
+    SUITE(TLS_RSA_WITH_AES_128_CBC_SHA256, 0x003C),
+    SUITE(TLS_RSA_WITH_AES_256_CBC_SHA256, 0x003D),
+    SUITE(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
+    SUITE(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
+    SUITE(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
+    SUITE(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
+    SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA, 0x0030),
+    SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA, 0x0031),
+    SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 0x0032),
+    SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 0x0033),
+    SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA, 0x0036),
+    SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA, 0x0037),
+    SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 0x0038),
+    SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 0x0039),
+    SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, 0x003E),
+    SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, 0x003F),
+    SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, 0x0040),
+    SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 0x0067),
+    SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, 0x0068),
+    SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, 0x0069),
+    SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 0x006A),
+    SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 0x006B),
+    SUITE(TLS_DH_anon_WITH_RC4_128_MD5, 0x0018),
+    SUITE(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
+    SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA, 0x0034),
+    SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA, 0x003A),
+    SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA256, 0x006C),
+    SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA256, 0x006D),
+    SUITE(TLS_PSK_WITH_RC4_128_SHA, 0x008A),
+    SUITE(TLS_PSK_WITH_3DES_EDE_CBC_SHA, 0x008B),
+    SUITE(TLS_PSK_WITH_AES_128_CBC_SHA, 0x008C),
+    SUITE(TLS_PSK_WITH_AES_256_CBC_SHA, 0x008D),
+    SUITE(TLS_DHE_PSK_WITH_RC4_128_SHA, 0x008E),
+    SUITE(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, 0x008F),
+    SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, 0x0090),
+    SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, 0x0091),
+    SUITE(TLS_RSA_PSK_WITH_RC4_128_SHA, 0x0092),
+    SUITE(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, 0x0093),
+    SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, 0x0094),
+    SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, 0x0095),
+    SUITE(TLS_PSK_WITH_NULL_SHA, 0x002C),
+    SUITE(TLS_DHE_PSK_WITH_NULL_SHA, 0x002D),
+    SUITE(TLS_RSA_PSK_WITH_NULL_SHA, 0x002E),
+    SUITE(TLS_RSA_WITH_AES_128_GCM_SHA256, 0x009C),
+    SUITE(TLS_RSA_WITH_AES_256_GCM_SHA384, 0x009D),
+    SUITE(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0x009E),
+    SUITE(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 0x009F),
+    SUITE(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, 0x00A0),
+    SUITE(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, 0x00A1),
+    SUITE(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, 0x00A2),
+    SUITE(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, 0x00A3),
+    SUITE(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, 0x00A4),
+    SUITE(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, 0x00A5),
+    SUITE(TLS_DH_anon_WITH_AES_128_GCM_SHA256, 0x00A6),
+    SUITE(TLS_DH_anon_WITH_AES_256_GCM_SHA384, 0x00A7),
+    SUITE(TLS_PSK_WITH_AES_128_GCM_SHA256, 0x00A8),
+    SUITE(TLS_PSK_WITH_AES_256_GCM_SHA384, 0x00A9),
+    SUITE(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, 0x00AA),
+    SUITE(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, 0x00AB),
+    SUITE(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, 0x00AC),
+    SUITE(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, 0x00AD),
+    SUITE(TLS_PSK_WITH_AES_128_CBC_SHA256, 0x00AE),
+    SUITE(TLS_PSK_WITH_AES_256_CBC_SHA384, 0x00AF),
+    SUITE(TLS_PSK_WITH_NULL_SHA256, 0x00B0),
+    SUITE(TLS_PSK_WITH_NULL_SHA384, 0x00B1),
+    SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, 0x00B2),
+    SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, 0x00B3),
+    SUITE(TLS_DHE_PSK_WITH_NULL_SHA256, 0x00B4),
+    SUITE(TLS_DHE_PSK_WITH_NULL_SHA384, 0x00B5),
+    SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, 0x00B6),
+    SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, 0x00B7),
+    SUITE(TLS_RSA_PSK_WITH_NULL_SHA256, 0x00B8),
+    SUITE(TLS_RSA_PSK_WITH_NULL_SHA384, 0x00B9),
+    SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 0xC023),
+    SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 0xC024),
+    SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, 0xC025),
+    SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, 0xC026),
+    SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0xC027),
+    SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 0xC028),
+    SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, 0xC029),
+    SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, 0xC02A),
+    SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02B),
+    SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02C),
+    SUITE(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02D),
+    SUITE(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02E),
+    SUITE(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0xC02F),
+    SUITE(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0xC030),
+    SUITE(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, 0xC031),
+    SUITE(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, 0xC032),
+    SUITE(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, 0x00FF),
+    SUITE(SSL_RSA_WITH_RC2_CBC_MD5, 0xFF80),
+    SUITE(SSL_RSA_WITH_IDEA_CBC_MD5, 0xFF81),
+    SUITE(SSL_RSA_WITH_DES_CBC_MD5, 0xFF82),
+    SUITE(SSL_RSA_WITH_3DES_EDE_CBC_MD5, 0xFF83),
+    SUITE(SSL_NO_SUCH_CIPHERSUITE, 0xFFFF)};
 #undef SUITE
 
 static inline std::string suiteToString(const SSLCipherSuite suite)
@@ -283,9 +291,8 @@ static inline std::string suiteToString(const SSLCipherSuite suite)
   return ss.str();
 }
 
-static const char* kBlocked[] = {
-  "NULL", "anon",    "MD5",   "EXPORT", "DES", "IDEA", "NO_SUCH", "EMPTY", "PSK"
-};
+static const char* kBlocked[] = {"NULL", "anon", "MD5",     "EXPORT",
+                                 "DES",  "IDEA", "NO_SUCH", "PSK"};
 
 static inline bool isBlockedSuite(SSLCipherSuite suite)
 {
@@ -309,7 +316,7 @@ static SSLCipherSuiteList constructEnabledSuites(SSLContextRef ctx)
 #ifndef CIPHER_CONSTRUCT_ALWAYS
   static
 #endif
-  SSLCipherSuiteList rv(0);
+      SSLCipherSuiteList rv(0);
 
 #ifndef CIPHER_CONSTRUCT_ALWAYS
   if (!rv.empty()) {
@@ -345,17 +352,16 @@ TLSSession* TLSSession::make(TLSContext* ctx)
 }
 
 AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
-  : sslCtx_(nullptr),
-    sockfd_(0),
-    state_(st_constructed),
-    lastError_(noErr),
-    writeBuffered_(0)
+    : sslCtx_(nullptr),
+      sockfd_(0),
+      state_(st_constructed),
+      lastError_(noErr),
+      writeBuffered_(0)
 {
 #if defined(__MAC_10_8)
-  sslCtx_ = SSLCreateContext(nullptr,
-                             ctx->getSide() == TLS_SERVER ? kSSLServerSide :
-                                                            kSSLClientSide,
-                             kSSLStreamType);
+  sslCtx_ = SSLCreateContext(
+      nullptr, ctx->getSide() == TLS_SERVER ? kSSLServerSide : kSSLClientSide,
+      kSSLStreamType);
   lastError_ = sslCtx_ ? noErr : paramErr;
 #else
   lastError_ = SSLNewContext(ctx->getSide() == TLS_SERVER, &sslCtx_);
@@ -388,13 +394,13 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
   switch (ctx->getMinTLSVersion()) {
   case TLS_PROTO_SSL3:
     (void)SSLSetProtocolVersionEnabled(sslCtx_, kSSLProtocol3, true);
-    // fall through
+  // fall through
   case TLS_PROTO_TLS10:
     (void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol1, true);
-    // fall through
+  // fall through
   case TLS_PROTO_TLS11:
     (void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol11, true);
-    // fall through
+  // fall through
   case TLS_PROTO_TLS12:
     (void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol12, true);
   default:
@@ -410,12 +416,16 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
                             (SSLSessionOption)0x4, // kSSLSessionOptionSendOneByteRecord
 #endif
                             true);
+// False Start, if available
+#if defined(__MAC_10_9)
+  (void)SSLSetSessionOption(sslCtx_, kSSLSessionOptionFalseStart, true);
+#endif
 
 #if defined(__MAC_10_8)
   if (!ctx->getVerifyPeer()) {
     // This disables client verification
-    (void)SSLSetSessionOption(
-        sslCtx_, kSSLSessionOptionBreakOnServerAuth, true);
+    (void)SSLSetSessionOption(sslCtx_, kSSLSessionOptionBreakOnServerAuth,
+                              true);
   }
 #else
   (void)SSLSetEnableCertVerify(sslCtx_, ctx->getVerifyPeer());
@@ -700,8 +710,7 @@ OSStatus AppleTLSSession::sockRead(void* data, size_t* len)
 }
 
 int AppleTLSSession::tlsConnect(const std::string& hostname,
-                                TLSVersion& version,
-                                std::string& handshakeErr)
+                                TLSVersion& version, std::string& handshakeErr)
 {
   if (state_ != st_initialized) {
     return TLS_ERR_ERROR;
@@ -733,27 +742,25 @@ int AppleTLSSession::tlsConnect(const std::string& hostname,
   (void)SSLGetNegotiatedProtocolVersion(sslCtx_, &proto);
   SSLCipherSuite suite = SSL_NO_SUCH_CIPHERSUITE;
   (void)SSLGetNegotiatedCipher(sslCtx_, &suite);
-  A2_LOG_INFO(fmt("AppleTLS: Connected to %s with %s (%s)",
-                  hostname.c_str(),
-                  protoToString(proto),
-                  suiteToString(suite).c_str()));
+  A2_LOG_INFO(fmt("AppleTLS: Connected to %s with %s (%s)", hostname.c_str(),
+                  protoToString(proto), suiteToString(suite).c_str()));
 
   switch (proto) {
-    case kSSLProtocol3:
-      version = TLS_PROTO_SSL3;
-      break;
-    case kTLSProtocol1:
-      version = TLS_PROTO_TLS10;
-      break;
-    case kTLSProtocol11:
-      version = TLS_PROTO_TLS11;
-      break;
-    case kTLSProtocol12:
-      version = TLS_PROTO_TLS12;
-      break;
-    default:
-      version = TLS_PROTO_NONE;
-      break;
+  case kSSLProtocol3:
+    version = TLS_PROTO_SSL3;
+    break;
+  case kTLSProtocol1:
+    version = TLS_PROTO_TLS10;
+    break;
+  case kTLSProtocol11:
+    version = TLS_PROTO_TLS11;
+    break;
+  case kTLSProtocol12:
+    version = TLS_PROTO_TLS12;
+    break;
+  default:
+    version = TLS_PROTO_NONE;
+    break;
   }
 
   return TLS_ERR_OK;

+ 6 - 6
src/AppleTLSSession.h

@@ -41,8 +41,7 @@
 
 namespace aria2 {
 
-class AppleTLSSession : public TLSSession
-{
+class AppleTLSSession : public TLSSession {
   enum state_t {
     st_constructed,
     st_initialized,
@@ -95,8 +94,7 @@ public:
   // if the underlying transport blocks, or TLS_ERR_ERROR.
   // When returning TLS_ERR_ERROR, provide certificate validation error
   // in |handshakeErr|.
-  virtual int tlsConnect(const std::string& hostname,
-                         TLSVersion& version,
+  virtual int tlsConnect(const std::string& hostname, TLSVersion& version,
                          std::string& handshakeErr) CXX11_OVERRIDE;
 
   // Performs server side handshake. This function returns TLS_ERR_OK
@@ -107,9 +105,11 @@ public:
   // Returns last error string
   virtual std::string getLastErrorString() CXX11_OVERRIDE;
 
+  virtual size_t getRecvBufferedLength() CXX11_OVERRIDE { return 0; }
+
 private:
-  static OSStatus
-  SocketWrite(SSLConnectionRef conn, const void* data, size_t* len)
+  static OSStatus SocketWrite(SSLConnectionRef conn, const void* data,
+                              size_t* len)
   {
     return ((AppleTLSSession*)conn)->sockWrite(data, len);
   }

+ 16 - 19
src/AsyncNameResolver.cc

@@ -46,50 +46,47 @@ namespace aria2 {
 void callback(void* arg, int status, int timeouts, struct hostent* host)
 {
   AsyncNameResolver* resolverPtr = reinterpret_cast<AsyncNameResolver*>(arg);
-  if(status != ARES_SUCCESS) {
+  if (status != ARES_SUCCESS) {
     resolverPtr->error_ = ares_strerror(status);
     resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
     return;
   }
-  for(char** ap = host->h_addr_list; *ap; ++ap) {
+  for (char** ap = host->h_addr_list; *ap; ++ap) {
     char addrstring[NI_MAXHOST];
-    if(inetNtop(host->h_addrtype, *ap, addrstring, sizeof(addrstring)) == 0) {
+    if (inetNtop(host->h_addrtype, *ap, addrstring, sizeof(addrstring)) == 0) {
       resolverPtr->resolvedAddresses_.push_back(addrstring);
     }
   }
-  if(resolverPtr->resolvedAddresses_.empty()) {
+  if (resolverPtr->resolvedAddresses_.empty()) {
     resolverPtr->error_ = "no address returned or address conversion failed";
     resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
-  } else {
+  }
+  else {
     resolverPtr->status_ = AsyncNameResolver::STATUS_SUCCESS;
   }
 }
 
-AsyncNameResolver::AsyncNameResolver
-(int family
+AsyncNameResolver::AsyncNameResolver(int family
 #ifdef HAVE_ARES_ADDR_NODE
- , ares_addr_node* servers
+                                     ,
+                                     ares_addr_node* servers
 #endif // HAVE_ARES_ADDR_NODE
- )
-  : status_(STATUS_READY),
-    family_(family)
+                                     )
+    : status_(STATUS_READY), family_(family)
 {
   // TODO evaluate return value
   ares_init(&channel_);
 #if defined(HAVE_ARES_SET_SERVERS) && defined(HAVE_ARES_ADDR_NODE)
-  if(servers) {
+  if (servers) {
     // ares_set_servers has been added since c-ares 1.7.1
-    if(ares_set_servers(channel_, servers) != ARES_SUCCESS) {
+    if (ares_set_servers(channel_, servers) != ARES_SUCCESS) {
       A2_LOG_DEBUG("ares_set_servers failed");
     }
   }
 #endif // HAVE_ARES_SET_SERVERS && HAVE_ARES_ADDR_NODE
 }
 
-AsyncNameResolver::~AsyncNameResolver()
-{
-  ares_destroy(channel_);
-}
+AsyncNameResolver::~AsyncNameResolver() { ares_destroy(channel_); }
 
 void AsyncNameResolver::resolve(const std::string& name)
 {
@@ -148,11 +145,11 @@ ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt)
   ares_addr_node root;
   root.next = nullptr;
   ares_addr_node* tail = &root;
-  for (const auto& s: servers) {
+  for (const auto& s : servers) {
     auto node = make_unique<ares_addr_node>();
 
     size_t len = net::getBinAddr(&node->addr, s.c_str());
-    if(len != 0) {
+    if (len != 0) {
       node->next = nullptr;
       node->family = (len == 4 ? AF_INET : AF_INET6);
       tail->next = node.release();

+ 13 - 24
src/AsyncNameResolver.h

@@ -47,8 +47,9 @@
 namespace aria2 {
 
 class AsyncNameResolver {
-  friend void callback
-  (void* arg, int status, int timeouts, struct hostent* host);
+  friend void callback(void* arg, int status, int timeouts,
+                       struct hostent* host);
+
 public:
   enum STATUS {
     STATUS_READY,
@@ -56,6 +57,7 @@ public:
     STATUS_SUCCESS,
     STATUS_ERROR,
   };
+
 private:
   STATUS status_;
   int family_;
@@ -64,13 +66,14 @@ private:
   std::vector<std::string> resolvedAddresses_;
   std::string error_;
   std::string hostname_;
+
 public:
-  AsyncNameResolver
-  (int family
+  AsyncNameResolver(int family
 #ifdef HAVE_ARES_ADDR_NODE
-   , ares_addr_node* servers
+                    ,
+                    ares_addr_node* servers
 #endif // HAVE_ARES_ADDR_NODE
-   );
+                    );
 
   ~AsyncNameResolver();
 
@@ -81,24 +84,15 @@ public:
     return resolvedAddresses_;
   }
 
-  const std::string& getError() const
-  {
-    return error_;
-  }
+  const std::string& getError() const { return error_; }
 
-  STATUS getStatus() const
-  {
-    return status_;
-  }
+  STATUS getStatus() const { return status_; }
 
   int getFds(fd_set* rfdsPtr, fd_set* wfdsPtr) const;
 
   void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
 
-  int getFamily() const
-  {
-    return family_;
-  }
+  int getFamily() const { return family_; }
 #ifdef HAVE_LIBCARES
 
   int getsock(sock_t* sockets) const;
@@ -113,11 +107,7 @@ public:
 
   void reset();
 
-  const std::string& getHostname() const
-  {
-    return hostname_;
-  }
-
+  const std::string& getHostname() const { return hostname_; }
 };
 
 #ifdef HAVE_ARES_ADDR_NODE
@@ -126,7 +116,6 @@ ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt);
 
 #endif // HAVE_ARES_ADDR_NODE
 
-
 } // namespace aria2
 
 #endif // D_ASYNC_NAME_RESOLVER_H

+ 40 - 47
src/AsyncNameResolverMan.cc

@@ -49,21 +49,16 @@
 namespace aria2 {
 
 AsyncNameResolverMan::AsyncNameResolverMan()
-  : numResolver_(0),
-    resolverCheck_(0),
-    ipv4_(true),
-    ipv6_(true)
-{}
-
-AsyncNameResolverMan::~AsyncNameResolverMan()
+    : numResolver_(0), resolverCheck_(0), ipv4_(true), ipv6_(true)
 {
-  assert(!resolverCheck_);
 }
 
+AsyncNameResolverMan::~AsyncNameResolverMan() { assert(!resolverCheck_); }
+
 bool AsyncNameResolverMan::started() const
 {
-  for(size_t i = 0; i < numResolver_; ++i) {
-    if(asyncNameResolver_[i]) {
+  for (size_t i = 0; i < numResolver_; ++i) {
+    if (asyncNameResolver_[i]) {
       return true;
     }
   }
@@ -71,46 +66,44 @@ bool AsyncNameResolverMan::started() const
 }
 
 void AsyncNameResolverMan::startAsync(const std::string& hostname,
-                                      DownloadEngine* e,
-                                      Command* command)
+                                      DownloadEngine* e, Command* command)
 {
   numResolver_ = 0;
   // Set IPv6 resolver first, so that we can push IPv6 address in
   // front of IPv6 address in getResolvedAddress().
-  if(ipv6_) {
+  if (ipv6_) {
     startAsyncFamily(hostname, AF_INET6, e, command);
     ++numResolver_;
   }
-  if(ipv4_) {
+  if (ipv4_) {
     startAsyncFamily(hostname, AF_INET, e, command);
     ++numResolver_;
   }
-  A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME, command->getCuid(),
-                  hostname.c_str()));
+  A2_LOG_INFO(
+      fmt(MSG_RESOLVING_HOSTNAME, command->getCuid(), hostname.c_str()));
 }
 
 void AsyncNameResolverMan::startAsyncFamily(const std::string& hostname,
-                                            int family,
-                                            DownloadEngine* e,
+                                            int family, DownloadEngine* e,
                                             Command* command)
 {
-  asyncNameResolver_[numResolver_] = std::make_shared<AsyncNameResolver>
-    (family
+  asyncNameResolver_[numResolver_] =
+      std::make_shared<AsyncNameResolver>(family
 #ifdef HAVE_ARES_ADDR_NODE
-     ,
-     e->getAsyncDNSServers()
+                                          ,
+                                          e->getAsyncDNSServers()
 #endif // HAVE_ARES_ADDR_NODE
-     );
+                                              );
   asyncNameResolver_[numResolver_]->resolve(hostname);
   setNameResolverCheck(numResolver_, e, command);
 }
 
-void AsyncNameResolverMan::getResolvedAddress(std::vector<std::string>& res)
-const
+void AsyncNameResolverMan::getResolvedAddress(
+    std::vector<std::string>& res) const
 {
-  for(size_t i = 0; i < numResolver_; ++i) {
-    if(asyncNameResolver_[i]->getStatus() ==
-       AsyncNameResolver::STATUS_SUCCESS) {
+  for (size_t i = 0; i < numResolver_; ++i) {
+    if (asyncNameResolver_[i]->getStatus() ==
+        AsyncNameResolver::STATUS_SUCCESS) {
       auto& addrs = asyncNameResolver_[i]->getResolvedAddresses();
       res.insert(std::end(res), std::begin(addrs), std::end(addrs));
     }
@@ -121,16 +114,15 @@ const
 void AsyncNameResolverMan::setNameResolverCheck(DownloadEngine* e,
                                                 Command* command)
 {
-  for(size_t i = 0; i < numResolver_; ++i) {
+  for (size_t i = 0; i < numResolver_; ++i) {
     setNameResolverCheck(i, e, command);
   }
 }
 
-void AsyncNameResolverMan::setNameResolverCheck(size_t index,
-                                                DownloadEngine* e,
+void AsyncNameResolverMan::setNameResolverCheck(size_t index, DownloadEngine* e,
                                                 Command* command)
 {
-  if(asyncNameResolver_[index]) {
+  if (asyncNameResolver_[index]) {
     assert((resolverCheck_ & (1 << index)) == 0);
     resolverCheck_ |= 1 << index;
     e->addNameResolverCheck(asyncNameResolver_[index], command);
@@ -140,7 +132,7 @@ void AsyncNameResolverMan::setNameResolverCheck(size_t index,
 void AsyncNameResolverMan::disableNameResolverCheck(DownloadEngine* e,
                                                     Command* command)
 {
-  for(size_t i = 0; i < numResolver_; ++i) {
+  for (size_t i = 0; i < numResolver_; ++i) {
     disableNameResolverCheck(i, e, command);
   }
 }
@@ -149,7 +141,7 @@ void AsyncNameResolverMan::disableNameResolverCheck(size_t index,
                                                     DownloadEngine* e,
                                                     Command* command)
 {
-  if(asyncNameResolver_[index] && (resolverCheck_ & (1 << index))) {
+  if (asyncNameResolver_[index] && (resolverCheck_ & (1 << index))) {
     resolverCheck_ &= ~(1 << index);
     e->deleteNameResolverCheck(asyncNameResolver_[index], command);
   }
@@ -160,11 +152,11 @@ int AsyncNameResolverMan::getStatus() const
   size_t success = 0;
   size_t error = 0;
   bool ipv4Success = false;
-  for(size_t i = 0; i < numResolver_; ++i) {
-    switch(asyncNameResolver_[i]->getStatus()) {
+  for (size_t i = 0; i < numResolver_; ++i) {
+    switch (asyncNameResolver_[i]->getStatus()) {
     case AsyncNameResolver::STATUS_SUCCESS:
       ++success;
-      if(asyncNameResolver_[i]->getFamily() == AF_INET) {
+      if (asyncNameResolver_[i]->getFamily() == AF_INET) {
         ipv4Success = true;
       }
       break;
@@ -180,19 +172,21 @@ int AsyncNameResolverMan::getStatus() const
   // have to wait for a long time before timeout. We don't do the
   // inverse, because, based on today's deployment of DNS servers,
   // almost all of them can respond to A queries just fine.
-  if((success && ipv4Success) || success == numResolver_) {
+  if ((success && ipv4Success) || success == numResolver_) {
     return 1;
-  } else if(error == numResolver_) {
+  }
+  else if (error == numResolver_) {
     return -1;
-  } else {
+  }
+  else {
     return 0;
   }
 }
 
 const std::string& AsyncNameResolverMan::getLastError() const
 {
-  for(size_t i = 0; i < numResolver_; ++i) {
-    if(asyncNameResolver_[i]->getStatus() == AsyncNameResolver::STATUS_ERROR) {
+  for (size_t i = 0; i < numResolver_; ++i) {
+    if (asyncNameResolver_[i]->getStatus() == AsyncNameResolver::STATUS_ERROR) {
       // TODO This is not last error chronologically.
       return asyncNameResolver_[i]->getError();
     }
@@ -204,7 +198,7 @@ void AsyncNameResolverMan::reset(DownloadEngine* e, Command* command)
 {
   disableNameResolverCheck(e, command);
   assert(resolverCheck_ == 0);
-  for(size_t i = 0; i < numResolver_; ++i) {
+  for (size_t i = 0; i < numResolver_; ++i) {
     asyncNameResolver_[i].reset();
   }
   numResolver_ = 0;
@@ -219,14 +213,13 @@ void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan,
   // before network interfaces up. To workaround this, we check
   // addresses again if both addresses are not configured at the
   // startup.
-  if(!net::getIPv4AddrConfigured() && !net::getIPv6AddrConfigured()) {
+  if (!net::getIPv4AddrConfigured() && !net::getIPv6AddrConfigured()) {
     net::checkAddrconfig();
   }
-  if(!net::getIPv4AddrConfigured()) {
+  if (!net::getIPv4AddrConfigured()) {
     asyncNameResolverMan->setIPv4(false);
   }
-  if(!net::getIPv6AddrConfigured() ||
-     option->getAsBool(PREF_DISABLE_IPV6)) {
+  if (!net::getIPv6AddrConfigured() || option->getAsBool(PREF_DISABLE_IPV6)) {
     asyncNameResolverMan->setIPv6(false);
   }
 }

+ 5 - 14
src/AsyncNameResolverMan.h

@@ -55,15 +55,9 @@ public:
   // must call it before the destruction of this object.
   ~AsyncNameResolverMan();
   // Enable IPv4 address lookup. default: true
-  void setIPv4(bool ipv4)
-  {
-    ipv4_ = ipv4;
-  }
+  void setIPv4(bool ipv4) { ipv4_ = ipv4; }
   // Enable IPv6 address lookup. default: true
-  void setIPv6(bool ipv6)
-  {
-    ipv6_ = ipv6;
-  }
+  void setIPv6(bool ipv6) { ipv6_ = ipv6; }
   // Returns true if asynchronous name resolution has been started.
   bool started() const;
   // Starts asynchronous name resolution.
@@ -76,10 +70,7 @@ public:
   // Removes resolvers from DownloadEngine.
   void disableNameResolverCheck(DownloadEngine* e, Command* command);
   // Returns true if any of resolvers are added in DownloadEngine.
-  bool resolverChecked() const
-  {
-    return resolverCheck_;
-  }
+  bool resolverChecked() const { return resolverCheck_; }
   // Returns status value: 0 for inprogress, 1 for success and -1 for
   // failure.
   int getStatus() const;
@@ -87,9 +78,9 @@ public:
   const std::string& getLastError() const;
   // Resets state. Also removes resolvers from DownloadEngine.
   void reset(DownloadEngine* e, Command* command);
+
 private:
-  void startAsyncFamily(const std::string& hostname,
-                        int family,
+  void startAsyncFamily(const std::string& hostname, int family,
                         DownloadEngine* e, Command* command);
   void setNameResolverCheck(size_t resolverIndex, DownloadEngine* e,
                             Command* command);

+ 8 - 7
src/AuthConfig.cc

@@ -43,9 +43,9 @@ namespace aria2 {
 AuthConfig::AuthConfig() {}
 
 AuthConfig::AuthConfig(std::string user, std::string password)
-  : user_(std::move(user)),
-    password_(std::move(password))
-{}
+    : user_(std::move(user)), password_(std::move(password))
+{
+}
 
 AuthConfig::~AuthConfig() {}
 
@@ -57,12 +57,13 @@ std::string AuthConfig::getAuthText() const
   return s;
 }
 
-std::unique_ptr<AuthConfig> AuthConfig::create
-(std::string user, std::string password)
+std::unique_ptr<AuthConfig> AuthConfig::create(std::string user,
+                                               std::string password)
 {
-  if(user.empty()) {
+  if (user.empty()) {
     return nullptr;
-  } else {
+  }
+  else {
     return make_unique<AuthConfig>(std::move(user), std::move(password));
   }
 }

+ 5 - 10
src/AuthConfig.h

@@ -48,6 +48,7 @@ private:
   std::string authScheme_;
   std::string user_;
   std::string password_;
+
 public:
   AuthConfig();
   AuthConfig(std::string user, std::string password);
@@ -59,18 +60,12 @@ public:
 
   std::string getAuthText() const;
 
-  const std::string& getUser() const
-  {
-    return user_;
-  }
+  const std::string& getUser() const { return user_; }
 
-  const std::string& getPassword() const
-  {
-    return password_;
-  }
+  const std::string& getPassword() const { return password_; }
 
-  static std::unique_ptr<AuthConfig> create
-  (std::string user, std::string password);
+  static std::unique_ptr<AuthConfig> create(std::string user,
+                                            std::string password);
 };
 
 std::ostream& operator<<(std::ostream& o,

Some files were not shown because too many files changed in this diff