diff --git a/.gitmodules b/.gitmodules index 10d3b546d..6848ebb62 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "deps/asio"] path = deps/asio url = https://github.com/chriskohlhoff/asio.git +[submodule "deps/uri"] + path = deps/uri + url = https://github.com/cpp-netlib/uri.git diff --git a/.travis.yml b/.travis.yml index cd77aad99..7e6154d4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,61 +1,139 @@ -sudo: false +# cpp-netlib Project Travis CI configuration. + language: cpp -compiler: -- g++ -- clang +os: linux +dist: trusty +sudo: false + +cache: + - apt + - ccache + env: -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" -- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" -# Support the sanitizers in clang only -# - BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" CMAKE_CXX_FLAGS="-fsanitize=thread" -# - BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" CMAKE_CXX_FLAGS="-fsanitize=address" -# TODO(deanberris): It seems Boost is not msan-clean yet; report bugs and maybe fix? -#- BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" CMAKE_CXX_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2" -# matrix: -# exclude: -# - compiler: g++ -# env: BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" CMAKE_CXX_FLAGS="-fsanitize=thread" -# - compiler: g++ -# env: BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" CMAKE_CXX_FLAGS="-fsanitize=address" -# TODO(deanberris): It seems Boost is not msan-clean yet; report bugs and maybe fix? -# - compiler: g++ -# env: BOOST_VER=1.59.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" CMAKE_CXX_FLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2" + global: + - CCACHE_CPP2=yes + +matrix: + include: + # GCC 4.9 configurations + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-4.9 NEWCXX=g++-4.9 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-4.9", "libboost1.55-all-dev"] } } + # GCC 5.0 configurations + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=gcc-5 NEWCXX=g++-5 + addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-5", "libboost1.55-all-dev"] } } + # Clang 3.8 configurations + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.8 NEWCXX=clang++-3.8 + addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["clang-3.8", "libboost1.55-all-dev"] } } + # Clang 3.9 configurations + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-3.9 NEWCXX=clang++-3.9 + addons: { apt: { sources: ["llvm-toolchain-trusty-3.9"], packages: ["clang-3.9", "libboost1.55-all-dev"] } } + # Clang 4.0 configurations + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-4.0 NEWCXX=clang++-4.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-4.0"], packages: ["clang-4.0", "libboost1.55-all-dev"] } } + # Clang 5.0 configurations + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + - env: BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" Uri_BUILD_TESTS=OFF Uri_DISABLE_LIBCXX=YES NEWCC=clang-5.0 NEWCXX=clang++-5.0 + addons: { apt: { sources: ["llvm-toolchain-trusty-5.0"], packages: ["clang-5.0", "libboost1.55-all-dev"] } } + install: -- mkdir -p ${HOME}/bin -- if [ "${CC}" = "gcc" ]; then export TOOLSET="gcc"; ln -s `which g++-4.8` ${HOME}/bin/g++; - ln -s `which gcc-4.8` ${HOME}/bin/gcc; fi -- if [ "${CC}" = "clang" ]; then export TOOLSET="clang"; ln -s `which clang-3.6` ${HOME}/bin/clang; - ln -s `which clang++-3.6` ${HOME}/bin/clang++; fi -- export BOOST_VERSION=${BOOST_VER//./_} -- export PATH=${HOME}/bin:${PATH} -- travis_wait ./install-boost.sh -- export BOOST_ROOT=${HOME}/${CC}-boost_${BOOST_VER//./_} -- "${CXX} --version" -cache: - directories: - - "${HOME}/${CC}-boost_${BOOST_VER//./_}" + - if [[ "${CXX}" != "" ]]; then export CXX=${NEWCXX}; fi + - if [[ "${CC}" != "" ]]; then export CC=${NEWCC}; fi + - "${CXX} --version" + - "${CC} --version" + - pwd + - export CUR_DIR=`pwd` + - mkdir -p ${CUR_DIR}/bin + script: -- pwd -- sh -x build.sh + - pwd + - sh -x build.sh + after_failure: -- cat build/Testing/Temporary/LastTest.log -addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.6 - - kalakris-cmake - packages: - - gcc-4.8 - - g++-4.8 - - clang-3.6 - - cmake + - cat build/Testing/Temporary/LastTest.log + notifications: slack: secure: Y7lLjqZ83+b/jaJ5+EKwvgCDeERi4bVbDn9tLp8sieTdu+ENsPI+JmLYSXZXPpe7JrItrXW6uJJXN2wG1h7au4mpVVTghd31HBzuzrqVxDphWPhp16NYzvbAgQQRBXvFVvfSdW/Kb/n2fX6xDApY0t6vNREb/GKg0GyzESb4ZjU= diff --git a/CMakeLists.txt b/CMakeLists.txt index 7912ac0a5..5946295ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,10 @@ project(CPP-NETLIB) option( CPP-NETLIB_BUILD_SHARED_LIBS "Build cpp-netlib as shared libraries." OFF ) option( CPP-NETLIB_BUILD_TESTS "Build the cpp-netlib project tests." ON) -# option( CPP-NETLIB_BUILD_EXPERIMENTS "Build the cpp-netlib project experiments." ON) option( CPP-NETLIB_BUILD_EXAMPLES "Build the cpp-netlib project examples." ON) option( CPP-NETLIB_ENABLE_HTTPS "Build cpp-netlib with support for https if OpenSSL is found." ON) +option( CPP-NETLIB_STATIC_OPENSSL "Build cpp-netlib using static OpenSSL" OFF) +option( CPP-NETLIB_STATIC_BOOST "Build cpp-netlib using static Boost" OFF) include(GNUInstallDirs) @@ -37,8 +38,10 @@ else() set(BUILD_SHARED_LIBS OFF) endif() -# Always use Boost's shared libraries. -set(Boost_USE_STATIC_LIBS OFF) +# Use Boost's static libraries +if (CPP-NETLIB_STATIC_BOOST) + set(Boost_USE_STATIC_LIBS ON) +endif() # We need this for all tests to use the dynamic version. add_definitions(-DBOOST_TEST_DYN_LINK) @@ -46,10 +49,33 @@ add_definitions(-DBOOST_TEST_DYN_LINK) # Always use multi-threaded Boost libraries. set(Boost_USE_MULTI_THREADED ON) -find_package(Boost 1.57.0 REQUIRED) +find_package(Boost 1.55.0 REQUIRED COMPONENTS system thread) if (CPP-NETLIB_ENABLE_HTTPS) - find_package( OpenSSL ) + if (APPLE) + # If we're on OSX check for Homebrew's copy of OpenSSL instead of Apple's + if (NOT OpenSSL_DIR) + find_program(HOMEBREW brew) + if (HOMEBREW STREQUAL "HOMEBREW-NOTFOUND") + message(WARNING "Homebrew not found: not using Homebrew's OpenSSL") + if (NOT OPENSSL_ROOT_DIR) + message(WARNING "Use -DOPENSSL_ROOT_DIR for non-Apple OpenSSL") + endif() + else() + execute_process(COMMAND brew --prefix openssl + OUTPUT_VARIABLE OPENSSL_ROOT_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + endif() + endif() + if (CPP-NETLIB_STATIC_OPENSSL) + if (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() + endif() + find_package(OpenSSL) endif() find_package( Threads ) @@ -75,14 +101,24 @@ if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU) elseif (${CMAKE_CXX_COMPILER_ID} MATCHES Clang) # We want to link in C++11 mode in Clang too, but also set a high enough # template depth for the template metaprogramming. - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -ftemplate-depth=256 -std=c++11") + set (CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -Wall -ftemplate-depth=256 -std=c++11 -DBOOST_ASIO_HAS_STD_CHRONO -DBOOST_ASIO_HAS_STD_ARRAY -DBOOST_ASIO_HAS_STD_SHARED_PTR -DBOOST_ASIO_HAS_STD_ATOMIC -DBOOST_ASIO_HAS_VARIADIC_TEMPLATES -DBOOST_ASIO_HAS_MOVE -DBOOST_THREAD_VERSION=3") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # Use libc++ only in OS X. set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lc++") + elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + # Use libstdc++ for Linux. + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lstdc++") endif() endif() +set(Uri_BUILD_TESTS OFF) +set(Uri_BUILD_DOCS OFF) +set(Uri_DISABLE_LIBCXX ON) +add_subdirectory(deps/uri) +include_directories(deps/uri/include) if (Boost_FOUND) if (MSVC) @@ -93,22 +129,17 @@ if (Boost_FOUND) endif(WIN32) include_directories(${Boost_INCLUDE_DIRS}) - # Asio - add_definitions(-DASIO_HEADER_ONLY) - include_directories(deps/asio/asio/include) + # # Asio + # add_definitions(-DASIO_STANDALONE) + # include_directories(deps/asio/asio/include) enable_testing() add_subdirectory(libs/network/src) if (CPP-NETLIB_BUILD_TESTS) add_subdirectory(deps/googletest) + add_subdirectory(deps/uri/test) add_subdirectory(libs/network/test) endif (CPP-NETLIB_BUILD_TESTS) - # if (CPP-NETLIB_BUILD_EXPERIMENTS) - # add_subdirectory(libs/network/experiment) - # endif (CPP-NETLIB_BUILD_EXPERIMENTS) - # if (NOT MSVC AND CPP-NETLIB_BUILD_TESTS) - # add_subdirectory(libs/mime/test) - # endif(NOT MSVC AND CPP-NETLIB_BUILD_TESTS) if (CPP-NETLIB_BUILD_EXAMPLES) add_subdirectory(libs/network/example) endif (CPP-NETLIB_BUILD_EXAMPLES) @@ -118,43 +149,50 @@ if (MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") endif() +# See whether we can find the ccache program -- if we can, then use it for the build. +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) +endif(CCACHE_FOUND) + enable_testing() install(DIRECTORY boost DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -### -## Export Targets -# (so cpp-netlib can be easily used by other CMake projects) -# [see http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file] - -# Add all targets to the build-tree export set -export(TARGETS cppnetlib-client-connections cppnetlib-server-parsers cppnetlib-uri - FILE "${PROJECT_BINARY_DIR}/cppnetlibTargets.cmake") -# Export the package for use from the build-tree -# (this registers the build-tree with a global CMake-registry) -export(PACKAGE cppnetlib) -# Create the cppnetlibConfig.cmake and cppnetlibConfigVersion files -file(RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}" - "${CMAKE_INSTALL_FULL_INCLUDEDIR}") -# ... for the build tree -set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" ${Boost_INCLUDE_DIRS}) -configure_file(cppnetlibConfig.cmake.in - "${PROJECT_BINARY_DIR}/cppnetlibConfig.cmake" @ONLY) -# ... for the install tree -set(CONF_INCLUDE_DIRS "\${CPPNETLIB_CMAKE_DIR}/${REL_INCLUDE_DIR}") -set(CONF_INCLUDE_DIRS ${CONF_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) -configure_file(cppnetlibConfig.cmake.in - "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cppnetlibConfig.cmake" @ONLY) -# ... for both -configure_file(cppnetlibConfigVersion.cmake.in - "${PROJECT_BINARY_DIR}/cppnetlibConfigVersion.cmake" @ONLY) -# Install the cppnetlibConfig.cmake and cppnetlibConfigVersion.cmake -install(FILES - "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cppnetlibConfig.cmake" - "${PROJECT_BINARY_DIR}/cppnetlibConfigVersion.cmake" - DESTINATION "${INSTALL_CMAKE_DIR}" - COMPONENT dev) -# Install the export set for use with the install-tree -install(EXPORT cppnetlibTargets - DESTINATION "${INSTALL_CMAKE_DIR}" - COMPONENT dev) +# ### +# ## Export Targets +# # (so cpp-netlib can be easily used by other CMake projects) +# # [see http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file] +# +# # Add all targets to the build-tree export set +# export(TARGETS cppnetlib-client-connections cppnetlib-server-parsers cppnetlib-uri +# FILE "${PROJECT_BINARY_DIR}/cppnetlibTargets.cmake") +# # Export the package for use from the build-tree +# # (this registers the build-tree with a global CMake-registry) +# export(PACKAGE cppnetlib) +# # Create the cppnetlibConfig.cmake and cppnetlibConfigVersion files +# file(RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}" +# "${CMAKE_INSTALL_FULL_INCLUDEDIR}") +# # ... for the build tree +# set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" ${Boost_INCLUDE_DIRS}) +# configure_file(cppnetlibConfig.cmake.in +# "${PROJECT_BINARY_DIR}/cppnetlibConfig.cmake" @ONLY) +# # ... for the install tree +# set(CONF_INCLUDE_DIRS "\${CPPNETLIB_CMAKE_DIR}/${REL_INCLUDE_DIR}") +# set(CONF_INCLUDE_DIRS ${CONF_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) +# configure_file(cppnetlibConfig.cmake.in +# "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cppnetlibConfig.cmake" @ONLY) +# # ... for both +# configure_file(cppnetlibConfigVersion.cmake.in +# "${PROJECT_BINARY_DIR}/cppnetlibConfigVersion.cmake" @ONLY) +# # Install the cppnetlibConfig.cmake and cppnetlibConfigVersion.cmake +# install(FILES +# "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cppnetlibConfig.cmake" +# "${PROJECT_BINARY_DIR}/cppnetlibConfigVersion.cmake" +# DESTINATION "${INSTALL_CMAKE_DIR}" +# COMPONENT dev) +# # Install the export set for use with the install-tree +# install(EXPORT cppnetlibTargets +# DESTINATION "${INSTALL_CMAKE_DIR}" +# COMPONENT dev) diff --git a/code_of_conduct.md b/CODE_OF_CONDUCT.md similarity index 100% rename from code_of_conduct.md rename to CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 000000000..f366794d3 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,154 @@ +Overview +======== + +In this page we document the process by which the developers of the +project collaborate and get things done. If you're interested in +contributing or getting involved please consider the guidelines and +tips that are outlined in this page. Please check-in often as we flesh +out this document further. + +Introduction +============ + +The first thing contributors and developers have to do is introduce +themselves to the community. We'd like to have all contributors +involved in the decision making process with regards to the +development of both the community and the library. We value +individuals and their personal styles, so the more everyone knows +about everyone the better we can work together to achieve the same +goal. + +If you haven't yet, please `subscribe`_ to the developers mailing list +and introduce yourself before proceeding. + +.. _`subscribe`: https://groups.google.com/group/cpp-netlib` + +Pull Requests +============= + +The maintainers of the project review and merge `Pull Requests`_ (from +here on out referred to as PR's) from contributors using the GitHub +Pull Request feature. This allows the project to move forward using +the Git distributed development workflow. If you need an introduction +to git, please refer to the following links for git-specific +information. + +.. _`Pull Requests`: https://help.github.com/articles/using-pull-requests + +* `ProGit`_ — a website dedicated to basic and advanced git usage. +* `GitHub Git Setup`_ — the GitHub help pages on setting up git to work + with GitHub. + +.. _`ProGit`: http://git-scm.com/book +.. _`GitHub Git Setup`: https://help.github.com/articles/set-up-git + +What follows in this section assumes that you're already familiar with +the basic git workflow. + +Forking the Repo +================ + +Forking requires that you already have a GitHub account. Before +continuing, please make sure that you've signed up for a GitHub +account (it's free to develop for open source projects) and have +familiarized yourself with the different development workflows. It's +important that you understand the GitHub workflow before continuing. + +The official repository is located in GitHub at +https://github.com/cpp-netlib/cpp-netlib. Before you can submit PR's +you should first create your own fork of the repository on GitHub. You +can fork the repository by clicking on `Fork`_ at the upper right portion +of the page. + +.. _`Fork`: https://github.com/cpp-netlib/cpp-netlib/fork + +Preparing a PR +============== + +Once you have a fork of the repo, determine to which branch you'd like +to send a PR to. In the next section we describe the various branches +we'll be dealing with in the course of development of a release. + +When you've determined the branch to which you'd like to send a PR to +you can follow these steps to prepare your change for inclusion in the +library. + +1. Create an integration branch. This integration branch should be + rooted off the branch you intend to send a PR to. For example, if + you're sending a PR to cpp-netlib/master and your fork is + user/master, you should create a user/master-integration branch. +2. Create a topic branch. From the integration branch, you can then + create as many topic branches as you want. It's recommended that you + isolate all experimentation to branches — once you're resonably sure + that your work is good to go, merge your topic branch into the + integration branch in your local repo, then push the changes to your + GitHub repo. +3. Make sure your integration branch is up to date. To do this you + should first pull changes to your local master (assuming that's where + you'd like to send a pull request to), rebase your integration branch + to the tip of master, then make sure all merge conflicts are dealt + with. Proceed only when your integration branch is up-to-date with the + official branch you're going to send your PR to. +4. Send the PR. Once you're reasonably happy with the state of your + integration branch, send off a PR to the official repo and set the + destination branch as the branch you intend to send the change to. +5. Address Comments The maintainers will be reviewing your changes, and + sometimes they may have comments they will ask you to address in + your PR. You can do this by going back to the second step of this + process, but you don't need to send another PR -- all you have to do + is push your changes to your GitHub hosted integration branch and + your PR will be updated automatically. That said, don't forget to + update the discussion on the PR that you're ready for the PR to be + reviewed again. +6. Your PR is merged. If you've done everything correctly up to this + point, your PR should be cleanly merge-able into the branch you sent + the PR to. A maintiner will merge you change into the project and + you're now officially a contributor to the project! + + +In case you have multiple PR's in flight, you may want to have +multiple integration branches — that is, one integration branch per PR +should be good to keep. + +Working Branches +================ + +The project always has the latest bleeding edge versions of the +library under development in the master branch. This version is +explicitly unstable and subject to (potentially massive) changes over +time. + +Once the state of master has stabilized and a release process is +initiated by the project maintainers (it will be announced on the +mailing list) a version-devel branch is started from master and a +release candidate is prepared. For example, if a 1.0 release is +initiated, a branch 1.0-devel is started off master. + +A release candidate is tagged off of the version-devel branch on a +regular basis, and is publicized as widely as possible. The tag name +should be of the form version-rcN. Again as an example, the first +release candidate for a 1.0 release will be tagged as 1.0.0-rc0. + +All PR's for the upcoming version should go directly to the +version-devel branch. + +During the stabilization of the version-devel branch, master remains +open for PR's for new functionality, new accepted libraries, and API +breaking changes. + +Once a release candidate is deemed "good to go" by the maintainers we +tag the library (and submodules appropriately) with a tag of the form +version-final. As with earlier examples, the tag for the 1.0 release +would be 1.0.0-final. + +Patch Releases +============== + +Critical bug fixes go into the version-devel branch after a final +release has been packaged. In case there's a need for update releases, +the release candidate process is followed until another final version +of the patch release is tagged. + +In our on-going example, this will be of the form 1.0.1-rc0, +1.0.1-rc1, and so on until it's stabilized — at which time a +1.0.1-final is tagged and packaged. diff --git a/RATIONALE.txt b/RATIONALE.txt index c9e8960f0..55ed22204 100644 --- a/RATIONALE.txt +++ b/RATIONALE.txt @@ -35,7 +35,7 @@ Goals * Implement an efficient easy to use URI class/parser. * Implement a fully compliant cross-platform asynchronous DNS resolver - either as a wrapper to external (C) libraries, or as hand-rolled + either as a wrapper to external (C) libraries or as hand-rolled implementation. * Implement a MIME handler which builds message objects from either diff --git a/README.rst b/README.rst index 5b8185fb2..4a19a91d5 100644 --- a/README.rst +++ b/README.rst @@ -9,6 +9,9 @@ Modern C++ network programming libraries. .. image:: https://scan.coverity.com/projects/6714/badge.svg :target: https://scan.coverity.com/projects/cpp-netlib +.. image:: https://img.shields.io/badge/license-boost-blue.svg + :target: https://github.com/cpp-netlib/cpp-netlib/blob/master/LICENSE_1_0.txt + Join us on Slack: http://slack.cpp-netlib.org/ Subscribe to the mailing list: https://groups.google.com/forum/#!forum/cpp-netlib @@ -31,12 +34,12 @@ follow these instructions for cloning the project repository:: Introduction ------------ -cpp-netlib is a collection of network related routines/implementations +cpp-netlib is a collection of network-related routines/implementations geared towards providing a robust cross-platform networking library. cpp-netlib offers the following implementations: * Common Message Type -- A generic message type which can be used - to encapsulate and store message related information, used by all + to encapsulate and store message-related information, used by all network implementations as the primary means of data exchange. * Network protocol message parsers -- A collection of parsers which generate message objects from strings. @@ -78,6 +81,19 @@ you can now build the tests and run them:: $ make $ make test +You can also download and install cpp-netlib using the ` vcpkg`_ dependency manager: + + $ git clone https://github.com/Microsoft/vcpkg.git + $ cd vcpkg + $ ./bootstrap-vcpkg.sh + $ ./vcpkg integrate install + $ vcpkg install cpp-netlib + +The cpp-netlib port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the ` vcpkg`_ repository. + +.. _`vcpkg`: https://github.com/Microsoft/vcpkg + + If for some reason some of the tests fail, you can send the files in ``Testing/Temporary/`` as attachments to the cpp-netlib `developers mailing list`_. @@ -101,7 +117,7 @@ you will need. These are: Hacking on cpp-netlib --------------------- -cpp-netlib uses git_ for tracking work, and is hosted on GitHub_. +cpp-netlib uses git_ for tracking work and is hosted on GitHub_. cpp-netlib is hosted on GitHub_ following the GitHub recommended practice of forking the repository and submitting pull requests to the source repository. You can read more about the forking_ process and submitting `pull requests`_ if diff --git a/boost/network.hpp b/boost/network.hpp deleted file mode 100644 index 552cbdc82..000000000 --- a/boost/network.hpp +++ /dev/null @@ -1,17 +0,0 @@ - -// Copyright Dean Michael Berris 2007. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_HPP__ -#define BOOST_NETWORK_HPP__ - -// Include all headers in network/ -// Author: Dean Michael Berris -// Date: May 20, 2007 - -#include // message type implementation -#include // protocols implementation - -#endif // BOOST_NETWORK_HPP__ diff --git a/boost/network/constants.hpp b/boost/network/constants.hpp index 3fd3060b8..6af51def6 100644 --- a/boost/network/constants.hpp +++ b/boost/network/constants.hpp @@ -18,80 +18,75 @@ template struct constants_narrow { static char const* crlf() { - static char crlf_[] = {'\r', '\n', 0}; + static char crlf_[] = "\r\n"; return crlf_; } static char const* dot() { - static char dot_[] = {'.', 0}; + static char dot_[] = "."; return dot_; } static char dot_char() { return '.'; } static char const* http_slash() { - static char http_slash_[] = {'H', 'T', 'T', 'P', '/', 0}; + static char http_slash_[] = "HTTP/"; return http_slash_; } static char const* space() { - static char space_[] = {' ', 0}; + static char space_[] = " "; return space_; } static char space_char() { return ' '; } static char const* slash() { - static char slash_[] = {'/', 0}; + static char slash_[] = "/"; return slash_; } static char slash_char() { return '/'; } static char const* host() { - static char host_[] = {'H', 'o', 's', 't', 0}; + static char host_[] = "Host"; return host_; } static char const* colon() { - static char colon_[] = {':', 0}; + static char colon_[] = ":"; return colon_; } static char colon_char() { return ':'; } static char const* accept() { - static char accept_[] = {'A', 'c', 'c', 'e', 'p', 't', 0}; + static char accept_[] = "Accept"; return accept_; } static char const* default_accept_mime() { - static char mime_[] = {'*', '/', '*', 0}; + static char mime_[] = "*/*"; return mime_; } static char const* accept_encoding() { - static char accept_encoding_[] = {'A', 'c', 'c', 'e', 'p', 't', '-', 'E', - 'n', 'c', 'o', 'd', 'i', 'n', 'g', 0}; + static char accept_encoding_[] = "Accept-Encoding"; return accept_encoding_; } static char const* default_accept_encoding() { - static char default_accept_encoding_[] = { - 'i', 'd', 'e', 'n', 't', 'i', 't', 'y', ';', 'q', '=', - '1', '.', '0', ',', ' ', '*', ';', 'q', '=', '0', 0}; + static char default_accept_encoding_[] = "identity;q=1.0, *;q=0"; return default_accept_encoding_; } static char const* user_agent() { - static char user_agent_[] = {'U', 's', 'e', 'r', '-', 'A', - 'g', 'e', 'n', 't', 0}; + static char user_agent_[] = "User-Agent"; return user_agent_; } static char const* cpp_netlib_slash() { - static char cpp_netlib_slash_[] = {'c', 'p', 'p', '-', 'n', 'e', - 't', 'l', 'i', 'b', '/', 0}; + static char cpp_netlib_slash_[] = "cpp-netlib/"; return cpp_netlib_slash_; } @@ -100,13 +95,12 @@ struct constants_narrow { static char hash_char() { return '#'; } static char const* connection() { - static char connection_[] = {'C', 'o', 'n', 'n', 'e', 'c', - 't', 'i', 'o', 'n', 0}; + static char connection_[] = "Connection"; return connection_; } static char const* close() { - static char close_[] = {'C', 'l', 'o', 's', 'e', 0}; + static char close_[] = "Close"; return close_; } diff --git a/boost/network/include/http/client.hpp b/boost/network/include/http/client.hpp deleted file mode 100644 index 3abc042e4..000000000 --- a/boost/network/include/http/client.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_ -#define BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_ - -// Copyright 2009 Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This is the modular include file for using the HTTP Client - -#include - -#endif // BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_ diff --git a/boost/network/include/http/server.hpp b/boost/network/include/http/server.hpp deleted file mode 100644 index 021eefe0b..000000000 --- a/boost/network/include/http/server.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef BOOST_NETWORK_INCLUDE_HTTP_SERVER_HPP_ -#define BOOST_NETWORK_INCLUDE_HTTP_SERVER_HPP_ - -// Copyright 2010 Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This is the modular include file for using the HTTP Client - -#include - -#endif diff --git a/boost/network/include/message.hpp b/boost/network/include/message.hpp deleted file mode 100644 index 8201ccf77..000000000 --- a/boost/network/include/message.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef BOOST_NETWORK_INCLUDE_MESSAGE_HPP_ -#define BOOST_NETWORK_INCLUDE_MESSAGE_HPP_ - -// Copyright 2009 Dean Michael Berris -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// This is the modular include file for using the basic message type - -#include -#include -#include -#include -#include - -#endif // BOOST_NETWORK_INCLUDE_MESSAGE_HPP_ diff --git a/boost/network/message/directives/detail/string_directive.hpp b/boost/network/message/directives/detail/string_directive.hpp index db07eceb4..3c1e652db 100644 --- a/boost/network/message/directives/detail/string_directive.hpp +++ b/boost/network/message/directives/detail/string_directive.hpp @@ -34,8 +34,8 @@ #define BOOST_NETWORK_STRING_DIRECTIVE(name, value, body, pod_body) \ template \ struct name##_directive { \ - ValueType const&((value)); \ - explicit name##_directive(ValueType const& value_) : value(value_) {} \ + ValueType const& value; \ + explicit name##_directive(ValueType const& v) : value(v) {} \ name##_directive(name##_directive const& other) : value(other.value) {} \ template class Message> \ typename enable_if, void>::type operator()( \ diff --git a/boost/network/message/directives/detail/string_value.hpp b/boost/network/message/directives/detail/string_value.hpp index 53bea1546..8a3fa7d26 100644 --- a/boost/network/message/directives/detail/string_value.hpp +++ b/boost/network/message/directives/detail/string_value.hpp @@ -6,10 +6,10 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include +#include #include #include #include @@ -20,7 +20,7 @@ namespace detail { template struct string_value - : mpl::if_, std::shared_future::type>, + : mpl::if_, boost::shared_future::type>, typename mpl::if_< mpl::or_, is_same, is_same >, diff --git a/boost/network/message/modifiers/clear_headers.hpp b/boost/network/message/modifiers/clear_headers.hpp index 1f54af0d9..ef758073f 100644 --- a/boost/network/message/modifiers/clear_headers.hpp +++ b/boost/network/message/modifiers/clear_headers.hpp @@ -6,11 +6,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include #include +#include #include namespace boost { @@ -34,8 +34,8 @@ template inline typename enable_if >, is_async >, void>::type clear_headers(Message const &message, Tag const &) { - std::promise header_promise; - std::shared_future headers_future( + boost::promise header_promise; + boost::shared_future headers_future( header_promise.get_future()); message.headers(headers_future); header_promise.set_value(typename Message::headers_container_type()); diff --git a/boost/network/message/traits/body.hpp b/boost/network/message/traits/body.hpp index 495fe2d9b..cd0c56b1f 100644 --- a/boost/network/message/traits/body.hpp +++ b/boost/network/message/traits/body.hpp @@ -8,12 +8,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include #include #include +#include #include namespace boost { @@ -27,7 +27,7 @@ template struct body : mpl::if_< is_async, - std::shared_future::type>, + boost::shared_future::type>, typename mpl::if_< mpl::or_, is_same #include #include #include #include #include +#include #include namespace boost { @@ -26,7 +26,7 @@ struct unsupported_tag; template struct destination : mpl::if_, - std::shared_future::type>, + boost::shared_future::type>, typename mpl::if_< mpl::or_, is_same #include #include #include @@ -15,6 +14,7 @@ #include #include #include +#include namespace boost { namespace network { @@ -28,7 +28,7 @@ template struct header_key : mpl::if_< is_async, - std::shared_future::type>, + boost::shared_future::type>, typename mpl::if_< mpl::or_, is_same, @@ -40,7 +40,7 @@ template struct header_value : mpl::if_< is_async, - std::shared_future::type>, + boost::shared_future::type>, typename mpl::if_< mpl::or_, is_same, diff --git a/boost/network/message/traits/source.hpp b/boost/network/message/traits/source.hpp index ad037a4a6..17f9b188e 100644 --- a/boost/network/message/traits/source.hpp +++ b/boost/network/message/traits/source.hpp @@ -6,12 +6,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include #include #include +#include #include namespace boost { @@ -24,7 +24,7 @@ struct unsupported_tag; template struct source : mpl::if_, - std::shared_future::type>, + boost::shared_future::type>, typename mpl::if_< mpl::or_, is_same #include #include -#include +#include #include #include diff --git a/boost/network/protocol/http/client/async_impl.hpp b/boost/network/protocol/http/client/async_impl.hpp index bb4eab191..fe8d2adae 100644 --- a/boost/network/protocol/http/client/async_impl.hpp +++ b/boost/network/protocol/http/client/async_impl.hpp @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include #include namespace boost { @@ -31,27 +31,28 @@ struct async_client typedef typename resolver::type resolver_type; typedef typename string::type string_type; - typedef std::function const&, - std::error_code const&)> + typedef std::function::type, 1024>::const_iterator> const&, + boost::system::error_code const&)> body_callback_function_type; typedef std::function body_generator_function_type; async_client(bool cache_resolved, bool follow_redirect, - bool always_verify_peer, int timeout, - std::shared_ptr service, + bool always_verify_peer, int timeout, bool remove_chunk_markers, + std::shared_ptr service, optional certificate_filename, optional verify_path, optional certificate_file, optional private_key_file, optional ciphers, optional sni_hostname, long ssl_options) - : connection_base(cache_resolved, follow_redirect, timeout), + : connection_base(cache_resolved, follow_redirect, timeout, + remove_chunk_markers), service_ptr(service.get() ? service - : std::make_shared()), + : std::make_shared()), service_(*service_ptr), resolver_(service_), - sentinel_(new asio::io_service::work(service_)), + sentinel_(new boost::asio::io_service::work(service_)), certificate_filename_(std::move(certificate_filename)), verify_path_(std::move(verify_path)), certificate_file_(std::move(certificate_file)), @@ -61,7 +62,7 @@ struct async_client ssl_options_(ssl_options), always_verify_peer_(always_verify_peer) { connection_base::resolver_strand_.reset( - new asio::io_service::strand(service_)); + new boost::asio::io_service::strand(service_)); if (!service) lifetime_thread_.reset(new std::thread([this]() { service_.run(); })); } @@ -89,10 +90,10 @@ struct async_client generator); } - std::shared_ptr service_ptr; - asio::io_service& service_; + std::shared_ptr service_ptr; + boost::asio::io_service& service_; resolver_type resolver_; - std::shared_ptr sentinel_; + std::shared_ptr sentinel_; std::shared_ptr lifetime_thread_; optional certificate_filename_; optional verify_path_; diff --git a/boost/network/protocol/http/client/connection/async_base.hpp b/boost/network/protocol/http/client/connection/async_base.hpp index 586202412..b1c1aa67a 100644 --- a/boost/network/protocol/http/client/connection/async_base.hpp +++ b/boost/network/protocol/http/client/connection/async_base.hpp @@ -9,11 +9,13 @@ // http://www.boost.org/LICENSE_1_0.txt) #include +#include #include #include #include #include #include +#include namespace boost { namespace network { @@ -29,8 +31,9 @@ struct async_connection_base { typedef typename string::type string_type; typedef basic_request request; typedef basic_response response; - typedef iterator_range char_const_range; - typedef std::function + typedef typename std::array::type, 1024>::const_iterator const_iterator; + typedef iterator_range char_const_range; + typedef std::function body_callback_function_type; typedef std::function body_generator_function_type; typedef std::shared_ptr connection_ptr; @@ -41,6 +44,7 @@ struct async_connection_base { static connection_ptr new_connection( resolve_function resolve, resolver_type &resolver, bool follow_redirect, bool always_verify_peer, bool https, int timeout, + bool remove_chunk_markers, optional certificate_filename = optional(), optional const &verify_path = optional(), optional certificate_file = optional(), @@ -56,7 +60,8 @@ struct async_connection_base { certificate_filename, verify_path, certificate_file, private_key_file, ciphers, sni_hostname, ssl_options); auto temp = std::make_shared( - resolver, resolve, follow_redirect, timeout, std::move(delegate)); + resolver, resolve, follow_redirect, timeout, remove_chunk_markers, + std::move(delegate)); BOOST_ASSERT(temp != nullptr); return temp; } diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index 1604a727e..ac10407c0 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -12,10 +12,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -30,6 +30,7 @@ #include #include #include +#include #include namespace boost { @@ -37,10 +38,86 @@ namespace network { namespace http { namespace impl { +template +struct chunk_encoding_parser { + chunk_encoding_parser() : state(state_t::header), chunk_size(0) {} + + enum class state_t { header, header_end, data, data_end }; + + state_t state; + size_t chunk_size; + std::array::type, 1024> buffer; + + void update_chunk_size( + boost::iterator_range::type, 1024>::const_iterator> const &range) { + if (range.empty()) return; + std::stringstream ss; + ss << std::hex << range; + size_t size; + ss >> size; + // New digits are appended as LSBs + chunk_size = (chunk_size << (range.size() * 4)) | size; + } + + boost::iterator_range< + typename std::array::type, 1024>::const_iterator> + operator()( + boost::iterator_range::type, 1024>::const_iterator> const &range) { + auto iter = boost::begin(range); + auto begin = iter; + auto pos = boost::begin(buffer); + + while (iter != boost::end(range)) switch (state) { + case state_t::header: + iter = std::find(iter, boost::end(range), '\r'); + update_chunk_size(boost::make_iterator_range(begin, iter)); + if (iter != boost::end(range)) { + state = state_t::header_end; + ++iter; + } + break; + + case state_t::header_end: + BOOST_ASSERT(*iter == '\n'); + ++iter; + state = state_t::data; + break; + + case state_t::data: + if (chunk_size == 0) { + BOOST_ASSERT(*iter == '\r'); + ++iter; + state = state_t::data_end; + } else { + auto len = std::min(chunk_size, + (size_t)std::distance(iter, boost::end(range))); + begin = iter; + iter = std::next(iter, len); + pos = std::copy(begin, iter, pos); + chunk_size -= len; + } + break; + + case state_t::data_end: + BOOST_ASSERT(*iter == '\n'); + ++iter; + begin = iter; + state = state_t::header; + break; + + default: + BOOST_ASSERT(false && "Bug, report this to the developers!"); + } + return boost::make_iterator_range(boost::begin(buffer), pos); + } +}; + template struct async_connection_base; -namespace placeholders = asio::placeholders; +namespace placeholders = boost::asio::placeholders; template struct http_async_connection @@ -71,9 +148,11 @@ struct http_async_connection connection_delegate_ptr; http_async_connection(resolver_type& resolver, resolve_function resolve, - bool follow_redirect, int timeout, + bool follow_redirect, int64_t timeout, + bool remove_chunk_markers, connection_delegate_ptr delegate) : timeout_(timeout), + remove_chunk_markers_(remove_chunk_markers), timer_(resolver.get_io_service()), is_timedout_(false), follow_redirect_(follow_redirect), @@ -82,11 +161,9 @@ struct http_async_connection request_strand_(resolver.get_io_service()), delegate_(std::move(delegate)) {} - // This is the main entry point for the connection/request pipeline. - // We're - // overriding async_connection_base<...>::start(...) here which is - // called - // by the client. + // This is the main entry point for the connection/request pipeline. We're + // overriding async_connection_base<...>::start(...) here which is called by + // the client. virtual response start(request const& request, string_type const& method, bool get_body, body_callback_function_type callback, body_generator_function_type generator) { @@ -101,36 +178,44 @@ struct http_async_connection std::uint16_t source_port = request.source_port(); auto self = this->shared_from_this(); + if (timeout_ > 0) { +#if defined(BOOST_ASIO_HAS_STD_CHRONO) + timer_.expires_from_now(std::chrono::seconds(timeout_)); +#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO) + timer_.expires_from_now(boost::chrono::seconds(timeout_)); +#else +#error Need a chrono implementation +#endif + timer_.async_wait(request_strand_.wrap([=] (boost::system::error_code const &ec) { + self->handle_timeout(ec); + })); + } resolve_(resolver_, host_, port_, request_strand_.wrap( - [=] (std::error_code const &ec, + [=] (boost::system::error_code const &ec, resolver_iterator_pair endpoint_range) { self->handle_resolved(host_, port_, source_port, get_body, callback, generator, ec, endpoint_range); })); - if (timeout_ > 0) { - timer_.expires_from_now(boost::posix_time::seconds(timeout_)); - timer_.async_wait(request_strand_.wrap([=] (std::error_code const &ec) { - self->handle_timeout(ec); - })); - } return response_; } private: - void set_errors(std::error_code const& ec) { - std::system_error error(ec); - this->version_promise.set_exception(std::make_exception_ptr(error)); - this->status_promise.set_exception(std::make_exception_ptr(error)); - this->status_message_promise.set_exception(std::make_exception_ptr(error)); - this->headers_promise.set_exception(std::make_exception_ptr(error)); - this->source_promise.set_exception(std::make_exception_ptr(error)); - this->destination_promise.set_exception(std::make_exception_ptr(error)); - this->body_promise.set_exception(std::make_exception_ptr(error)); + void set_errors(boost::system::error_code const& ec, body_callback_function_type callback) { + boost::system::system_error error(ec); + this->version_promise.set_exception(boost::copy_exception(error)); + this->status_promise.set_exception(boost::copy_exception(error)); + this->status_message_promise.set_exception(boost::copy_exception(error)); + this->headers_promise.set_exception(boost::copy_exception(error)); + this->source_promise.set_exception(boost::copy_exception(error)); + this->destination_promise.set_exception(boost::copy_exception(error)); + this->body_promise.set_exception(boost::copy_exception(error)); + if ( callback ) + callback( boost::iterator_range::type, 1024>::const_iterator>(), ec ); this->timer_.cancel(); } - void handle_timeout(std::error_code const& ec) { + void handle_timeout(boost::system::error_code const& ec) { if (!ec) delegate_->disconnect(); is_timedout_ = true; } @@ -139,25 +224,23 @@ struct http_async_connection std::uint16_t source_port, bool get_body, body_callback_function_type callback, body_generator_function_type generator, - std::error_code const& ec, + boost::system::error_code const& ec, resolver_iterator_pair endpoint_range) { if (!ec && !boost::empty(endpoint_range)) { // Here we deal with the case that there was an error encountered and // that there's still more endpoints to try connecting to. resolver_iterator iter = boost::begin(endpoint_range); - asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); + boost::asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); auto self = this->shared_from_this(); delegate_->connect( endpoint, host, source_port, - request_strand_.wrap([=] (std::error_code const &ec) { + request_strand_.wrap([=] (boost::system::error_code const &ec) { auto iter_copy = iter; self->handle_connected(host, port, source_port, get_body, callback, generator, std::make_pair(++iter_copy, resolver_iterator()), ec); })); } else { - set_errors(ec ? ec : asio::error::host_not_found); - boost::iterator_range range; - if (callback) callback(range, ec); + set_errors((ec ? ec : boost::asio::error::host_not_found), callback); } } @@ -166,15 +249,15 @@ struct http_async_connection body_callback_function_type callback, body_generator_function_type generator, resolver_iterator_pair endpoint_range, - std::error_code const& ec) { + boost::system::error_code const& ec) { if (is_timedout_) { - set_errors(asio::error::timed_out); + set_errors(boost::asio::error::timed_out, callback); } else if (!ec) { BOOST_ASSERT(delegate_.get() != 0); auto self = this->shared_from_this(); delegate_->write( command_streambuf, - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_sent_request(get_body, callback, generator, ec, bytes_transferred); @@ -182,20 +265,18 @@ struct http_async_connection } else { if (!boost::empty(endpoint_range)) { resolver_iterator iter = boost::begin(endpoint_range); - asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); + boost::asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); auto self = this->shared_from_this(); delegate_->connect( endpoint, host, source_port, - request_strand_.wrap([=] (std::error_code const &ec) { + request_strand_.wrap([=] (boost::system::error_code const &ec) { auto iter_copy = iter; self->handle_connected(host, port, source_port, get_body, callback, generator, std::make_pair(++iter_copy, resolver_iterator()), ec); })); } else { - set_errors(ec ? ec : asio::error::host_not_found); - boost::iterator_range range; - if (callback) callback(range, ec); + set_errors((ec ? ec : boost::asio::error::host_not_found), callback); } } } @@ -204,7 +285,7 @@ struct http_async_connection void handle_sent_request(bool get_body, body_callback_function_type callback, body_generator_function_type generator, - std::error_code const& ec, + boost::system::error_code const& ec, std::size_t bytes_transferred) { if (!is_timedout_ && !ec) { if (generator) { @@ -220,7 +301,7 @@ struct http_async_connection auto self = this->shared_from_this(); delegate_->write( command_streambuf, - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_sent_request(get_body, callback, generator, ec, bytes_transferred); @@ -231,41 +312,41 @@ struct http_async_connection auto self = this->shared_from_this(); delegate_->read_some( - asio::mutable_buffers_1(this->part.data(), + boost::asio::mutable_buffers_1(this->part.data(), this->part.size()), - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(version, get_body, callback, ec, bytes_transferred); })); } else { - set_errors(is_timedout_ ? asio::error::timed_out : ec); + set_errors((is_timedout_ ? boost::asio::error::timed_out : ec), callback); } } void handle_received_data(state_t state, bool get_body, body_callback_function_type callback, - std::error_code const& ec, + boost::system::error_code const& ec, std::size_t bytes_transferred) { static const long short_read_error = 335544539; bool is_ssl_short_read_error = #ifdef BOOST_NETWORK_ENABLE_HTTPS - ec.category() == asio::error::ssl_category && + ec.category() == boost::asio::error::ssl_category && ec.value() == short_read_error; #else false && short_read_error; #endif if (!is_timedout_ && - (!ec || ec == asio::error::eof || is_ssl_short_read_error)) { + (!ec || ec == boost::asio::error::eof || is_ssl_short_read_error)) { logic::tribool parsed_ok; size_t remainder; auto self = this->shared_from_this(); switch (state) { case version: - if (ec == asio::error::eof) return; + if (ec == boost::asio::error::eof) return; parsed_ok = this->parse_version( delegate_, - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(version, get_body, callback, ec, bytes_transferred); @@ -275,10 +356,10 @@ struct http_async_connection return; } case status: - if (ec == asio::error::eof) return; + if (ec == boost::asio::error::eof) return; parsed_ok = this->parse_status( delegate_, - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(status, get_body, callback, ec, bytes_transferred); @@ -288,9 +369,9 @@ struct http_async_connection return; } case status_message: - if (ec == asio::error::eof) return; + if (ec == boost::asio::error::eof) return; parsed_ok = this->parse_status_message( - delegate_, request_strand_.wrap([=] (std::error_code const &, + delegate_, request_strand_.wrap([=] (boost::system::error_code const &, std::size_t bytes_transferred) { self->handle_received_data(status_message, get_body, callback, ec, bytes_transferred); @@ -300,14 +381,14 @@ struct http_async_connection return; } case headers: - if (ec == asio::error::eof) return; + if (ec == boost::asio::error::eof) return; // In the following, remainder is the number of bytes that remain in // the buffer. We need this in the body processing to make sure that // the data remaining in the buffer is dealt with before another call // to get more data for the body is scheduled. std::tie(parsed_ok, remainder) = this->parse_headers( delegate_, - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(headers, get_body, callback, ec, bytes_transferred); @@ -322,6 +403,8 @@ struct http_async_connection // We short-circuit here because the user does not want to get the // body (in the case of a HEAD request). this->body_promise.set_value(""); + if ( callback ) + callback( boost::iterator_range::type, 1024>::const_iterator>(), boost::asio::error::eof ); this->destination_promise.set_value(""); this->source_promise.set_value(""); // this->part.assign('\0'); @@ -348,13 +431,16 @@ struct http_async_connection // The invocation of the callback is synchronous to allow us to // wait before scheduling another read. - callback(make_iterator_range(begin, end), ec); - + if (this->is_chunk_encoding && remove_chunk_markers_) { + callback(parse_chunk_encoding(make_iterator_range(begin, end)), ec); + } else { + callback(make_iterator_range(begin, end), ec); + } auto self = this->shared_from_this(); delegate_->read_some( - asio::mutable_buffers_1(this->part.data(), + boost::asio::mutable_buffers_1(this->part.data(), this->part.size()), - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(body, get_body, callback, ec, bytes_transferred); @@ -365,7 +451,7 @@ struct http_async_connection auto self = this->shared_from_this(); this->parse_body( delegate_, - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(body, get_body, callback, ec, bytes_transferred); @@ -374,7 +460,7 @@ struct http_async_connection } return; case body: - if (ec == asio::error::eof || is_ssl_short_read_error) { + if (ec == boost::asio::error::eof || is_ssl_short_read_error) { // Here we're handling the case when the connection has been closed // from the server side, or at least that the end of file has been // reached while reading the socket. This signals the end of the @@ -388,14 +474,33 @@ struct http_async_connection // We call the callback function synchronously passing the error // condition (in this case, end of file) so that it can handle it // appropriately. - callback(make_iterator_range(begin, end), ec); + if (this->is_chunk_encoding && remove_chunk_markers_) { + callback(parse_chunk_encoding(make_iterator_range(begin, end)), ec); + } else { + callback(make_iterator_range(begin, end), ec); + } } else { string_type body_string; - std::swap(body_string, this->partial_parsed); - body_string.append(this->part.begin(), bytes_transferred); - if (this->is_chunk_encoding) { - this->body_promise.set_value(parse_chunk_encoding(body_string)); + if (this->is_chunk_encoding && remove_chunk_markers_) { + for (size_t i = 0; i < this->partial_parsed.size(); i += 1024) { + auto range = parse_chunk_encoding(boost::make_iterator_range( + static_cast::type, 1024>::const_iterator>( + this->partial_parsed.data()) + i, + static_cast::type, 1024>::const_iterator>( + this->partial_parsed.data()) + + std::min(i + 1024, this->partial_parsed.size()))); + body_string.append(boost::begin(range), boost::end(range)); + } + this->partial_parsed.clear(); + auto range = parse_chunk_encoding(boost::make_iterator_range( + this->part.begin(), + this->part.begin() + bytes_transferred)); + body_string.append(boost::begin(range), boost::end(range)); + this->body_promise.set_value(body_string); } else { + std::swap(body_string, this->partial_parsed); + body_string.append(this->part.begin(), + this->part.begin() + bytes_transferred); this->body_promise.set_value(body_string); } } @@ -417,12 +522,16 @@ struct http_async_connection this->part.begin(); typename protocol_base::buffer_type::const_iterator end = begin; std::advance(end, bytes_transferred); - callback(make_iterator_range(begin, end), ec); + if (this->is_chunk_encoding && remove_chunk_markers_) { + callback(parse_chunk_encoding(make_iterator_range(begin, end)), ec); + } else { + callback(make_iterator_range(begin, end), ec); + } auto self = this->shared_from_this(); delegate_->read_some( - asio::mutable_buffers_1(this->part.data(), + boost::asio::mutable_buffers_1(this->part.data(), this->part.size()), - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(body, get_body, callback, ec, bytes_transferred); @@ -433,7 +542,7 @@ struct http_async_connection // have data that's still in the buffer. this->parse_body( delegate_, - request_strand_.wrap([=] (std::error_code const &ec, + request_strand_.wrap([=] (boost::system::error_code const &ec, std::size_t bytes_transferred) { self->handle_received_data(body, get_body, callback, ec, bytes_transferred); @@ -446,8 +555,8 @@ struct http_async_connection BOOST_ASSERT(false && "Bug, report this to the developers!"); } } else { - std::system_error error(is_timedout_ ? asio::error::timed_out - : ec); + boost::system::error_code report_code = is_timedout_ ? boost::asio::error::timed_out : ec; + boost::system::system_error error(report_code); this->source_promise.set_exception(std::make_exception_ptr(error)); this->destination_promise.set_exception(std::make_exception_ptr(error)); switch (state) { @@ -467,6 +576,8 @@ struct http_async_connection // so no exception should be set this->body_promise.set_exception(std::make_exception_ptr(error)); } + else + callback( boost::iterator_range::type, 1024>::const_iterator>(), report_code ); break; default: BOOST_ASSERT(false && "Bug, report this to the developers!"); @@ -474,47 +585,18 @@ struct http_async_connection } } - string_type parse_chunk_encoding(string_type& body_string) { - string_type body; - string_type crlf = "\r\n"; - - typename string_type::iterator begin = body_string.begin(); - for (typename string_type::iterator iter = - std::search(begin, body_string.end(), crlf.begin(), crlf.end()); - iter != body_string.end(); - iter = - std::search(begin, body_string.end(), crlf.begin(), crlf.end())) { - string_type line(begin, iter); - if (line.empty()) { - break; - } - std::stringstream stream(line); - int len; - stream >> std::hex >> len; - std::advance(iter, 2); - if (len == 0) { - break; - } - if (len <= body_string.end() - iter) { - body.insert(body.end(), iter, iter + len); - std::advance(iter, len + 2); - } - begin = iter; - } - - return body; - } - - int timeout_; - asio::deadline_timer timer_; + int64_t timeout_; + bool remove_chunk_markers_; + boost::asio::steady_timer timer_; bool is_timedout_; bool follow_redirect_; resolver_type& resolver_; resolve_function resolve_; - asio::io_service::strand request_strand_; + boost::asio::io_service::strand request_strand_; connection_delegate_ptr delegate_; - asio::streambuf command_streambuf; + boost::asio::streambuf command_streambuf; string_type method; + chunk_encoding_parser parse_chunk_encoding; }; } // namespace impl diff --git a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp index a860efb61..a0ce75bce 100644 --- a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp +++ b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace boost { namespace network { @@ -57,30 +58,30 @@ struct http_async_protocol_handler { // TODO(dberris): review parameter necessity. (void)get_body; - std::shared_future source_future( + boost::shared_future source_future( source_promise.get_future()); source(response_, source_future); - std::shared_future destination_future( + boost::shared_future destination_future( destination_promise.get_future()); destination(response_, destination_future); - std::shared_future::type> headers_future( + boost::shared_future::type> headers_future( headers_promise.get_future()); headers(response_, headers_future); - std::shared_future body_future(body_promise.get_future()); + boost::shared_future body_future(body_promise.get_future()); body(response_, body_future); - std::shared_future version_future( + boost::shared_future version_future( version_promise.get_future()); version(response_, version_future); - std::shared_future status_future( + boost::shared_future status_future( status_promise.get_future()); status(response_, status_future); - std::shared_future status_message_future( + boost::shared_future status_message_future( status_message_promise.get_future()); status_message(response_, status_message_future); } @@ -139,7 +140,7 @@ struct http_async_protocol_handler { std::end(result_range)); part_begin = part.begin(); delegate_->read_some( - asio::mutable_buffers_1(part.data(), part.size()), + boost::asio::mutable_buffers_1(part.data(), part.size()), callback); } return parsed_ok; @@ -185,7 +186,7 @@ struct http_async_protocol_handler { std::end(result_range)); part_begin = part.begin(); delegate_->read_some( - asio::mutable_buffers_1(part.data(), part.size()), + boost::asio::mutable_buffers_1(part.data(), part.size()), callback); } return parsed_ok; @@ -230,7 +231,7 @@ struct http_async_protocol_handler { std::end(result_range)); part_begin = part.begin(); delegate_->read_some( - asio::mutable_buffers_1(part.data(), part.size()), + boost::asio::mutable_buffers_1(part.data(), part.size()), callback); } return parsed_ok; @@ -245,6 +246,10 @@ struct http_async_protocol_handler { response_parser_type::http_header_line_done); typename headers_container::type headers; std::pair header_pair; + //init params + is_content_length = false; + content_length = -1; + is_chunk_end = false; while (!boost::empty(input_range)) { std::tie(parsed_ok, result_range) = headers_parser.parse_until( response_parser_type::http_header_colon, input_range); @@ -265,6 +270,16 @@ struct http_async_protocol_handler { } trim(header_pair.second); headers.insert(header_pair); + if (!is_content_length && + boost::iequals(header_pair.first, "Content-Length")) { + try { + content_length = std::stoll(header_pair.second); + is_content_length = true; + } + catch (std::exception&) { + //is_content_length = false; + } + } } // determine if the body parser will need to handle chunked encoding typename headers_range >::type transfer_encoding_range = @@ -317,21 +332,68 @@ struct http_async_protocol_handler { std::end(result_range)); part_begin = part.begin(); delegate_->read_some( - asio::mutable_buffers_1(part.data(), part.size()), + boost::asio::mutable_buffers_1(part.data(), part.size()), callback); } return std::make_tuple( parsed_ok, std::distance(std::end(result_range), part_end)); } + inline bool check_parse_body_complete() const { + if (this->is_chunk_encoding) { + return parse_chunk_encoding_complete(); + } + if (this->is_content_length && this->content_length >= 0) { + return parse_content_length_complete(); + } + return false; + } + + inline bool parse_content_length_complete() const { + return static_cast(this->partial_parsed.length()) >= this->content_length; + } + + bool parse_chunk_encoding_complete() const { + string_type body; + string_type crlf = "\r\n"; + + typename string_type::const_iterator begin = partial_parsed.begin(); + for (typename string_type::const_iterator iter = + std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end()); + iter != partial_parsed.end(); + iter = + std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end())) { + string_type line(begin, iter); + if (line.empty()) { + std::advance(iter, 2); + begin = iter; + continue; + } + std::stringstream stream(line); + int len; + stream >> std::hex >> len; + std::advance(iter, 2); + if (!len) return true; + if (len <= partial_parsed.end() - iter) { + std::advance(iter, len + 2); + } + begin = iter; + } + return false; + } + template void parse_body(Delegate& delegate_, Callback callback, size_t bytes) { // TODO(dberris): we should really not use a string for the partial body // buffer. - partial_parsed.append(part_begin, bytes); + partial_parsed.append(part_begin, part_begin + bytes); part_begin = part.begin(); - delegate_->read_some( - asio::mutable_buffers_1(part.data(), part.size()), callback); + if (check_parse_body_complete()) { + callback(boost::asio::error::eof, 0); + } else { + delegate_->read_some( + boost::asio::mutable_buffers_1(part.data(), part.size()), callback); + } } typedef response_parser response_parser_type; @@ -339,17 +401,20 @@ struct http_async_protocol_handler { typedef std::array::type, 1024> buffer_type; response_parser_type response_parser_; - std::promise version_promise; - std::promise status_promise; - std::promise status_message_promise; - std::promise::type> headers_promise; - std::promise source_promise; - std::promise destination_promise; - std::promise body_promise; + boost::promise version_promise; + boost::promise status_promise; + boost::promise status_message_promise; + boost::promise::type> headers_promise; + boost::promise source_promise; + boost::promise destination_promise; + boost::promise body_promise; buffer_type part; typename buffer_type::const_iterator part_begin; string_type partial_parsed; bool is_chunk_encoding; + bool is_chunk_end; + bool is_content_length; + long long content_length; }; } // namespace impl diff --git a/boost/network/protocol/http/client/connection/connection_delegate.hpp b/boost/network/protocol/http/client/connection/connection_delegate.hpp index fb18a04a1..4e223864e 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate.hpp +++ b/boost/network/protocol/http/client/connection/connection_delegate.hpp @@ -9,8 +9,8 @@ #include #include -#include -#include +#include +#include namespace boost { namespace network { @@ -18,15 +18,15 @@ namespace http { namespace impl { struct connection_delegate { - virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, + virtual void connect(boost::asio::ip::tcp::endpoint &endpoint, std::string host, std::uint16_t source_port, - std::function handler) = 0; + std::function handler) = 0; virtual void write( - asio::streambuf &command_streambuf, - std::function handler) = 0; + boost::asio::streambuf &command_streambuf, + std::function handler) = 0; virtual void read_some( - asio::mutable_buffers_1 const &read_buffer, - std::function handler) = 0; + boost::asio::mutable_buffers_1 const &read_buffer, + std::function handler) = 0; virtual void disconnect() = 0; virtual ~connection_delegate() = default; }; diff --git a/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp b/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp index 7a78002e5..fa419e1e6 100644 --- a/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp +++ b/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp @@ -34,7 +34,7 @@ struct connection_delegate_factory { // This is the factory method that actually returns the delegate instance. // TODO(dberris): Support passing in proxy settings when crafting connections. static connection_delegate_ptr new_connection_delegate( - asio::io_service& service, bool https, bool always_verify_peer, + boost::asio::io_service& service, bool https, bool always_verify_peer, optional certificate_filename, optional verify_path, optional certificate_file, optional private_key_file, optional ciphers, diff --git a/boost/network/protocol/http/client/connection/normal_delegate.hpp b/boost/network/protocol/http/client/connection/normal_delegate.hpp index eb8b43a69..a4187f7fc 100644 --- a/boost/network/protocol/http/client/connection/normal_delegate.hpp +++ b/boost/network/protocol/http/client/connection/normal_delegate.hpp @@ -10,10 +10,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include namespace boost { @@ -22,16 +22,16 @@ namespace http { namespace impl { struct normal_delegate : connection_delegate { - explicit normal_delegate(asio::io_service &service); + explicit normal_delegate(boost::asio::io_service &service); - void connect(asio::ip::tcp::endpoint &endpoint, std::string host, + void connect(boost::asio::ip::tcp::endpoint &endpoint, std::string host, std::uint16_t source_port, - std::function handler) override; - void write(asio::streambuf &command_streambuf, - std::function handler) + std::function handler) override; + void write(boost::asio::streambuf &command_streambuf, + std::function handler) override; - void read_some(asio::mutable_buffers_1 const &read_buffer, - std::function handler) + void read_some(boost::asio::mutable_buffers_1 const &read_buffer, + std::function handler) override; void disconnect() override; ~normal_delegate() override = default; @@ -40,8 +40,8 @@ struct normal_delegate : connection_delegate { normal_delegate &operator=(normal_delegate) = delete; private: - asio::io_service &service_; - std::unique_ptr socket_; + boost::asio::io_service &service_; + std::unique_ptr socket_; }; } // namespace impl diff --git a/boost/network/protocol/http/client/connection/normal_delegate.ipp b/boost/network/protocol/http/client/connection/normal_delegate.ipp index 091313c99..552f50417 100644 --- a/boost/network/protocol/http/client/connection/normal_delegate.ipp +++ b/boost/network/protocol/http/client/connection/normal_delegate.ipp @@ -9,46 +9,46 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include boost::network::http::impl::normal_delegate::normal_delegate( - asio::io_service &service) + boost::asio::io_service &service) : service_(service) {} void boost::network::http::impl::normal_delegate::connect( - asio::ip::tcp::endpoint &endpoint, std::string host, + boost::asio::ip::tcp::endpoint &endpoint, std::string host, std::uint16_t source_port, - std::function handler) { + std::function handler) { // TODO(dberris): review parameter necessity. (void)host; - socket_.reset(new asio::ip::tcp::socket( + socket_.reset(new boost::asio::ip::tcp::socket( service_, - asio::ip::tcp::endpoint(asio::ip::address(), source_port))); + boost::asio::ip::tcp::endpoint(boost::asio::ip::address(), source_port))); socket_->async_connect(endpoint, handler); } void boost::network::http::impl::normal_delegate::write( - asio::streambuf &command_streambuf, - std::function handler) { - asio::async_write(*socket_, command_streambuf, handler); + boost::asio::streambuf &command_streambuf, + std::function handler) { + boost::asio::async_write(*socket_, command_streambuf, handler); } void boost::network::http::impl::normal_delegate::read_some( - asio::mutable_buffers_1 const &read_buffer, - std::function handler) { + boost::asio::mutable_buffers_1 const &read_buffer, + std::function handler) { socket_->async_read_some(read_buffer, handler); } void boost::network::http::impl::normal_delegate::disconnect() { if (socket_.get() && socket_->is_open()) { - std::error_code ignored; - socket_->shutdown(asio::ip::tcp::socket::shutdown_both, ignored); + boost::system::error_code ignored; + socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored); if (!ignored) { socket_->close(ignored); } diff --git a/boost/network/protocol/http/client/connection/ssl_delegate.hpp b/boost/network/protocol/http/client/connection/ssl_delegate.hpp index 0916af235..63adc1818 100644 --- a/boost/network/protocol/http/client/connection/ssl_delegate.hpp +++ b/boost/network/protocol/http/client/connection/ssl_delegate.hpp @@ -10,8 +10,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -24,7 +24,7 @@ namespace impl { struct ssl_delegate : public connection_delegate, public std::enable_shared_from_this { - ssl_delegate(asio::io_service &service, bool always_verify_peer, + ssl_delegate(boost::asio::io_service &service, bool always_verify_peer, optional certificate_filename, optional verify_path, optional certificate_file, @@ -32,20 +32,20 @@ struct ssl_delegate : public connection_delegate, optional ciphers, optional sni_hostname, long ssl_options); - void connect(asio::ip::tcp::endpoint &endpoint, std::string host, + void connect(boost::asio::ip::tcp::endpoint &endpoint, std::string host, std::uint16_t source_port, - std::function handler) override; + std::function handler) override; void write( - asio::streambuf &command_streambuf, - std::function handler) override; + boost::asio::streambuf &command_streambuf, + std::function handler) override; void read_some( - asio::mutable_buffers_1 const &read_buffer, - std::function handler) override; + boost::asio::mutable_buffers_1 const &read_buffer, + std::function handler) override; void disconnect() override; ~ssl_delegate() override; private: - asio::io_service &service_; + boost::asio::io_service &service_; optional certificate_filename_; optional verify_path_; optional certificate_file_; @@ -53,16 +53,16 @@ struct ssl_delegate : public connection_delegate, optional ciphers_; optional sni_hostname_; long ssl_options_; - std::unique_ptr context_; - std::unique_ptr tcp_socket_; - std::unique_ptr > socket_; + std::unique_ptr context_; + std::unique_ptr tcp_socket_; + std::unique_ptr > socket_; bool always_verify_peer_; ssl_delegate(ssl_delegate const &); // = delete ssl_delegate &operator=(ssl_delegate); // = delete - void handle_connected(std::error_code const &ec, - std::function handler); + void handle_connected(boost::system::error_code const &ec, + std::function handler); }; } // namespace impl diff --git a/boost/network/protocol/http/client/connection/ssl_delegate.ipp b/boost/network/protocol/http/client/connection/ssl_delegate.ipp index b303a24de..e9d955b40 100644 --- a/boost/network/protocol/http/client/connection/ssl_delegate.ipp +++ b/boost/network/protocol/http/client/connection/ssl_delegate.ipp @@ -9,11 +9,11 @@ #include #include -#include +#include #include boost::network::http::impl::ssl_delegate::ssl_delegate( - asio::io_service &service, bool always_verify_peer, + boost::asio::io_service &service, bool always_verify_peer, optional certificate_filename, optional verify_path, optional certificate_file, optional private_key_file, optional ciphers, @@ -29,11 +29,11 @@ boost::network::http::impl::ssl_delegate::ssl_delegate( always_verify_peer_(always_verify_peer) {} void boost::network::http::impl::ssl_delegate::connect( - asio::ip::tcp::endpoint &endpoint, std::string host, + boost::asio::ip::tcp::endpoint &endpoint, std::string host, std::uint16_t source_port, - std::function handler) { + std::function handler) { context_.reset( - new asio::ssl::context(asio::ssl::context::method::sslv23_client)); + new boost::asio::ssl::context(boost::asio::ssl::context::method::sslv23_client)); if (ciphers_) { ::SSL_CTX_set_cipher_list(context_->native_handle(), ciphers_->c_str()); } @@ -41,69 +41,69 @@ void boost::network::http::impl::ssl_delegate::connect( context_->set_options(ssl_options_); } else { // By default, disable v3 support. - context_->set_options(asio::ssl::context::no_sslv3); + context_->set_options(boost::asio::ssl::context::no_sslv3); } if (certificate_filename_ || verify_path_) { - context_->set_verify_mode(asio::ssl::context::verify_peer); + context_->set_verify_mode(boost::asio::ssl::context::verify_peer); if (certificate_filename_) context_->load_verify_file(*certificate_filename_); if (verify_path_) context_->add_verify_path(*verify_path_); } else { if (always_verify_peer_) { - context_->set_verify_mode(asio::ssl::context::verify_peer); + context_->set_verify_mode(boost::asio::ssl::context::verify_peer); // use openssl default verify paths. uses openssl environment variables // SSL_CERT_DIR, SSL_CERT_FILE context_->set_default_verify_paths(); } else { - context_->set_verify_mode(asio::ssl::context::verify_none); + context_->set_verify_mode(boost::asio::ssl::context::verify_none); } } if (certificate_file_) - context_->use_certificate_file(*certificate_file_, asio::ssl::context::pem); + context_->use_certificate_file(*certificate_file_, boost::asio::ssl::context::pem); if (private_key_file_) - context_->use_private_key_file(*private_key_file_, asio::ssl::context::pem); + context_->use_private_key_file(*private_key_file_, boost::asio::ssl::context::pem); - tcp_socket_.reset(new asio::ip::tcp::socket( - service_, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), source_port))); - socket_.reset(new asio::ssl::stream( + tcp_socket_.reset(new boost::asio::ip::tcp::socket( + service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), source_port))); + socket_.reset(new boost::asio::ssl::stream( *(tcp_socket_.get()), *context_)); if (sni_hostname_) SSL_set_tlsext_host_name(socket_->native_handle(), sni_hostname_->c_str()); if (always_verify_peer_) - socket_->set_verify_callback(asio::ssl::rfc2818_verification(host)); + socket_->set_verify_callback(boost::asio::ssl::rfc2818_verification(host)); auto self = this->shared_from_this(); socket_->lowest_layer().async_connect( endpoint, - [=](std::error_code const &ec) { self->handle_connected(ec, handler); }); + [=](boost::system::error_code const &ec) { self->handle_connected(ec, handler); }); } void boost::network::http::impl::ssl_delegate::handle_connected( - std::error_code const &ec, - std::function handler) { + boost::system::error_code const &ec, + std::function handler) { if (!ec) { - socket_->async_handshake(asio::ssl::stream_base::client, handler); + socket_->async_handshake(boost::asio::ssl::stream_base::client, handler); } else { handler(ec); } } void boost::network::http::impl::ssl_delegate::write( - asio::streambuf &command_streambuf, - std::function handler) { - asio::async_write(*socket_, command_streambuf, handler); + boost::asio::streambuf &command_streambuf, + std::function handler) { + boost::asio::async_write(*socket_, command_streambuf, handler); } void boost::network::http::impl::ssl_delegate::read_some( - asio::mutable_buffers_1 const &read_buffer, - std::function handler) { + boost::asio::mutable_buffers_1 const &read_buffer, + std::function handler) { socket_->async_read_some(read_buffer, handler); } void boost::network::http::impl::ssl_delegate::disconnect() { if (socket_.get() && socket_->lowest_layer().is_open()) { - std::error_code ignored; - socket_->lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, + boost::system::error_code ignored; + socket_->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored); if (!ignored) { socket_->lowest_layer().close(ignored); diff --git a/boost/network/protocol/http/client/connection/sync_base.hpp b/boost/network/protocol/http/client/connection/sync_base.hpp index 4d940c334..efe488c11 100644 --- a/boost/network/protocol/http/client/connection/sync_base.hpp +++ b/boost/network/protocol/http/client/connection/sync_base.hpp @@ -8,10 +8,10 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -41,8 +41,8 @@ struct sync_connection_base_impl { void init_socket(Socket& socket_, resolver_type& resolver_, string_type /*unused*/ const& hostname, string_type const& port, resolver_function_type resolve_) { - using asio::ip::tcp; - std::error_code error = asio::error::host_not_found; + using boost::asio::ip::tcp; + boost::system::error_code error = boost::asio::error::host_not_found; typename resolver_type::iterator endpoint_iterator, end; boost::tie(endpoint_iterator, end) = resolve_(resolver_, hostname, port); while (error && endpoint_iterator != end) { @@ -53,13 +53,13 @@ struct sync_connection_base_impl { ++endpoint_iterator; } - if (error) throw std::system_error(error); + if (error) throw boost::system::system_error(error); } template void read_status(Socket& socket_, basic_response& response_, - asio::streambuf& response_buffer) { - asio::read_until(socket_, response_buffer, "\r\n"); + boost::asio::streambuf& response_buffer) { + boost::asio::read_until(socket_, response_buffer, "\r\n"); std::istream response_stream(&response_buffer); string_type http_version; unsigned int status_code; @@ -78,8 +78,8 @@ struct sync_connection_base_impl { template void read_headers(Socket& socket_, basic_response& response_, - asio::streambuf& response_buffer) { - asio::read_until(socket_, response_buffer, "\r\n\r\n"); + boost::asio::streambuf& response_buffer) { + boost::asio::read_until(socket_, response_buffer, "\r\n\r\n"); std::istream response_stream(&response_buffer); string_type header_line, name; while (std::getline(response_stream, header_line) && header_line != "\r") { @@ -101,7 +101,7 @@ struct sync_connection_base_impl { template void send_request_impl(Socket& socket_, string_type /*unused*/ const& method, - asio::streambuf& request_buffer) { + boost::asio::streambuf& request_buffer) { // TODO(dberris): review parameter necessity. (void)method; @@ -110,15 +110,15 @@ struct sync_connection_base_impl { template void read_body_normal(Socket& socket_, basic_response& response_, - asio::streambuf& response_buffer, + boost::asio::streambuf& response_buffer, typename ostringstream::type& body_stream) { // TODO(dberris): review parameter necessity. (void)response_; - std::error_code error; + boost::system::error_code error; if (response_buffer.size() > 0) body_stream << &response_buffer; - while (asio::read(socket_, response_buffer, asio::transfer_at_least(1), + while (boost::asio::read(socket_, response_buffer, boost::asio::transfer_at_least(1), error)) { body_stream << &response_buffer; } @@ -127,9 +127,9 @@ struct sync_connection_base_impl { template void read_body_transfer_chunk_encoding( Socket& socket_, basic_response& response_, - asio::streambuf& response_buffer, + boost::asio::streambuf& response_buffer, typename ostringstream::type& body_stream) { - std::error_code error; + boost::system::error_code error; // look for the content-length header typename headers_range >::type content_length_range = headers(response_)["Content-Length"]; @@ -146,8 +146,8 @@ struct sync_connection_base_impl { do { std::size_t chunk_size_line = read_until(socket_, response_buffer, "\r\n", error); - if ((chunk_size_line == 0) && (error != asio::error::eof)) - throw std::system_error(error); + if ((chunk_size_line == 0) && (error != boost::asio::error::eof)) + throw boost::system::system_error(error); std::size_t chunk_size = 0; string_type data; { @@ -159,8 +159,8 @@ struct sync_connection_base_impl { if (chunk_size == 0) { stopping = true; if (!read_until(socket_, response_buffer, "\r\n", error) && - (error != asio::error::eof)) - throw std::system_error(error); + (error != boost::asio::error::eof)) + throw boost::system::system_error(error); } else { bool stopping_inner = false; do { @@ -169,9 +169,9 @@ struct sync_connection_base_impl { (chunk_size + 2) - response_buffer.size(); std::size_t chunk_bytes_read = read(socket_, response_buffer, - asio::transfer_at_least(bytes_to_read), error); + boost::asio::transfer_at_least(bytes_to_read), error); if (chunk_bytes_read == 0) { - if (error != asio::error::eof) throw std::system_error(error); + if (error != boost::asio::error::eof) throw boost::system::system_error(error); stopping_inner = true; } } @@ -200,8 +200,8 @@ struct sync_connection_base_impl { return; } size_t bytes_read = 0; - while ((bytes_read = asio::read(socket_, response_buffer, - asio::transfer_at_least(1), error))) { + while ((bytes_read = boost::asio::read(socket_, response_buffer, + boost::asio::transfer_at_least(1), error))) { body_stream << &response_buffer; length -= bytes_read; if ((length <= 0) || error) break; @@ -211,7 +211,7 @@ struct sync_connection_base_impl { template void read_body(Socket& socket_, basic_response& response_, - asio::streambuf& response_buffer) { + boost::asio::streambuf& response_buffer) { typename ostringstream::type body_stream; // TODO(dberris): tag dispatch based on whether it's HTTP 1.0 or HTTP 1.1 if (version_major == 1 && version_minor == 0) { @@ -282,11 +282,11 @@ struct sync_connection_base { basic_request const& request_, body_generator_function_type generator) = 0; virtual void read_status(basic_response& response_, - asio::streambuf& response_buffer) = 0; + boost::asio::streambuf& response_buffer) = 0; virtual void read_headers(basic_response& response_, - asio::streambuf& response_buffer) = 0; + boost::asio::streambuf& response_buffer) = 0; virtual void read_body(basic_response& response_, - asio::streambuf& response_buffer) = 0; + boost::asio::streambuf& response_buffer) = 0; virtual bool is_open() = 0; virtual void close_socket() = 0; virtual ~sync_connection_base() = default; diff --git a/boost/network/protocol/http/client/connection/sync_normal.hpp b/boost/network/protocol/http/client/connection/sync_normal.hpp index 27e1e1cc6..c5909e131 100644 --- a/boost/network/protocol/http/client/connection/sync_normal.hpp +++ b/boost/network/protocol/http/client/connection/sync_normal.hpp @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -61,7 +61,7 @@ struct http_sync_connection void send_request_impl(string_type const& method, basic_request const& request_, body_generator_function_type generator) { - asio::streambuf request_buffer; + boost::asio::streambuf request_buffer; linearize( request_, method, version_major, version_minor, std::ostreambuf_iterator::type>(&request_buffer)); @@ -77,26 +77,32 @@ struct http_sync_connection } } if (timeout_ > 0) { - timer_.expires_from_now(boost::posix_time::seconds(timeout_)); +#if defined(BOOST_ASIO_HAS_STD_CHRONO) + timer_.expires_from_now(std::chrono::seconds(timeout_)); +#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO) + timer_.expires_from_now(boost::chrono::seconds(timeout_)); +#else +#error Need a chrono implementation +#endif auto self = this->shared_from_this(); - timer_.async_wait([=] (std::error_code const &ec) { + timer_.async_wait([=] (boost::system::error_code const &ec) { self->handle_timeout(ec); }); } } void read_status(basic_response& response_, - asio::streambuf& response_buffer) { + boost::asio::streambuf& response_buffer) { connection_base::read_status(socket_, response_, response_buffer); } void read_headers(basic_response& response, - asio::streambuf& response_buffer) { + boost::asio::streambuf& response_buffer) { connection_base::read_headers(socket_, response, response_buffer); } void read_body(basic_response& response_, - asio::streambuf& response_buffer) { + boost::asio::streambuf& response_buffer) { connection_base::read_body(socket_, response_, response_buffer); typename headers_range >::type connection_range = headers(response_)["Connection"]; @@ -116,8 +122,8 @@ struct http_sync_connection if (!is_open()) { return; } - std::error_code ignored; - socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored); + boost::system::error_code ignored; + socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored); if (ignored) { return; } @@ -125,17 +131,17 @@ struct http_sync_connection } private: - void handle_timeout(std::error_code const& ec) { + void handle_timeout(boost::system::error_code const& ec) { if (!ec) { close_socket(); } } int timeout_; - asio::deadline_timer timer_; + boost::asio::steady_timer timer_; resolver_type& resolver_; resolver_function_type resolve_; - asio::ip::tcp::socket socket_; + boost::asio::ip::tcp::socket socket_; }; } // namespace impl diff --git a/boost/network/protocol/http/client/connection/sync_ssl.hpp b/boost/network/protocol/http/client/connection/sync_ssl.hpp index d973fc0d6..c7d5ac72e 100644 --- a/boost/network/protocol/http/client/connection/sync_ssl.hpp +++ b/boost/network/protocol/http/client/connection/sync_ssl.hpp @@ -9,10 +9,10 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -63,7 +63,7 @@ struct https_sync_connection timer_(resolver.get_io_service()), resolver_(resolver), resolve_(std::move(resolve)), - context_(resolver.get_io_service(), asio::ssl::context::sslv23_client), + context_(resolver.get_io_service(), boost::asio::ssl::context::sslv23_client), socket_(resolver.get_io_service(), context_) { if (ciphers) { ::SSL_CTX_set_cipher_list(context_.native_handle(), ciphers->c_str()); @@ -72,7 +72,7 @@ struct https_sync_connection context_.set_options(ssl_options); } if (certificate_filename || verify_path) { - context_.set_verify_mode(asio::ssl::context::verify_peer); + context_.set_verify_mode(boost::asio::ssl::context::verify_peer); // FIXME make the certificate filename and verify path parameters // be // optional ranges @@ -81,14 +81,14 @@ struct https_sync_connection if (verify_path) context_.add_verify_path(*verify_path); } else { if (always_verify_peer) - context_.set_verify_mode(asio::ssl::context_base::verify_peer); + context_.set_verify_mode(boost::asio::ssl::context_base::verify_peer); else - context_.set_verify_mode(asio::ssl::context_base::verify_none); + context_.set_verify_mode(boost::asio::ssl::context_base::verify_none); } if (certificate_file) - context_.use_certificate_file(*certificate_file, asio::ssl::context::pem); + context_.use_certificate_file(*certificate_file, boost::asio::ssl::context::pem); if (private_key_file) - context_.use_private_key_file(*private_key_file, asio::ssl::context::pem); + context_.use_private_key_file(*private_key_file, boost::asio::ssl::context::pem); if (sni_hostname) SSL_set_tlsext_host_name(socket_.native_handle(), sni_hostname->c_str()); } @@ -97,13 +97,13 @@ struct https_sync_connection string_type const& port) { connection_base::init_socket(socket_.lowest_layer(), resolver_, hostname, port, resolve_); - socket_.handshake(asio::ssl::stream_base::client); + socket_.handshake(boost::asio::ssl::stream_base::client); } void send_request_impl(string_type /*unused*/ const& method, basic_request const& request_, body_generator_function_type generator) { - asio::streambuf request_buffer; + boost::asio::streambuf request_buffer; linearize( request_, method, version_major, version_minor, std::ostreambuf_iterator::type>(&request_buffer)); @@ -119,25 +119,31 @@ struct https_sync_connection } } if (timeout_ > 0) { - timer_.expires_from_now(boost::posix_time::seconds(timeout_)); +#if defined(BOOST_ASIO_HAS_STD_CHRONO) + timer_.expires_from_now(std::chrono::seconds(timeout_)); +#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO) + timer_.expires_from_now(boost::chrono::seconds(timeout_)); +#else +#error Need a chrono implementation +#endif auto self = this->shared_from_this(); timer_.async_wait( - [=](std::error_code const& ec) { self->handle_timeout(ec); }); + [=](boost::system::error_code const& ec) { self->handle_timeout(ec); }); } } void read_status(basic_response& response_, - asio::streambuf& response_buffer) { + boost::asio::streambuf& response_buffer) { connection_base::read_status(socket_, response_, response_buffer); } void read_headers(basic_response& response_, - asio::streambuf& response_buffer) { + boost::asio::streambuf& response_buffer) { connection_base::read_headers(socket_, response_, response_buffer); } void read_body(basic_response& response_, - asio::streambuf& response_buffer) { + boost::asio::streambuf& response_buffer) { connection_base::read_body(socket_, response_, response_buffer); typename headers_range >::type connection_range = headers(response_)["Connection"]; @@ -154,8 +160,8 @@ struct https_sync_connection void close_socket() { timer_.cancel(); - std::error_code ignored; - socket_.lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, + boost::system::error_code ignored; + socket_.lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored); if (ignored) { return; @@ -166,18 +172,18 @@ struct https_sync_connection ~https_sync_connection() { close_socket(); } private: - void handle_timeout(std::error_code const& ec) { + void handle_timeout(boost::system::error_code const& ec) { if (!ec) { close_socket(); } } int timeout_; - asio::deadline_timer timer_; + boost::asio::steady_timer timer_; resolver_type& resolver_; resolver_function_type resolve_; - asio::ssl::context context_; - asio::ssl::stream socket_; + boost::asio::ssl::context context_; + boost::asio::ssl::stream socket_; }; } // namespace impl diff --git a/boost/network/protocol/http/client/facade.hpp b/boost/network/protocol/http/client/facade.hpp index ff05d078b..07ddbd8af 100644 --- a/boost/network/protocol/http/client/facade.hpp +++ b/boost/network/protocol/http/client/facade.hpp @@ -10,19 +10,13 @@ #include #include #include -#include -#include +#include +#include namespace boost { namespace network { namespace http { -template -struct basic_request; - -template -struct basic_response; - template class basic_client_facade { typedef basic_client_impl pimpl_type; @@ -45,8 +39,8 @@ class basic_client_facade { * body as it comes in. In case of errors, the second argument is an error * code. */ - typedef std::function const&, - std::error_code const&)> + typedef std::function::type, 1024>::const_iterator> const&, + boost::system::error_code const&)> body_callback_function_type; /** @@ -128,7 +122,7 @@ class basic_client_facade { } else { if (boost::empty(content_type_headers)) { typedef typename char_::type char_type; - static char_type content_type[] = "x-application/octet-stream"; + static char_type* content_type = "x-application/octet-stream"; request << header("Content-Type", content_type); } } @@ -233,7 +227,7 @@ class basic_client_facade { } else { if (boost::empty(content_type_headers)) { typedef typename char_::type char_type; - static char_type content_type[] = "x-application/octet-stream"; + static char_type* content_type = "x-application/octet-stream"; request << header("Content-Type", content_type); } } @@ -309,7 +303,8 @@ class basic_client_facade { options.openssl_verify_path(), options.openssl_certificate_file(), options.openssl_private_key_file(), options.openssl_ciphers(), options.openssl_sni_hostname(), options.openssl_options(), - options.io_service(), options.timeout())); + options.io_service(), options.timeout(), + options.remove_chunk_markers())); } }; diff --git a/boost/network/protocol/http/client/macros.hpp b/boost/network/protocol/http/client/macros.hpp index 81135f548..6a46ac2a1 100644 --- a/boost/network/protocol/http/client/macros.hpp +++ b/boost/network/protocol/http/client/macros.hpp @@ -6,14 +6,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include +#include #include #ifndef BOOST_NETWORK_HTTP_BODY_CALLBACK #define BOOST_NETWORK_HTTP_BODY_CALLBACK(function_name, range_name, \ error_name) \ - void function_name(boost::iterator_range const& (range_name), \ - std::error_code const& (error_name)) + void function_name(boost::iterator_range::const_iterator> const& (range_name), \ + boost::system::error_code const& (error_name)) #endif #endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_MACROS_HPP_20110430 */ diff --git a/boost/network/protocol/http/client/options.hpp b/boost/network/protocol/http/client/options.hpp index 2c109a88d..bcc266789 100644 --- a/boost/network/protocol/http/client/options.hpp +++ b/boost/network/protocol/http/client/options.hpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include #include @@ -34,7 +34,8 @@ class client_options { openssl_options_(0), io_service_(), always_verify_peer_(true), - timeout_(0) {} + timeout_(0), + remove_chunk_markers_(true) {} client_options(client_options const& other) : cache_resolved_(other.cache_resolved_), @@ -48,7 +49,8 @@ class client_options { openssl_options_(other.openssl_options_), io_service_(other.io_service_), always_verify_peer_(other.always_verify_peer_), - timeout_(other.timeout_) {} + timeout_(other.timeout_), + remove_chunk_markers_(other.remove_chunk_markers_) {} client_options& operator=(client_options other) { other.swap(*this); @@ -69,6 +71,7 @@ class client_options { swap(io_service_, other.io_service_); swap(always_verify_peer_, other.always_verify_peer_); swap(timeout_, other.timeout_); + swap(remove_chunk_markers_, other.remove_chunk_markers_); } /// Specify whether the client should cache resolved endpoints. @@ -133,8 +136,8 @@ class client_options { return *this; } - /// Provide an `asio::io_service` hosted in a shared pointer. - client_options& io_service(std::shared_ptr v) { + /// Provide an `boost::asio::io_service` hosted in a shared pointer. + client_options& io_service(std::shared_ptr v) { io_service_ = v; return *this; } @@ -154,6 +157,12 @@ class client_options { return *this; } + /// Set whether we process chunked-encoded streams. + client_options& remove_chunk_markers(bool v) { + remove_chunk_markers_ = v; + return *this; + } + bool cache_resolved() const { return cache_resolved_; } bool follow_redirects() const { return follow_redirects_; } @@ -184,12 +193,14 @@ class client_options { long openssl_options() const { return openssl_options_; } - std::shared_ptr io_service() const { return io_service_; } + std::shared_ptr io_service() const { return io_service_; } bool always_verify_peer() const { return always_verify_peer_; } int timeout() const { return timeout_; } + bool remove_chunk_markers() const { return remove_chunk_markers_; } + private: bool cache_resolved_; bool follow_redirects_; @@ -200,9 +211,10 @@ class client_options { boost::optional openssl_ciphers_; boost::optional openssl_sni_hostname_; long openssl_options_; - std::shared_ptr io_service_; + std::shared_ptr io_service_; bool always_verify_peer_; int timeout_; + bool remove_chunk_markers_; }; template diff --git a/boost/network/protocol/http/client/pimpl.hpp b/boost/network/protocol/http/client/pimpl.hpp index 2f7f28c67..01c77ca70 100644 --- a/boost/network/protocol/http/client/pimpl.hpp +++ b/boost/network/protocol/http/client/pimpl.hpp @@ -7,7 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include #include #include @@ -74,10 +74,12 @@ struct basic_client_impl optional const& private_key_file, optional const& ciphers, optional const& sni_hostname, long ssl_options, - std::shared_ptr service, int timeout) - : base_type(cache_resolved, follow_redirect, always_verify_peer, timeout, - service, certificate_filename, verify_path, certificate_file, - private_key_file, ciphers, sni_hostname, ssl_options) {} + std::shared_ptr service, int timeout, + bool remove_chunk_markers) + : base_type(cache_resolved, follow_redirect, always_verify_peer, timeout, + remove_chunk_markers, service, certificate_filename, verify_path, + certificate_file, private_key_file, ciphers, sni_hostname, + ssl_options) {} ~basic_client_impl() = default; }; diff --git a/boost/network/protocol/http/client/request.hpp b/boost/network/protocol/http/client/request.hpp new file mode 100644 index 000000000..100970040 --- /dev/null +++ b/boost/network/protocol/http/client/request.hpp @@ -0,0 +1,19 @@ +// Copyright 2016 Glyn Matthews. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_REQUEST_INC) +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_REQUEST_INC + +#include + +namespace boost { +namespace network { +namespace http { +using client_request = basic_request; +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_REQUEST_INC diff --git a/boost/network/protocol/http/client/response.hpp b/boost/network/protocol/http/client/response.hpp new file mode 100644 index 000000000..ca0c9e2e3 --- /dev/null +++ b/boost/network/protocol/http/client/response.hpp @@ -0,0 +1,19 @@ +// Copyright 2016 Glyn Matthews. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_RESPONSE_INC) +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_RESPONSE_INC + +#include + +namespace boost { +namespace network { +namespace http { +using client_response = basic_response; +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_RESPONSE_INC diff --git a/boost/network/protocol/http/client/sync_impl.hpp b/boost/network/protocol/http/client/sync_impl.hpp index 4f07446f5..354dfd3eb 100644 --- a/boost/network/protocol/http/client/sync_impl.hpp +++ b/boost/network/protocol/http/client/sync_impl.hpp @@ -32,13 +32,13 @@ struct sync_client connection_base; typedef typename resolver::type resolver_type; typedef std::function const&, - std::error_code const&)> + boost::system::error_code const&)> body_callback_function_type; typedef std::function body_generator_function_type; friend struct basic_client_impl; - std::shared_ptr service_ptr; - asio::io_service& service_; + std::shared_ptr service_ptr; + boost::asio::io_service& service_; resolver_type resolver_; optional certificate_filename_; optional verify_path_; @@ -51,7 +51,7 @@ struct sync_client sync_client( bool cache_resolved, bool follow_redirect, bool always_verify_peer, - int timeout, std::shared_ptr service, + int timeout, std::shared_ptr service, optional certificate_filename = optional(), optional verify_path = optional(), optional certificate_file = optional(), @@ -61,7 +61,7 @@ struct sync_client long ssl_options = 0) : connection_base(cache_resolved, follow_redirect, timeout), service_ptr(service.get() ? service - : std::make_shared()), + : std::make_shared()), service_(*service_ptr), resolver_(service_), certificate_filename_(std::move(certificate_filename)), diff --git a/boost/network/protocol/http/impl/request.hpp b/boost/network/protocol/http/impl/request.hpp index 85ab0f3ae..771075b88 100644 --- a/boost/network/protocol/http/impl/request.hpp +++ b/boost/network/protocol/http/impl/request.hpp @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include namespace boost { namespace network { @@ -50,7 +50,7 @@ namespace http { */ template struct basic_request : public basic_message { - mutable boost::network::uri::uri uri_; + ::network::uri uri_; std::uint16_t source_port_; typedef basic_message base_type; @@ -62,13 +62,9 @@ struct basic_request : public basic_message { explicit basic_request(string_type const& uri_) : uri_(uri_), source_port_(0) {} - explicit basic_request(boost::network::uri::uri const& uri_) + explicit basic_request(::network::uri const& uri_) : uri_(uri_), source_port_(0) {} - void uri(string_type const& new_uri) { uri_ = new_uri; } - - void uri(boost::network::uri::uri const& new_uri) { uri_ = new_uri; } - basic_request() : base_type(), source_port_(0) {} basic_request(basic_request const& other) @@ -87,29 +83,29 @@ struct basic_request : public basic_message { boost::swap(other.source_port_, this->source_port_); } - string_type const host() const { return uri_.host(); } + string_type const host() const { return uri_.host().to_string(); } port_type port() const { - boost::optional port = uri::port_us(uri_); - if (!port) { + if (uri_.has_port()) { + return uri_.port(); + } + else { typedef constants consts; - return boost::iequals(uri_.scheme(), string_type(consts::https())) ? 443 - : 80; + return boost::iequals(uri_.scheme(), string_type(consts::https())) ? 443 : 80; } - return *port; } - string_type const path() const { return uri_.path(); } + string_type const path() const { return uri_.path().to_string(); } - string_type const query() const { return uri_.query(); } + string_type const query() const { return uri_.query().to_string(); } - string_type const anchor() const { return uri_.fragment(); } + string_type const anchor() const { return uri_.fragment().to_string(); } - string_type const protocol() const { return uri_.scheme(); } + string_type const protocol() const { return uri_.scheme().to_string(); } void uri(string_type const& new_uri) const { uri_ = new_uri; } - boost::network::uri::uri const& uri() const { return uri_; } + ::network::uri const& uri() const { return uri_; } void source_port(const std::uint16_t port) { source_port_ = port; } diff --git a/boost/network/protocol/http/impl/response.ipp b/boost/network/protocol/http/impl/response.ipp index 24055776c..a685a2169 100644 --- a/boost/network/protocol/http/impl/response.ipp +++ b/boost/network/protocol/http/impl/response.ipp @@ -16,7 +16,7 @@ #ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_RESPONSE_RESPONSE_IPP #define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_RESPONSE_RESPONSE_IPP -#include +#include #include #include #include @@ -100,9 +100,9 @@ struct basic_response { /// underlying memory blocks, therefore the reply object must remain /// valid and /// not be changed until the write operation has completed. - std::vector to_buffers() { - using asio::const_buffer; - using asio::buffer; + std::vector to_buffers() { + using boost::asio::const_buffer; + using boost::asio::buffer; static const char name_value_separator[] = {':', ' '}; static const char crlf[] = {'\r', '\n'}; std::vector buffers; @@ -408,13 +408,13 @@ struct basic_response { } } - asio::const_buffer trim_null(asio::const_buffer buffer) { - std::size_t size = asio::buffer_size(buffer); - return asio::buffer(buffer, size - 1); + boost::asio::const_buffer trim_null(boost::asio::const_buffer buffer) { + std::size_t size = boost::asio::buffer_size(buffer); + return boost::asio::buffer(buffer, size - 1); } - asio::const_buffer to_buffer(status_type status) { - using asio::buffer; + boost::asio::const_buffer to_buffer(status_type status) { + using boost::asio::buffer; switch (status) { // 2xx Success case basic_response::ok: diff --git a/boost/network/protocol/http/message/async_message.hpp b/boost/network/protocol/http/message/async_message.hpp index bca9148b2..747a962ed 100644 --- a/boost/network/protocol/http/message/async_message.hpp +++ b/boost/network/protocol/http/message/async_message.hpp @@ -9,13 +9,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include #include +#include // FIXME move this out to a trait -#include #include +#include +#include namespace boost { namespace network { @@ -26,12 +26,11 @@ namespace impl { template struct ready_wrapper; -} // namespace impl - /* impl */ +} // namespace impl + /* impl */ template struct async_message { - typedef typename string::type string_type; typedef typename headers_container::type headers_container_type; typedef typename headers_container_type::value_type header_type; @@ -54,65 +53,97 @@ struct async_message { headers_(other.headers_), body_(other.body_) {} - string_type const status_message() const { return status_message_.get(); } + string_type status_message() const { + status_message_.wait(); + if (status_message_.has_exception()) + boost::rethrow_exception(status_message_.get_exception_ptr()); + return status_message_.get(); + } - void status_message(std::shared_future const& future) const { + void status_message(boost::shared_future const& future) const { status_message_ = future; } - string_type const version() const { return version_.get(); } + string_type version() const { + version_.wait(); + if (version_.has_exception()) + boost::rethrow_exception(version_.get_exception_ptr()); + return version_.get(); + } - void version(std::shared_future const& future) const { + void version(boost::shared_future const& future) const { version_ = future; } - std::uint16_t status() const { return status_.get(); } + std::uint16_t status() const { + status_.wait(); + if (status_.has_exception()) + boost::rethrow_exception(status_.get_exception_ptr()); + return status_.get(); + } - void status(std::shared_future const& future) const { + void status(boost::shared_future const& future) const { status_ = future; } - string_type const source() const { return source_.get(); } + string_type source() const { + source_.wait(); + if (source_.has_exception()) + boost::rethrow_exception(source_.get_exception_ptr()); + return source_.get(); + } - void source(std::shared_future const& future) const { + void source(boost::shared_future const& future) const { source_ = future; } - string_type const destination() const { return destination_.get(); } + string_type destination() const { + destination_.wait(); + if (destination_.has_exception()) + boost::rethrow_exception(source_.get_exception_ptr()); + return destination_.get(); + } - void destination(std::shared_future const& future) const { + void destination(boost::shared_future const& future) const { destination_ = future; } headers_container_type const& headers() const { if (retrieved_headers_) return *retrieved_headers_; + if (headers_.has_exception()) + boost::rethrow_exception(headers_.get_exception_ptr()); headers_container_type raw_headers = headers_.get(); raw_headers.insert(added_headers.begin(), added_headers.end()); - for (string_type const & key : removed_headers) { + for (string_type const& key : removed_headers) { raw_headers.erase(key); } retrieved_headers_ = raw_headers; return *retrieved_headers_; } - void headers(std::shared_future const& future) - const { + void headers( + boost::shared_future const& future) const { headers_ = future; } - void add_header(typename headers_container_type::value_type const& pair_) - const { + void add_header( + typename headers_container_type::value_type const& pair_) const { added_headers.insert(added_headers.end(), pair_); } - void remove_header(typename headers_container_type::key_type const& key_) - const { + void remove_header( + typename headers_container_type::key_type const& key_) const { removed_headers.insert(key_); } - string_type const body() const { return body_.get(); } + string_type body() const { + body_.wait(); + if (body_.has_exception()) + boost::rethrow_exception(body_.get_exception_ptr()); + return body_.get(); + } - void body(std::shared_future const& future) const { + void body(boost::shared_future const& future) const { body_ = future; } @@ -132,13 +163,13 @@ struct async_message { } private: - mutable std::shared_future status_message_, version_, source_, + mutable boost::shared_future status_message_, version_, source_, destination_; - mutable std::shared_future status_; - mutable std::shared_future headers_; + mutable boost::shared_future status_; + mutable boost::shared_future headers_; mutable headers_container_type added_headers; mutable std::set removed_headers; - mutable std::shared_future body_; + mutable boost::shared_future body_; mutable boost::optional retrieved_headers_; friend struct boost::network::http::impl::ready_wrapper; diff --git a/boost/network/protocol/http/message/directives/status.hpp b/boost/network/protocol/http/message/directives/status.hpp index 010ad2f2a..f64cb94d3 100644 --- a/boost/network/protocol/http/message/directives/status.hpp +++ b/boost/network/protocol/http/message/directives/status.hpp @@ -7,11 +7,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include #include +#include #include #include #include @@ -25,18 +25,18 @@ struct basic_response; struct status_directive { - boost::variant > + boost::variant > status_; explicit status_directive(std::uint16_t status) : status_(status) {} - explicit status_directive(std::shared_future const &status) + explicit status_directive(boost::shared_future const &status) : status_(status) {} status_directive(status_directive const &other) : status_(other.status_) {} template - struct value : mpl::if_, std::shared_future, + struct value : mpl::if_, boost::shared_future, std::uint16_t> {}; template diff --git a/boost/network/protocol/http/message/traits/status.hpp b/boost/network/protocol/http/message/traits/status.hpp index ce1b551a8..92c6c3d6c 100644 --- a/boost/network/protocol/http/message/traits/status.hpp +++ b/boost/network/protocol/http/message/traits/status.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace boost { namespace network { @@ -23,7 +24,7 @@ template struct status : mpl::if_< is_async, - std::shared_future, + boost::shared_future, typename mpl::if_, std::uint16_t, unsupported_tag >::type> {}; diff --git a/boost/network/protocol/http/message/traits/status_message.hpp b/boost/network/protocol/http/message/traits/status_message.hpp index 544d55b3f..61b89ec02 100644 --- a/boost/network/protocol/http/message/traits/status_message.hpp +++ b/boost/network/protocol/http/message/traits/status_message.hpp @@ -6,11 +6,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include #include +#include namespace boost { namespace network { @@ -25,7 +25,7 @@ template struct status_message : mpl::if_< is_async, - std::shared_future::type>, + boost::shared_future::type>, typename mpl::if_< mpl::or_, is_same, diff --git a/boost/network/protocol/http/message/traits/version.hpp b/boost/network/protocol/http/message/traits/version.hpp index 103483fcc..3fbcc7348 100644 --- a/boost/network/protocol/http/message/traits/version.hpp +++ b/boost/network/protocol/http/message/traits/version.hpp @@ -6,12 +6,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include #include #include #include #include #include +#include namespace boost { namespace network { @@ -30,7 +30,7 @@ struct version { template struct version >::type> { - typedef std::shared_future::type> + typedef boost::shared_future::type> type; }; diff --git a/boost/network/protocol/http/message/wrappers/port.hpp b/boost/network/protocol/http/message/wrappers/port.hpp index 8e7abd759..a4f17f06e 100644 --- a/boost/network/protocol/http/message/wrappers/port.hpp +++ b/boost/network/protocol/http/message/wrappers/port.hpp @@ -10,7 +10,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include #include @@ -38,13 +38,14 @@ struct port_wrapper { // conversions no longer work correctly with MSVC. The conversion therefore // has to be done explicitly with as_optional(). boost::optional as_optional() const { - return uri::port_us(message_.uri()); - } #else operator boost::optional() const { - return uri::port_us(message_.uri()); - } #endif + if (message_.uri().has_port()) { + return message_.uri().template port(); + } + return boost::optional(); + } }; diff --git a/boost/network/protocol/http/message/wrappers/uri.hpp b/boost/network/protocol/http/message/wrappers/uri.hpp index 67d8745b1..802fd5390 100644 --- a/boost/network/protocol/http/message/wrappers/uri.hpp +++ b/boost/network/protocol/http/message/wrappers/uri.hpp @@ -7,7 +7,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include namespace boost { namespace network { @@ -22,8 +22,8 @@ struct uri_wrapper { basic_request const& message_; explicit uri_wrapper(basic_request const& message) : message_(message) {} typedef typename basic_request::string_type string_type; - operator string_type() { return message_.uri().raw(); } - operator boost::network::uri::uri() { return message_.uri(); } + operator string_type() { return message_.uri().to_string(); } + operator ::network::uri() { return message_.uri(); } }; } // namespace impl diff --git a/boost/network/protocol/http/policies/async_connection.hpp b/boost/network/protocol/http/policies/async_connection.hpp index 34a1f0c21..900a37e59 100644 --- a/boost/network/protocol/http/policies/async_connection.hpp +++ b/boost/network/protocol/http/policies/async_connection.hpp @@ -30,15 +30,15 @@ struct async_connection_policy : resolver_policy::type { typedef typename resolver_base::resolve_function resolve_function; typedef typename resolver_base::resolve_completion_function resolve_completion_function; - typedef std::function const&, - std::error_code const&)> + typedef std::function::type, 1024>::const_iterator> const&, + boost::system::error_code const&)> body_callback_function_type; typedef std::function body_generator_function_type; struct connection_impl { connection_impl( bool follow_redirect, bool always_verify_peer, resolve_function resolve, - resolver_type& resolver, bool https, int timeout, + resolver_type& resolver, bool https, int timeout, bool remove_chunk_markers, optional /*unused*/ const& certificate_filename, optional const& verify_path, optional const& certificate_file, @@ -47,9 +47,9 @@ struct async_connection_policy : resolver_policy::type { optional const& sni_hostname, long ssl_options) { pimpl = impl::async_connection_base:: new_connection(resolve, resolver, follow_redirect, always_verify_peer, - https, timeout, certificate_filename, verify_path, - certificate_file, private_key_file, ciphers, - sni_hostname, ssl_options); + https, timeout, remove_chunk_markers, + certificate_filename, verify_path, certificate_file, + private_key_file, ciphers, sni_hostname, ssl_options); } basic_response send_request(string_type /*unused*/ const& method, @@ -86,20 +86,22 @@ struct async_connection_policy : resolver_policy::type { this->resolve(resolver, host, port, once_resolved); }, resolver, boost::iequals(protocol_, string_type("https")), timeout_, - certificate_filename, verify_path, certificate_file, private_key_file, - ciphers, sni_hostname, ssl_options); + remove_chunk_markers_, certificate_filename, verify_path, + certificate_file, private_key_file, ciphers, sni_hostname, ssl_options); } void cleanup() {} async_connection_policy(bool cache_resolved, bool follow_redirect, - int timeout) + int timeout, bool remove_chunk_markers) : resolver_base(cache_resolved), follow_redirect_(follow_redirect), - timeout_(timeout) {} + timeout_(timeout), + remove_chunk_markers_(remove_chunk_markers) {} bool follow_redirect_; int timeout_; + bool remove_chunk_markers_; }; } // namespace http diff --git a/boost/network/protocol/http/policies/async_resolver.hpp b/boost/network/protocol/http/policies/async_resolver.hpp index ac30d1586..4e508364a 100644 --- a/boost/network/protocol/http/policies/async_resolver.hpp +++ b/boost/network/protocol/http/policies/async_resolver.hpp @@ -10,8 +10,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -31,27 +31,30 @@ struct async_resolver : std::enable_shared_from_this > { typedef typename string::type string_type; typedef std::unordered_map endpoint_cache; - typedef std::function + typedef std::function resolve_completion_function; typedef std::function resolve_function; + void clear_resolved_cache() { clear_cache_.store(true); } + protected: bool cache_resolved_; + std::atomic clear_cache_; endpoint_cache endpoint_cache_; - std::shared_ptr service_; - std::shared_ptr resolver_strand_; + std::shared_ptr service_; + std::shared_ptr resolver_strand_; explicit async_resolver(bool cache_resolved) - : cache_resolved_(cache_resolved), endpoint_cache_() {} + : cache_resolved_(cache_resolved), clear_cache_(false), endpoint_cache_() {} void resolve(resolver_type &resolver_, string_type const &host, std::uint16_t port, resolve_completion_function once_resolved) { - if (cache_resolved_) { + if (cache_resolved_ && !clear_cache_.load()) { typename endpoint_cache::iterator iter = endpoint_cache_.find(boost::to_lower_copy(host)); if (iter != endpoint_cache_.end()) { - std::error_code ignored; + boost::system::error_code ignored; once_resolved(ignored, iter->second); return; } @@ -60,7 +63,7 @@ struct async_resolver : std::enable_shared_from_this > { typename resolver_type::query q(host, std::to_string(port)); auto self = this->shared_from_this(); resolver_.async_resolve( - q, resolver_strand_->wrap([=](std::error_code const &ec, + q, resolver_strand_->wrap([=](boost::system::error_code const &ec, resolver_iterator endpoint_iterator) { self->handle_resolve(boost::to_lower_copy(host), once_resolved, ec, endpoint_iterator); @@ -69,11 +72,14 @@ struct async_resolver : std::enable_shared_from_this > { void handle_resolve(string_type /*unused*/ const &host, resolve_completion_function once_resolved, - std::error_code const &ec, + boost::system::error_code const &ec, resolver_iterator endpoint_iterator) { typename endpoint_cache::iterator iter; bool inserted = false; if (!ec && cache_resolved_) { + if (clear_cache_.exchange(false)) { + endpoint_cache_.clear(); + } std::tie(iter, inserted) = endpoint_cache_.insert(std::make_pair( host, std::make_pair(endpoint_iterator, resolver_iterator()))); once_resolved(ec, iter->second); diff --git a/boost/network/protocol/http/policies/pooled_connection.hpp b/boost/network/protocol/http/policies/pooled_connection.hpp index 845dd0d4a..34339367d 100644 --- a/boost/network/protocol/http/policies/pooled_connection.hpp +++ b/boost/network/protocol/http/policies/pooled_connection.hpp @@ -35,7 +35,7 @@ struct pooled_connection_policy : resolver_policy::type { resolver_type&, string_type const&, string_type const&)> resolver_function_type; typedef std::function const&, - std::error_code const&)> + boost::system::error_code const&)> body_callback_function_type; typedef std::function body_generator_function_type; @@ -110,12 +110,12 @@ struct pooled_connection_policy : resolver_policy::type { response_ << ::boost::network::source(request_.host()); pimpl->send_request_impl(method, request_, generator); - asio::streambuf response_buffer; + boost::asio::streambuf response_buffer; try { pimpl->read_status(response_, response_buffer); - } catch (std::system_error& e) { - if (!retry && e.code() == asio::error::eof) { + } catch (boost::system::system_error& e) { + if (!retry && e.code() == boost::asio::error::eof) { retry = true; pimpl->init_socket(request_.host(), std::to_string(request_.port())); diff --git a/boost/network/protocol/http/policies/simple_connection.hpp b/boost/network/protocol/http/policies/simple_connection.hpp index 5a96c5ade..dca2fb354 100644 --- a/boost/network/protocol/http/policies/simple_connection.hpp +++ b/boost/network/protocol/http/policies/simple_connection.hpp @@ -36,7 +36,7 @@ struct simple_connection_policy : resolver_policy::type { typedef typename resolver_base::resolver_completion_function resolver_completion_function; typedef std::function const&, - std::error_code const&)> + boost::system::error_code const&)> body_callback_function_type; typedef std::function body_generator_function_type; @@ -80,7 +80,7 @@ struct simple_connection_policy : resolver_policy::type { response_ = basic_response(); response_ << network::source(request_.host()); - asio::streambuf response_buffer; + boost::asio::streambuf response_buffer; pimpl->read_status(response_, response_buffer); pimpl->read_headers(response_, response_buffer); if (get_body) pimpl->read_body(response_, response_buffer); diff --git a/boost/network/protocol/http/policies/sync_resolver.hpp b/boost/network/protocol/http/policies/sync_resolver.hpp index 7c9c2c7f4..09d373b87 100644 --- a/boost/network/protocol/http/policies/sync_resolver.hpp +++ b/boost/network/protocol/http/policies/sync_resolver.hpp @@ -27,19 +27,26 @@ struct sync_resolver { typedef std::pair resolver_iterator_pair; + void clear_resolved_cache() { clear_cache_.store(true); } + protected: typedef typename string::type string_type; typedef std::unordered_map resolved_cache; resolved_cache endpoint_cache_; bool cache_resolved_; + std::atomic clear_cache_; - explicit sync_resolver(bool cache_resolved) : cache_resolved_(cache_resolved) {} + explicit sync_resolver(bool cache_resolved) + : cache_resolved_(cache_resolved), clear_cache_(false) {} resolver_iterator_pair resolve(resolver_type& resolver_, string_type /*unused*/const& hostname, string_type const& port) { if (cache_resolved_) { + if (clear_cache_.exchange(false)) { + endpoint_cache_.clear(); + } typename resolved_cache::iterator cached_iterator = endpoint_cache_.find(hostname); if (cached_iterator == endpoint_cache_.end()) { diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index e5c361ab6..b2a736f7b 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -16,11 +16,11 @@ #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include @@ -183,7 +183,7 @@ struct async_connection public: async_connection( - asio::io_service& io_service, Handler& handler, + boost::asio::io_service& io_service, Handler& handler, utils::thread_pool& thread_pool, std::shared_ptr ctx = std::shared_ptr()) : strand(io_service), @@ -205,8 +205,8 @@ struct async_connection } ~async_connection() throw() { - std::error_code ignored; - socket_.shutdown(asio::ip::tcp::socket::shutdown_receive, ignored); + boost::system::error_code ignored; + socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_receive, ignored); } /** @@ -228,7 +228,7 @@ struct async_connection std::logic_error("Headers have already been sent.")); if (error_encountered) - boost::throw_exception(std::system_error(*error_encountered)); + boost::throw_exception(boost::system::system_error(*error_encountered)); typedef constants consts; { @@ -264,7 +264,7 @@ struct async_connection boost::throw_exception(std::logic_error( "Headers have already been sent, cannot reset status.")); if (error_encountered) - boost::throw_exception(std::system_error(*error_encountered)); + boost::throw_exception(boost::system::system_error(*error_encountered)); status = new_status; } @@ -289,7 +289,7 @@ struct async_connection * set_status and/or set_headers before any calls to write. * * @param[in] range A Boost.Range ``Single Pass Range`` of char's for writing. - * @throw std::system_error The encountered underlying error in previous + * @throw boost::system::system_error The encountered underlying error in previous * operations. * @post Status and headers have been sent, contents in the range have been * serialized. @@ -298,9 +298,9 @@ struct async_connection void write(Range const& range) { lock_guard lock(headers_mutex); if (error_encountered) - boost::throw_exception(std::system_error(*error_encountered)); + boost::throw_exception(boost::system::system_error(*error_encountered)); auto self = this->shared_from_this(); - auto f = [this, self](std::error_code ec) { this->default_error(ec); }; + auto f = [this, self](boost::system::error_code ec) { this->default_error(ec); }; write_impl(boost::make_iterator_range(range), f); } @@ -313,32 +313,32 @@ struct async_connection * memory at once. * * @param[in] range A Boost.Range ``Single Pass Range`` of char's for writing. - * @param[in] callback A function of type `void(std::error_code)`. - * @throw std::system_error The encountered underlying error in previous + * @param[in] callback A function of type `void(boost::system::error_code)`. + * @throw boost::system::system_error The encountered underlying error in previous * operations. * @post Status and headers have been sent, contents in the range have been * serialized and scheduled for writing through the socket. */ template typename disable_if< - is_base_of, void>::type + is_base_of, void>::type write(Range const& range, Callback const& callback) { lock_guard lock(headers_mutex); if (error_encountered) - boost::throw_exception(std::system_error(*error_encountered)); + boost::throw_exception(boost::system::system_error(*error_encountered)); write_impl(boost::make_iterator_range(range), callback); } /** - * Writes a given set of `asio::const_buffer`s out using a more efficient + * Writes a given set of `boost::asio::const_buffer`s out using a more efficient * implementation. * - * @param[in] seq A sequence of `asio::const_buffer` objects. - * @param[in] callback A function of type `void(std::error_code)`. + * @param[in] seq A sequence of `boost::asio::const_buffer` objects. + * @param[in] callback A function of type `void(boost::system::error_code)`. */ template typename enable_if< - is_base_of, + is_base_of, void>::type write(ConstBufferSeq const& seq, Callback const& callback) { write_vec_impl(seq, callback, shared_array_list(), shared_buffers()); @@ -355,7 +355,7 @@ struct async_connection /// Type required for ``read`` callbacks. Takes an input range, an error /// code, the number of bytes read, and a connection pointer. - typedef std::function read_callback_function; /** @@ -370,15 +370,15 @@ struct async_connection * void(input_range, error_code, size_t, connection_ptr) * * @param[in] callback Invoked when the read has data ready for processing. - * @throw std::system_error The underlying error encountered in previous + * @throw boost::system::system_error The underlying error encountered in previous * operations. */ void read(read_callback_function callback) { if (error_encountered) - boost::throw_exception(std::system_error(*error_encountered)); + boost::throw_exception(boost::system::system_error(*error_encountered)); if (new_start != read_buffer_.begin()) { input_range input = - boost::make_iterator_range(new_start, read_buffer_.end()); + boost::make_iterator_range(new_start, data_end); buffer_type::iterator start_tmp = new_start; new_start = read_buffer_.begin(); auto self = this->shared_from_this(); @@ -389,10 +389,11 @@ struct async_connection } auto self = this->shared_from_this(); - socket().async_read_some(asio::buffer(read_buffer_), + socket().async_read_some(boost::asio::buffer(read_buffer_), strand.wrap([this, self, callback]( - std::error_code ec, size_t bytes_transferred) { - callback(ec, bytes_transferred); + boost::system::error_code ec, size_t bytes_transferred) { + this->wrap_read_handler(callback, ec, + bytes_transferred); })); } @@ -407,13 +408,13 @@ struct async_connection bool has_error() { return (!!error_encountered); } /// Returns the most recent error encountered. - optional error() { return error_encountered; } + optional error() { return error_encountered; } private: void wrap_read_handler(read_callback_function callback, - std::error_code const& ec, + boost::system::error_code const& ec, std::size_t bytes_transferred) { - if (ec) error_encountered = in_place(ec); + if (ec) error_encountered = in_place(ec); buffer_type::const_iterator data_start = read_buffer_.begin(), data_end = read_buffer_.begin(); std::advance(data_end, bytes_transferred); @@ -424,23 +425,23 @@ struct async_connection }); } - void default_error(std::error_code const& ec) { - if (ec) error_encountered = in_place(ec); + void default_error(boost::system::error_code const& ec) { + if (ec) error_encountered = in_place(ec); } typedef std::array array; typedef std::list > array_list; typedef std::shared_ptr shared_array_list; - typedef std::shared_ptr > shared_buffers; + typedef std::shared_ptr > shared_buffers; typedef request_parser request_parser_type; typedef std::lock_guard lock_guard; typedef std::list > pending_actions_list; - asio::io_service::strand strand; + boost::asio::io_service::strand strand; Handler& handler; utils::thread_pool& thread_pool_; - asio::streambuf headers_buffer; + boost::asio::streambuf headers_buffer; boost::network::stream_handler socket_; bool handshake_done; volatile bool headers_already_sent, headers_in_progress; @@ -452,7 +453,7 @@ struct async_connection request request_; buffer_type::iterator new_start, data_end; string_type partial_parsed; - optional error_encountered; + optional error_encountered; pending_actions_list pending_actions; template @@ -472,15 +473,15 @@ struct async_connection auto self = this->shared_from_this(); #ifdef BOOST_NETWORK_ENABLE_HTTPS if (socket_.is_ssl_enabled() && !handshake_done) { - socket_.async_handshake(asio::ssl::stream_base::server, - [this, self, state](std::error_code ec) { + socket_.async_handshake(boost::asio::ssl::stream_base::server, + [this, self, state](boost::system::error_code ec) { handle_handshake(ec, state); }); } else { #endif socket_.async_read_some( - asio::buffer(read_buffer_), - strand.wrap([this, self, state](std::error_code ec, + boost::asio::buffer(read_buffer_), + strand.wrap([this, self, state](boost::system::error_code ec, size_t bytes_transferred) { handle_read_data(state, ec, bytes_transferred); })); @@ -489,7 +490,7 @@ struct async_connection #endif } - void handle_read_data(state_t state, std::error_code const& ec, + void handle_read_data(state_t state, boost::system::error_code const& ec, std::size_t bytes_transferred) { if (!ec) { logic::tribool parsed_ok; @@ -578,7 +579,7 @@ struct async_connection } new_start = std::end(result_range); auto self = this->shared_from_this(); - thread_pool().post([this, self] { handler(request_, self); }); + thread_pool().post([this, self] { this->handler(this->request_, self); }); return; } else { partial_parsed.append(std::begin(result_range), @@ -594,7 +595,7 @@ struct async_connection std::abort(); } } else { - error_encountered = in_place(ec); + error_encountered = in_place(ec); } } @@ -604,20 +605,20 @@ struct async_connection "text/plain\r\nContent-Length: 12\r\n\r\nBad Request."; auto self = this->shared_from_this(); - asio::async_write( - socket(), asio::buffer(bad_request, strlen(bad_request)), - strand.wrap([this, self](std::error_code ec, size_t bytes_transferred) { + boost::asio::async_write( + socket(), boost::asio::buffer(bad_request, strlen(bad_request)), + strand.wrap([this, self](boost::system::error_code ec, size_t bytes_transferred) { client_error_sent(ec, bytes_transferred); })); } - void client_error_sent(std::error_code const& ec, std::size_t) { + void client_error_sent(boost::system::error_code const& ec, std::size_t) { if (!ec) { - std::error_code ignored; - socket().shutdown(asio::ip::tcp::socket::shutdown_both, ignored); + boost::system::error_code ignored; + socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored); socket().close(ignored); } else { - error_encountered = in_place(ec); + error_encountered = in_place(ec); } } @@ -625,15 +626,15 @@ struct async_connection if (headers_in_progress) return; headers_in_progress = true; auto self = this->shared_from_this(); - asio::async_write(socket(), headers_buffer, + boost::asio::async_write(socket(), headers_buffer, strand.wrap([this, self, callback]( - std::error_code ec, size_t bytes_transferred) { + boost::system::error_code ec, size_t bytes_transferred) { handle_write_headers(callback, ec, bytes_transferred); })); } void handle_write_headers(std::function callback, - std::error_code const& ec, std::size_t) { + boost::system::error_code const& ec, std::size_t) { lock_guard lock(headers_mutex); if (!ec) { headers_buffer.consume(headers_buffer.size()); @@ -645,19 +646,19 @@ struct async_connection } pending_actions_list().swap(pending_actions); } else { - error_encountered = in_place(ec); + error_encountered = in_place(ec); } } - void handle_write(std::function callback, + void handle_write(std::function callback, shared_array_list, shared_buffers, - std::error_code const& ec, std::size_t) { + boost::system::error_code const& ec, std::size_t) { // we want to forget the temporaries and buffers thread_pool().post([callback, ec] { callback(ec); }); } template - void write_impl(Range range, std::function callback) { + void write_impl(Range range, std::function callback) { // linearize the whole range into a vector // of fixed-sized buffers, then schedule an asynchronous // write of these buffers -- make sure they are live @@ -675,7 +676,7 @@ struct async_connection BOOST_NETWORK_HTTP_SERVER_CONNECTION_BUFFER_SIZE; shared_array_list temporaries = std::make_shared(); shared_buffers buffers = - std::make_shared >(0); + std::make_shared >(0); std::size_t range_size = boost::distance(range); buffers->reserve((range_size / connection_buffer_size) + @@ -687,7 +688,7 @@ struct async_connection std::shared_ptr new_array = std::make_shared(); boost::copy(range | sliced(0, slice_size), new_array->begin()); temporaries->push_back(new_array); - buffers->push_back(asio::buffer(new_array->data(), slice_size)); + buffers->push_back(boost::asio::buffer(new_array->data(), slice_size)); std::advance(start, slice_size); range = boost::make_iterator_range(start, end); range_size = boost::distance(range); @@ -704,7 +705,7 @@ struct async_connection shared_array_list temporaries, shared_buffers buffers) { lock_guard lock(headers_mutex); if (error_encountered) - boost::throw_exception(std::system_error(*error_encountered)); + boost::throw_exception(boost::system::system_error(*error_encountered)); auto self = this->shared_from_this(); auto continuation = [this, self, seq, callback, temporaries, buffers] { write_vec_impl(seq, callback, temporaries, buffers); @@ -717,19 +718,19 @@ struct async_connection pending_actions.push_back(continuation); return; } - asio::async_write( + boost::asio::async_write( socket_, seq, [this, self, callback, temporaries, buffers]( - std::error_code ec, size_t bytes_transferred) { + boost::system::error_code ec, size_t bytes_transferred) { handle_write(callback, temporaries, buffers, ec, bytes_transferred); }); } - void handle_handshake(const std::error_code& ec, state_t state) { + void handle_handshake(const boost::system::error_code& ec, state_t state) { if (!ec) { handshake_done = true; read_more(state); } else { - error_encountered = in_place(ec); + error_encountered = in_place(ec); } } }; diff --git a/boost/network/protocol/http/server/async_server.hpp b/boost/network/protocol/http/server/async_server.hpp index 954e0a5c3..c1e3c662e 100644 --- a/boost/network/protocol/http/server/async_server.hpp +++ b/boost/network/protocol/http/server/async_server.hpp @@ -35,13 +35,17 @@ struct async_server_base : server_storage_base, socket_options_base { /// Defines the type for the connection pointer. typedef std::shared_ptr connection_ptr; + /// Defines the type for the options. + typedef server_options options; + /// Constructs and initializes the asynchronous server core. - explicit async_server_base(server_options const &options) + explicit async_server_base(options const &options) : server_storage_base(options), socket_options_base(options), handler(options.handler()), address_(options.address()), port_(options.port()), + protocol_family(options.protocol_family()), thread_pool(options.thread_pool() ? options.thread_pool() : std::make_shared()), @@ -86,7 +90,7 @@ struct async_server_base : server_storage_base, socket_options_base { // listening scoped_mutex_lock stopping_lock(stopping_mutex_); stopping = true; - std::error_code ignored; + boost::system::error_code ignored; acceptor.close(ignored); listening = false; service_.post([this]() { this->handle_stop(); }); @@ -108,13 +112,21 @@ struct async_server_base : server_storage_base, socket_options_base { } } + /// Returns the server socket address, either IPv4 or IPv6 depending on + /// options.protocol_family() + const string_type& address() const { return address_; } + + /// Returns the server socket port + const string_type& port() const { return port_; } + private: typedef std::unique_lock scoped_mutex_lock; Handler &handler; string_type address_, port_; + typename options::protocol_family_t protocol_family; std::shared_ptr thread_pool; - asio::ip::tcp::acceptor acceptor; + boost::asio::ip::tcp::acceptor acceptor; bool stopping; connection_ptr new_connection; std::mutex listening_mutex_; @@ -129,7 +141,7 @@ struct async_server_base : server_storage_base, socket_options_base { // the stop command is reached } - void handle_accept(std::error_code const &ec) { + void handle_accept(boost::system::error_code const &ec) { { scoped_mutex_lock stopping_lock(stopping_mutex_); if (stopping) @@ -156,16 +168,24 @@ struct async_server_base : server_storage_base, socket_options_base { #else new_connection->socket(), #endif - [this](std::error_code const &ec) { this->handle_accept(ec); }); + [this](boost::system::error_code const &ec) { this->handle_accept(ec); }); } void start_listening() { - using asio::ip::tcp; - std::error_code error; + using boost::asio::ip::tcp; + boost::system::error_code error; // this allows repeated cycles of run -> stop -> run service_.reset(); tcp::resolver resolver(service_); - tcp::resolver::query query(address_, port_); + tcp::resolver::query query( [&]{ + switch(protocol_family) { + case options::ipv4: + return tcp::resolver::query(tcp::v4(), address_, port_); + case options::ipv6: + return tcp::resolver::query(tcp::v6(), address_, port_); + default: + return tcp::resolver::query(address_, port_); + }}()); tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, error); if (error) { BOOST_NETWORK_MESSAGE("Error resolving '" << address_ << ':' << port_); @@ -185,7 +205,9 @@ struct async_server_base : server_storage_base, socket_options_base { << port_); return; } - acceptor.listen(asio::socket_base::max_connections, error); + address_ = acceptor.local_endpoint().address().to_string(); + port_ = std::to_string(acceptor.local_endpoint().port()); + acceptor.listen(boost::asio::socket_base::max_connections, error); if (error) { BOOST_NETWORK_MESSAGE("Error listening on socket: '" << error << "' on " << address_ << ":" << port_); @@ -198,7 +220,7 @@ struct async_server_base : server_storage_base, socket_options_base { #else new_connection->socket(), #endif - [this](std::error_code const &ec) { this->handle_accept(ec); }); + [this](boost::system::error_code const &ec) { this->handle_accept(ec); }); listening = true; scoped_mutex_lock stopping_lock(stopping_mutex_); stopping = false; // if we were in the process of stopping, we revoke diff --git a/boost/network/protocol/http/server/impl/parsers.ipp b/boost/network/protocol/http/server/impl/parsers.ipp deleted file mode 100644 index b0de37597..000000000 --- a/boost/network/protocol/http/server/impl/parsers.ipp +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef SERVER_REQUEST_PARSERS_IMPL_UW3PM6V6 -#define SERVER_REQUEST_PARSERS_IMPL_UW3PM6V6 - -#define BOOST_SPIRIT_UNICODE -#include - -// Copyright 2013 Google, Inc. -// Copyright 2010 Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -#ifdef BOOST_NETWORK_NO_LIB -#ifndef BOOST_NETWORK_INLINE -#define BOOST_NETWORK_INLINE inline -#endif -#else -#define BOOST_NETWORK_INLINE -#endif -#include - -namespace boost { -namespace spirit { -namespace traits { - -typedef std::basic_string u32_string; - -template <> // -struct assign_to_container_from_value { - static void call(u32_string const& val, std::string& attr) { - u32_to_u8_iterator begin = val.begin(), - end = val.end(); - for (; begin != end; ++begin) attr += *begin; - } -}; - -} // namespace traits -} // namespace spirit -} // namespace boost - -namespace boost { -namespace network { -namespace http { - -BOOST_NETWORK_INLINE void parse_version( - std::string const& partial_parsed, - std::tuple& version_pair) { - using namespace boost::spirit::qi; - parse(partial_parsed.begin(), partial_parsed.end(), - (lit("HTTP/") >> ushort_ >> '.' >> ushort_), version_pair); -} - -BOOST_NETWORK_INLINE void parse_headers( - std::string const& input, std::vector& container) { - using namespace boost::spirit::qi; - u8_to_u32_iterator begin = input.begin(), - end = input.end(); - typedef as as_u32_string; - parse(begin, end, - *(+((alnum | punct) - ':') >> lit(": ") >> - as_u32_string()[+((unicode::alnum | space | punct) - '\r' - '\n')] >> - lit("\r\n")) >> - lit("\r\n"), - container); -} - -} // namespace http -} // namespace network -} // namespace boost - -#endif /* SERVER_REQUEST_PARSERS_IMPL_UW3PM6V6 */ diff --git a/boost/network/protocol/http/server/options.hpp b/boost/network/protocol/http/server/options.hpp index d3d9f03a1..e84188bf3 100644 --- a/boost/network/protocol/http/server/options.hpp +++ b/boost/network/protocol/http/server/options.hpp @@ -9,8 +9,8 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include -#include +#include +#include #include #include #include @@ -34,6 +34,7 @@ struct server_options { handler_(handler), address_("localhost"), port_("80"), + protocol_family_(undefined), reuse_address_(false), report_aborted_(false), non_blocking_io_(true), @@ -71,7 +72,7 @@ struct server_options { } /// Provides an Asio io_service for the server. Default is nullptr. - server_options &io_service(std::shared_ptr v) { + server_options &io_service(std::shared_ptr v) { io_service_ = v; return *this; } @@ -88,6 +89,14 @@ struct server_options { return *this; } + enum protocol_family_t { ipv4, ipv6, undefined }; + + /// Set the protocol family for address resolving. Default is AF_UNSPEC. + server_options &protocol_family(protocol_family_t v) { + protocol_family_ = v; + return *this; + } + /// Set whether to reuse the address (SO_REUSE_ADDR). Default is false. server_options &reuse_address(bool v) { reuse_address_ = v; @@ -120,26 +129,26 @@ struct server_options { /// Set the socket receive buffer size. Unset by default. server_options &receive_buffer_size( - asio::socket_base::receive_buffer_size v) { + boost::asio::socket_base::receive_buffer_size v) { receive_buffer_size_ = v; return *this; } /// Set the send buffer size. Unset by default. - server_options &send_buffer_size(asio::socket_base::send_buffer_size v) { + server_options &send_buffer_size(boost::asio::socket_base::send_buffer_size v) { send_buffer_size_ = v; return *this; } /// Set the socket receive low watermark. Unset by default. server_options &receive_low_watermark( - asio::socket_base::receive_low_watermark v) { + boost::asio::socket_base::receive_low_watermark v) { receive_low_watermark_ = v; return *this; } /// Set the socket send low watermark. Unset by default. - server_options &send_low_watermark(asio::socket_base::send_low_watermark v) { + server_options &send_low_watermark(boost::asio::socket_base::send_low_watermark v) { send_low_watermark_ = v; return *this; } @@ -151,7 +160,7 @@ struct server_options { } /// Returns the provided Asio io_service. - std::shared_ptr io_service() const { return io_service_; } + std::shared_ptr io_service() const { return io_service_; } /// Returns the address to listen on. string_type address() const { return address_; } @@ -159,6 +168,9 @@ struct server_options { /// Returns the port to listen on. string_type port() const { return port_; } + /// Returns the protocol family used for address resolving. + protocol_family_t protocol_family() const { return protocol_family_; } + /// Returns a reference to the provided handler. Handler &handler() const { return handler_; } @@ -178,25 +190,25 @@ struct server_options { size_t linger_timeout() const { return linger_timeout_; } /// Returns the optional receive buffer size. - boost::optional receive_buffer_size() + boost::optional receive_buffer_size() const { return receive_buffer_size_; } /// Returns the optional send buffer size. - boost::optional send_buffer_size() + boost::optional send_buffer_size() const { return send_buffer_size_; } /// Returns the optional receive low watermark. - boost::optional + boost::optional receive_low_watermark() const { return receive_low_watermark_; } /// Returns the optional send low watermark. - boost::optional send_low_watermark() + boost::optional send_low_watermark() const { return send_low_watermark_; } @@ -215,6 +227,7 @@ struct server_options { swap(io_service_, other.io_service_); swap(address_, other.address_); swap(port_, other.port_); + swap(protocol_family_, other.protocol_family_); swap(reuse_address_, other.reuse_address_); swap(report_aborted_, other.report_aborted_); swap(non_blocking_io_, other.non_blocking_io_); @@ -229,20 +242,21 @@ struct server_options { } private: - std::shared_ptr io_service_; + std::shared_ptr io_service_; Handler &handler_; string_type address_; string_type port_; + protocol_family_t protocol_family_; bool reuse_address_; bool report_aborted_; bool non_blocking_io_; bool linger_; size_t linger_timeout_; - boost::optional receive_buffer_size_; - boost::optional send_buffer_size_; - boost::optional + boost::optional receive_buffer_size_; + boost::optional send_buffer_size_; + boost::optional receive_low_watermark_; - boost::optional send_low_watermark_; + boost::optional send_low_watermark_; std::shared_ptr thread_pool_; std::shared_ptr context_; }; diff --git a/boost/network/protocol/http/server/request.hpp b/boost/network/protocol/http/server/request.hpp deleted file mode 100644 index f559ebf2d..000000000 --- a/boost/network/protocol/http/server/request.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// request.hpp -// ~~~~~~~~~~~ -// -// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2009 Dean Michael Berris (mikhailberis@gmail.com) -// Copyright (c) 2009 Tarro, Inc. -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_NETWORK_HTTP_REQUEST_HPP -#define BOOST_NETWORK_HTTP_REQUEST_HPP - -#include -#include -#include -#include "header.hpp" - -namespace boost { -namespace network { -namespace http { - -/// A request received from a client. -struct request { - std::string method; - std::string uri; - int http_version_major; - int http_version_minor; - std::vector
headers; - std::string body; -}; - -inline void swap(request& l, request& r) { - using std::swap; - swap(l.method, r.method); - swap(l.uri, r.uri); - swap(l.http_version_major, r.http_version_major); - swap(l.http_version_minor, r.http_version_minor); - swap(l.headers, r.headers); - swap(l.body, r.body); -} - -} // namespace http - -} // namespace network - -} // namespace boost - -#endif // BOOST_NETWORK_HTTP_REQUEST_HPP diff --git a/boost/network/protocol/http/server/socket_options_base.hpp b/boost/network/protocol/http/server/socket_options_base.hpp index dc1bd15c5..f82a3d7b9 100644 --- a/boost/network/protocol/http/server/socket_options_base.hpp +++ b/boost/network/protocol/http/server/socket_options_base.hpp @@ -14,15 +14,15 @@ namespace http { struct socket_options_base { protected: - asio::socket_base::reuse_address acceptor_reuse_address; - asio::socket_base::enable_connection_aborted acceptor_report_aborted; - boost::optional receive_buffer_size; - boost::optional send_buffer_size; - boost::optional + boost::asio::socket_base::reuse_address acceptor_reuse_address; + boost::asio::socket_base::enable_connection_aborted acceptor_report_aborted; + boost::optional receive_buffer_size; + boost::optional send_buffer_size; + boost::optional receive_low_watermark; - boost::optional send_low_watermark; + boost::optional send_low_watermark; bool non_blocking_io; - asio::socket_base::linger linger; + boost::asio::socket_base::linger linger; template explicit socket_options_base(server_options const &options) @@ -35,13 +35,13 @@ struct socket_options_base { non_blocking_io(options.non_blocking_io()), linger(options.linger(), options.linger_timeout()) {} - void acceptor_options(asio::ip::tcp::acceptor &acceptor) { + void acceptor_options(boost::asio::ip::tcp::acceptor &acceptor) { acceptor.set_option(acceptor_reuse_address); acceptor.set_option(acceptor_report_aborted); } - void socket_options(asio::ip::tcp::socket &socket) { - std::error_code ignored; + void socket_options(boost::asio::ip::tcp::socket &socket) { + boost::system::error_code ignored; socket.non_blocking(non_blocking_io); socket.set_option(linger, ignored); if (receive_buffer_size) socket.set_option(*receive_buffer_size, ignored); diff --git a/boost/network/protocol/http/server/storage_base.hpp b/boost/network/protocol/http/server/storage_base.hpp index 9383e5e92..ec134a9f3 100644 --- a/boost/network/protocol/http/server/storage_base.hpp +++ b/boost/network/protocol/http/server/storage_base.hpp @@ -22,11 +22,11 @@ struct server_storage_base { explicit server_storage_base(server_options const& options) : self_service_(options.io_service() ? options.io_service() - : std::make_shared()), + : std::make_shared()), service_(*self_service_) {} - std::shared_ptr self_service_; - asio::io_service& service_; + std::shared_ptr self_service_; + boost::asio::io_service& service_; }; } /* http */ diff --git a/boost/network/protocol/http/traits/resolver.hpp b/boost/network/protocol/http/traits/resolver.hpp index cfcfc19fd..dec498745 100644 --- a/boost/network/protocol/http/traits/resolver.hpp +++ b/boost/network/protocol/http/traits/resolver.hpp @@ -6,8 +6,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include -#include +#include +#include #include #include #include @@ -26,9 +26,9 @@ struct unsupported_tag; template struct resolver : mpl::if_, is_http >, - asio::ip::tcp::resolver, + boost::asio::ip::tcp::resolver, typename mpl::if_, is_http >, - asio::ip::udp::resolver, + boost::asio::ip::udp::resolver, unsupported_tag >::type> { static_assert(mpl::not_, is_tcp > >::value, "Transport protocol must be TCP or UDP"); diff --git a/boost/network/protocol/stream_handler.hpp b/boost/network/protocol/stream_handler.hpp index ae355b724..cd98b6875 100644 --- a/boost/network/protocol/stream_handler.hpp +++ b/boost/network/protocol/stream_handler.hpp @@ -11,32 +11,32 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #ifdef BOOST_NETWORK_ENABLE_HTTPS -#include +#include #endif namespace boost { namespace network { -typedef asio::ip::tcp::socket tcp_socket; +typedef boost::asio::ip::tcp::socket tcp_socket; #ifndef BOOST_NETWORK_ENABLE_HTTPS typedef tcp_socket stream_handler; typedef void ssl_context; #else -typedef asio::ssl::stream ssl_socket; -typedef asio::ssl::context ssl_context; +typedef boost::asio::ssl::stream ssl_socket; +typedef boost::asio::ssl::context ssl_context; struct stream_handler { public: @@ -48,7 +48,7 @@ struct stream_handler { stream_handler(std::shared_ptr socket) : ssl_sock_(std::move(socket)), ssl_enabled(true) {} - stream_handler(asio::io_service& io, + stream_handler(boost::asio::io_service& io, std::shared_ptr ctx = std::shared_ptr()) { tcp_sock_ = std::make_shared(boost::ref(io)); @@ -62,10 +62,10 @@ struct stream_handler { } template - ASIO_INITFN_RESULT_TYPE(WriteHandler, - void(std::error_code, std::size_t)) + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void(boost::system::error_code, std::size_t)) async_write_some(const ConstBufferSequence& buffers, - ASIO_MOVE_ARG(WriteHandler) handler) { + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { try { if (ssl_enabled) { ssl_sock_->async_write_some(buffers, handler); @@ -73,19 +73,16 @@ struct stream_handler { tcp_sock_->async_write_some(buffers, handler); } } - catch (const std::error_code& e) { - std::cerr << e.message() << std::endl; - } - catch (const std::system_error& e) { - std::cerr << e.code() << ": " << e.what() << std::endl; + catch (const boost::system::system_error&) { + // print system error } } template - ASIO_INITFN_RESULT_TYPE(ReadHandler, - void(std::error_code, std::size_t)) + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void(boost::system::error_code, std::size_t)) async_read_some(const MutableBufferSequence& buffers, - ASIO_MOVE_ARG(ReadHandler) handler) { + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { try { if (ssl_enabled) { ssl_sock_->async_read_some(buffers, handler); @@ -93,15 +90,12 @@ struct stream_handler { tcp_sock_->async_read_some(buffers, handler); } } - catch (const std::error_code& e) { - std::cerr << e.message() << std::endl; - } - catch (const std::system_error& e) { - std::cerr << e.code() << ": " << e.what() << std::endl; + catch (const boost::system::system_error& e) { + // print system error } } - void close(std::error_code& e) { + void close(boost::system::error_code& e) { if (ssl_enabled) { ssl_sock_->next_layer().close(); } else { @@ -117,20 +111,17 @@ struct stream_handler { } } - void shutdown(asio::socket_base::shutdown_type st, - std::error_code& e) { + void shutdown(boost::asio::socket_base::shutdown_type st, + boost::system::error_code& e) { try { if (ssl_enabled) { ssl_sock_->shutdown(e); } else { - tcp_sock_->shutdown(asio::ip::tcp::socket::shutdown_send, e); + tcp_sock_->shutdown(boost::asio::ip::tcp::socket::shutdown_send, e); } } - catch (const std::error_code& e) { - std::cerr << e.message() << std::endl; - } - catch (const std::system_error& e) { - std::cerr << e.code() << ": " << e.what() << std::endl; + catch (const boost::system::system_error& e) { + } } @@ -151,10 +142,10 @@ struct stream_handler { } template - ASIO_INITFN_RESULT_TYPE(HandshakeHandler, - void(std::error_code)) + BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, + void(boost::system::error_code)) async_handshake(ssl_socket::handshake_type type, - ASIO_MOVE_ARG(HandshakeHandler) handler) { + BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler) { try { if (ssl_enabled) { return ssl_sock_->async_handshake(type, handler); @@ -162,11 +153,8 @@ struct stream_handler { // NOOP } } - catch (const std::error_code& e) { - std::cerr << e.message() << std::endl; - } - catch (const std::system_error& e) { - std::cerr << e.code() << ": " << e.what() << std::endl; + catch (const boost::system::system_error& e) { + } } std::shared_ptr get_tcp_socket() { return tcp_sock_; } diff --git a/boost/network/uri.hpp b/boost/network/uri.hpp deleted file mode 100644 index 7d36bec1e..000000000 --- a/boost/network/uri.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef BOOST_NETWORK_URL_HPP_ -#define BOOST_NETWORK_URL_HPP_ - -// Copyright 2009 Dean Michael Berris. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -#endif diff --git a/boost/network/uri/accessors.hpp b/boost/network/uri/accessors.hpp deleted file mode 100644 index 4a312488e..000000000 --- a/boost/network/uri/accessors.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Glyn Matthews 2011. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_URI_ACCESSORS_INC__ -#define BOOST_NETWORK_URI_URI_ACCESSORS_INC__ - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -namespace details { -template -struct key_value_sequence : spirit::qi::grammar { - typedef typename Map::key_type key_type; - typedef typename Map::mapped_type mapped_type; - typedef std::pair pair_type; - - key_value_sequence() : key_value_sequence::base_type(query) { - query = pair >> *((spirit::qi::lit(';') | '&') >> pair); - pair = key >> -('=' >> value); - key = - spirit::qi::char_("a-zA-Z_") >> *spirit::qi::char_("-+.~a-zA-Z_0-9/%"); - value = *spirit::qi::char_("-+.~a-zA-Z_0-9/%"); - }; - - spirit::qi::rule query; - spirit::qi::rule pair; - spirit::qi::rule key; - spirit::qi::rule value; -}; -} // namespace details - -template -inline Map &query_map(const uri &uri_, Map &map) { - const uri::string_type range = uri_.query(); - details::key_value_sequence parser; - spirit::qi::parse(std::begin(range), std::end(range), parser, map); - return map; -} - -inline uri::string_type username(const uri &uri_) { - const uri::string_type user_info = uri_.user_info(); - uri::const_iterator it(std::begin(user_info)), end(std::end(user_info)); - for (; it != end; ++it) { - if (*it == ':') { - break; - } - } - return uri::string_type(std::begin(user_info), it); -} - -inline uri::string_type password(const uri &uri_) { - const uri::string_type user_info = uri_.user_info(); - uri::const_iterator it(std::begin(user_info)), end(std::end(user_info)); - for (; it != end; ++it) { - if (*it == ':') { - ++it; - break; - } - } - return uri::string_type(it, std::end(user_info)); -} - -inline uri::string_type decoded_path(const uri &uri_) { - const uri::string_type path = uri_.path(); - uri::string_type decoded_path; - decode(path, std::back_inserter(decoded_path)); - return decoded_path; -} - -inline uri::string_type decoded_query(const uri &uri_) { - const uri::string_type query = uri_.query(); - uri::string_type decoded_query; - decode(query, std::back_inserter(decoded_query)); - return decoded_query; -} - -inline uri::string_type decoded_fragment(const uri &uri_) { - const uri::string_type fragment = uri_.fragment(); - uri::string_type decoded_fragment; - decode(fragment, std::back_inserter(decoded_fragment)); - return decoded_fragment; -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_URI_ACCESSORS_INC__ diff --git a/boost/network/uri/builder.hpp b/boost/network/uri/builder.hpp deleted file mode 100644 index c30d1fd86..000000000 --- a/boost/network/uri/builder.hpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) Glyn Matthews 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_BUILDER_INC__ -#define __BOOST_NETWORK_URI_BUILDER_INC__ - -#include -#include - -namespace boost { -namespace network { -namespace uri { -class builder { - - typedef uri::string_type string_type; - - public: - explicit builder(uri &uri_) : uri_(uri_) {} - - builder &set_scheme(const string_type &scheme) { - uri_.uri_.append(scheme); - if (opaque_schemes::exists(scheme)) { - uri_.uri_.append(":"); - } else { - uri_.uri_.append("://"); - } - uri_.parse(); - return *this; - } - - builder &scheme(const string_type &scheme) { return set_scheme(scheme); } - - builder &set_user_info(const string_type &user_info) { - uri_.uri_.append(user_info); - uri_.uri_.append("@"); - uri_.parse(); - return *this; - } - - builder &user_info(const string_type &user_info) { - return set_user_info(user_info); - } - - builder &set_host(const string_type &host) { - uri_.uri_.append(host); - uri_.parse(); - return *this; - } - - builder &host(const string_type &host) { return set_host(host); } - - builder &set_host(const asio::ip::address &address) { - uri_.uri_.append(address.to_string()); - uri_.parse(); - return *this; - } - - builder &host(const asio::ip::address &host) { return set_host(host); } - - builder &set_host(const asio::ip::address_v4 &address) { - uri_.uri_.append(address.to_string()); - uri_.parse(); - return *this; - } - - builder &host(const asio::ip::address_v4 &host) { return set_host(host); } - - builder &set_host(const asio::ip::address_v6 &address) { - uri_.uri_.append("["); - uri_.uri_.append(address.to_string()); - uri_.uri_.append("]"); - uri_.parse(); - return *this; - } - - builder &host(const asio::ip::address_v6 &host) { return set_host(host); } - - builder &set_port(const string_type &port) { - uri_.uri_.append(":"); - uri_.uri_.append(port); - uri_.parse(); - return *this; - } - - builder &port(const string_type &port) { return set_port(port); } - - builder &port(uint16_t port) { - return set_port(std::to_string(port)); - } - - builder &set_path(const string_type &path) { - uri_.uri_.append(path); - uri_.parse(); - return *this; - } - - builder &path(const string_type &path) { return set_path(path); } - - builder &encoded_path(const string_type &path) { - string_type encoded_path; - encode(path, std::back_inserter(encoded_path)); - return set_path(encoded_path); - } - - builder &set_query(const string_type &query) { - uri_.uri_.append("?"); - uri_.uri_.append(query); - uri_.parse(); - return *this; - } - - builder &set_query(const string_type &key, const string_type &value) { - if (!uri_.query_range()) { - uri_.uri_.append("?"); - } else { - uri_.uri_.append("&"); - } - uri_.uri_.append(key); - uri_.uri_.append("="); - uri_.uri_.append(value); - uri_.parse(); - return *this; - } - - builder &query(const string_type &query) { return set_query(query); } - - builder &query(const string_type &key, const string_type &value) { - return set_query(key, value); - } - - builder &set_fragment(const string_type &fragment) { - uri_.uri_.append("#"); - uri_.uri_.append(fragment); - uri_.parse(); - return *this; - } - - builder &fragment(const string_type &fragment) { - return set_fragment(fragment); - } - - private: - uri &uri_; -}; -} // namespace uri -} // namespace network -} // namespace boost - -#endif // __BOOST_NETWORK_URI_BUILDER_INC__ diff --git a/boost/network/uri/config.hpp b/boost/network/uri/config.hpp deleted file mode 100644 index de6ae447e..000000000 --- a/boost/network/uri/config.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Glyn Matthews 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_CONFIG_INC__ -#define __BOOST_NETWORK_URI_CONFIG_INC__ - -#include -#include - -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_URI_DYN_LINK) -#define BOOST_URI_DECL -#else -#define BOOST_URI_DECL -#endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_URI_DYN_LINK) - -#endif // __BOOST_NETWORK_URI_CONFIG_INC__ diff --git a/boost/network/uri/decode.hpp b/boost/network/uri/decode.hpp deleted file mode 100644 index df815b976..000000000 --- a/boost/network/uri/decode.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Glyn Matthews 2011. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_DECODE_INC__ -#define __BOOST_NETWORK_URI_DECODE_INC__ - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -namespace detail { -template -CharT letter_to_hex(CharT in) { - switch (in) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return in - '0'; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - return in + 10 - 'a'; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - return in + 10 - 'A'; - } - return CharT(); -} -} // namespace detail - -template -OutputIterator decode(const InputIterator &in_begin, - const InputIterator &in_end, - const OutputIterator &out_begin) { - typedef typename boost::iterator_value::type value_type; - - InputIterator it = in_begin; - OutputIterator out = out_begin; - while (it != in_end) { - if (*it == '%') { - if (++it == in_end) throw std::out_of_range("unexpected end of stream"); - value_type v0 = detail::letter_to_hex(*it); - if (++it == in_end) throw std::out_of_range("unexpected end of stream"); - value_type v1 = detail::letter_to_hex(*it); - ++it; - *out++ = 0x10 * v0 + v1; - } else if (*it == '+') { - *out++ = ' '; - ++it; - } else { - *out++ = *it++; - } - } - return out; -} - -template -inline OutputIterator decode(const SinglePassRange &range, - const OutputIterator &out) { - return decode(std::begin(range), std::end(range), out); -} - -inline std::string decoded(const std::string &input) { - std::string decoded; - decode(input, std::back_inserter(decoded)); - return decoded; -} - -} // namespace uri -} // namespace network -} // namespace boost - -#endif // __BOOST_NETWORK_URI_DECODE_INC__ diff --git a/boost/network/uri/detail/uri_parts.hpp b/boost/network/uri/detail/uri_parts.hpp deleted file mode 100644 index e250396c6..000000000 --- a/boost/network/uri/detail/uri_parts.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2009, 2010, 2011, 2012 Dean Michael Berris, Jeroen Habraken, Glyn -// Matthews. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_ -#define BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_ - -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -namespace detail { -template -struct hierarchical_part { - optional > user_info; - optional > host; - optional > port; - optional > path; - - FwdIter begin() const { return std::begin(user_info); } - - FwdIter end() const { return std::end(path); } - - void update() { - if (!user_info) { - if (host) { - user_info = iterator_range(std::begin(host.get()), - std::begin(host.get())); - } else if (path) { - user_info = iterator_range(std::begin(path.get()), - std::begin(path.get())); - } - } - - if (!host) { - host = iterator_range(std::begin(path.get()), - std::begin(path.get())); - } - - if (!port) { - port = iterator_range(std::end(host.get()), - std::end(host.get())); - } - - if (!path) { - path = iterator_range(std::end(port.get()), - std::end(port.get())); - } - } -}; - -template -struct uri_parts { - iterator_range scheme; - hierarchical_part hier_part; - optional > query; - optional > fragment; - - FwdIter begin() const { return std::begin(scheme); } - - FwdIter end() const { return std::end(fragment); } - - void update() { - - hier_part.update(); - - if (!query) { - query = iterator_range(std::end(hier_part.path.get()), - std::end(hier_part.path.get())); - } - - if (!fragment) { - fragment = iterator_range(std::end(query.get()), - std::end(query.get())); - } - } -}; -} // namespace detail -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_ diff --git a/boost/network/uri/directives.hpp b/boost/network/uri/directives.hpp deleted file mode 100644 index 44a539971..000000000 --- a/boost/network/uri/directives.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_DIRECTIVES_INC__ -#define __BOOST_NETWORK_URI_DIRECTIVES_INC__ - -#include -#include - -namespace boost { -namespace network { -namespace uri { -inline uri &operator<<(uri &uri_, const uri &root_uri) { - if (empty(uri_) && valid(root_uri)) { - uri_.append(std::begin(root_uri), std::end(root_uri)); - } - return uri_; -} - -template -inline uri &operator<<(uri &uri_, const Directive &directive) { - directive(uri_); - return uri_; -} -} // namespace uri -} // namespace network -} // namespace boost - -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // __BOOST_NETWORK_URI_DIRECTIVES_INC__ diff --git a/boost/network/uri/directives/authority.hpp b/boost/network/uri/directives/authority.hpp deleted file mode 100644 index 3206b3916..000000000 --- a/boost/network/uri/directives/authority.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_DIRECTIVES_AUTHORITY_INC__ -#define BOOST_NETWORK_URI_DIRECTIVES_AUTHORITY_INC__ - -#include - -namespace boost { -namespace network { -namespace uri { - -struct authority_directive { - - explicit authority_directive(std::string authority) - : authority_(std::move(authority)) {} - - template - void operator()(Uri &uri) const { - uri.append(authority_); - } - - std::string authority_; -}; - -inline authority_directive authority(const std::string &authority) { - return authority_directive(authority); -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_DIRECTIVES_AUTHORITY_INC__ diff --git a/boost/network/uri/directives/fragment.hpp b/boost/network/uri/directives/fragment.hpp deleted file mode 100644 index 90b9e0ea4..000000000 --- a/boost/network/uri/directives/fragment.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_DIRECTIVES_FRAGMENT_INC__ -#define BOOST_NETWORK_URI_DIRECTIVES_FRAGMENT_INC__ - -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -struct fragment_directive { - - explicit fragment_directive(std::string fragment) - : fragment_(std::move(fragment)) {} - - template - void operator()(Uri &uri) const { - uri.append("#"); - uri.append(fragment_); - } - - std::string fragment_; -}; - -inline fragment_directive fragment(const std::string &fragment) { - return fragment_directive(fragment); -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_DIRECTIVES_FRAGMENT_INC__ diff --git a/boost/network/uri/directives/host.hpp b/boost/network/uri/directives/host.hpp deleted file mode 100644 index 0ffead99e..000000000 --- a/boost/network/uri/directives/host.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_DIRECTIVES_HOST_INC__ -#define BOOST_NETWORK_URI_DIRECTIVES_HOST_INC__ - -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -struct host_directive { - - explicit host_directive(std::string host) : host_(std::move(host)) {} - - template - void operator()(Uri &uri) const { - uri.append(host_); - } - - std::string host_; -}; - -inline host_directive host(const std::string &host) { - return host_directive(host); -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_DIRECTIVES_HOST_INC__ diff --git a/boost/network/uri/directives/path.hpp b/boost/network/uri/directives/path.hpp deleted file mode 100644 index 336912a17..000000000 --- a/boost/network/uri/directives/path.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_DIRECTIVES_PATH_INC__ -#define __BOOST_NETWORK_URI_DIRECTIVES_PATH_INC__ - -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -struct path_directive { - - explicit path_directive(std::string path) : path_(std::move(path)) {} - - template - void operator()(Uri &uri) const { - uri.append(path_); - } - - std::string path_; -}; - -struct encoded_path_directive { - - explicit encoded_path_directive(std::string path) : path_(std::move(path)) {} - - void operator()(uri &uri_) const { - std::string encoded_path; - encode(path_, std::back_inserter(encoded_path)); - uri_.append(encoded_path); - } - - std::string path_; -}; - -inline path_directive path(const std::string &path) { - return path_directive(path); -} - -inline encoded_path_directive encoded_path(const std::string &path) { - return encoded_path_directive(path); -} - -} // namespace uri -} // namespace network -} // namespace boost - -#endif // __BOOST_NETWORK_URI_DIRECTIVES_PATH_INC__ diff --git a/boost/network/uri/directives/port.hpp b/boost/network/uri/directives/port.hpp deleted file mode 100644 index 122b3d46f..000000000 --- a/boost/network/uri/directives/port.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_DIRECTIVES_PORT_INC__ -#define BOOST_NETWORK_URI_DIRECTIVES_PORT_INC__ - -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -struct port_directive { - - explicit port_directive(std::string port) : port_(std::move(port)) {} - - explicit port_directive(std::uint16_t port) - : port_(std::to_string(port)) {} - - template - void operator()(Uri &uri) const { - uri.append(":"); - uri.append(port_); - } - - std::string port_; -}; - -inline port_directive port(const std::string &port) { - return port_directive(port); -} - -inline port_directive port(std::uint16_t port) { - return port_directive(port); -} - -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_DIRECTIVES_PORT_INC__ diff --git a/boost/network/uri/directives/query.hpp b/boost/network/uri/directives/query.hpp deleted file mode 100644 index 94309273f..000000000 --- a/boost/network/uri/directives/query.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_DIRECTIVES_QUERY_INC__ -#define BOOST_NETWORK_URI_DIRECTIVES_QUERY_INC__ - -#include -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -struct query_directive { - - explicit query_directive(std::string query) : query_(std::move(query)) {} - - template - void operator()(Uri &uri) const { - uri.append("?"); - uri.append(query_); - } - - std::string query_; -}; - -inline query_directive query(const std::string &query) { - return query_directive(query); -} - -struct query_key_query_directive { - - query_key_query_directive(std::string key, std::string query) - : key_(std::move(key)), query_(std::move(query)) {} - - template - void operator()(Uri &uri) const { - std::string encoded_key, encoded_query; - if (boost::empty(uri.query())) { - uri.append("?"); - } else { - uri.append("&"); - } - uri.append(key_); - uri.append("="); - uri.append(query_); - } - - std::string key_; - std::string query_; -}; - -inline query_key_query_directive query(const std::string &key, - const std::string &query) { - return query_key_query_directive(key, query); -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_DIRECTIVES_QUERY_INC__ diff --git a/boost/network/uri/directives/scheme.hpp b/boost/network/uri/directives/scheme.hpp deleted file mode 100644 index 8e79d85be..000000000 --- a/boost/network/uri/directives/scheme.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_DIRECTIVES_SCHEME_INC__ -#define __BOOST_NETWORK_URI_DIRECTIVES_SCHEME_INC__ - -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -struct scheme_directive { - - explicit scheme_directive(std::string scheme) : scheme(std::move(scheme)) {} - - template - void operator()(Uri &uri) const { - uri.append(scheme); - if (opaque_schemes::exists(scheme)) { - uri.append(":"); - } else { - uri.append("://"); - } - } - - std::string scheme; -}; - -inline scheme_directive scheme(const std::string &scheme) { - return scheme_directive(scheme); -} - -namespace schemes { -inline uri &http(uri &uri_) { return uri_ << scheme("http"); } - -inline uri &https(uri &uri_) { return uri_ << scheme("https"); } - -inline uri &file(uri &uri_) { return uri_ << scheme("file"); } -} // namespace schemes -} // namespace uri -} // namespace network -} // namespace boost - -#endif // __BOOST_NETWORK_URI_DIRECTIVES_SCHEME_INC__ diff --git a/boost/network/uri/directives/user_info.hpp b/boost/network/uri/directives/user_info.hpp deleted file mode 100644 index ccc92fd2a..000000000 --- a/boost/network/uri/directives/user_info.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_DIRECTIVES_USER_INFO_INC__ -#define BOOST_NETWORK_URI_DIRECTIVES_USER_INFO_INC__ - -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -struct user_info_directive { - - explicit user_info_directive(std::string user_info) - : user_info_(std::move(user_info)) {} - - template - void operator()(Uri &uri) const { - uri.append(user_info_); - uri.append("@"); - } - - std::string user_info_; -}; - -inline user_info_directive user_info(const std::string &user_info) { - return user_info_directive(user_info); -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_DIRECTIVES_USER_INFO_INC__ diff --git a/boost/network/uri/encode.hpp b/boost/network/uri/encode.hpp deleted file mode 100644 index 334a7eee3..000000000 --- a/boost/network/uri/encode.hpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) Glyn Matthews 2011. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_ENCODE_INC__ -#define __BOOST_NETWORK_URI_ENCODE_INC__ - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -namespace detail { - -template -inline CharT hex_to_letter(CharT in) { - switch (in) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - return in + '0'; - case 10: - case 11: - case 12: - case 13: - case 14: - default: - return in - 10 + 'A'; - } - return CharT(); -} - -template -void encode_char(CharT in, OutputIterator &out) { - switch (in) { - case 'a': - case 'A': - case 'b': - case 'B': - case 'c': - case 'C': - case 'd': - case 'D': - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'h': - case 'H': - case 'i': - case 'I': - case 'j': - case 'J': - case 'k': - case 'K': - case 'l': - case 'L': - case 'm': - case 'M': - case 'n': - case 'N': - case 'o': - case 'O': - case 'p': - case 'P': - case 'q': - case 'Q': - case 'r': - case 'R': - case 's': - case 'S': - case 't': - case 'T': - case 'u': - case 'U': - case 'v': - case 'V': - case 'w': - case 'W': - case 'x': - case 'X': - case 'y': - case 'Y': - case 'z': - case 'Z': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - case '.': - case '_': - case '~': - case '/': - out++ = in; - break; - default: - out++ = '%'; - out++ = hex_to_letter((in >> 4) & 0x0f); - out++ = hex_to_letter(in & 0x0f); - ; - } -} -} // namespace detail - -template -OutputIterator encode(const InputIterator &in_begin, - const InputIterator &in_end, - const OutputIterator &out_begin) { - InputIterator it = in_begin; - OutputIterator out = out_begin; - while (it != in_end) { - detail::encode_char(*it, out); - ++it; - } - return out; -} - -template -inline OutputIterator encode(const SinglePassRange &range, - const OutputIterator &out) { - return encode(std::begin(range), std::end(range), out); -} - -inline std::string encoded(const std::string &input) { - std::string encoded; - encode(input, std::back_inserter(encoded)); - return encoded; -} - -} // namespace uri -} // namespace network -} // namespace boost - -#endif // __BOOST_NETWORK_URI_ENCODE_INC__ diff --git a/boost/network/uri/schemes.hpp b/boost/network/uri/schemes.hpp deleted file mode 100644 index 6aef37266..000000000 --- a/boost/network/uri/schemes.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2012 Glyn Matthews. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_SCHEMES_INC__ -#define __BOOST_NETWORK_URI_SCHEMES_INC__ - -#include - -namespace boost { -namespace network { -namespace uri { -class hierarchical_schemes { - - public: - static bool exists(const std::string &scheme); -}; - -class opaque_schemes { - - public: - static bool exists(const std::string &scheme); -}; -} // namespace uri -} // namespace network -} // namespace boost - -#endif // __BOOST_NETWORK_URI_SCHEMES_INC__ diff --git a/boost/network/uri/uri.hpp b/boost/network/uri/uri.hpp deleted file mode 100644 index df47c67b8..000000000 --- a/boost/network/uri/uri.hpp +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright 2009, 2010, 2011, 2012 Dean Michael Berris, Jeroen Habraken, Glyn -// Matthews. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_NETWORK_URI_INC__ -#define BOOST_NETWORK_URI_INC__ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -namespace detail { -bool parse(std::string::const_iterator first, std::string::const_iterator last, - uri_parts &parts); -} // namespace detail - -class BOOST_URI_DECL uri { - - friend class builder; - - public: - typedef std::string string_type; - typedef string_type::value_type value_type; - typedef string_type::const_iterator const_iterator; - typedef boost::iterator_range const_range_type; - - uri() : is_valid_(false) {} - - // uri(const value_type *uri) - // : uri_(uri), is_valid_(false) { - // parse(); - //} - - uri(string_type str) : uri_(std::move(str)), is_valid_(false) { parse(); } - - template - uri(const FwdIter &first, const FwdIter &last) - : uri_(first, last), is_valid_(false) { - parse(); - } - - uri(const uri &other) : uri_(other.uri_) { parse(); } - - uri &operator=(const uri &other) { - uri(other).swap(*this); - return *this; - } - - uri &operator=(const string_type &uri_string) { - uri(uri_string).swap(*this); - return *this; - } - - ~uri() = default; - - void swap(uri &other) { - boost::swap(uri_, other.uri_); - other.parse(); - boost::swap(is_valid_, other.is_valid_); - } - - const_iterator begin() const { return uri_.begin(); } - - const_iterator end() const { return uri_.end(); } - - const_range_type scheme_range() const { return uri_parts_.scheme; } - - const_range_type user_info_range() const { - return uri_parts_.hier_part.user_info ? uri_parts_.hier_part.user_info.get() - : const_range_type(); - } - - const_range_type host_range() const { - return uri_parts_.hier_part.host ? uri_parts_.hier_part.host.get() - : const_range_type(); - } - - const_range_type port_range() const { - return uri_parts_.hier_part.port ? uri_parts_.hier_part.port.get() - : const_range_type(); - } - - const_range_type path_range() const { - return uri_parts_.hier_part.path ? uri_parts_.hier_part.path.get() - : const_range_type(); - } - - const_range_type query_range() const { - return uri_parts_.query ? uri_parts_.query.get() : const_range_type(); - } - - const_range_type fragment_range() const { - return uri_parts_.fragment ? uri_parts_.fragment.get() : const_range_type(); - } - -// hackfix by Simon Haegler, Esri R&D Zurich -// this workaround is needed to avoid running into the "incompatible string -// iterator" assertion triggered by the default-constructed string iterators -// employed by cpp-netlib (see uri.ipp qi::rule declarations) -#if defined(_MSC_VER) && defined(_DEBUG) -# define CATCH_EMPTY_ITERATOR_RANGE if (range.begin()._Getcont() == 0 || range.end()._Getcont() == 0) { return string_type(); } -#else -# define CATCH_EMPTY_ITERATOR_RANGE -#endif - - string_type scheme() const { - const_range_type range = scheme_range(); - CATCH_EMPTY_ITERATOR_RANGE - return range ? string_type(std::begin(range), std::end(range)) - : string_type(); - } - - string_type user_info() const { - const_range_type range = user_info_range(); - CATCH_EMPTY_ITERATOR_RANGE - return range ? string_type(std::begin(range), std::end(range)) - : string_type(); - } - - string_type host() const { - const_range_type range = host_range(); - CATCH_EMPTY_ITERATOR_RANGE - return range ? string_type(std::begin(range), std::end(range)) - : string_type(); - } - - string_type port() const { - const_range_type range = port_range(); - CATCH_EMPTY_ITERATOR_RANGE - return range ? string_type(std::begin(range), std::end(range)) - : string_type(); - } - - string_type path() const { - const_range_type range = path_range(); - CATCH_EMPTY_ITERATOR_RANGE - return range ? string_type(std::begin(range), std::end(range)) - : string_type(); - } - - string_type query() const { - const_range_type range = query_range(); - CATCH_EMPTY_ITERATOR_RANGE - return range ? string_type(std::begin(range), std::end(range)) - : string_type(); - } - - string_type fragment() const { - const_range_type range = fragment_range(); - CATCH_EMPTY_ITERATOR_RANGE - return range ? string_type(std::begin(range), std::end(range)) - : string_type(); - } - -#ifdef CATCH_EMPTY_ITERATOR_RANGE -#undef CATCH_EMPTY_ITERATOR_RANGE -#endif - - string_type string() const { return uri_; } - - bool is_valid() const { return is_valid_; } - - void append(const string_type &data) { - uri_.append(data); - parse(); - } - - template - void append(const FwdIter &first, const FwdIter &last) { - uri_.append(first, last); - parse(); - } - - private: - void parse(); - - string_type uri_; - detail::uri_parts uri_parts_; - bool is_valid_; -}; - -inline void uri::parse() { - const_iterator first(std::begin(uri_)), last(std::end(uri_)); - is_valid_ = detail::parse(first, last, uri_parts_); - if (is_valid_) { - if (!uri_parts_.scheme) { - uri_parts_.scheme = - const_range_type(std::begin(uri_), std::begin(uri_)); - } - uri_parts_.update(); - } -} - -inline uri::string_type scheme(const uri &uri_) { return uri_.scheme(); } - -inline uri::string_type user_info(const uri &uri_) { return uri_.user_info(); } - -inline uri::string_type host(const uri &uri_) { return uri_.host(); } - -inline uri::string_type port(const uri &uri_) { return uri_.port(); } - -inline boost::optional port_us(const uri &uri_) { - uri::string_type port = uri_.port(); - return (port.empty()) ? boost::optional() - : boost::optional(std::stoi(port)); -} - -inline uri::string_type path(const uri &uri_) { return uri_.path(); } - -inline uri::string_type query(const uri &uri_) { return uri_.query(); } - -inline uri::string_type fragment(const uri &uri_) { return uri_.fragment(); } - -inline uri::string_type hierarchical_part(const uri &uri_) { - uri::string_type::const_iterator first, last; - uri::const_range_type user_info = uri_.user_info_range(); - uri::const_range_type host = uri_.host_range(); - uri::const_range_type port = uri_.port_range(); - uri::const_range_type path = uri_.path_range(); - if (user_info) { - first = std::begin(user_info); - } else { - first = std::begin(host); - } - if (path) { - last = std::end(path); - } else if (port) { - last = std::end(port); - } else { - last = std::end(host); - } - return uri::string_type(first, last); -} - -inline uri::string_type authority(const uri &uri_) { - uri::string_type::const_iterator first, last; - uri::const_range_type user_info = uri_.user_info_range(); - uri::const_range_type host = uri_.host_range(); - uri::const_range_type port = uri_.port_range(); - if (user_info) { - first = std::begin(user_info); - } else { - first = std::begin(host); - } - - if (port) { - last = std::end(port); - } else { - last = std::end(host); - } - return uri::string_type(first, last); -} - -inline bool valid(const uri &uri_) { return uri_.is_valid(); } - -inline bool is_absolute(const uri &uri_) { - return uri_.is_valid() && !boost::empty(uri_.scheme_range()); -} - -inline bool is_relative(const uri &uri_) { - return uri_.is_valid() && boost::empty(uri_.scheme_range()); -} - -inline bool is_hierarchical(const uri &uri_) { - return is_absolute(uri_) && hierarchical_schemes::exists(scheme(uri_)); -} - -inline bool is_opaque(const uri &uri_) { - return is_absolute(uri_) && opaque_schemes::exists(scheme(uri_)); -} - -inline bool is_valid(const uri &uri_) { return valid(uri_); } - -inline void swap(uri &lhs, uri &rhs) { lhs.swap(rhs); } - -inline std::size_t hash_value(const uri &uri_) { - std::size_t seed = 0; - for (uri::const_iterator it = begin(uri_); it != end(uri_); ++it) { - hash_combine(seed, *it); - } - return seed; -} -} // namespace uri -} // namespace network -} // namespace boost - -namespace std { -template <> -struct hash { - - std::size_t operator()(const boost::network::uri::uri &uri_) const { - std::size_t seed = 0; - std::for_each(std::begin(uri_), std::end(uri_), - [&seed](boost::network::uri::uri::value_type v) { - std::hash hasher; - seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - }); - return seed; - } -}; -} // namespace std - -namespace boost { -namespace network { -namespace uri { -inline bool operator==(const uri &lhs, const uri &rhs) { - return boost::equal(lhs, rhs); -} - -inline bool operator==(const uri &lhs, const uri::string_type &rhs) { - return boost::equal(lhs, rhs); -} - -inline bool operator==(const uri::string_type &lhs, const uri &rhs) { - return boost::equal(lhs, rhs); -} - -inline bool operator==(const uri &lhs, const uri::value_type *rhs) { - auto rlen = std::strlen(rhs); - size_t llen = std::labs(std::distance(lhs.begin(), lhs.end())); - if (rlen != llen) return false; - return boost::equal(lhs, boost::make_iterator_range(rhs, rhs + rlen)); -} - -inline bool operator==(const uri::value_type *lhs, const uri &rhs) { - return boost::equal(boost::as_literal(lhs), rhs); -} - -inline bool operator!=(const uri &lhs, const uri &rhs) { return !(lhs == rhs); } - -inline bool operator<(const uri &lhs, const uri &rhs) { - return lhs.string() < rhs.string(); -} -} // namespace uri -} // namespace network -} // namespace boost - -#include -#include -#include - -namespace boost { -namespace network { -namespace uri { -inline uri from_parts(const uri &base_uri, const uri::string_type &path_, - const uri::string_type &query_, - const uri::string_type &fragment_) { - uri uri_(base_uri); - builder(uri_).path(path_).query(query_).fragment(fragment_); - return uri_; -} - -inline uri from_parts(const uri &base_uri, const uri::string_type &path_, - const uri::string_type &query_) { - uri uri_(base_uri); - builder(uri_).path(path_).query(query_); - return uri_; -} - -inline uri from_parts(const uri &base_uri, const uri::string_type &path_) { - uri uri_(base_uri); - builder(uri_).path(path_); - return uri_; -} - -inline uri from_parts(const uri::string_type &base_uri, - const uri::string_type &path, - const uri::string_type &query, - const uri::string_type &fragment) { - return from_parts(uri(base_uri), path, query, fragment); -} - -inline uri from_parts(const uri::string_type &base_uri, - const uri::string_type &path, - const uri::string_type &query) { - return from_parts(uri(base_uri), path, query); -} - -inline uri from_parts(const uri::string_type &base_uri, - const uri::string_type &path) { - return from_parts(uri(base_uri), path); -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // BOOST_NETWORK_URI_INC__ diff --git a/boost/network/uri/uri.ipp b/boost/network/uri/uri.ipp deleted file mode 100644 index 19bea7743..000000000 --- a/boost/network/uri/uri.ipp +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright 2009, 2010, 2011, 2012 Dean Michael Berris, Jeroen Habraken, Glyn -// Matthews. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include -#include - -BOOST_FUSION_ADAPT_TPL_STRUCT( - (FwdIter), (boost::network::uri::detail::hierarchical_part)(FwdIter), - (boost::optional >, - user_info)(boost::optional >, - host)(boost::optional >, - port)(boost::optional >, - path)); - -BOOST_FUSION_ADAPT_TPL_STRUCT( - (FwdIter), (boost::network::uri::detail::uri_parts)(FwdIter), - (boost::iterator_range, - scheme)(boost::network::uri::detail::hierarchical_part, - hier_part)(boost::optional >, - query)(boost::optional >, - fragment)); - -namespace boost { -namespace network { -namespace uri { -namespace detail { -namespace qi = boost::spirit::qi; - -template -struct uri_grammar - : qi::grammar()> { - - typedef String string_type; - typedef typename String::const_iterator const_iterator; - - uri_grammar() : uri_grammar::base_type(start, "uri") { - // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" - gen_delims %= qi::char_(":/?#[]@"); - // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," - // / ";" / "=" - sub_delims %= qi::char_("!$&'()*+,;="); - // reserved = gen-delims / sub-delims - reserved %= gen_delims | sub_delims; - // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - unreserved %= qi::alnum | qi::char_("-._~"); - // pct-encoded = "%" HEXDIG HEXDIG - pct_encoded %= qi::char_("%") >> qi::repeat(2)[qi::xdigit]; - - // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - pchar %= qi::raw[unreserved | pct_encoded | sub_delims | qi::char_(":@")]; - - // segment = *pchar - segment %= qi::raw[*pchar]; - // segment-nz = 1*pchar - segment_nz %= qi::raw[+pchar]; - // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) - segment_nz_nc %= - qi::raw[+(unreserved | pct_encoded | sub_delims | qi::char_("@"))]; - // path-abempty = *( "/" segment ) - path_abempty %= qi::raw[*(qi::char_("/") >> segment)]; - // path-absolute = "/" [ segment-nz *( "/" segment ) ] - path_absolute %= qi::raw - [qi::char_("/") >> -(segment_nz >> *(qi::char_("/") >> segment))]; - // path-rootless = segment-nz *( "/" segment ) - path_rootless %= qi::raw[segment_nz >> *(qi::char_("/") >> segment)]; - // path-empty = 0 - path_empty %= qi::raw[qi::eps]; - - // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - scheme %= qi::raw[qi::alpha >> *(qi::alnum | qi::char_("+.-"))]; - - // user_info = *( unreserved / pct-encoded / sub-delims / ":" ) - user_info %= - qi::raw[*(unreserved | pct_encoded | sub_delims | qi::char_(":"))]; - - ip_literal %= qi::lit('[') >> (ipv6address | ipvfuture) >> ']'; - - ipvfuture %= - qi::lit('v') >> +qi::xdigit >> '.' >> +(unreserved | sub_delims | ':'); - - ipv6addresses[0] %= qi::repeat(6)[h16 >> ':'] >> ls32; - ipv6addresses[1] %= "::" >> qi::repeat(5)[h16 >> ':'] >> ls32; - ipv6addresses[2] %= -qi::raw[h16] >> "::" >> qi::repeat(4)[h16 >> ':'] - >> ls32; - ipv6addresses[3] %= -qi::raw[h16] >> "::" >> qi::repeat(3)[h16 >> ':'] - >> ls32; - ipv6addresses[4] %= -qi::raw[h16] >> "::" >> qi::repeat(2)[h16 >> ':'] - >> ls32; - ipv6addresses[5] %= -qi::raw[h16] >> "::" >> h16 >> ':' >> ls32; - ipv6addresses[6] %= -qi::raw[h16] >> "::" >> ls32; - ipv6addresses[7] %= -qi::raw[h16] >> "::" >> h16; - ipv6addresses[8] %= -qi::raw[h16] >> "::"; - ipv6addresses[9] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> - "::" >> qi::repeat(3)[h16 >> ':'] >> ls32; - ipv6addresses[10] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> - "::" >> qi::repeat(2)[h16 >> ':'] >> ls32; - ipv6addresses[11] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> - "::" >> h16 >> ':' >> ls32; - ipv6addresses[12] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> - "::" >> ls32; - ipv6addresses[13] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> - "::" >> h16; - ipv6addresses[14] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> - "::"; - ipv6addresses[15] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> - "::" >> qi::repeat(2)[h16 >> ':'] >> ls32; - ipv6addresses[16] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> - "::" >> h16 >> ':' >> ls32; - ipv6addresses[17] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> - "::" >> ls32; - ipv6addresses[18] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> - "::" >> h16; - ipv6addresses[19] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> - "::"; - ipv6addresses[20] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> - "::" >> h16 >> ':' >> ls32; - ipv6addresses[21] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> - "::" >> ls32; - ipv6addresses[22] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> - "::" >> h16; - ipv6addresses[23] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> - "::"; - ipv6addresses[24] %= -qi::raw[qi::repeat(4)[(h16 >> ':')] >> h16] >> - "::" >> ls32; - ipv6addresses[25] %= -qi::raw[qi::repeat(4)[(h16 >> ':')] >> h16] >> - "::" >> h16; - ipv6addresses[26] %= -qi::raw[qi::repeat(4)[(h16 >> ':')] >> h16] >> - "::"; - ipv6addresses[27] %= -qi::raw[qi::repeat(5)[(h16 >> ':')] >> h16] >> - "::" >> h16; - ipv6addresses[28] %= -qi::raw[qi::repeat(5)[(h16 >> ':')] >> h16] >> - "::"; - ipv6addresses[29] %= -qi::raw[qi::repeat(6)[(h16 >> ':')] >> h16] >> - "::"; - - ipv6address %= qi::raw - [ipv6addresses[0] | - ipv6addresses[1] | - ipv6addresses[2] | - ipv6addresses[3] | - ipv6addresses[4] | - ipv6addresses[5] | - ipv6addresses[6] | - ipv6addresses[7] | - ipv6addresses[8] | - ipv6addresses[9] | - ipv6addresses[10] | - ipv6addresses[11] | - ipv6addresses[12] | - ipv6addresses[13] | - ipv6addresses[14] | - ipv6addresses[15] | - ipv6addresses[16] | - ipv6addresses[17] | - ipv6addresses[18] | - ipv6addresses[19] | - ipv6addresses[20] | - ipv6addresses[21] | - ipv6addresses[22] | - ipv6addresses[23] | - ipv6addresses[24] | - ipv6addresses[25] | - ipv6addresses[26] | - ipv6addresses[27] | - ipv6addresses[28] | - ipv6addresses[29]]; - - // ls32 = ( h16 ":" h16 ) / IPv4address - ls32 %= (h16 >> ':' >> h16) | ipv4address; - - // h16 = 1*4HEXDIG - h16 %= qi::repeat(1, 4)[qi::xdigit]; - - // dec-octet = DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 - // DIGIT / "25" %x30-35 - dec_octet %= !(qi::lit('0') >> qi::digit) >> - qi::raw[qi::uint_parser()]; - - // IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet - ipv4address %= - qi::raw[dec_octet >> qi::repeat(3)[qi::lit('.') >> dec_octet]]; - - // reg-name = *( unreserved / pct-encoded / sub-delims ) - reg_name %= qi::raw[*(unreserved | pct_encoded | sub_delims)]; - - // TODO, host = IP-literal / IPv4address / reg-name - host %= qi::raw[ip_literal | ipv4address | reg_name]; - - // port %= qi::ushort_; - port %= qi::raw[*qi::digit]; - - // query = *( pchar / "/" / "?" ) - query %= qi::raw[*(pchar | qi::char_("/?"))]; - - // fragment = *( pchar / "/" / "?" ) - fragment %= qi::raw[*(pchar | qi::char_("/?"))]; - - // hier-part = "//" authority path-abempty / path-absolute / - // path-rootless / path-empty - // authority = [ userinfo "@" ] host [ ":" port ] - hier_part %= ((("//" >> user_info >> '@') | "//") >> host >> - -(':' >> port) >> path_abempty) | - (qi::attr(iterator_range()) >> - qi::attr(iterator_range()) >> - qi::attr(iterator_range()) >> - (path_absolute | path_rootless | path_empty)); - - start %= - (scheme >> ':') >> hier_part >> -('?' >> query) >> -('#' >> fragment); - } - - qi::rule::value_type()> gen_delims, - sub_delims, reserved, unreserved; - qi::rule pct_encoded, pchar; - - qi::rule segment, segment_nz, segment_nz_nc; - qi::rule()> path_abempty, - path_absolute, path_rootless, path_empty; - - qi::rule dec_octet, ipv4address, reg_name, - ipv6address, ipvfuture, ip_literal; - - qi::rule h16, ls32; - qi::rule ipv6addresses[30]; - - - qi::rule()> host, port; - - qi::rule()> scheme, user_info, - query, fragment; - - qi::rule()> hier_part; - - // actual uri parser - qi::rule()> start; -}; - -bool parse(std::string::const_iterator first, std::string::const_iterator last, - uri_parts &parts) { - namespace qi = boost::spirit::qi; - static detail::uri_grammar grammar; - bool is_valid = qi::parse(first, last, grammar, parts); - return is_valid && (first == last); -} -} // namespace detail -} // namespace uri -} // namespace network -} // namespace boost diff --git a/boost/network/uri/uri_io.hpp b/boost/network/uri/uri_io.hpp deleted file mode 100644 index 5b7b22bc2..000000000 --- a/boost/network/uri/uri_io.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Glyn Matthews 2011, 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __BOOST_NETWORK_URI_URI_IO_INC__ -#define __BOOST_NETWORK_URI_URI_IO_INC__ - -#include - -namespace boost { -namespace network { -namespace uri { - -inline std::ostream &operator<<(std::ostream &os, const uri &uri_) { - return os << uri_.string(); -} -} // namespace uri -} // namespace network -} // namespace boost - -#endif // __BOOST_NETWORK_URI_URI_IO_INC__ diff --git a/boost/network/utils/thread_group.hpp b/boost/network/utils/thread_group.hpp index 0540b6afb..d1cb62633 100644 --- a/boost/network/utils/thread_group.hpp +++ b/boost/network/utils/thread_group.hpp @@ -9,54 +9,30 @@ #include #include -#include -#include -#include +#include namespace boost { namespace network { namespace utils { class thread_group { - private: - thread_group(thread_group const&); - thread_group& operator=(thread_group const&); - public: - thread_group() {} - ~thread_group() {} + thread_group() = default; + ~thread_group() = default; + thread_group(thread_group const&) = delete; + thread_group& operator=(thread_group const&) = delete; template - std::thread* create_thread(F threadfunc) { - std::lock_guard guard(m); - std::unique_ptr new_thread(new std::thread(threadfunc)); - threads.push_back(std::move(new_thread)); - return threads.back().get(); - } - - void add_thread(std::thread* thrd) { - if (thrd) { - std::lock_guard guard(m); - threads.push_back(std::unique_ptr(thrd)); - } - } - - void remove_thread(std::thread* thrd) { + std::thread &create_thread(F threadfunc) { std::lock_guard guard(m); - auto const it = std::find_if(threads.begin(), threads.end(), - [&thrd] (std::unique_ptr &arg) { - return arg.get() == thrd; - }); - if (it != threads.end()) { - threads.erase(it); - } + threads.emplace_back(threadfunc); + return threads.back(); } void join_all() { std::unique_lock guard(m); - - for (auto &thread : threads) { - if (thread->joinable()) { - thread->join(); + for (auto& thread : threads) { + if (thread.joinable()) { + thread.join(); } } } @@ -67,7 +43,7 @@ class thread_group { } private: - std::list> threads; + std::vector threads; mutable std::mutex m; }; diff --git a/boost/network/utils/thread_pool.hpp b/boost/network/utils/thread_pool.hpp index bea9ab5ad..08549881b 100644 --- a/boost/network/utils/thread_pool.hpp +++ b/boost/network/utils/thread_pool.hpp @@ -9,9 +9,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -19,22 +17,22 @@ namespace boost { namespace network { namespace utils { -typedef std::shared_ptr io_service_ptr; +typedef std::shared_ptr io_service_ptr; typedef std::shared_ptr worker_threads_ptr; -typedef std::shared_ptr sentinel_ptr; +typedef std::shared_ptr sentinel_ptr; -template -struct basic_thread_pool { - basic_thread_pool(basic_thread_pool const &) = delete; - basic_thread_pool &operator=(basic_thread_pool) = delete; - basic_thread_pool(basic_thread_pool&&) noexcept = default; - basic_thread_pool &operator=(basic_thread_pool&&) = default; +class thread_pool { + public: + thread_pool(thread_pool const &) = delete; + thread_pool &operator=(thread_pool const &) = delete; + thread_pool(thread_pool &&) noexcept = default; + thread_pool &operator=(thread_pool &&) = default; - basic_thread_pool() : basic_thread_pool(1) {} + thread_pool() : thread_pool(1) {} - explicit basic_thread_pool(std::size_t threads, - io_service_ptr io_service = io_service_ptr(), - worker_threads_ptr worker_threads = worker_threads_ptr()) + explicit thread_pool(std::size_t threads, + io_service_ptr io_service = io_service_ptr(), + worker_threads_ptr worker_threads = worker_threads_ptr()) : threads_(threads), io_service_(std::move(io_service)), worker_threads_(std::move(worker_threads)), @@ -46,7 +44,6 @@ struct basic_thread_pool { sentinel_.reset(); io_service_.reset(); if (worker_threads_.get()) { - // worker_threads_->interrupt_all(); worker_threads_->join_all(); } worker_threads_.reset(); @@ -55,7 +52,7 @@ struct basic_thread_pool { BOOST_SCOPE_EXIT_END if (!io_service_.get()) { - io_service_.reset(new asio::io_service); + io_service_.reset(new boost::asio::io_service); } if (!worker_threads_.get()) { @@ -63,11 +60,11 @@ struct basic_thread_pool { } if (!sentinel_.get()) { - sentinel_.reset(new asio::io_service::work(*io_service_)); + sentinel_.reset(new boost::asio::io_service::work(*io_service_)); } for (std::size_t counter = 0; counter < threads_; ++counter) { - worker_threads_->create_thread([=] () { io_service_->run(); }); + worker_threads_->create_thread([=]() { io_service_->run(); }); } commit = true; @@ -77,18 +74,16 @@ struct basic_thread_pool { void post(std::function f) { io_service_->post(f); } - ~basic_thread_pool() throw() { + ~thread_pool() { sentinel_.reset(); try { worker_threads_->join_all(); - } - catch (...) { - BOOST_ASSERT(false && - "A handler was not supposed to throw, but one did."); + } catch (const std::exception &) { + assert(!"A handler was not supposed to throw, but one did."); } } - void swap(basic_thread_pool &other) { + void swap(thread_pool &other) { using std::swap; swap(other.threads_, threads_); swap(other.io_service_, io_service_); @@ -101,15 +96,9 @@ struct basic_thread_pool { io_service_ptr io_service_; worker_threads_ptr worker_threads_; sentinel_ptr sentinel_; - }; -template -void swap(basic_thread_pool &a, basic_thread_pool &b) { - a.swap(b); -} - -typedef basic_thread_pool thread_pool; +inline void swap(thread_pool &a, thread_pool &b) { a.swap(b); } } // namespace utils } // namespace network diff --git a/build.sh b/build.sh index 63f05de7e..8e3e31d7e 100755 --- a/build.sh +++ b/build.sh @@ -6,10 +6,13 @@ cd build cmake -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \ -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS \ -DCPP-NETLIB_ENABLE_HTTPS=$ENABLE_HTTPS \ - -DBOOST_INCLUDEDIR="${HOME}/${CC}-boost_${BOOST_VERSION}/include" \ - -DBOOST_LIBRARYDIR="${HOME}/${CC}-boost_${BOOST_VERSION}/lib" \ + -DCPP-NETLIB_BUILD_EXAMPLES=OFF \ + -DCPP-NETLIB_BUILD_DOCS=$BUILD_DOCS \ + -DUri_BUILD_TESTS=$BUILD_TESTS \ + -DUri_BUILD_DOCS=$BUILD_DOCS \ + -DUri_DISABLE_LIBCXX=$Uri_DISABLE_LIBCXX \ -DCMAKE_CXX_FLAGS="-std=c++11 ${CMAKE_CXX_FLAGS}" \ .. -make -j2 +make make test cd .. diff --git a/contrib/cpp-netlib-devel.spec b/contrib/cpp-netlib-devel.spec new file mode 100644 index 000000000..8c138cb05 --- /dev/null +++ b/contrib/cpp-netlib-devel.spec @@ -0,0 +1,38 @@ +Name: cpp-netlib-devel +Version: 0.9.4 +Release: 1%{?dist} +Summary: The C++ Network Library Project +License: Boost +URL: http://cpp-netlib.org/ +Source: https://github.com/downloads/cpp-netlib/cpp-netlib/cpp-netlib-%{version}.tar.gz +BuildArch: noarch + +%description +The project aims to build upon the latest C++ standard (currently +C++11) to provide easy to use libraries for network programming. We use +the latest compiler versions and features with an eye on pushing the +boundaries on leveraging what's available in C++. + +Currently the library contains an HTTP client and server implementation, +a stand-alone URI library, a network message framework, and some +concurrency tools. + +%prep +%setup -q -n cpp-netlib-%{version} + +%build + +# The source file will contain the header files needed, so there is no need to build anything + +%install +mkdir -p %{buildroot}%{_includedir} +tar cf - boost | (cd %{buildroot}%{_includedir}; tar xf -) + +%files +%doc RATIONALE.txt README.rst +%license LICENSE_1_0.txt +%{_includedir}/boost + +%changelog +* Fri Jul 15 2016 Håkon Løvdal - 0.9.4-1 +- Created diff --git a/deps/asio b/deps/asio index 66e76b9e4..22afb8608 160000 --- a/deps/asio +++ b/deps/asio @@ -1 +1 @@ -Subproject commit 66e76b9e4252ff4681227d0d8e34374ec1fa20e5 +Subproject commit 22afb86087a77037cd296d27134756c9b0d2cb75 diff --git a/deps/cxxopts b/deps/cxxopts index aec97a6f5..3d405ef16 160000 --- a/deps/cxxopts +++ b/deps/cxxopts @@ -1 +1 @@ -Subproject commit aec97a6f53c3486fc51e0d9857f10b683180d668 +Subproject commit 3d405ef1639a918ea8798666e2b02eb9cef889c0 diff --git a/deps/googletest b/deps/googletest index d225acc90..3880b13e4 160000 --- a/deps/googletest +++ b/deps/googletest @@ -1 +1 @@ -Subproject commit d225acc90bc3a8c420a9bcd1f033033c1ccd7fe0 +Subproject commit 3880b13e4c0b04ca88f69b9c93da6058bd836c34 diff --git a/deps/uri b/deps/uri new file mode 160000 index 000000000..76f0781f4 --- /dev/null +++ b/deps/uri @@ -0,0 +1 @@ +Subproject commit 76f0781f45d9a79c2a2bde9cabe76368cc6892c1 diff --git a/libs/network/doc/_ext/breathe b/libs/network/doc/_ext/breathe index 853385ef4..1767274e0 160000 --- a/libs/network/doc/_ext/breathe +++ b/libs/network/doc/_ext/breathe @@ -1 +1 @@ -Subproject commit 853385ef4f0c3dd126887750e20d5f7456065998 +Subproject commit 1767274e0f59eb707f2b6256d51b12a3a4341da8 diff --git a/libs/network/doc/conf.py b/libs/network/doc/conf.py index 79137328e..d541be499 100644 --- a/libs/network/doc/conf.py +++ b/libs/network/doc/conf.py @@ -62,9 +62,9 @@ # built documents. # # The short X.Y version. -version = '0.11' +version = '0.12' # The full version, including alpha/beta/rc tags. -release = '0.11.2' +release = '0.12.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -111,7 +111,7 @@ # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = 'cpp-netlib v0.11.2' +html_title = 'cpp-netlib v0.12.0' # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = 'cpp-netlib' diff --git a/libs/network/doc/html/contents.html b/libs/network/doc/html/contents.html index ce952c360..0c448720b 100644 --- a/libs/network/doc/html/contents.html +++ b/libs/network/doc/html/contents.html @@ -6,7 +6,7 @@ - Contents — cpp-netlib v0.11.2 + Contents — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -40,7 +40,7 @@

Navigation

  • next
  • - + @@ -231,7 +231,7 @@

    Navigation

  • next
  • - + @@ -124,7 +124,7 @@

    Navigation

  • previous |
  • - + @@ -169,7 +169,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/examples/http/hello_world_client.html b/libs/network/doc/html/examples/http/hello_world_client.html index e9ff6a48e..c83408f56 100644 --- a/libs/network/doc/html/examples/http/hello_world_client.html +++ b/libs/network/doc/html/examples/http/hello_world_client.html @@ -6,7 +6,7 @@ - “Hello world” HTTP client — cpp-netlib v0.11.2 + “Hello world” HTTP client — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -186,7 +186,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/examples/http/hello_world_server.html b/libs/network/doc/html/examples/http/hello_world_server.html index cdea75e8f..59a516872 100644 --- a/libs/network/doc/html/examples/http/hello_world_server.html +++ b/libs/network/doc/html/examples/http/hello_world_server.html @@ -6,7 +6,7 @@ - “Hello world” HTTP server — cpp-netlib v0.11.2 + “Hello world” HTTP server — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -236,7 +236,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/examples/http/http_client.html b/libs/network/doc/html/examples/http/http_client.html index b5ef618f8..33eaead94 100644 --- a/libs/network/doc/html/examples/http/http_client.html +++ b/libs/network/doc/html/examples/http/http_client.html @@ -6,7 +6,7 @@ - HTTP client — cpp-netlib v0.11.2 + HTTP client — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -200,7 +200,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/examples/http/simple_wget.html b/libs/network/doc/html/examples/http/simple_wget.html index 709d941cd..5031909b8 100644 --- a/libs/network/doc/html/examples/http/simple_wget.html +++ b/libs/network/doc/html/examples/http/simple_wget.html @@ -6,7 +6,7 @@ - Simple wget — cpp-netlib v0.11.2 + Simple wget — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -197,7 +197,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/examples/http/twitter_search.html b/libs/network/doc/html/examples/http/twitter_search.html index 62018b073..9a5a7ff75 100644 --- a/libs/network/doc/html/examples/http/twitter_search.html +++ b/libs/network/doc/html/examples/http/twitter_search.html @@ -6,7 +6,7 @@ - Twitter search — cpp-netlib v0.11.2 + Twitter search — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -203,7 +203,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/getting_started.html b/libs/network/doc/html/getting_started.html index 3c8a000cc..ec5e72de5 100644 --- a/libs/network/doc/html/getting_started.html +++ b/libs/network/doc/html/getting_started.html @@ -6,7 +6,7 @@ - Getting Started — cpp-netlib v0.11.2 + Getting Started — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -44,7 +44,7 @@

    Navigation

  • previous |
  • - + @@ -345,7 +345,7 @@

    Navigation

  • previous |
  • - + @@ -197,7 +197,7 @@

    Navigation

  • previous |
  • - + @@ -128,7 +128,7 @@

    Navigation

  • previous |
  • - + @@ -756,7 +756,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/reference/http_request.html b/libs/network/doc/html/reference/http_request.html index 2f916959f..d1a959c39 100644 --- a/libs/network/doc/html/reference/http_request.html +++ b/libs/network/doc/html/reference/http_request.html @@ -6,7 +6,7 @@ - HTTP Request — cpp-netlib v0.11.2 + HTTP Request — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -430,7 +430,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/reference/http_response.html b/libs/network/doc/html/reference/http_response.html index 8d8338e5c..b28c02e62 100644 --- a/libs/network/doc/html/reference/http_response.html +++ b/libs/network/doc/html/reference/http_response.html @@ -6,7 +6,7 @@ - HTTP Response — cpp-netlib v0.11.2 + HTTP Response — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -463,7 +463,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/reference/http_server.html b/libs/network/doc/html/reference/http_server.html index d8329e200..1826bc201 100644 --- a/libs/network/doc/html/reference/http_server.html +++ b/libs/network/doc/html/reference/http_server.html @@ -6,7 +6,7 @@ - HTTP Server API — cpp-netlib v0.11.2 + HTTP Server API — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -45,7 +45,7 @@

    Navigation

  • previous |
  • - + @@ -931,7 +931,7 @@

    Navigation

  • previous |
  • - + diff --git a/libs/network/doc/html/references.html b/libs/network/doc/html/references.html index d372a2c6a..b4f5e6a8f 100644 --- a/libs/network/doc/html/references.html +++ b/libs/network/doc/html/references.html @@ -6,7 +6,7 @@ - References — cpp-netlib v0.11.2 + References — cpp-netlib v0.12.0 @@ -14,7 +14,7 @@ - + @@ -40,7 +40,7 @@

    Navigation

  • previous
  • - + @@ -111,7 +111,7 @@

    Navigation

  • previous
  • - +