mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-05 03:35:51 +00:00
Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cafe18c592 | ||
|
|
3e5490ef6d | ||
|
|
c76656cf7f | ||
|
|
c7c1b3cc3b | ||
|
|
39f9135104 | ||
|
|
dd52bdd2c4 | ||
|
|
7a0fa312ea | ||
|
|
fc640504ba | ||
|
|
3c0b35092c | ||
|
|
89e8ea436a | ||
|
|
21dc05fc33 | ||
|
|
589570daa3 | ||
|
|
a02a469b20 | ||
|
|
be1f734845 | ||
|
|
98d7fa3fd9 | ||
|
|
74823cb7d1 | ||
|
|
e47bfa223f | ||
|
|
5c1ec051f0 | ||
|
|
65094d9c90 | ||
|
|
c00341a97e | ||
|
|
36423a5f77 | ||
|
|
60dd194b72 | ||
|
|
9ae717c433 | ||
|
|
d90a0647d6 | ||
|
|
35d81e65c1 | ||
|
|
cca574c9a9 | ||
|
|
c96c423afb | ||
|
|
463b154e3d | ||
|
|
3666948610 | ||
|
|
397410bac6 | ||
|
|
7aa838c091 | ||
|
|
458ac470aa | ||
|
|
a79cb95c85 | ||
|
|
5ad49454f1 | ||
|
|
1a56b9c5f2 | ||
|
|
efe3700f70 | ||
|
|
fc89d2e014 | ||
|
|
3c37539cee | ||
|
|
3d977aeacb | ||
|
|
4308b124c2 | ||
|
|
b23e9c207d | ||
|
|
c3a6b1600f | ||
|
|
138e1ba9a8 | ||
|
|
2858661bce | ||
|
|
afc791835e | ||
|
|
d981bff8ea | ||
|
|
b24d47c093 | ||
|
|
df086301b6 | ||
|
|
01b4d5cdd4 | ||
|
|
8c155dd875 | ||
|
|
3f9a38697d | ||
|
|
87742a5e6c | ||
|
|
5b9e8a77ca | ||
|
|
2821624ede | ||
|
|
ac1ab720c4 | ||
|
|
e0168b98d7 | ||
|
|
18801b81de | ||
|
|
1daefeb594 | ||
|
|
068048718e | ||
|
|
56946e8128 | ||
|
|
3dfb4a13f1 | ||
|
|
7ae3c91015 | ||
|
|
95f107d487 | ||
|
|
61316c7f95 | ||
|
|
49bdf2e72d | ||
|
|
f0f96bd1da |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -33,9 +33,6 @@ Release/*.*
|
||||
*.gcda
|
||||
*.gcov
|
||||
|
||||
# Ignore locally installed node_modules
|
||||
/node_modules
|
||||
|
||||
# Ignore tmp directory.
|
||||
tmp
|
||||
|
||||
@@ -50,7 +47,6 @@ debug_log.txt
|
||||
# Ignore customized configs
|
||||
rippled.cfg
|
||||
validators.txt
|
||||
test/config.js
|
||||
|
||||
# Doxygen generated documentation output
|
||||
HtmlDocumentation
|
||||
|
||||
12
.travis.yml
12
.travis.yml
@@ -10,9 +10,13 @@ env:
|
||||
# namepart must match the folder name internal
|
||||
# to boost's .tar.gz.
|
||||
- LCOV_ROOT=$HOME/lcov
|
||||
- GDB_ROOT=$HOME/gdb
|
||||
- BOOST_ROOT=$HOME/boost_1_60_0
|
||||
- BOOST_URL='http://sourceforge.net/projects/boost/files/boost/1.60.0/boost_1_60_0.tar.gz'
|
||||
|
||||
# Travis is timing out on Trusty. So, for now, use Precise. July 2017
|
||||
dist: precise
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
@@ -27,6 +31,8 @@ addons:
|
||||
- binutils-gold
|
||||
# Provides a backtrace if the unittests crash
|
||||
- gdb
|
||||
# needed to build gdb
|
||||
- texinfo
|
||||
|
||||
matrix:
|
||||
include:
|
||||
@@ -40,6 +46,9 @@ matrix:
|
||||
|
||||
- compiler: clang
|
||||
env: GCC_VER=5 TARGET=debug CLANG_VER=3.8 PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH
|
||||
cache:
|
||||
directories:
|
||||
- $GDB_ROOT
|
||||
|
||||
- compiler: clang
|
||||
env: GCC_VER=5 TARGET=debug.nounity CLANG_VER=3.8 PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH
|
||||
@@ -56,6 +65,7 @@ cache:
|
||||
- $BOOST_ROOT
|
||||
- llvm-$LLVM_VERSION
|
||||
- cmake
|
||||
- $GDB_ROOT
|
||||
|
||||
before_install:
|
||||
- bin/ci/ubuntu/install-dependencies.sh
|
||||
@@ -69,3 +79,5 @@ notifications:
|
||||
irc:
|
||||
channels:
|
||||
- "chat.freenode.net#ripple-dev"
|
||||
|
||||
dist: precise
|
||||
|
||||
@@ -12,7 +12,7 @@ endif()
|
||||
|
||||
macro(parse_target)
|
||||
|
||||
if (NOT target)
|
||||
if (NOT target OR target STREQUAL "default")
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif()
|
||||
@@ -110,14 +110,27 @@ macro(parse_target)
|
||||
|
||||
endwhile()
|
||||
endif()
|
||||
# Promote these values to the CACHE, then unset the locals
|
||||
# to prevent shadowing.
|
||||
set(CMAKE_C_COMPILER ${CMAKE_C_COMPILER} CACHE FILEPATH
|
||||
"Path to a program" FORCE)
|
||||
unset(CMAKE_C_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE FILEPATH
|
||||
"Path to a program" FORCE)
|
||||
unset(CMAKE_CXX_COMPILER)
|
||||
|
||||
if(CMAKE_C_COMPILER MATCHES "-NOTFOUND$" OR
|
||||
CMAKE_CXX_COMPILER MATCHES "-NOTFOUND$")
|
||||
message(FATAL_ERROR "Can not find appropriate compiler for target ${target}")
|
||||
endif()
|
||||
|
||||
# If defined, promote the compiler path values to the CACHE, then
|
||||
# unset the locals to prevent shadowing. Some scenarios do not
|
||||
# need or want to find a compiler, such as -GNinja under Windows.
|
||||
# Setting these values in those case may prevent CMake from finding
|
||||
# a valid compiler.
|
||||
if (CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER ${CMAKE_C_COMPILER} CACHE FILEPATH
|
||||
"Path to a program" FORCE)
|
||||
unset(CMAKE_C_COMPILER)
|
||||
endif (CMAKE_C_COMPILER)
|
||||
if (CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE FILEPATH
|
||||
"Path to a program" FORCE)
|
||||
unset(CMAKE_CXX_COMPILER)
|
||||
endif (CMAKE_CXX_COMPILER)
|
||||
|
||||
if (release)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
@@ -156,11 +169,17 @@ macro(setup_build_cache)
|
||||
set(assert false CACHE BOOL "Enables asserts, even in release builds")
|
||||
set(static false CACHE BOOL
|
||||
"On linux, link protobuf, openssl, libc++, and boost statically")
|
||||
set(jemalloc false CACHE BOOL "Enables jemalloc for heap profiling")
|
||||
set(perf false CACHE BOOL "Enables flags that assist with perf recording")
|
||||
|
||||
if (static AND (WIN32 OR APPLE))
|
||||
message(FATAL_ERROR "Static linking is only supported on linux.")
|
||||
endif()
|
||||
|
||||
if (perf AND (WIN32 OR APPLE))
|
||||
message(FATAL_ERROR "perf flags are only supported on linux.")
|
||||
endif()
|
||||
|
||||
if (${CMAKE_GENERATOR} STREQUAL "Unix Makefiles" AND NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif()
|
||||
@@ -302,6 +321,7 @@ macro(use_boost)
|
||||
if ((NOT DEFINED BOOST_ROOT) AND (DEFINED ENV{BOOST_ROOT}))
|
||||
set(BOOST_ROOT $ENV{BOOST_ROOT})
|
||||
endif()
|
||||
file(TO_CMAKE_PATH "${BOOST_ROOT}" BOOST_ROOT)
|
||||
if(WIN32 OR CYGWIN)
|
||||
# Workaround for MSVC having two boost versions - x86 and x64 on same PC in stage folders
|
||||
if(DEFINED BOOST_ROOT)
|
||||
@@ -368,6 +388,11 @@ macro(use_openssl openssl_min)
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL)
|
||||
# depending on how openssl is built, it might depend
|
||||
# on zlib. In fact, the openssl find package should
|
||||
# figure this out for us, but it does not currently...
|
||||
# so let's add zlib ourselves to the lib list
|
||||
find_package(ZLIB)
|
||||
|
||||
if (static)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES tmp)
|
||||
@@ -375,6 +400,7 @@ macro(use_openssl openssl_min)
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
list(APPEND OPENSSL_LIBRARIES ${ZLIB_LIBRARIES})
|
||||
else()
|
||||
message(FATAL_ERROR "OpenSSL not found")
|
||||
endif()
|
||||
@@ -507,6 +533,10 @@ macro(setup_build_boilerplate)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (perf)
|
||||
add_compile_options(-fno-omit-frame-pointer)
|
||||
endif()
|
||||
|
||||
############################################################
|
||||
|
||||
add_definitions(
|
||||
@@ -525,8 +555,18 @@ macro(setup_build_boilerplate)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version
|
||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||
if ("${LD_VERSION}" MATCHES "GNU gold")
|
||||
append_flags(CMAKE_EXE_LINKER_FLAGS -fuse-ld=gold)
|
||||
# NOTE: THE gold linker inserts -rpath as DT_RUNPATH by default
|
||||
# intead of DT_RPATH, so you might have slightly unexpected
|
||||
# runtime ld behavior if you were expecting DT_RPATH.
|
||||
# Specify --disable-new-dtags to gold if you do not want
|
||||
# the default DT_RUNPATH behavior. This rpath treatment as well
|
||||
# as static/dynamic selection means that gold does not currently
|
||||
# have ideal default behavior when we are using jemalloc. Thus
|
||||
# for simplicity we don't use it when jemalloc is requested.
|
||||
# An alternative to disabling would be to figure out all the settings
|
||||
# required to make gold play nicely with jemalloc.
|
||||
if (("${LD_VERSION}" MATCHES "GNU gold") AND (NOT jemalloc))
|
||||
append_flags(CMAKE_EXE_LINKER_FLAGS -fuse-ld=gold)
|
||||
endif ()
|
||||
unset(LD_VERSION)
|
||||
endif()
|
||||
@@ -555,6 +595,15 @@ macro(setup_build_boilerplate)
|
||||
STRING(REGEX REPLACE "[-/]DNDEBUG" "" CMAKE_C_FLAGS_RELEASECLASSIC "${CMAKE_C_FLAGS_RELEASECLASSIC}")
|
||||
endif()
|
||||
|
||||
if (jemalloc)
|
||||
find_package(jemalloc REQUIRED)
|
||||
add_definitions(-DPROFILE_JEMALLOC)
|
||||
include_directories(SYSTEM ${JEMALLOC_INCLUDE_DIRS})
|
||||
link_libraries(${JEMALLOC_LIBRARIES})
|
||||
get_filename_component(JEMALLOC_LIB_PATH ${JEMALLOC_LIBRARIES} DIRECTORY)
|
||||
set(CMAKE_BUILD_RPATH ${CMAKE_BUILD_RPATH} ${JEMALLOC_LIB_PATH})
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
append_flags(CMAKE_CXX_FLAGS -frtti -std=c++14 -Wno-invalid-offsetof
|
||||
@@ -585,7 +634,7 @@ macro(setup_build_boilerplate)
|
||||
if (APPLE)
|
||||
add_definitions(-DBEAST_COMPILE_OBJECTIVE_CPP=1)
|
||||
add_compile_options(
|
||||
-Wno-deprecated -Wno-deprecated-declarations -Wno-unused-variable -Wno-unused-function)
|
||||
-Wno-deprecated -Wno-deprecated-declarations -Wno-unused-function)
|
||||
endif()
|
||||
|
||||
if (is_gcc)
|
||||
@@ -594,27 +643,27 @@ macro(setup_build_boilerplate)
|
||||
endif (is_gcc)
|
||||
else(NOT WIN32)
|
||||
add_compile_options(
|
||||
/bigobj # Increase object file max size
|
||||
/EHa # ExceptionHandling all
|
||||
/fp:precise # Floating point behavior
|
||||
/Gd # __cdecl calling convention
|
||||
/Gm- # Minimal rebuild: disabled
|
||||
/GR # Enable RTTI
|
||||
/Gy- # Function level linking: disabled
|
||||
/bigobj # Increase object file max size
|
||||
/EHa # ExceptionHandling all
|
||||
/fp:precise # Floating point behavior
|
||||
/Gd # __cdecl calling convention
|
||||
/Gm- # Minimal rebuild: disabled
|
||||
/GR # Enable RTTI
|
||||
/Gy- # Function level linking: disabled
|
||||
/FS
|
||||
/MP # Multiprocessor compilation
|
||||
/openmp- # pragma omp: disabled
|
||||
/Zc:forScope # Language extension: for scope
|
||||
/Zi # Generate complete debug info
|
||||
/errorReport:none # No error reporting to Internet
|
||||
/nologo # Suppress login banner
|
||||
/W3 # Warning level 3
|
||||
/WX- # Disable warnings as errors
|
||||
/wd"4018"
|
||||
/wd"4244"
|
||||
/wd"4267"
|
||||
/wd"4800" # Disable C4800(int to bool performance)
|
||||
/wd"4503" # Decorated name length exceeded, name was truncated
|
||||
/MP # Multiprocessor compilation
|
||||
/openmp- # pragma omp: disabled
|
||||
/Zc:forScope # Language conformance: for scope
|
||||
/Zi # Generate complete debug info
|
||||
/errorReport:none # No error reporting to Internet
|
||||
/nologo # Suppress login banner
|
||||
/W3 # Warning level 3
|
||||
/WX- # Disable warnings as errors
|
||||
/wd4018 # Disable signed/unsigned comparison warnings
|
||||
/wd4244 # Disable float to int possible loss of data warnings
|
||||
/wd4267 # Disable size_t to T possible loss of data warnings
|
||||
/wd4800 # Disable C4800(int to bool performance)
|
||||
/wd4503 # Decorated name length exceeded, name was truncated
|
||||
)
|
||||
add_definitions(
|
||||
-D_WIN32_WINNT=0x6000
|
||||
@@ -699,7 +748,7 @@ macro(link_common_libraries cur_project)
|
||||
find_library(app_kit AppKit)
|
||||
find_library(foundation Foundation)
|
||||
target_link_libraries(${cur_project}
|
||||
crypto ssl ${app_kit} ${foundation})
|
||||
${app_kit} ${foundation})
|
||||
else()
|
||||
target_link_libraries(${cur_project} rt)
|
||||
endif()
|
||||
|
||||
47
Builds/CMake/Findjemalloc.cmake
Normal file
47
Builds/CMake/Findjemalloc.cmake
Normal file
@@ -0,0 +1,47 @@
|
||||
# - Try to find jemalloc
|
||||
# Once done this will define
|
||||
# JEMALLOC_FOUND - System has jemalloc
|
||||
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
|
||||
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
|
||||
|
||||
if(NOT USE_BUNDLED_JEMALLOC)
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
|
||||
endif()
|
||||
else()
|
||||
set(PC_JEMALLOC_INCLUDEDIR)
|
||||
set(PC_JEMALLOC_INCLUDE_DIRS)
|
||||
set(PC_JEMALLOC_LIBDIR)
|
||||
set(PC_JEMALLOC_LIBRARY_DIRS)
|
||||
set(LIMIT_SEARCH NO_DEFAULT_PATH)
|
||||
endif()
|
||||
|
||||
set(JEMALLOC_DEFINITIONS ${PC_JEMALLOC_CFLAGS_OTHER})
|
||||
|
||||
find_path(JEMALLOC_INCLUDE_DIR jemalloc/jemalloc.h
|
||||
PATHS ${PC_JEMALLOC_INCLUDEDIR} ${PC_JEMALLOC_INCLUDE_DIRS}
|
||||
${LIMIT_SEARCH})
|
||||
|
||||
# If we're asked to use static linkage, add libjemalloc.a as a preferred library name.
|
||||
if(JEMALLOC_USE_STATIC)
|
||||
list(APPEND JEMALLOC_NAMES
|
||||
"${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
endif()
|
||||
|
||||
list(APPEND JEMALLOC_NAMES jemalloc)
|
||||
|
||||
find_library(JEMALLOC_LIBRARY NAMES ${JEMALLOC_NAMES}
|
||||
HINTS ${PC_JEMALLOC_LIBDIR} ${PC_JEMALLOC_LIBRARY_DIRS}
|
||||
${LIMIT_SEARCH})
|
||||
|
||||
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
|
||||
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(JeMalloc DEFAULT_MSG
|
||||
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)
|
||||
295
Builds/Test.py
295
Builds/Test.py
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# This file is part of rippled: https://github.com/ripple/rippled
|
||||
# Copyright (c) 2012 - 2015 Ripple Labs Inc.
|
||||
# Copyright (c) 2012 - 2017 Ripple Labs Inc.
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -27,6 +27,11 @@ the -- flag - like this:
|
||||
|
||||
./Builds/Test.py -- -j4 # Pass -j4 to scons.
|
||||
|
||||
To build with CMake, use the --cmake flag, or any of the specific configuration
|
||||
flags
|
||||
|
||||
./Builds/Test.py --cmake -- -j4 # Pass -j4 to cmake --build
|
||||
|
||||
|
||||
Common problems:
|
||||
|
||||
@@ -61,6 +66,38 @@ def powerset(iterable):
|
||||
IS_WINDOWS = platform.system().lower() == 'windows'
|
||||
IS_OS_X = platform.system().lower() == 'darwin'
|
||||
|
||||
# CMake
|
||||
if IS_WINDOWS:
|
||||
CMAKE_UNITY_CONFIGS = ['Debug', 'Release']
|
||||
CMAKE_NONUNITY_CONFIGS = ['DebugClassic', 'ReleaseClassic']
|
||||
else:
|
||||
CMAKE_UNITY_CONFIGS = []
|
||||
CMAKE_NONUNITY_CONFIGS = []
|
||||
CMAKE_UNITY_COMBOS = { '' : [['rippled', 'rippled_classic'], CMAKE_UNITY_CONFIGS],
|
||||
'.nounity' : [['rippled', 'rippled_unity'], CMAKE_NONUNITY_CONFIGS] }
|
||||
|
||||
if IS_WINDOWS:
|
||||
CMAKE_DIR_TARGETS = { ('msvc' + unity,) : targets for unity, targets in
|
||||
CMAKE_UNITY_COMBOS.iteritems() }
|
||||
elif IS_OS_X:
|
||||
CMAKE_DIR_TARGETS = { (build + unity,) : targets
|
||||
for build in ['debug', 'release']
|
||||
for unity, targets in CMAKE_UNITY_COMBOS.iteritems() }
|
||||
else:
|
||||
CMAKE_DIR_TARGETS = { (cc + "." + build + unity,) : targets
|
||||
for cc in ['gcc', 'clang']
|
||||
for build in ['debug', 'release', 'coverage', 'profile']
|
||||
for unity, targets in CMAKE_UNITY_COMBOS.iteritems() }
|
||||
|
||||
# list of tuples of all possible options
|
||||
if IS_WINDOWS or IS_OS_X:
|
||||
CMAKE_ALL_GENERATE_OPTIONS = [tuple(x) for x in powerset(['-GNinja', '-Dassert=true'])]
|
||||
else:
|
||||
CMAKE_ALL_GENERATE_OPTIONS = list(set(
|
||||
[tuple(x) for x in powerset(['-GNinja', '-Dstatic=true', '-Dassert=true', '-Dsan=address'])] +
|
||||
[tuple(x) for x in powerset(['-GNinja', '-Dstatic=true', '-Dassert=true', '-Dsan=thread'])]))
|
||||
|
||||
# Scons
|
||||
if IS_WINDOWS or IS_OS_X:
|
||||
ALL_TARGETS = [('debug',), ('release',)]
|
||||
else:
|
||||
@@ -71,7 +108,7 @@ else:
|
||||
|
||||
# list of tuples of all possible options
|
||||
if IS_WINDOWS or IS_OS_X:
|
||||
ALL_OPTIONS = [tuple(x) for x in powerset(['--assert'])]
|
||||
ALL_OPTIONS = [tuple(x) for x in powerset(['--ninja', '--assert'])]
|
||||
else:
|
||||
ALL_OPTIONS = list(set(
|
||||
[tuple(x) for x in powerset(['--ninja', '--static', '--assert', '--sanitize=address'])] +
|
||||
@@ -129,14 +166,76 @@ parser.add_argument(
|
||||
help='Reduce output where possible (unit tests)',
|
||||
)
|
||||
|
||||
# Scons and CMake parameters are too different to run
|
||||
# both side-by-side
|
||||
pgroup = parser.add_mutually_exclusive_group()
|
||||
|
||||
pgroup.add_argument(
|
||||
'--cmake',
|
||||
action='store_true',
|
||||
help='Build using CMake.',
|
||||
)
|
||||
|
||||
pgroup.add_argument(
|
||||
'--scons',
|
||||
action='store_true',
|
||||
help='Build using Scons. Default behavior.')
|
||||
|
||||
parser.add_argument(
|
||||
'scons_args',
|
||||
'--dir', '-d',
|
||||
default=(),
|
||||
nargs='*'
|
||||
nargs='*',
|
||||
help='Specify one or more CMake dir names. Implies --cmake. '
|
||||
'Will also be used as -Dtarget=<dir> running cmake.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--target',
|
||||
default=(),
|
||||
nargs='*',
|
||||
help='Specify one or more CMake build targets. Implies --cmake. '
|
||||
'Will be used as --target <target> running cmake --build.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--config',
|
||||
default=(),
|
||||
nargs='*',
|
||||
help='Specify one or more CMake build configs. Implies --cmake. '
|
||||
'Will be used as --config <config> running cmake --build.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--generator_option',
|
||||
action='append',
|
||||
help='Specify a CMake generator option. Repeat for multiple options. '
|
||||
'Implies --cmake. Will be passed to the cmake generator. '
|
||||
'Due to limits of the argument parser, arguments starting with \'-\' '
|
||||
'must be attached to this option. e.g. --generator_option=-GNinja.')
|
||||
|
||||
parser.add_argument(
|
||||
'--build_option',
|
||||
action='append',
|
||||
help='Specify a build option. Repeat for multiple options. Implies --cmake. '
|
||||
'Will be passed to the build tool via cmake --build. '
|
||||
'Due to limits of the argument parser, arguments starting with \'-\' '
|
||||
'must be attached to this option. e.g. --build_option=-j8.')
|
||||
|
||||
parser.add_argument(
|
||||
'extra_args',
|
||||
default=(),
|
||||
nargs='*',
|
||||
help='Extra arguments are passed through to the tools'
|
||||
)
|
||||
|
||||
ARGS = parser.parse_args()
|
||||
|
||||
def decodeString(line):
|
||||
# Python 2 vs. Python 3
|
||||
if isinstance(line, str):
|
||||
return line
|
||||
else:
|
||||
return line.decode()
|
||||
|
||||
def shell(cmd, args=(), silent=False):
|
||||
""""Execute a shell command and return the output."""
|
||||
@@ -147,6 +246,7 @@ def shell(cmd, args=(), silent=False):
|
||||
|
||||
command = (cmd,) + args
|
||||
|
||||
# shell is needed in Windows to find scons in the path
|
||||
process = subprocess.Popen(
|
||||
command,
|
||||
stdin=subprocess.PIPE,
|
||||
@@ -155,12 +255,9 @@ def shell(cmd, args=(), silent=False):
|
||||
shell=IS_WINDOWS)
|
||||
lines = []
|
||||
count = 0
|
||||
for line in process.stdout:
|
||||
# Python 2 vs. Python 3
|
||||
if isinstance(line, str):
|
||||
decoded = line
|
||||
else:
|
||||
decoded = line.decode()
|
||||
# readline returns '' at EOF
|
||||
for line in iter(process.stdout.readline, ''):
|
||||
decoded = decodeString(line)
|
||||
lines.append(decoded)
|
||||
if verbose:
|
||||
print(decoded, end='')
|
||||
@@ -227,45 +324,163 @@ def run_build(args=None):
|
||||
print(*lines, sep='')
|
||||
sys.exit(1)
|
||||
|
||||
def get_cmake_dir(cmake_dir):
|
||||
return os.path.join('build' , 'cmake' , cmake_dir)
|
||||
|
||||
def run_cmake(directory, cmake_dir, args):
|
||||
print('Generating build in', directory, 'with', *args or ('default options',))
|
||||
old_dir = os.getcwd()
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
os.chdir(directory)
|
||||
if IS_WINDOWS and not any(arg.startswith("-G") for arg in args) and not os.path.exists("CMakeCache.txt"):
|
||||
if '--ninja' in args:
|
||||
args += ( '-GNinja', )
|
||||
else:
|
||||
args += ( '-GVisual Studio 14 2015 Win64', )
|
||||
args += ( '-Dtarget=' + cmake_dir, os.path.join('..', '..', '..'), )
|
||||
resultcode, lines = shell('cmake', args)
|
||||
|
||||
if resultcode:
|
||||
print('Generating FAILED:')
|
||||
if not ARGS.verbose:
|
||||
print(*lines, sep='')
|
||||
sys.exit(1)
|
||||
|
||||
os.chdir(old_dir)
|
||||
|
||||
def run_cmake_build(directory, target, config, args):
|
||||
print('Building', target, config, 'in', directory, 'with', *args or ('default options',))
|
||||
build_args=('--build', directory)
|
||||
if target:
|
||||
build_args += ('--target', target)
|
||||
if config:
|
||||
build_args += ('--config', config)
|
||||
if args:
|
||||
build_args += ('--',)
|
||||
build_args += tuple(args)
|
||||
resultcode, lines = shell('cmake', build_args)
|
||||
|
||||
if resultcode:
|
||||
print('Build FAILED:')
|
||||
if not ARGS.verbose:
|
||||
print(*lines, sep='')
|
||||
sys.exit(1)
|
||||
|
||||
def run_cmake_tests(directory, target, config):
|
||||
failed = []
|
||||
if IS_WINDOWS:
|
||||
target += '.exe'
|
||||
executable = os.path.join(directory, config if config else 'Debug', target)
|
||||
if(not os.path.exists(executable)):
|
||||
executable = os.path.join(directory, target)
|
||||
print('Unit tests for', executable)
|
||||
testflag = '--unittest'
|
||||
quiet = ''
|
||||
if ARGS.test:
|
||||
testflag += ('=' + ARGS.test)
|
||||
if ARGS.quiet:
|
||||
quiet = '-q'
|
||||
resultcode, lines = shell(executable, (testflag, quiet,))
|
||||
|
||||
if resultcode:
|
||||
if not ARGS.verbose:
|
||||
print('ERROR:', *lines, sep='')
|
||||
failed.append([target, 'unittest'])
|
||||
|
||||
return failed
|
||||
|
||||
def main():
|
||||
if ARGS.all:
|
||||
to_build = ALL_BUILDS
|
||||
else:
|
||||
to_build = [tuple(ARGS.scons_args)]
|
||||
|
||||
all_failed = []
|
||||
|
||||
for build in to_build:
|
||||
args = ()
|
||||
# additional arguments come first
|
||||
for arg in list(ARGS.scons_args):
|
||||
if arg not in build:
|
||||
args += (arg,)
|
||||
args += build
|
||||
if ARGS.dir or ARGS.target or ARGS.config or ARGS.build_option or ARGS.generator_option:
|
||||
ARGS.cmake=True
|
||||
|
||||
run_build(args)
|
||||
failed = run_tests(args)
|
||||
|
||||
if failed:
|
||||
print('FAILED:', *(':'.join(f) for f in failed))
|
||||
if not ARGS.keep_going:
|
||||
sys.exit(1)
|
||||
else:
|
||||
all_failed.extend([','.join(build), ':'.join(f)]
|
||||
for f in failed)
|
||||
if not ARGS.cmake:
|
||||
if ARGS.all:
|
||||
to_build = ALL_BUILDS
|
||||
else:
|
||||
print('Success')
|
||||
to_build = [tuple(ARGS.extra_args)]
|
||||
|
||||
if ARGS.clean:
|
||||
shutil.rmtree('build')
|
||||
if '--ninja' in args:
|
||||
os.remove('build.ninja')
|
||||
os.remove('.ninja_deps')
|
||||
os.remove('.ninja_log')
|
||||
for build in to_build:
|
||||
args = ()
|
||||
# additional arguments come first
|
||||
for arg in list(ARGS.extra_args):
|
||||
if arg not in build:
|
||||
args += (arg,)
|
||||
args += build
|
||||
|
||||
run_build(args)
|
||||
failed = run_tests(args)
|
||||
|
||||
if failed:
|
||||
print('FAILED:', *(':'.join(f) for f in failed))
|
||||
if not ARGS.keep_going:
|
||||
sys.exit(1)
|
||||
else:
|
||||
all_failed.extend([','.join(build), ':'.join(f)]
|
||||
for f in failed)
|
||||
else:
|
||||
print('Success')
|
||||
|
||||
if ARGS.clean:
|
||||
shutil.rmtree('build')
|
||||
if '--ninja' in args:
|
||||
os.remove('build.ninja')
|
||||
os.remove('.ninja_deps')
|
||||
os.remove('.ninja_log')
|
||||
else:
|
||||
if ARGS.all:
|
||||
build_dir_targets = CMAKE_DIR_TARGETS
|
||||
generator_options = CMAKE_ALL_GENERATE_OPTIONS
|
||||
else:
|
||||
build_dir_targets = { tuple(ARGS.dir) : [ARGS.target, ARGS.config] }
|
||||
if ARGS.generator_option:
|
||||
generator_options = [tuple(ARGS.generator_option)]
|
||||
else:
|
||||
generator_options = [tuple()]
|
||||
|
||||
if not build_dir_targets:
|
||||
# Let CMake choose the build tool.
|
||||
build_dir_targets = { () : [] }
|
||||
|
||||
if ARGS.build_option:
|
||||
ARGS.build_option = ARGS.build_option + list(ARGS.extra_args)
|
||||
else:
|
||||
ARGS.build_option = list(ARGS.extra_args)
|
||||
|
||||
for args in generator_options:
|
||||
for build_dirs, (build_targets, build_configs) in build_dir_targets.iteritems():
|
||||
if not build_dirs:
|
||||
build_dirs = ('default',)
|
||||
if not build_targets:
|
||||
build_targets = ('rippled',)
|
||||
if not build_configs:
|
||||
build_configs = ('',)
|
||||
for cmake_dir in build_dirs:
|
||||
cmake_full_dir = get_cmake_dir(cmake_dir)
|
||||
run_cmake(cmake_full_dir, cmake_dir, args)
|
||||
|
||||
for target in build_targets:
|
||||
for config in build_configs:
|
||||
run_cmake_build(cmake_full_dir, target, config, ARGS.build_option)
|
||||
failed = run_cmake_tests(cmake_full_dir, target, config)
|
||||
|
||||
if failed:
|
||||
print('FAILED:', *(':'.join(f) for f in failed))
|
||||
if not ARGS.keep_going:
|
||||
sys.exit(1)
|
||||
else:
|
||||
all_failed.extend([decodeString(cmake_dir +
|
||||
"." + target + "." + config), ':'.join(f)]
|
||||
for f in failed)
|
||||
else:
|
||||
print('Success')
|
||||
if ARGS.clean:
|
||||
shutil.rmtree(cmake_full_dir)
|
||||
|
||||
if all_failed:
|
||||
if len(to_build) > 1:
|
||||
if len(all_failed) > 1:
|
||||
print()
|
||||
print('FAILED:', *(':'.join(f) for f in all_failed))
|
||||
sys.exit(1)
|
||||
|
||||
@@ -266,13 +266,15 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\config.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\async_completion.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\async_result.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\bind_handler.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffered_read_stream.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffer_cat.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffer_concepts.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffer_prefix.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\consuming_buffers.hpp">
|
||||
</ClInclude>
|
||||
@@ -280,155 +282,183 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\bind_handler.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\buffer_cat.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\buffer_concepts.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\ci_char_traits.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\buffers_ref.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\clamp.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\empty_base_optimization.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\config.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\get_lowest_layer.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\cpu_info.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\empty_base_optimization.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\integer_sequence.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\is_call_possible.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\in_place_init.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\prepare_buffers.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\ostream.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\sha1.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\stream_concepts.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\static_ostream.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\sync_ostream.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\static_string.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\type_traits.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\write_dynabuf.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\dynabuf_readstream.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\error.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_base.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_posix.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_stdio.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_win32.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_alloc.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_concepts.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_helpers.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_ptr.hpp">
|
||||
</ClInclude>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\buffered_read_stream.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\buffer_cat.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\buffer_prefix.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\consuming_buffers.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\dynabuf_readstream.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\file_posix.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\file_stdio.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\file_win32.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\handler_ptr.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\static_streambuf.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\multi_buffer.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\streambuf.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\read_size.ipp">
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\placeholders.hpp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\static_buffer.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\static_string.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\string_param.ipp">
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\multi_buffer.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\prepare_buffer.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\ostream.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\prepare_buffers.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\read_size.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\static_streambuf.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\span.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\static_buffer.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\static_string.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\streambuf.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\string.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\stream_concepts.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\string_param.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\to_string.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\write_dynabuf.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\type_traits.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_dynabuf_body.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_parser.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_fields.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\buffer_body.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_parser_v1.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_parsed_list.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\chunk_encode.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\concepts.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_fields.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_parser_v1.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_parser.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\chunk_encode.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\rfc7230.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\type_traits.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\dynamic_body.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\empty_body.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\error.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\field.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\fields.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\header_parser_v1.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\file_body.hpp">
|
||||
</ClInclude>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\basic_fields.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\basic_parser.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\basic_parser_v1.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\error.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\field.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\fields.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\file_body_win32.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\message.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\parse.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\parse_error.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\parser.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\read.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\rfc7230.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\serializer.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\status.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\verb.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\write.ipp">
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\message.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parse.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parser_v1.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parse_error.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parser.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\read.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\reason.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\rfc7230.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\streambuf_body.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\serializer.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\span_body.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\status.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\string_body.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\type_traits.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\vector_body.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\verb.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\write.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\version.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\decorator.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\endian.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\frame.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\hybi13.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\invokable.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\mask.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\pausation.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\pmd_extension.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\stream_base.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\type_traits.hpp">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\utf8_checker.hpp">
|
||||
</ClInclude>
|
||||
@@ -446,6 +476,8 @@
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\websocket\impl\read.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\websocket\impl\rfc6455.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\websocket\impl\ssl.ipp">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\websocket\impl\stream.ipp">
|
||||
@@ -835,6 +867,12 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\consensus\RCLCxTx.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\consensus\RCLValidations.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\consensus\RCLValidations.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\AbstractFetchPackContainer.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\AcceptedLedger.cpp">
|
||||
@@ -1061,6 +1099,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\misc\impl\ValidatorKeys.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\misc\impl\ValidatorList.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -1093,11 +1135,7 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\TxQ.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\misc\Validations.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\Validations.h">
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\ValidatorKeys.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\ValidatorList.h">
|
||||
</ClInclude>
|
||||
@@ -1431,10 +1469,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\basics\impl\RangeSet.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\basics\impl\ResolverAsio.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -1495,6 +1529,8 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\basics\TaggedCache.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\basics\tagged_integer.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\basics\ToString.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\basics\UnorderedContainers.h">
|
||||
@@ -1793,8 +1829,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\beast\utility\tagged_integer.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\beast\utility\temp_dir.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\beast\utility\weak_fn.h">
|
||||
@@ -1827,18 +1861,26 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\conditions\impl\utils.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\Consensus.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\ConsensusProposal.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\DisputedTx.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\consensus\LedgerTiming.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\consensus\Consensus.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\Consensus.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\ConsensusParms.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\ConsensusProposal.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\ConsensusTypes.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\DisputedTx.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\LedgerTiming.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\Validations.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\ClosureCounter.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\Config.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\ConfigSections.h">
|
||||
@@ -1847,8 +1889,6 @@
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\ripple\core\DatabaseCon.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\DeadlineTimer.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\Config.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -1861,12 +1901,6 @@
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\DeadlineTimer.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\DummySociDynamicBackend.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -1941,8 +1975,6 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\Job.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\JobCounter.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\JobQueue.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\JobTypeData.h">
|
||||
@@ -2085,6 +2117,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\ledger\impl\ApplyView.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\ledger\impl\ApplyViewBase.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -3157,7 +3193,15 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_main.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_ledger_impl.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_main1.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_main2.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -3165,6 +3209,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_misc_impl.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_paths.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
@@ -3221,7 +3269,11 @@
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug|x64'">..\..\src\rocksdb2\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release|x64'">..\..\src\rocksdb2\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\overlay.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\unity\overlay1.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\overlay2.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -3247,7 +3299,11 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\unity\rocksdb.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\unity\rpcx.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\unity\rpcx1.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\rpcx2.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -4291,6 +4347,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\app\ValidatorKeys_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\app\ValidatorList_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -4343,6 +4403,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\basics\tagged_integer_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\beast\aged_associative_container_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -4375,10 +4439,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\beast\beast_tagged_integer_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\beast\beast_weak_fn_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -4423,6 +4483,14 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\consensus\Validations_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\ClosureCounter_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\Config_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -4435,11 +4503,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\DeadlineTimer_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\JobCounter_test.cpp">
|
||||
<ClCompile Include="..\..\src\test\core\JobQueue_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -4895,6 +4959,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\AmendmentBlocked_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\Book_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -4943,6 +5011,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\OwnerInfo_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\Peers_test.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
@@ -4997,7 +5069,11 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\app_test_unity.cpp">
|
||||
<ClCompile Include="..\..\src\test\unity\app_test_unity1.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\app_test_unity2.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -5005,7 +5081,11 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\beast_test_unity.cpp">
|
||||
<ClCompile Include="..\..\src\test\unity\beast_test_unity1.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\beast_test_unity2.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -5029,7 +5109,11 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\jtx_unity.cpp">
|
||||
<ClCompile Include="..\..\src\test\unity\jtx_unity1.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\jtx_unity2.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -5063,6 +5147,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\server_status_test_unity.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\server_test_unity.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">True</ExcludedFromBuild>
|
||||
|
||||
@@ -558,16 +558,19 @@
|
||||
<ClInclude Include="..\..\src\beast\include\beast\config.hpp">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\async_completion.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\async_result.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\bind_handler.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffered_read_stream.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffer_cat.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffer_concepts.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\buffer_prefix.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\consuming_buffers.hpp">
|
||||
@@ -579,130 +582,145 @@
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\bind_handler.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\buffer_cat.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\buffer_concepts.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\ci_char_traits.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\buffers_ref.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\clamp.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\empty_base_optimization.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\config.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\get_lowest_layer.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\cpu_info.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\empty_base_optimization.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\integer_sequence.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\is_call_possible.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\in_place_init.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\prepare_buffers.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\ostream.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\sha1.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\stream_concepts.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\static_ostream.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\sync_ostream.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\static_string.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\type_traits.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\detail\write_dynabuf.hpp">
|
||||
<Filter>beast\core\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\dynabuf_readstream.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\error.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\error.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_base.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_posix.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_stdio.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\file_win32.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_alloc.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_concepts.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_helpers.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\handler_ptr.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\buffered_read_stream.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\buffer_cat.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\buffer_prefix.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\consuming_buffers.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\dynabuf_readstream.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\file_posix.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\file_stdio.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\file_win32.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\handler_ptr.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\static_streambuf.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\multi_buffer.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\streambuf.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\read_size.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\placeholders.hpp">
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\static_buffer.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\static_string.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\core\impl\string_param.ipp">
|
||||
<Filter>beast\core\impl</Filter>
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\multi_buffer.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\prepare_buffer.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\ostream.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\prepare_buffers.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\read_size.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\static_streambuf.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\span.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\static_buffer.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\static_string.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\streambuf.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\string.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\stream_concepts.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\string_param.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\to_string.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\write_dynabuf.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\core\type_traits.hpp">
|
||||
<Filter>beast\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http.hpp">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_dynabuf_body.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_parser.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_fields.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\buffer_body.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\basic_parser_v1.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\chunk_encode.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\concepts.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_fields.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_parsed_list.hpp">
|
||||
<Filter>beast\http\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_parser_v1.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\basic_parser.hpp">
|
||||
<Filter>beast\http\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\chunk_encode.hpp">
|
||||
@@ -711,28 +729,46 @@
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\rfc7230.hpp">
|
||||
<Filter>beast\http\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\detail\type_traits.hpp">
|
||||
<Filter>beast\http\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\dynamic_body.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\empty_body.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\error.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\field.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\fields.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\header_parser_v1.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\file_body.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\basic_fields.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\basic_parser.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\basic_parser_v1.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\error.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\field.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\fields.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\file_body_win32.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\message.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\parse.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\parse_error.ipp">
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\parser.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\read.ipp">
|
||||
@@ -741,36 +777,51 @@
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\rfc7230.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\serializer.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\status.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\verb.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\http\impl\write.ipp">
|
||||
<Filter>beast\http\impl</Filter>
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\message.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parse.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parser_v1.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parse_error.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\parser.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\read.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\reason.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\rfc7230.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\streambuf_body.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\serializer.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\span_body.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\status.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\string_body.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\type_traits.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\vector_body.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\verb.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\http\write.hpp">
|
||||
<Filter>beast\http</Filter>
|
||||
</ClInclude>
|
||||
@@ -780,28 +831,22 @@
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket.hpp">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\decorator.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\endian.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\frame.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\hybi13.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\invokable.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\mask.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\mask.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\pausation.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\pmd_extension.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\stream_base.hpp">
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\type_traits.hpp">
|
||||
<Filter>beast\websocket\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\include\beast\websocket\detail\utf8_checker.hpp">
|
||||
@@ -828,6 +873,9 @@
|
||||
<None Include="..\..\src\beast\include\beast\websocket\impl\read.ipp">
|
||||
<Filter>beast\websocket\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\websocket\impl\rfc6455.ipp">
|
||||
<Filter>beast\websocket\impl</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\include\beast\websocket\impl\ssl.ipp">
|
||||
<Filter>beast\websocket\impl</Filter>
|
||||
</None>
|
||||
@@ -1353,6 +1401,12 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\consensus\RCLCxTx.h">
|
||||
<Filter>ripple\app\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\consensus\RCLValidations.cpp">
|
||||
<Filter>ripple\app\consensus</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\consensus\RCLValidations.h">
|
||||
<Filter>ripple\app\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\AbstractFetchPackContainer.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
@@ -1581,6 +1635,9 @@
|
||||
<ClCompile Include="..\..\src\ripple\app\misc\impl\TxQ.cpp">
|
||||
<Filter>ripple\app\misc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\misc\impl\ValidatorKeys.cpp">
|
||||
<Filter>ripple\app\misc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\misc\impl\ValidatorList.cpp">
|
||||
<Filter>ripple\app\misc\impl</Filter>
|
||||
</ClCompile>
|
||||
@@ -1617,10 +1674,7 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\TxQ.h">
|
||||
<Filter>ripple\app\misc</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\misc\Validations.cpp">
|
||||
<Filter>ripple\app\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\Validations.h">
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\ValidatorKeys.h">
|
||||
<Filter>ripple\app\misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\app\misc\ValidatorList.h">
|
||||
@@ -1959,9 +2013,6 @@
|
||||
<ClCompile Include="..\..\src\ripple\basics\impl\mulDiv.cpp">
|
||||
<Filter>ripple\basics\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\basics\impl\RangeSet.cpp">
|
||||
<Filter>ripple\basics\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\basics\impl\ResolverAsio.cpp">
|
||||
<Filter>ripple\basics\impl</Filter>
|
||||
</ClCompile>
|
||||
@@ -2034,6 +2085,9 @@
|
||||
<ClInclude Include="..\..\src\ripple\basics\TaggedCache.h">
|
||||
<Filter>ripple\basics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\basics\tagged_integer.h">
|
||||
<Filter>ripple\basics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\basics\ToString.h">
|
||||
<Filter>ripple\basics</Filter>
|
||||
</ClInclude>
|
||||
@@ -2412,9 +2466,6 @@
|
||||
<ClCompile Include="..\..\src\ripple\beast\utility\src\beast_PropertyStream.cpp">
|
||||
<Filter>ripple\beast\utility\src</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\beast\utility\tagged_integer.h">
|
||||
<Filter>ripple\beast\utility</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\beast\utility\temp_dir.h">
|
||||
<Filter>ripple\beast\utility</Filter>
|
||||
</ClInclude>
|
||||
@@ -2454,21 +2505,33 @@
|
||||
<ClInclude Include="..\..\src\ripple\conditions\impl\utils.h">
|
||||
<Filter>ripple\conditions\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\consensus\Consensus.cpp">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\Consensus.h">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\ConsensusParms.h">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\ConsensusProposal.h">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\ConsensusTypes.h">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\DisputedTx.h">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\consensus\LedgerTiming.cpp">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\LedgerTiming.h">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\consensus\Validations.h">
|
||||
<Filter>ripple\consensus</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\ClosureCounter.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\Config.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
@@ -2481,18 +2544,12 @@
|
||||
<ClInclude Include="..\..\src\ripple\core\DatabaseCon.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\DeadlineTimer.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\Config.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\DatabaseCon.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\DeadlineTimer.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\DummySociDynamicBackend.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
@@ -2538,9 +2595,6 @@
|
||||
<ClInclude Include="..\..\src\ripple\core\Job.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\JobCounter.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\JobQueue.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
@@ -2706,6 +2760,9 @@
|
||||
<ClCompile Include="..\..\src\ripple\ledger\impl\ApplyStateTable.cpp">
|
||||
<Filter>ripple\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\ledger\impl\ApplyView.cpp">
|
||||
<Filter>ripple\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\ledger\impl\ApplyViewBase.cpp">
|
||||
<Filter>ripple\ledger\impl</Filter>
|
||||
</ClCompile>
|
||||
@@ -3762,12 +3819,21 @@
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_ledger.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_main.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_ledger_impl.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_main1.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_main2.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_misc.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_misc_impl.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\app_paths.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
@@ -3810,7 +3876,10 @@
|
||||
<ClCompile Include="..\..\src\ripple\unity\nodestore.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\overlay.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\unity\overlay1.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\overlay2.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\peerfinder.cpp">
|
||||
@@ -3834,7 +3903,10 @@
|
||||
<ClInclude Include="..\..\src\ripple\unity\rocksdb.h">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\unity\rpcx.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\unity\rpcx1.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\rpcx2.cpp">
|
||||
<Filter>ripple\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\unity\secp256k1.cpp">
|
||||
@@ -5070,6 +5142,9 @@
|
||||
<ClCompile Include="..\..\src\test\app\TxQ_test.cpp">
|
||||
<Filter>test\app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\app\ValidatorKeys_test.cpp">
|
||||
<Filter>test\app</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\app\ValidatorList_test.cpp">
|
||||
<Filter>test\app</Filter>
|
||||
</ClCompile>
|
||||
@@ -5109,6 +5184,9 @@
|
||||
<ClCompile Include="..\..\src\test\basics\TaggedCache_test.cpp">
|
||||
<Filter>test\basics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\basics\tagged_integer_test.cpp">
|
||||
<Filter>test\basics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\beast\aged_associative_container_test.cpp">
|
||||
<Filter>test\beast</Filter>
|
||||
</ClCompile>
|
||||
@@ -5133,9 +5211,6 @@
|
||||
<ClCompile Include="..\..\src\test\beast\beast_PropertyStream_test.cpp">
|
||||
<Filter>test\beast</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\beast\beast_tagged_integer_test.cpp">
|
||||
<Filter>test\beast</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\beast\beast_weak_fn_test.cpp">
|
||||
<Filter>test\beast</Filter>
|
||||
</ClCompile>
|
||||
@@ -5169,6 +5244,12 @@
|
||||
<ClCompile Include="..\..\src\test\consensus\LedgerTiming_test.cpp">
|
||||
<Filter>test\consensus</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\consensus\Validations_test.cpp">
|
||||
<Filter>test\consensus</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\ClosureCounter_test.cpp">
|
||||
<Filter>test\core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\Config_test.cpp">
|
||||
<Filter>test\core</Filter>
|
||||
</ClCompile>
|
||||
@@ -5178,10 +5259,7 @@
|
||||
<ClCompile Include="..\..\src\test\core\CryptoPRNG_test.cpp">
|
||||
<Filter>test\core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\DeadlineTimer_test.cpp">
|
||||
<Filter>test\core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\JobCounter_test.cpp">
|
||||
<ClCompile Include="..\..\src\test\core\JobQueue_test.cpp">
|
||||
<Filter>test\core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\core\SociDB_test.cpp">
|
||||
@@ -5592,6 +5670,9 @@
|
||||
<ClCompile Include="..\..\src\test\rpc\AccountSet_test.cpp">
|
||||
<Filter>test\rpc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\AmendmentBlocked_test.cpp">
|
||||
<Filter>test\rpc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\Book_test.cpp">
|
||||
<Filter>test\rpc</Filter>
|
||||
</ClCompile>
|
||||
@@ -5628,6 +5709,9 @@
|
||||
<ClCompile Include="..\..\src\test\rpc\NoRipple_test.cpp">
|
||||
<Filter>test\rpc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\OwnerInfo_test.cpp">
|
||||
<Filter>test\rpc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\rpc\Peers_test.cpp">
|
||||
<Filter>test\rpc</Filter>
|
||||
</ClCompile>
|
||||
@@ -5670,13 +5754,19 @@
|
||||
<ClCompile Include="..\..\src\test\shamap\SHAMap_test.cpp">
|
||||
<Filter>test\shamap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\app_test_unity.cpp">
|
||||
<ClCompile Include="..\..\src\test\unity\app_test_unity1.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\app_test_unity2.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\basics_test_unity.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\beast_test_unity.cpp">
|
||||
<ClCompile Include="..\..\src\test\unity\beast_test_unity1.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\beast_test_unity2.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\conditions_test_unity.cpp">
|
||||
@@ -5694,7 +5784,10 @@
|
||||
<ClCompile Include="..\..\src\test\unity\json_test_unity.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\jtx_unity.cpp">
|
||||
<ClCompile Include="..\..\src\test\unity\jtx_unity1.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\jtx_unity2.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\ledger_test_unity.cpp">
|
||||
@@ -5718,6 +5811,9 @@
|
||||
<ClCompile Include="..\..\src\test\unity\rpc_test_unity.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\server_status_test_unity.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\test\unity\server_test_unity.cpp">
|
||||
<Filter>test\unity</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
## Important
|
||||
|
||||
We don't recommend OS X for rippled production use at this time. Currently, the
|
||||
We don't recommend macos for rippled production use at this time. Currently, the
|
||||
Ubuntu platform has received the highest level of quality assurance and
|
||||
testing.
|
||||
testing. That said, macos is suitable for many development/test tasks.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You'll need OSX 10.8 or later
|
||||
You'll need macos 10.8 or later
|
||||
|
||||
To clone the source code repository, create branches for inspection or
|
||||
modification, build rippled using clang, and run the system tests you will need
|
||||
@@ -17,7 +17,7 @@ these software components:
|
||||
* [XCode](https://developer.apple.com/xcode/)
|
||||
* [Homebrew](http://brew.sh/)
|
||||
* [Git](http://git-scm.com/)
|
||||
* [Scons](http://www.scons.org/)
|
||||
* [CMake](http://cmake.org/)
|
||||
|
||||
## Install Software
|
||||
|
||||
@@ -64,14 +64,14 @@ later.
|
||||
|
||||
### Install Scons
|
||||
|
||||
Requires version 2.3.0 or later
|
||||
Requires version 3.6.0 or later
|
||||
|
||||
```
|
||||
brew install scons
|
||||
brew install cmake
|
||||
```
|
||||
|
||||
`brew` will generally install the latest stable version of any package, which
|
||||
will satisfy the scons minimum version requirement for rippled.
|
||||
should satisfy the cmake minimum version requirement for rippled.
|
||||
|
||||
### Install Package Config
|
||||
|
||||
@@ -163,10 +163,16 @@ export BOOST_ROOT=/Users/Abigail/Downloads/boost_1_61_0
|
||||
## Build
|
||||
|
||||
```
|
||||
scons
|
||||
mkdir xcode_build && cd xcode_build
|
||||
cmake -GXcode ..
|
||||
```
|
||||
|
||||
See: [here](https://ripple.com/wiki/Rippled_build_instructions#Building)
|
||||
There are a number of variables/options that our CMake files support and they
|
||||
can be added to the above command as needed (e.g. `-Dassert=ON` to enable
|
||||
asserts)
|
||||
|
||||
After generation succeeds, the xcode project file can be opened and used to
|
||||
build and debug.
|
||||
|
||||
## Unit Tests (Recommended)
|
||||
|
||||
|
||||
6
Builds/build_all.sh
Normal file → Executable file
6
Builds/build_all.sh
Normal file → Executable file
@@ -2,5 +2,7 @@
|
||||
|
||||
num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # number of physical cores
|
||||
|
||||
cd ..
|
||||
./Builds/Test.py -a -c -- -j${num_procs}
|
||||
path=$(cd $(dirname $0) && pwd)
|
||||
cd $(dirname $path)
|
||||
${path}/Test.py -a -c --test=TxQ -- -j${num_procs}
|
||||
${path}/Test.py -a -c -k --test=TxQ --cmake -- -j${num_procs}
|
||||
|
||||
@@ -15,24 +15,30 @@
|
||||
# * ninja builds
|
||||
# * check openssl version on linux
|
||||
# * static builds (swd TBD: needs to be tested by building & deploying on different systems)
|
||||
#
|
||||
# TBD:
|
||||
# * jemalloc support
|
||||
# * count
|
||||
# * Windows protobuf compiler puts generated file in src directory instead of build directory.
|
||||
# * jemalloc enabled builds (linux and macos only)
|
||||
# * perf builds (linux only) - which just sets recommended compiler flags
|
||||
# for running perf on the executable
|
||||
#
|
||||
# Notes:
|
||||
# * Use the -G"Visual Studio 14 2015 Win64" generator on Windows. Without this
|
||||
# a 32-bit project will be created. There is no way to set the generator or
|
||||
# force a 64-bit build in CMakeLists.txt (setting CMAKE_GENERATOR_PLATFORM won't work).
|
||||
# The best solution may be to wrap cmake with a script.
|
||||
# * Use the -G"Visual Studio 14 2015 Win64" generator, or the "VS2015 x86 x64
|
||||
# Cross Tools" Command Prompt on Windows. Without this a 32-bit project will be
|
||||
# created. There is no way to set the generator or force a 64-bit build in
|
||||
# CMakeLists.txt (setting CMAKE_GENERATOR_PLATFORM won't work). The best solution
|
||||
# may be to wrap cmake with a script.
|
||||
#
|
||||
# * Ninja command line builds seem to work under Windows, but only from within
|
||||
# the "VS2015 x86 x64 Cross Tools" Command Prompt.
|
||||
#
|
||||
# * It is not possible to generate a visual studio project on linux or
|
||||
# mac. The visual studio generator is only available on windows.
|
||||
#
|
||||
# * The visual studio project can be _either_ unity or
|
||||
# non-unity (selected at generation time). It does not appear possible
|
||||
# to disable compilation based on configuration.
|
||||
# * The Visual Studio solution will be generated with two projects, one
|
||||
# unity, one non-unity. Which is default depends on the nounity flag in
|
||||
# -Dtarget. Unity targets will create `rippled` and `rippled_classic`.
|
||||
# Non-unity targets will create `rippled` and `rippled_unity`. In either
|
||||
# case, only the `rippled` build will be enabled by default. It does
|
||||
# not appear possible to include both unity and non-unity configs in one
|
||||
# project and disable compilation based on configuration.
|
||||
#
|
||||
# * Language is _much_ worse than python, poor documentation and "quirky"
|
||||
# language support (for example, generator expressions can only be used
|
||||
@@ -181,8 +187,11 @@ prepend(ripple_unity_srcs
|
||||
src/ripple/unity/
|
||||
app_consensus.cpp
|
||||
app_ledger.cpp
|
||||
app_main.cpp
|
||||
app_ledger_impl.cpp
|
||||
app_main1.cpp
|
||||
app_main2.cpp
|
||||
app_misc.cpp
|
||||
app_misc_impl.cpp
|
||||
app_paths.cpp
|
||||
app_tx.cpp
|
||||
conditions.cpp
|
||||
@@ -192,19 +201,23 @@ basics.cpp
|
||||
crypto.cpp
|
||||
ledger.cpp
|
||||
net.cpp
|
||||
overlay.cpp
|
||||
overlay1.cpp
|
||||
overlay2.cpp
|
||||
peerfinder.cpp
|
||||
json.cpp
|
||||
protocol.cpp
|
||||
rpcx.cpp
|
||||
rpcx1.cpp
|
||||
rpcx2.cpp
|
||||
shamap.cpp
|
||||
server.cpp)
|
||||
|
||||
prepend(test_unity_srcs
|
||||
src/test/unity/
|
||||
app_test_unity.cpp
|
||||
app_test_unity1.cpp
|
||||
app_test_unity2.cpp
|
||||
basics_test_unity.cpp
|
||||
beast_test_unity.cpp
|
||||
beast_test_unity1.cpp
|
||||
beast_test_unity2.cpp
|
||||
conditions_test_unity.cpp
|
||||
consensus_test_unity.cpp
|
||||
core_test_unity.cpp
|
||||
@@ -216,8 +229,10 @@ protocol_test_unity.cpp
|
||||
resource_test_unity.cpp
|
||||
rpc_test_unity.cpp
|
||||
server_test_unity.cpp
|
||||
server_status_test_unity.cpp
|
||||
shamap_test_unity.cpp
|
||||
jtx_unity.cpp
|
||||
jtx_unity1.cpp
|
||||
jtx_unity2.cpp
|
||||
csf_unity.cpp)
|
||||
|
||||
list(APPEND rippled_src_unity ${beast_unity_srcs} ${ripple_unity_srcs} ${test_unity_srcs})
|
||||
@@ -294,8 +309,11 @@ foreach(curdir
|
||||
basics
|
||||
beast
|
||||
conditions
|
||||
consensus
|
||||
core
|
||||
csf
|
||||
json
|
||||
jtx
|
||||
ledger
|
||||
nodestore
|
||||
overlay
|
||||
@@ -304,9 +322,7 @@ foreach(curdir
|
||||
resource
|
||||
rpc
|
||||
server
|
||||
shamap
|
||||
jtx
|
||||
csf)
|
||||
shamap)
|
||||
file(GLOB_RECURSE cursrcs src/test/${curdir}/*.cpp)
|
||||
list(APPEND test_srcs "${cursrcs}")
|
||||
endforeach()
|
||||
|
||||
@@ -78,8 +78,8 @@ git-subtree. See the corresponding README for more details.
|
||||
|
||||
* [Ripple Knowledge Center](https://ripple.com/learn/)
|
||||
* [Ripple Developer Center](https://ripple.com/build/)
|
||||
* [Ripple Whitepapers & Reports](https://ripple.com/whitepapers-reports/)
|
||||
* [Ripple Consensus Whitepaper](https://ripple.com/consensus-whitepaper/)
|
||||
* Ripple Whitepapers & Reports
|
||||
* [Ripple Consensus Whitepaper](https://ripple.com/files/ripple_consensus_whitepaper.pdf)
|
||||
* [Ripple Solutions Guide](https://ripple.com/files/ripple_solutions_guide.pdf)
|
||||
|
||||
To learn about how Ripple is transforming global payments visit
|
||||
|
||||
@@ -11,6 +11,35 @@ If you are using Red Hat Enterprise Linux 7 or CentOS 7, you can [update using `
|
||||
|
||||
# Releases
|
||||
|
||||
## Version 0.80.0
|
||||
|
||||
The `rippled` 0.80.0 release introduces several enhancements that improve the reliability, scalability and security of the XRP Ledger.
|
||||
|
||||
Highlights of this release include:
|
||||
|
||||
- The `SortedDirectories` amendment, which allows the entries stored within a page to be sorted, and corrects a technical flaw that could, in some edge cases, prevent an empty intermediate page from being deleted.
|
||||
- Changes to the UNL and quorum rules
|
||||
+ Use a fixed size UNL if the total listed validators are below threshold
|
||||
+ Ensure a quorum of 0 cannot be configured
|
||||
+ Set a quorum to provide Byzantine fault tolerance until a threshold of total validators is exceeded, at which time the quorum is 80%
|
||||
|
||||
**New and Updated Features**
|
||||
|
||||
- Improve directory insertion and deletion ([#2165](https://github.com/ripple/rippled/issues/2165))
|
||||
- Move consensus thread safety logic from the generic implementation in Consensus into the RCL adapted version RCLConsensus ([#2106](https://github.com/ripple/rippled/issues/2106))
|
||||
- Refactor Validations class into a generic version that can be adapted ([#2084](https://github.com/ripple/rippled/issues/2084))
|
||||
- Make minimum quorum Byzantine fault tolerant ([#2093](https://github.com/ripple/rippled/issues/2093))
|
||||
- Make amendment blocked state thread-safe and simplify a constructor ([#2207](https://github.com/ripple/rippled/issues/2207))
|
||||
- Use ledger hash to break ties ([#2169](https://github.com/ripple/rippled/issues/2169))
|
||||
- Refactor RangeSet ([#2113](https://github.com/ripple/rippled/issues/2113))
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix an issue where `setAmendmentBlocked` is only called when processing the `EnableAmendment` transaction for the amendment ([#2137](https://github.com/ripple/rippled/issues/2137))
|
||||
- Track escrow in recipient's owner directory ([#2212](https://github.com/ripple/rippled/issues/2212))
|
||||
|
||||
**New and Updated Features**
|
||||
|
||||
## Version 0.70.2
|
||||
|
||||
The `rippled` 0.70.2 release corrects an emergent behavior which causes large numbers of transactions to get
|
||||
|
||||
23
SConstruct
23
SConstruct
@@ -976,7 +976,7 @@ def get_classic_sources(toolchain):
|
||||
append_sources(result, *list_sources('src/test/server', '.cpp'))
|
||||
append_sources(result, *list_sources('src/test/shamap', '.cpp'))
|
||||
append_sources(result, *list_sources('src/test/jtx', '.cpp'))
|
||||
append_sources(result, *list_sources('src/test/csf', '.cpp'))
|
||||
append_sources(result, *list_sources('src/test/csf', '.cpp'))
|
||||
|
||||
|
||||
if use_shp(toolchain):
|
||||
@@ -1008,8 +1008,11 @@ def get_unity_sources(toolchain):
|
||||
'src/ripple/beast/unity/beast_utility_unity.cpp',
|
||||
'src/ripple/unity/app_consensus.cpp',
|
||||
'src/ripple/unity/app_ledger.cpp',
|
||||
'src/ripple/unity/app_main.cpp',
|
||||
'src/ripple/unity/app_ledger_impl.cpp',
|
||||
'src/ripple/unity/app_main1.cpp',
|
||||
'src/ripple/unity/app_main2.cpp',
|
||||
'src/ripple/unity/app_misc.cpp',
|
||||
'src/ripple/unity/app_misc_impl.cpp',
|
||||
'src/ripple/unity/app_paths.cpp',
|
||||
'src/ripple/unity/app_tx.cpp',
|
||||
'src/ripple/unity/conditions.cpp',
|
||||
@@ -1019,16 +1022,20 @@ def get_unity_sources(toolchain):
|
||||
'src/ripple/unity/crypto.cpp',
|
||||
'src/ripple/unity/ledger.cpp',
|
||||
'src/ripple/unity/net.cpp',
|
||||
'src/ripple/unity/overlay.cpp',
|
||||
'src/ripple/unity/overlay1.cpp',
|
||||
'src/ripple/unity/overlay2.cpp',
|
||||
'src/ripple/unity/peerfinder.cpp',
|
||||
'src/ripple/unity/json.cpp',
|
||||
'src/ripple/unity/protocol.cpp',
|
||||
'src/ripple/unity/rpcx.cpp',
|
||||
'src/ripple/unity/rpcx1.cpp',
|
||||
'src/ripple/unity/rpcx2.cpp',
|
||||
'src/ripple/unity/shamap.cpp',
|
||||
'src/ripple/unity/server.cpp',
|
||||
'src/test/unity/app_test_unity.cpp',
|
||||
'src/test/unity/app_test_unity1.cpp',
|
||||
'src/test/unity/app_test_unity2.cpp',
|
||||
'src/test/unity/basics_test_unity.cpp',
|
||||
'src/test/unity/beast_test_unity.cpp',
|
||||
'src/test/unity/beast_test_unity1.cpp',
|
||||
'src/test/unity/beast_test_unity2.cpp',
|
||||
'src/test/unity/consensus_test_unity.cpp',
|
||||
'src/test/unity/core_test_unity.cpp',
|
||||
'src/test/unity/conditions_test_unity.cpp',
|
||||
@@ -1040,8 +1047,10 @@ def get_unity_sources(toolchain):
|
||||
'src/test/unity/resource_test_unity.cpp',
|
||||
'src/test/unity/rpc_test_unity.cpp',
|
||||
'src/test/unity/server_test_unity.cpp',
|
||||
'src/test/unity/server_status_test_unity.cpp',
|
||||
'src/test/unity/shamap_test_unity.cpp',
|
||||
'src/test/unity/jtx_unity.cpp',
|
||||
'src/test/unity/jtx_unity1.cpp',
|
||||
'src/test/unity/jtx_unity2.cpp',
|
||||
'src/test/unity/csf_unity.cpp'
|
||||
)
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@ echo "using TARGET: $TARGET"
|
||||
|
||||
# Ensure APP defaults to rippled if it's not set.
|
||||
: ${APP:=rippled}
|
||||
|
||||
JOBS=${NUM_PROCESSORS:-2}
|
||||
if [[ ${TARGET} == *.nounity ]]; then
|
||||
JOBS=$((2*${JOBS}))
|
||||
fi
|
||||
|
||||
if [[ ${BUILD:-scons} == "cmake" ]]; then
|
||||
echo "cmake building ${APP}"
|
||||
CMAKE_TARGET=$CC.$TARGET
|
||||
@@ -19,7 +25,7 @@ if [[ ${BUILD:-scons} == "cmake" ]]; then
|
||||
mkdir -p "build/${CMAKE_TARGET}"
|
||||
pushd "build/${CMAKE_TARGET}"
|
||||
cmake ../.. -Dtarget=$CMAKE_TARGET
|
||||
cmake --build . -- -j${NUM_PROCESSORS:-2}
|
||||
cmake --build . -- -j${JOBS}
|
||||
popd
|
||||
export APP_PATH="$PWD/build/${CMAKE_TARGET}/${APP}"
|
||||
echo "using APP_PATH: $APP_PATH"
|
||||
@@ -33,7 +39,7 @@ else
|
||||
# $CC will be either `clang` or `gcc`
|
||||
# http://docs.travis-ci.com/user/migrating-from-legacy/?utm_source=legacy-notice&utm_medium=banner&utm_campaign=legacy-upgrade
|
||||
# indicates that 2 cores are available to containers.
|
||||
scons -j${NUM_PROCESSORS:-2} $CC.$TARGET
|
||||
scons -j${JOBS} $CC.$TARGET
|
||||
fi
|
||||
# We can be sure we're using the build/$CC.$TARGET variant
|
||||
# (-f so never err)
|
||||
@@ -62,15 +68,19 @@ if [[ $TARGET == "coverage" ]]; then
|
||||
lcov --no-external -c -i -d . -o baseline.info
|
||||
fi
|
||||
|
||||
# Execute unit tests under gdb, printing a call stack
|
||||
# if we get a crash.
|
||||
gdb -return-child-result -quiet -batch \
|
||||
-ex "set env MALLOC_CHECK_=3" \
|
||||
-ex "set print thread-events off" \
|
||||
-ex run \
|
||||
-ex "thread apply all backtrace full" \
|
||||
-ex "quit" \
|
||||
--args $APP_PATH $APP_ARGS
|
||||
if [[ ${TARGET} == debug ]]; then
|
||||
# Execute unit tests under gdb, printing a call stack
|
||||
# if we get a crash.
|
||||
$GDB_ROOT/bin/gdb -return-child-result -quiet -batch \
|
||||
-ex "set env MALLOC_CHECK_=3" \
|
||||
-ex "set print thread-events off" \
|
||||
-ex run \
|
||||
-ex "thread apply all backtrace full" \
|
||||
-ex "quit" \
|
||||
--args $APP_PATH $APP_ARGS
|
||||
else
|
||||
$APP_PATH $APP_ARGS
|
||||
fi
|
||||
|
||||
if [[ $TARGET == "coverage" ]]; then
|
||||
# Create test coverage data file
|
||||
@@ -87,6 +97,8 @@ if [[ $TARGET == "coverage" ]]; then
|
||||
|
||||
# Push the results (lcov.info) to codecov
|
||||
codecov -X gcov # don't even try and look for .gcov files ;)
|
||||
|
||||
find . -name "*.gcda" | xargs rm -f
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ TWD=$( cd ${TWD:-${1:-${PWD:-$( pwd )}}}; pwd )
|
||||
echo "Target path is: $TWD"
|
||||
# Override gcc version to $GCC_VER.
|
||||
# Put an appropriate symlink at the front of the path.
|
||||
mkdir -v $HOME/bin
|
||||
mkdir -pv $HOME/bin
|
||||
for g in gcc g++ gcov gcc-ar gcc-nm gcc-ranlib
|
||||
do
|
||||
test -x $( type -p ${g}-$GCC_VER )
|
||||
@@ -66,3 +66,17 @@ tar xfvz lcov-1.12.tar.gz -C $HOME
|
||||
# Set install path
|
||||
mkdir -p $LCOV_ROOT
|
||||
cd $HOME/lcov-1.12 && make install PREFIX=$LCOV_ROOT
|
||||
|
||||
|
||||
if [[ ${TARGET} == debug && ! -x ${GDB_ROOT}/bin/gdb ]]; then
|
||||
pushd $HOME
|
||||
#install gdb
|
||||
wget https://ftp.gnu.org/gnu/gdb/gdb-8.0.tar.xz
|
||||
tar xf gdb-8.0.tar.xz
|
||||
pushd gdb-8.0
|
||||
./configure CFLAGS='-w -O2' CXXFLAGS='-std=gnu++11 -g -O2 -w' --prefix=$GDB_ROOT
|
||||
make -j2
|
||||
make install
|
||||
popd
|
||||
popd
|
||||
fi
|
||||
|
||||
@@ -16,7 +16,7 @@ then
|
||||
tar xzf /tmp/boost.tar.gz
|
||||
cd $BOOST_ROOT && \
|
||||
./bootstrap.sh --prefix=$BOOST_ROOT && \
|
||||
./b2 -d1 define=_GLIBCXX_USE_CXX11_ABI=0 -j${NUM_PROCESSORS:-2} &&\
|
||||
./b2 -d1 define=_GLIBCXX_USE_CXX11_ABI=0 -j$((2*${NUM_PROCESSORS:-2})) &&\
|
||||
./b2 -d0 define=_GLIBCXX_USE_CXX11_ABI=0 install
|
||||
else
|
||||
echo "Using cached boost at $BOOST_ROOT"
|
||||
|
||||
@@ -8,7 +8,7 @@ dependencies:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get purge -qq libboost1.48-dev
|
||||
- sudo apt-get install -qq libboost1.60-all-dev
|
||||
- sudo apt-get install -qq clang-3.6 gcc-5 g++-5 libobjc-5-dev libgcc-5-dev libstdc++-5-dev libclang1-3.6 libgcc1 libgomp1 libstdc++6 scons protobuf-compiler libprotobuf-dev libssl-dev exuberant-ctags
|
||||
- sudo apt-get install -qq clang-3.6 gcc-5 g++-5 libobjc-5-dev libgcc-5-dev libstdc++-5-dev libclang1-3.6 libgcc1 libgomp1 libstdc++6 scons protobuf-compiler libprotobuf-dev libssl-dev exuberant-ctags texinfo
|
||||
- lsb_release -a
|
||||
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 99
|
||||
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 99
|
||||
@@ -16,6 +16,11 @@ dependencies:
|
||||
- gcc --version
|
||||
- clang --version
|
||||
- clang++ --version
|
||||
- if [[ ! -e gdb-8.0 ]]; then wget https://ftp.gnu.org/gnu/gdb/gdb-8.0.tar.xz && tar xf gdb-8.0.tar.xz && cd gdb-8.0 && ./configure && make && cd ..; fi
|
||||
- pushd gdb-8.0 && sudo make install && popd
|
||||
- gdb --version
|
||||
cache_directories:
|
||||
- gdb-8.0
|
||||
test:
|
||||
pre:
|
||||
- scons clang.debug
|
||||
|
||||
@@ -172,6 +172,13 @@
|
||||
# NOTE If no ports support the peer protocol, rippled cannot
|
||||
# receive incoming peer connections or become a superpeer.
|
||||
#
|
||||
# limit = <number>
|
||||
#
|
||||
# Optional. An integer value that will limit the number of connected
|
||||
# clients that the port will accept. Once the limit is reached, new
|
||||
# connections will be refused until other clients disconnect.
|
||||
# Omit or set to 0 to allow unlimited numbers of clients.
|
||||
#
|
||||
# user = <text>
|
||||
# password = <text>
|
||||
#
|
||||
|
||||
@@ -480,69 +480,87 @@ struct Ledger
|
||||
//... implementation specific
|
||||
};
|
||||
```
|
||||
[heading Generic Consensus Interface]
|
||||
|
||||
Following the
|
||||
[@https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern CRTP]
|
||||
idiom, generic =Consensus= relies on a deriving class implementing a set of
|
||||
helpers and callbacks that encapsulate implementation specific details of the
|
||||
algorithm. Below are excerpts of the generic consensus implementation and of
|
||||
helper types that will interact with the concrete implementing class.
|
||||
|
||||
[heading PeerProposal] The =PeerProposal= type represents the signed position taken
|
||||
by a peer during consensus. The only type requirement is owning an instance of a
|
||||
generic =ConsensusProposal=.
|
||||
```
|
||||
|
||||
// Represents our proposed position or a peer's proposed position
|
||||
// and is provided with the generic code
|
||||
template <class NodeID_t, class LedgerID_t, class Position_t> class ConsensusProposal;
|
||||
|
||||
struct PeerPosition
|
||||
{
|
||||
ConsensusProposal<
|
||||
NodeID_t,
|
||||
typename Ledger::ID,
|
||||
typename TxSet::ID> const &
|
||||
proposal() const;
|
||||
|
||||
// ... implementation specific
|
||||
};
|
||||
```
|
||||
[heading Generic Consensus Interface]
|
||||
|
||||
The generic =Consensus= relies on =Adaptor= template class to implement a set
|
||||
of helper functions that plug the consensus algorithm into a specific application.
|
||||
The =Adaptor= class also defines the types above needed by the algorithm. Below
|
||||
are excerpts of the generic consensus implementation and of helper types that will
|
||||
interact with the concrete implementing class.
|
||||
|
||||
```
|
||||
// Represents a transction under dispute this round
|
||||
template <class Tx_t, class NodeID_t> class DisputedTx;
|
||||
|
||||
template <class Derived, class Traits> class Consensus
|
||||
// Represents how the node participates in Consensus this round
|
||||
enum class ConsensusMode { proposing, observing, wrongLedger, switchedLedger};
|
||||
|
||||
// Measure duration of phases of consensus
|
||||
class ConsensusTimer
|
||||
{
|
||||
protected:
|
||||
enum class Mode { proposing, observing, wrongLedger, switchedLedger};
|
||||
|
||||
// Measure duration of phases of consensus
|
||||
class Stopwatch
|
||||
{
|
||||
public:
|
||||
std::chrono::milliseconds read() const;
|
||||
// details omitted ...
|
||||
};
|
||||
|
||||
// Initial ledger close times, not rounded by closeTimeResolution
|
||||
// Used to gauge degree of synchronization between a node and its peers
|
||||
struct CloseTimes
|
||||
{
|
||||
std::map<NetClock::time_point, int> peers;
|
||||
NetClock::time_point self;
|
||||
};
|
||||
|
||||
// Encapsulates the result of consensus.
|
||||
struct Result
|
||||
{
|
||||
//! The set of transactions consensus agrees go in the ledger
|
||||
TxSet_t set;
|
||||
|
||||
//! Our proposed position on transactions/close time
|
||||
Proposal_t position;
|
||||
|
||||
//! Transactions which are under dispute with our peers
|
||||
using Dispute_t = DisputedTx<Tx_t, NodeID_t>;
|
||||
hash_map<typename Tx_t::ID, Dispute_t> disputes;
|
||||
|
||||
// Set of TxSet ids we have already compared/created disputes
|
||||
hash_set<typename TxSet_t::ID> compares;
|
||||
|
||||
// Measures the duration of the establish phase for this consensus round
|
||||
Stopwatch roundTime;
|
||||
|
||||
// Indicates state in which consensus ended. Once in the accept phase
|
||||
// will be either Yes or MovedOn
|
||||
ConsensusState state = ConsensusState::No;
|
||||
};
|
||||
|
||||
public:
|
||||
std::chrono::milliseconds read() const;
|
||||
// details omitted ...
|
||||
};
|
||||
|
||||
// Initial ledger close times, not rounded by closeTimeResolution
|
||||
// Used to gauge degree of synchronization between a node and its peers
|
||||
struct ConsensusCloseTimes
|
||||
{
|
||||
std::map<NetClock::time_point, int> peers;
|
||||
NetClock::time_point self;
|
||||
};
|
||||
|
||||
// Encapsulates the result of consensus.
|
||||
template <class Adaptor>
|
||||
struct ConsensusResult
|
||||
{
|
||||
//! The set of transactions consensus agrees go in the ledger
|
||||
Adaptor::TxSet_t set;
|
||||
|
||||
//! Our proposed position on transactions/close time
|
||||
ConsensusProposal<...> position;
|
||||
|
||||
//! Transactions which are under dispute with our peers
|
||||
hash_map<Adaptor::Tx_t::ID, DisputedTx<...>> disputes;
|
||||
|
||||
// Set of TxSet ids we have already compared/created disputes
|
||||
hash_set<typename Adaptor::TxSet_t::ID> compares;
|
||||
|
||||
// Measures the duration of the establish phase for this consensus round
|
||||
ConsensusTimer roundTime;
|
||||
|
||||
// Indicates state in which consensus ended. Once in the accept phase
|
||||
// will be either Yes or MovedOn
|
||||
ConsensusState state = ConsensusState::No;
|
||||
};
|
||||
|
||||
template <class Adaptor>
|
||||
class Consensus
|
||||
{
|
||||
public:
|
||||
Consensus(clock_type, Adaptor &, beast::journal);
|
||||
|
||||
// Kick-off the next round of consensus.
|
||||
void startRound(
|
||||
NetClock::time_point const& now,
|
||||
@@ -568,26 +586,20 @@ public:
|
||||
The stub below shows the set of callback/helper functions required in the implementing class.
|
||||
|
||||
```
|
||||
struct Traits
|
||||
struct Adaptor
|
||||
{
|
||||
using Ledger_t = Ledger;
|
||||
using TxSet_t = TxSet;
|
||||
using NodeID_t = ...; // Integer-like std::uint32_t to uniquely identify a node
|
||||
using Ledger_t = Ledger;
|
||||
using TxSet_t = TxSet;
|
||||
using PeerProposal_t = PeerProposal;
|
||||
using NodeID_t = ...; // Integer-like std::uint32_t to uniquely identify a node
|
||||
|
||||
};
|
||||
|
||||
class ConsensusImp : public Consensus<ConsensusImp, Traits>
|
||||
{
|
||||
// Attempt to acquire a specific ledger from the network.
|
||||
boost::optional<Ledger> acquireLedger(Ledger::ID const & ledgerID);
|
||||
|
||||
// Acquire the transaction set associated with a proposed position.
|
||||
boost::optional<TxSet> acquireTxSet(TxSet::ID const & setID);
|
||||
|
||||
// Get peers' proposed positions. Returns an iterable
|
||||
// with value_type convertable to ConsensusPosition<...>
|
||||
auto const & proposals(Ledger::ID const & ledgerID);
|
||||
|
||||
// Whether any transactions are in the open ledger
|
||||
bool hasOpenTransactions() const;
|
||||
|
||||
@@ -602,24 +614,27 @@ class ConsensusImp : public Consensus<ConsensusImp, Traits>
|
||||
// application thinks consensus should use as the prior ledger.
|
||||
Ledger::ID getPrevLedger(Ledger::ID const & prevLedgerID,
|
||||
Ledger const & prevLedger,
|
||||
Mode mode);
|
||||
ConsensusMode mode);
|
||||
|
||||
// Called when consensus operating mode changes
|
||||
void onModeChange(ConsensuMode before, ConsensusMode after);
|
||||
|
||||
// Called when ledger closes. Implementation should generate an initial Result
|
||||
// with position based on the current open ledger's transactions.
|
||||
Result onClose(Ledger const &, Ledger const & prev, Mode mode);
|
||||
ConsensusResult onClose(Ledger const &, Ledger const & prev, ConsensusMode mode);
|
||||
|
||||
// Called when ledger is accepted by consensus
|
||||
void onAccept(Result const & result,
|
||||
void onAccept(ConsensusResult const & result,
|
||||
RCLCxLedger const & prevLedger,
|
||||
NetClock::duration closeResolution,
|
||||
CloseTimes const & rawCloseTimes,
|
||||
Mode const & mode);
|
||||
ConsensusCloseTimes const & rawCloseTimes,
|
||||
ConsensusMode const & mode);
|
||||
|
||||
// Propose the position to peers.
|
||||
void propose(ConsensusProposal<...> const & pos);
|
||||
|
||||
// Relay a received peer proposal on to other peer's.
|
||||
void relay(ConsensusProposal<...> const & pos);
|
||||
void relay(PeerPosition_t const & pos);
|
||||
|
||||
// Relay a disputed transaction to peers
|
||||
void relay(TxSet::Tx const & tx);
|
||||
|
||||
@@ -111,8 +111,11 @@ INPUT = \
|
||||
../src/test/jtx/WSClient.h \
|
||||
../src/ripple/consensus/Consensus.h \
|
||||
../src/ripple/consensus/ConsensusProposal.h \
|
||||
../src/ripple/consensus/ConsensusTypes.h \
|
||||
../src/ripple/consensus/DisputedTx.h \
|
||||
../src/ripple/consensus/LedgerTiming.h \
|
||||
../src/ripple/consensus/Validations.h \
|
||||
../src/ripple/consensus/ConsensusParms.h \
|
||||
../src/ripple/app/consensus/RCLCxTx.h \
|
||||
../src/ripple/app/consensus/RCLCxLedger.h \
|
||||
../src/ripple/app/consensus/RCLConsensus.h \
|
||||
@@ -120,6 +123,7 @@ INPUT = \
|
||||
../src/ripple/app/tx/apply.h \
|
||||
../src/ripple/app/tx/applySteps.h \
|
||||
../src/ripple/app/tx/impl/InvariantCheck.h \
|
||||
../src/ripple/app/consensus/RCLValidations.h \
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS =
|
||||
|
||||
23
src/beast/.github/ISSUE_TEMPLATE.md
vendored
Normal file
23
src/beast/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
PLEASE DON'T FORGET TO "STAR" THIS REPOSITORY :)
|
||||
|
||||
When reporting a bug please include the following:
|
||||
|
||||
### Version of Beast
|
||||
|
||||
You can find the version number in <beast/version.hpp>
|
||||
or using the command "git log -1".
|
||||
|
||||
### Steps necessary to reproduce the problem
|
||||
|
||||
A small compiling program is the best. If your code is
|
||||
public, you can provide a link to the repository.
|
||||
|
||||
### All relevant compiler information
|
||||
|
||||
If you are unable to compile please include the type and
|
||||
version of compiler you are using as well as all compiler
|
||||
output including the error message, file, and line numbers
|
||||
involved.
|
||||
|
||||
The more information you provide the sooner your issue
|
||||
can get resolved!
|
||||
5
src/beast/.gitignore
vendored
5
src/beast/.gitignore
vendored
@@ -1,2 +1,7 @@
|
||||
bin/
|
||||
bin64/
|
||||
|
||||
# Because of CMake and VS2017
|
||||
Win32/
|
||||
x64/
|
||||
|
||||
|
||||
@@ -11,17 +11,15 @@ env:
|
||||
# to boost's .tar.gz.
|
||||
- LCOV_ROOT=$HOME/lcov
|
||||
- VALGRIND_ROOT=$HOME/valgrind-install
|
||||
- BOOST_ROOT=$HOME/boost_1_61_0
|
||||
- BOOST_URL='http://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz'
|
||||
- BOOST_ROOT=$HOME/boost_1_58_0
|
||||
- BOOST_URL='http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz'
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages:
|
||||
- gcc-5
|
||||
- g++-5
|
||||
sources: &base_sources
|
||||
- ubuntu-toolchain-r-test
|
||||
packages: &base_packages
|
||||
- python-software-properties
|
||||
- libssl-dev
|
||||
- libffi-dev
|
||||
- libstdc++6
|
||||
- binutils-gold
|
||||
@@ -35,35 +33,81 @@ addons:
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# GCC/Coverage/Autobahn (if master or develop branch)
|
||||
# gcc coverage
|
||||
- compiler: gcc
|
||||
env:
|
||||
- GCC_VER=6
|
||||
- VARIANT=coverage
|
||||
- ADDRESS_MODEL=64
|
||||
- DO_VALGRIND=false
|
||||
- BUILD_SYSTEM=cmake
|
||||
- PATH=$PWD/cmake/bin:$PATH
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-6
|
||||
- g++-6
|
||||
- libssl-dev
|
||||
- *base_packages
|
||||
sources:
|
||||
- *base_sources
|
||||
|
||||
# older GCC, release
|
||||
- compiler: gcc
|
||||
env:
|
||||
- GCC_VER=4.8
|
||||
- VARIANT=release
|
||||
- DO_VALGRIND=false
|
||||
- ADDRESS_MODEL=64
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-4.8
|
||||
- g++-4.8
|
||||
- *base_packages
|
||||
sources:
|
||||
- *base_sources
|
||||
|
||||
# later GCC
|
||||
- compiler: gcc
|
||||
env:
|
||||
- GCC_VER=5
|
||||
- VARIANT=coverage
|
||||
- VARIANT=release
|
||||
- DO_VALGRIND=true
|
||||
- ADDRESS_MODEL=64
|
||||
- BUILD_SYSTEM=cmake
|
||||
- PATH=$PWD/cmake/bin:$PATH
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-5
|
||||
- g++-5
|
||||
- libssl-dev
|
||||
- *base_packages
|
||||
sources:
|
||||
- *base_sources
|
||||
|
||||
# Clang/UndefinedBehaviourSanitizer
|
||||
# clang ubsan+asan
|
||||
- compiler: clang
|
||||
env:
|
||||
- GCC_VER=5
|
||||
- VARIANT=usan
|
||||
- VARIANT=ubasan
|
||||
- CLANG_VER=3.8
|
||||
- DO_VALGRIND=false
|
||||
- ADDRESS_MODEL=64
|
||||
- UBSAN_OPTIONS='print_stacktrace=1'
|
||||
- BUILD_SYSTEM=cmake
|
||||
- PATH=$PWD/cmake/bin:$PATH
|
||||
- PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH
|
||||
|
||||
# Clang/AddressSanitizer
|
||||
- compiler: clang
|
||||
env:
|
||||
- GCC_VER=5
|
||||
- VARIANT=asan
|
||||
- CLANG_VER=3.8
|
||||
- ADDRESS_MODEL=64
|
||||
- PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-5
|
||||
- g++-5
|
||||
- libssl-dev
|
||||
- *base_packages
|
||||
sources:
|
||||
- *base_sources
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -72,7 +116,7 @@ cache:
|
||||
- llvm-$LLVM_VERSION
|
||||
- cmake
|
||||
|
||||
before_install:
|
||||
before_install: &base_before_install
|
||||
- scripts/install-dependencies.sh
|
||||
|
||||
script:
|
||||
|
||||
@@ -1,3 +1,829 @@
|
||||
Version 79:
|
||||
|
||||
* Remove spurious fallthrough guidance
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 78:
|
||||
|
||||
* Add span
|
||||
* Documentation work
|
||||
* Use make_unique_noinit
|
||||
* Fix warning in zlib
|
||||
* Header file tidying
|
||||
* Tidy up FieldsReader doc
|
||||
* Add Boost.Locale utf8 benchmark comparison
|
||||
* Tidy up dstream for existing Boost versions
|
||||
* Tidy up file_posix unused variable
|
||||
* Fix warning in root ca declaration
|
||||
|
||||
HTTP:
|
||||
|
||||
* Tidy up basic_string_body
|
||||
* Add vector_body
|
||||
* span, string, vector bodies are public
|
||||
* Fix spurious uninitialized warning
|
||||
* fields temp string uses allocator
|
||||
|
||||
API Changes:
|
||||
|
||||
* Add message::keep_alive()
|
||||
* Add message::chunked() and message::content_length()
|
||||
* Remove string_view_body
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Change user defined implementations of Fields and
|
||||
FieldsReader to meet the new requirements.
|
||||
|
||||
* Use span_body<char> instead of string_view_body
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 77:
|
||||
|
||||
* file_posix works without large file support
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 76:
|
||||
|
||||
* Always go through write_some
|
||||
* Use Boost.Config
|
||||
* BodyReader may construct from a non-const message
|
||||
* Add serializer::get
|
||||
* Add serializer::chunked
|
||||
* Serializer members are not const
|
||||
* serializing file_body is not const
|
||||
* Add file_body_win32
|
||||
* Fix parse illegal characters in obs-fold
|
||||
* Disable SSE4.2 optimizations
|
||||
|
||||
API Changes:
|
||||
|
||||
* Rename to serializer::keep_alive
|
||||
* BodyReader, BodyWriter use two-phase init
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Use serializer::keep_alive instead of serializer::close and
|
||||
take the logical NOT of the return value.
|
||||
|
||||
* Modify instances of user-defined BodyReader and BodyWriter
|
||||
types to perfrom two-phase initialization, as per the
|
||||
updated documented type requirements.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 75:
|
||||
|
||||
* Use file_body for valid requests, string_body otherwise.
|
||||
* Construct buffer_prefix_view in-place
|
||||
* Shrink serializer buffers using buffers_ref
|
||||
* Tidy up BEAST_NO_BIG_VARIANTS
|
||||
* Shrink serializer buffers using buffers_ref
|
||||
* Add serializer::limit
|
||||
* file_body tests
|
||||
* Using SSE4.2 intrinsics in basic_parser if available
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 74:
|
||||
|
||||
* Add file_stdio and File concept
|
||||
* Add file_win32
|
||||
* Add file_body
|
||||
* Remove common/file_body.hpp
|
||||
* Add file_posix
|
||||
* Fix Beast include directories for cmake targets
|
||||
* remove redundant flush() from example
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 73:
|
||||
|
||||
* Jamroot tweak
|
||||
* Verify certificates in SSL clients
|
||||
* Adjust benchmarks
|
||||
* Initialize local variable in basic_parser
|
||||
* Fixes for gcc-4.8
|
||||
|
||||
HTTP:
|
||||
|
||||
* basic_parser optimizations
|
||||
* Add basic_parser tests
|
||||
|
||||
API Changes:
|
||||
|
||||
* Refactor header and message constructors
|
||||
* serializer::next replaces serializer::get
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Evaluate each message constructor call site and
|
||||
adjust the constructor argument list as needed.
|
||||
|
||||
* Use serializer::next instead of serializer::get at call sites
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 72:
|
||||
|
||||
HTTP:
|
||||
|
||||
* Tidy up set payload in http-server-fast
|
||||
* Refine Body::size specification
|
||||
* Newly constructed responses have a 200 OK result
|
||||
* Refactor file_body for best practices
|
||||
* Add http-server-threaded example
|
||||
* Documentation tidying
|
||||
* Various improvements to http_server_fast.cpp
|
||||
|
||||
WebSocket:
|
||||
|
||||
* Add websocket-server-async example
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 71:
|
||||
|
||||
* Fix extra ; warning
|
||||
* Documentation revision
|
||||
* Fix spurious on_chunk invocation
|
||||
* Call prepare_payload in HTTP example
|
||||
* Check trailers in test
|
||||
* Fix buffer overflow handling for string_body and mutable_body
|
||||
* Concept check in basic_dynamic_body
|
||||
* Tidy up http_sync_port error check
|
||||
* Tidy up Jamroot /permissive-
|
||||
|
||||
WebSockets:
|
||||
|
||||
* Fine tune websocket op asserts
|
||||
* Refactor websocket composed ops
|
||||
* Allow close, ping, and write to happen concurrently
|
||||
* Fix race in websocket read op
|
||||
* Fix websocket write op
|
||||
* Add cmake options for examples and tests
|
||||
|
||||
API Changes:
|
||||
|
||||
* Return `std::size_t` from `Body::writer::put`
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Return the number of bytes actually transferred from the
|
||||
input buffers in user defined `Body::writer::put` functions.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 70:
|
||||
|
||||
* Serialize in one step when possible
|
||||
* Add basic_parser header and body limits
|
||||
* Add parser::on_header to set a callback
|
||||
* Fix BEAST_FALLTHROUGH
|
||||
* Fix HEAD response in file_service
|
||||
|
||||
API Changes:
|
||||
|
||||
* Rename to message::base
|
||||
* basic_parser default limits are now 1MB/8MB
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Change calls to message::header_part() with message::base()
|
||||
|
||||
* Call body_limit and/or header_limit as needed to adjust the
|
||||
limits to suitable values if the defaults are insufficient.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 69:
|
||||
|
||||
* basic_parser optimizations
|
||||
* Use BEAST_FALLTHROUGH to silence warnings
|
||||
* Add /permissive- to msvc toolchain
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 68:
|
||||
|
||||
* Split common tests to a new project
|
||||
* Small speed up in fields comparisons
|
||||
* Adjust buffer size in fast server
|
||||
* Use string_ref in older Boost versions
|
||||
* Optimize field lookups
|
||||
* Add const_body, mutable_body to examples
|
||||
* Link statically on cmake MSVC
|
||||
|
||||
API Changes:
|
||||
|
||||
* Change BodyReader, BodyWriter requirements
|
||||
* Remove BodyReader::is_deferred
|
||||
* http::error::bad_target replaces bad_path
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Change user defined instances of BodyReader and BodyWriter
|
||||
to meet the new requirements.
|
||||
|
||||
* Replace references to http::error::bad_path with http::error::bad_target
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 67:
|
||||
|
||||
* Fix doc example link
|
||||
* Add http-server-small example
|
||||
* Merge stream_base to stream and tidy
|
||||
* Use boost::string_view
|
||||
* Rename to http-server-fast
|
||||
* Appveyor use Boost 1.64.0
|
||||
* Group common example headers
|
||||
|
||||
API Changes:
|
||||
|
||||
* control_callback replaces ping_callback
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Change calls to websocket::stream::ping_callback to use
|
||||
websocket::stream::control_callback
|
||||
|
||||
* Change user defined ping callbacks to have the new
|
||||
signature and adjust the callback definition appropriately.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 66:
|
||||
|
||||
* string_param optimizations
|
||||
* Add serializer request/response aliases
|
||||
* Make consuming_buffers smaller
|
||||
* Fix costly potential value-init in parser
|
||||
* Fix unused parameter warning
|
||||
* Handle bad_alloc in parser
|
||||
* Tidy up message piecewise ctors
|
||||
* Add header aliases
|
||||
* basic_fields optimizations
|
||||
* Add http-server example
|
||||
* Squelch spurious warning on gcc
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 65:
|
||||
|
||||
* Enable narrowing warning on msvc cmake
|
||||
* Fix integer types in deflate_stream::bi_reverse
|
||||
* Fix narrowing in static_ostream
|
||||
* Fix narrowing in ostream
|
||||
* Fix narrowing in inflate_stream
|
||||
* Fix narrowing in deflate_stream
|
||||
* Fix integer warnings
|
||||
* Enable unused variable warning on msvc cmake
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 64:
|
||||
|
||||
* Simplify buffered_read_stream composed op
|
||||
* Simplify ssl teardown composed op
|
||||
* Simplify websocket write_op
|
||||
* Exemplars are compiled code
|
||||
* Better User-Agent in examples
|
||||
* async_write requires a non-const message
|
||||
* Doc tidying
|
||||
* Add link_directories to cmake
|
||||
|
||||
API Changes:
|
||||
|
||||
* Remove make_serializer
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Replace calls to make_serializer with variable declarations
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 63:
|
||||
|
||||
* Use std::to_string instead of lexical_cast
|
||||
* Don't use cached Boost
|
||||
* Put num_jobs back up on Travis
|
||||
* Only build and run tests in variant=coverage
|
||||
* Move benchmarks to a separate project
|
||||
* Only run the tests under ubasan
|
||||
* Tidy up CMakeLists.txt
|
||||
* Tidy up Jamfiles
|
||||
* Control running with valgrind explicitly
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 62:
|
||||
|
||||
* Remove libssl-dev from a Travis matrix item
|
||||
* Increase detail::static_ostream coverage
|
||||
* Add server-framework tests
|
||||
* Doc fixes and tidy
|
||||
* Tidy up namespaces in examples
|
||||
* Clear the error faster
|
||||
* Avoid explicit operator bool for error
|
||||
* Add http::is_fields trait
|
||||
* Squelch harmless not_connected errors
|
||||
* Put slow tests back for coverage builds
|
||||
|
||||
API Changes:
|
||||
|
||||
* parser requires basic_fields
|
||||
* Refine FieldsReader concept
|
||||
* message::prepare_payload replaces message::prepare
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Callers using `parser` with Fields types other than basic_fields
|
||||
will need to create their own subclass of basic_parser to work
|
||||
with their custom fields type.
|
||||
|
||||
* Implement chunked() and keep_alive() for user defined FieldsReader types.
|
||||
|
||||
* Change calls to msg.prepare to msg.prepare_payload. For messages
|
||||
with a user-defined Fields, provide the function prepare_payload_impl
|
||||
in the fields type according to the Fields requirements.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 61:
|
||||
|
||||
* Remove Spirit dependency
|
||||
* Use generic_cateogry for errno
|
||||
* Reorganize SSL examples
|
||||
* Tidy up some integer conversion warnings
|
||||
* Add message::header_part()
|
||||
* Tidy up names in error categories
|
||||
* Flush the output stream in the example
|
||||
* Clean close in Secure WebSocket client
|
||||
* Add server-framework SSL HTTP and WebSocket ports
|
||||
* Fix shadowing warnings
|
||||
* Tidy up http-crawl example
|
||||
* Add multi_port to server-framework
|
||||
* Tidy up resolver calls
|
||||
* Use one job on CI
|
||||
* Don't run slow tests on certain targets
|
||||
|
||||
API Changes:
|
||||
|
||||
* header::version is unsigned
|
||||
* status-codes is unsigned
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 60:
|
||||
|
||||
* String comparisons are public interfaces
|
||||
* Fix response message type in async websocket accept
|
||||
* New server-framework, full featured server example
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 59:
|
||||
|
||||
* Integrated Beast INTERFACE (cmake)
|
||||
* Fix base64 alphabet
|
||||
* Remove obsolete doc/README.md
|
||||
|
||||
API Changes:
|
||||
|
||||
* Change Body::size signature (API Change):
|
||||
|
||||
Actions Required:
|
||||
|
||||
* For any user-defined models of Body, change the function signature
|
||||
to accept `value_type const&` and modify the function definition
|
||||
accordingly.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 58:
|
||||
|
||||
* Fix unaligned reads in utf8-checker
|
||||
* Qualify size_t in message template
|
||||
* Reorganize examples
|
||||
* Specification for http read
|
||||
* Avoid `std::string` in websocket
|
||||
* Fix basic_fields insert ordering
|
||||
* basic_fields::set optimization
|
||||
* basic_parser::put doc
|
||||
* Use static string in basic_fields::reader
|
||||
* Remove redundant code
|
||||
* Fix parsing chunk size with leading zeroes
|
||||
* Better message formal parameter names
|
||||
|
||||
API Changes:
|
||||
|
||||
* `basic_fields::set` renamed from `basic_fields::replace`
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Rename calls to `basic_fields::replace` to `basic_fields::set`
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 57:
|
||||
|
||||
* Fix message.hpp javadocs
|
||||
* Fix warning in basic_parser.cpp
|
||||
* Integrate docca for documentation and tidy
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 56:
|
||||
|
||||
* Add provisional IANA header field names
|
||||
* Add string_view_body
|
||||
* Call on_chunk when the extension is empty
|
||||
* HTTP/1.1 is the default version
|
||||
* Try harder to find Boost (cmake)
|
||||
* Reset error codes
|
||||
* More basic_parser tests
|
||||
* Add an INTERFACE cmake target
|
||||
* Convert buffer in range loops
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 55:
|
||||
|
||||
* Don't allocate memory to handle obs-fold
|
||||
* Avoid a parser allocation using non-flat buffer
|
||||
* read_size replaces read_size_helper
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 54:
|
||||
|
||||
* static_buffer coverage
|
||||
* flat_buffer coverage
|
||||
* multi_buffer coverage
|
||||
* consuming_buffers members and coverage
|
||||
* basic_fields members and coverage
|
||||
* Add string_param
|
||||
* Retain ownership when reading using a message
|
||||
* Fix incorrect use of [[fallthrough]]
|
||||
|
||||
API Changes:
|
||||
|
||||
* basic_fields refactor
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 53:
|
||||
|
||||
* Fix basic_parser::maybe_flatten
|
||||
* Fix read_size_helper usage
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 52:
|
||||
|
||||
* flat_buffer is an AllocatorAwareContainer
|
||||
* Add drain_buffer class
|
||||
|
||||
API Changes:
|
||||
|
||||
* `auto_fragment` is a member of `stream`
|
||||
* `binary`, `text` are members of `stream`
|
||||
* read_buffer_size is a member of `stream`
|
||||
* read_message_max is a member of `stream`
|
||||
* `write_buffer_size` is a member of `stream`
|
||||
* `ping_callback` is a member of stream
|
||||
* Remove `opcode` from `read`, `async_read`
|
||||
* `read_frame` returns `bool` fin
|
||||
* `opcode` is private
|
||||
* finish(error_code&) is a BodyReader requirement
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Change call sites which use `auto_fragment` with `set_option`
|
||||
to call `stream::auto_fragment` instead.
|
||||
|
||||
* Change call sites which use message_type with `set_option`
|
||||
to call `stream::binary` or `stream::text` instead.
|
||||
|
||||
* Change call sites which use `read_buffer_size` with `set_option` to
|
||||
call `stream::read_buffer_size` instead.
|
||||
|
||||
* Change call sites which use `read_message_max` with `set_option` to
|
||||
call `stream::read_message_max` instead.
|
||||
|
||||
* Change call sites which use `write_buffer_size` with `set_option` to
|
||||
call `stream::write_buffer_size` instead.
|
||||
|
||||
* Change call sites which use `ping_callback1 with `set_option` to
|
||||
call `stream::ping_callback` instead.
|
||||
|
||||
* Remove the `opcode` reference parameter from calls to synchronous
|
||||
and asynchronous read functions, replace the logic with calls to
|
||||
`stream::got_binary` and `stream::got_text` instead.
|
||||
|
||||
* Remove the `frame_info` parameter from all read frame call sites
|
||||
|
||||
* Check the return value 'fin' for calls to `read_frame`
|
||||
|
||||
* Change ReadHandlers passed to `async_read_frame` to have
|
||||
the signature `void(error_code, bool fin)`, use the `bool`
|
||||
to indicate if the frame is the last frame.
|
||||
|
||||
* Remove all occurrences of the `opcode` enum at call sites
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 51
|
||||
|
||||
* Fix operator<< for header
|
||||
* Tidy up file_body
|
||||
* Fix file_body::get() not setting the more flag correctly
|
||||
* Use BOOST_FALLTHROUGH
|
||||
* Use BOOST_STRINGIZE
|
||||
* DynamicBuffer benchmarks
|
||||
* Add construct, destroy to handler_alloc
|
||||
* Fix infinite loop in basic_parser
|
||||
|
||||
API Changes:
|
||||
|
||||
* Tune up static_buffer
|
||||
* multi_buffer implementation change
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Call sites passing a number to multi_buffer's constructor
|
||||
will need to be adjusted, see the corresponding commit message.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 50
|
||||
|
||||
* parser is constructible from other body types
|
||||
* Add field enumeration
|
||||
* Use allocator more in basic_fields
|
||||
* Fix basic_fields allocator awareness
|
||||
* Use field in basic_fields and call sites
|
||||
* Use field in basic_parser
|
||||
* Tidy up basic_fields, header, and field concepts
|
||||
* Fields concept work
|
||||
* Body documentation work
|
||||
* Add missing handler_alloc nested types
|
||||
* Fix chunk delimiter parsing
|
||||
* Fix test::pipe read_size
|
||||
* Fix chunk header parsing
|
||||
|
||||
API Changes:
|
||||
|
||||
* Remove header_parser
|
||||
* Add verb to on_request for parsers
|
||||
* Refactor prepare
|
||||
* Protect basic_fields special members
|
||||
* Remove message connection settings
|
||||
* Remove message free functions
|
||||
* Remove obsolete serializer allocator
|
||||
* http read_some, async_read_some don't return bytes
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 49
|
||||
|
||||
* Use <iosfwd> instead of <ostream>
|
||||
|
||||
HTTP:
|
||||
|
||||
* Add HEAD request example
|
||||
|
||||
API Changes:
|
||||
|
||||
* Refactor method and verb
|
||||
* Canonicalize string_view parameter types
|
||||
* Tidy up empty_body writer error
|
||||
* Refactor header status, reason, and target
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 48
|
||||
|
||||
* Make buffer_prefix_view public
|
||||
* Remove detail::sync_ostream
|
||||
* Tidy up core type traits
|
||||
|
||||
API Changes:
|
||||
|
||||
* Tidy up chunk decorator
|
||||
* Rename to buffer_cat_view
|
||||
* Consolidate parsers to parser.hpp
|
||||
* Rename to parser
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 47
|
||||
|
||||
* Disable operator<< for buffer_body
|
||||
* buffer_size overload for basic_multi_buffer::const_buffers_type
|
||||
* Fix undefined behavior in pausation
|
||||
* Fix leak in basic_flat_buffer
|
||||
|
||||
API Changes:
|
||||
|
||||
* Refactor treatment of request-method
|
||||
* Refactor treatment of status code and obsolete reason
|
||||
* Refactor HTTP serialization and parsing
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 46
|
||||
|
||||
* Add test::pipe
|
||||
* Documentation work
|
||||
|
||||
API Changes:
|
||||
|
||||
* Remove HTTP header aliases
|
||||
* Refactor HTTP serialization
|
||||
* Refactor type traits
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 45
|
||||
|
||||
* Workaround for boost::asio::basic_streambuf type check
|
||||
* Fix message doc image
|
||||
* Better test::enable_yield_to
|
||||
* Fix header::reason
|
||||
* Documentation work
|
||||
* buffer_view skips empty buffer sequences
|
||||
* Disable reverse_iterator buffer_view test
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 44
|
||||
|
||||
* Use BOOST_THROW_EXCEPTION
|
||||
* Tidy up read_size_helper and dynamic buffers
|
||||
* Require Boost 1.58.0 or later
|
||||
* Tidy up and make get_lowest_layer public
|
||||
* Use BOOST_STATIC_ASSERT
|
||||
* Fix async return values in docs
|
||||
* Fix README websocket example
|
||||
* Add buffers_adapter regression test
|
||||
* Tidy up is_dynamic_buffer traits test
|
||||
* Make buffers_adapter meet requirements
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 43
|
||||
|
||||
* Require Boost 1.64.0
|
||||
* Fix strict aliasing warnings in buffers_view
|
||||
* Tidy up buffer_prefix overloads and test
|
||||
* Add write limit to test::string_ostream
|
||||
* Additional constructors for consuming_buffers
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 42
|
||||
|
||||
* Fix javadoc typo
|
||||
* Add formal review notes
|
||||
* Make buffers_view a public interface
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 41
|
||||
|
||||
* Trim Appveyor matrix rows
|
||||
* Concept revision and documentation
|
||||
* Remove coveralls integration
|
||||
* Tidy up formal parameter names
|
||||
|
||||
WebSocket
|
||||
|
||||
* Tidy up websocket::close_code enum and constructors
|
||||
|
||||
API Changes
|
||||
|
||||
* Return http::error::end_of_stream on HTTP read eof
|
||||
* Remove placeholders
|
||||
* Rename prepare_buffer(s) to buffer_prefix
|
||||
* Remove handler helpers, tidy up hook invocations
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 40
|
||||
|
||||
* Add to_static_string
|
||||
* Consolidate get_lowest_layer in type_traits.hpp
|
||||
* Fix basic_streambuf movable trait
|
||||
* Tidy up .travis.yml
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 39
|
||||
|
||||
Beast versions are now identified by a single integer which
|
||||
is incremented on each merge. The macro BEAST_VERSION
|
||||
identifies the version number, currently at 39. A version
|
||||
setting commit will always be at the tip of the master
|
||||
and develop branches.
|
||||
|
||||
* Use beast::string_view alias
|
||||
* Fixed braced-init error with older gcc
|
||||
|
||||
HTTP
|
||||
|
||||
* Tidy up basic_parser javadocs
|
||||
|
||||
WebSocket:
|
||||
|
||||
* Add websocket async echo ssl server test:
|
||||
* Fix eof error on ssl::stream shutdown
|
||||
|
||||
API Changes:
|
||||
|
||||
* Refactor http::header contents
|
||||
* New ostream() returns dynamic buffer output stream
|
||||
* New buffers() replaces to_string()
|
||||
* Rename to multi_buffer, basic_multi_buffer
|
||||
* Rename to flat_buffer, basic_flat_buffer
|
||||
* Rename to static_buffer, static_buffer_n
|
||||
* Rename to buffered_read_stream
|
||||
* Harmonize concepts and identifiers with net-ts
|
||||
* Tidy up HTTP reason_string
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b38
|
||||
|
||||
* Refactor static_string
|
||||
* Refactor base64
|
||||
* Use static_string for WebSocket handshakes
|
||||
* Simplify get_lowest_layer test
|
||||
* Add test_allocator to extras/test
|
||||
* More flat_streambuf tests
|
||||
* WebSocket doc work
|
||||
* Prevent basic_fields operator[] assignment
|
||||
|
||||
API Changes:
|
||||
|
||||
* Refactor WebSocket error codes
|
||||
* Remove websocket::keep_alive option
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b37
|
||||
|
||||
* CMake hide command lines in .vcxproj Output windows"
|
||||
* Rename to detail::is_invocable
|
||||
* Rename project to http-bench
|
||||
* Fix flat_streambuf
|
||||
* Add ub sanitizer blacklist
|
||||
* Add -funsigned-char to asan build target
|
||||
* Fix narrowing warning in table constants
|
||||
|
||||
WebSocket:
|
||||
|
||||
* Add is_upgrade() free function
|
||||
* Document websocket::stream thread safety
|
||||
* Rename to websocket::detail::pausation
|
||||
|
||||
API Changes:
|
||||
|
||||
* Provide websocket::stream accept() overloads
|
||||
* Refactor websocket decorators
|
||||
* Move everything in basic_fields.hpp to fields.hpp
|
||||
* Rename to http::dynamic_body, consolidate header
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b36
|
||||
|
||||
* Update README.md
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b35
|
||||
|
||||
* Add Appveyor build scripts and badge
|
||||
* Tidy up MSVC CMake configuration
|
||||
* Make close_code a proper enum
|
||||
* Add flat_streambuf
|
||||
* Rename to BEAST_DOXYGEN
|
||||
* Update .gitignore for VS2017
|
||||
* Fix README.md CMake instructions
|
||||
|
||||
API Changes:
|
||||
|
||||
* New HTTP interfaces
|
||||
* Remove http::empty_body
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
1.0.0-b34
|
||||
|
||||
* Fix and tidy up CMake build scripts
|
||||
|
||||
@@ -2,19 +2,26 @@
|
||||
|
||||
cmake_minimum_required (VERSION 3.5.2)
|
||||
|
||||
project (Beast)
|
||||
project (Beast VERSION 79)
|
||||
|
||||
set_property (GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
option (Beast_BUILD_EXAMPLES "Build examples" ON)
|
||||
option (Beast_BUILD_TESTS "Build tests" ON)
|
||||
|
||||
if (MSVC)
|
||||
# /wd4244 /wd4127
|
||||
set (CMAKE_VERBOSE_MAKEFILE FALSE)
|
||||
|
||||
add_definitions (-D_WIN32_WINNT=0x0601)
|
||||
add_definitions (-D_SCL_SECURE_NO_WARNINGS=1)
|
||||
add_definitions (-D_CRT_SECURE_NO_WARNINGS=1)
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4100 /wd4244 /wd4251 /MP /W4 /bigobj")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GL")
|
||||
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi /Ot")
|
||||
set (Boost_USE_STATIC_LIBS ON)
|
||||
set (Boost_USE_STATIC_RUNTIME ON)
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W4 /bigobj /permissive-")
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GL /MT")
|
||||
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi /Ot /MT")
|
||||
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
@@ -28,11 +35,15 @@ if (MSVC)
|
||||
set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacement_flags})
|
||||
|
||||
else()
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads)
|
||||
set (THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package (Threads)
|
||||
|
||||
set(CMAKE_CXX_FLAGS
|
||||
set( CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-parameter")
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wrange-loop-analysis")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -42,31 +53,18 @@ endif()
|
||||
|
||||
option (Boost_USE_STATIC_LIBS "Use static libraries for boost" ON)
|
||||
|
||||
set (Boost_NO_SYSTEM_PATHS ON)
|
||||
set (Boost_USE_MULTITHREADED ON)
|
||||
set(BOOST_COMPONENTS system)
|
||||
if (Beast_BUILD_EXAMPLES OR Beast_BUILD_TESTS)
|
||||
list(APPEND BOOST_COMPONENTS coroutine context filesystem program_options thread)
|
||||
endif()
|
||||
find_package (Boost 1.58.0 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
|
||||
unset (Boost_INCLUDE_DIR CACHE)
|
||||
unset (Boost_LIBRARY_DIRS CACHE)
|
||||
find_package (Boost REQUIRED COMPONENTS
|
||||
coroutine
|
||||
context
|
||||
filesystem
|
||||
program_options
|
||||
system
|
||||
thread
|
||||
)
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
|
||||
include_directories (SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
link_libraries (${Boost_LIBRARIES})
|
||||
|
||||
if (MSVC)
|
||||
add_definitions (-DBOOST_ALL_NO_LIB) # disable autolinking
|
||||
elseif (MINGW)
|
||||
if (MINGW)
|
||||
link_libraries(ws2_32 mswsock)
|
||||
endif()
|
||||
|
||||
add_definitions (-DBOOST_COROUTINES_NO_DEPRECATION_WARNING=1) # for asio
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# OpenSSL
|
||||
@@ -83,15 +81,23 @@ endif()
|
||||
|
||||
find_package(OpenSSL)
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
add_definitions (-DBEAST_USE_OPENSSL=1)
|
||||
|
||||
else()
|
||||
add_definitions (-DBEAST_USE_OPENSSL=0)
|
||||
message("OpenSSL not found.")
|
||||
endif()
|
||||
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
function(DoGroupSources curdir rootdir folder)
|
||||
file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
|
||||
foreach(child ${children})
|
||||
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
file (GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
|
||||
foreach (child ${children})
|
||||
if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
DoGroupSources(${curdir}/${child} ${rootdir} ${folder})
|
||||
elseif(${child} STREQUAL "CMakeLists.txt")
|
||||
elseif (${child} STREQUAL "CMakeLists.txt")
|
||||
source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
else()
|
||||
string(REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir})
|
||||
@@ -102,77 +108,87 @@ function(DoGroupSources curdir rootdir folder)
|
||||
endfunction()
|
||||
|
||||
function(GroupSources curdir folder)
|
||||
DoGroupSources(${curdir} ${curdir} ${folder})
|
||||
DoGroupSources (${curdir} ${curdir} ${folder})
|
||||
endfunction()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
if ("${VARIANT}" STREQUAL "coverage")
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||
set(CMAKE_BUILD_TYPE RELWITHDEBINFO)
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov")
|
||||
elseif ("${VARIANT}" STREQUAL "asan")
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
set(CMAKE_BUILD_TYPE RELWITHDEBINFO)
|
||||
elseif ("${VARIANT}" STREQUAL "usan")
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
|
||||
set(CMAKE_BUILD_TYPE RELWITHDEBINFO)
|
||||
if (MSVC)
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 -fprofile-arcs -ftest-coverage")
|
||||
set (CMAKE_BUILD_TYPE RELWITHDEBINFO)
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov")
|
||||
endif()
|
||||
|
||||
elseif ("${VARIANT}" STREQUAL "ubasan")
|
||||
if (MSVC)
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -DBEAST_NO_SLOW_TESTS=1 -msse4.2 -funsigned-char -fno-omit-frame-pointer -fsanitize=address,undefined -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/scripts/blacklist.supp")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined")
|
||||
set (CMAKE_BUILD_TYPE RELWITHDEBINFO)
|
||||
endif()
|
||||
|
||||
elseif ("${VARIANT}" STREQUAL "debug")
|
||||
set(CMAKE_BUILD_TYPE DEBUG)
|
||||
set (CMAKE_BUILD_TYPE DEBUG)
|
||||
|
||||
elseif ("${VARIANT}" STREQUAL "release")
|
||||
set(CMAKE_BUILD_TYPE RELEASE)
|
||||
set (CMAKE_BUILD_TYPE RELEASE)
|
||||
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# Library interface
|
||||
#
|
||||
|
||||
add_library (${PROJECT_NAME} INTERFACE)
|
||||
target_link_libraries (${PROJECT_NAME} INTERFACE ${Boost_SYSTEM_LIBRARY})
|
||||
if (NOT MSVC)
|
||||
target_link_libraries (${PROJECT_NAME} INTERFACE Threads::Threads)
|
||||
endif()
|
||||
target_compile_definitions (${PROJECT_NAME} INTERFACE BOOST_COROUTINES_NO_DEPRECATION_WARNING=1)
|
||||
target_include_directories(${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include)
|
||||
target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE ${Boost_INCLUDE_DIRS})
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# Tests and examples
|
||||
#
|
||||
|
||||
include_directories (.)
|
||||
include_directories (extras)
|
||||
include_directories (include)
|
||||
|
||||
set(ZLIB_SOURCES
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/crc32.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/deflate.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/inffast.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/inffixed.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/inflate.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/inftrees.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/trees.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/zlib.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/zutil.h
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/adler32.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/compress.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/crc32.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/deflate.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/infback.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/inffast.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/inflate.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/inftrees.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/trees.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/uncompr.c
|
||||
${PROJECT_SOURCE_DIR}/test/zlib/zlib-1.2.8/zutil.c
|
||||
)
|
||||
if (OPENSSL_FOUND)
|
||||
include_directories (${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE BEAST_INCLUDES
|
||||
${PROJECT_SOURCE_DIR}/include/beast/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/beast/*.ipp
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE COMMON_INCLUDES
|
||||
${PROJECT_SOURCE_DIR}/example/common/*.hpp
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE EXAMPLE_INCLUDES
|
||||
${PROJECT_SOURCE_DIR}/example/*.hpp
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE EXTRAS_INCLUDES
|
||||
${PROJECT_SOURCE_DIR}/extras/beast/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/extras/beast/*.ipp
|
||||
)
|
||||
|
||||
add_subdirectory (examples)
|
||||
if (NOT OPENSSL_FOUND)
|
||||
message("OpenSSL not found. Not building examples/ssl")
|
||||
else()
|
||||
add_subdirectory (examples/ssl)
|
||||
if (Beast_BUILD_TESTS)
|
||||
add_subdirectory (test)
|
||||
endif()
|
||||
|
||||
add_subdirectory (test)
|
||||
add_subdirectory (test/core)
|
||||
add_subdirectory (test/http)
|
||||
add_subdirectory (test/websocket)
|
||||
add_subdirectory (test/zlib)
|
||||
if (Beast_BUILD_EXAMPLES AND
|
||||
(NOT "${VARIANT}" STREQUAL "coverage") AND
|
||||
(NOT "${VARIANT}" STREQUAL "ubasan"))
|
||||
add_subdirectory (example)
|
||||
endif()
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
import os ;
|
||||
import feature ;
|
||||
import boost ;
|
||||
import modules ;
|
||||
import testing ;
|
||||
|
||||
boost.use-project ;
|
||||
|
||||
@@ -50,40 +52,24 @@ if [ os.name ] = MACOSX
|
||||
using clang : : ;
|
||||
}
|
||||
|
||||
variant coverage
|
||||
:
|
||||
debug
|
||||
:
|
||||
<cxxflags>"-fprofile-arcs -ftest-coverage"
|
||||
variant coverage :
|
||||
release
|
||||
:
|
||||
<cxxflags>"-msse4.2 -fprofile-arcs -ftest-coverage"
|
||||
<linkflags>"-lgcov"
|
||||
;
|
||||
;
|
||||
|
||||
variant asan
|
||||
variant ubasan
|
||||
:
|
||||
release
|
||||
:
|
||||
<cxxflags>"-fsanitize=address -fno-omit-frame-pointer"
|
||||
<linkflags>"-fsanitize=address"
|
||||
;
|
||||
|
||||
variant msan
|
||||
:
|
||||
debug
|
||||
:
|
||||
<cxxflags>"-fsanitize=memory -fno-omit-frame-pointer -fsanitize-memory-track-origins=2 -fsanitize-memory-use-after-dtor"
|
||||
<linkflags>"-fsanitize=memory"
|
||||
;
|
||||
|
||||
variant usan
|
||||
:
|
||||
debug
|
||||
:
|
||||
<cxxflags>"-fsanitize=undefined -fno-omit-frame-pointer"
|
||||
<linkflags>"-fsanitize=undefined"
|
||||
<cxxflags>"-msse4.2 -funsigned-char -fno-omit-frame-pointer -fsanitize=address,undefined -fsanitize-blacklist=scripts/blacklist.supp"
|
||||
<linkflags>"-fsanitize=address,undefined"
|
||||
;
|
||||
|
||||
project beast
|
||||
: requirements
|
||||
<implicit-dependency>/boost//headers
|
||||
<include>.
|
||||
<include>./extras
|
||||
<include>./include
|
||||
@@ -103,9 +89,10 @@ project beast
|
||||
<toolset>clang:<cxxflags>-std=c++11
|
||||
<toolset>clang:<cxxflags>-Wno-unused-parameter
|
||||
<toolset>clang:<cxxflags>-Wno-unused-variable # Temporary until we can figure out -isystem
|
||||
<toolset>clang:<cxxflags>-Wrange-loop-analysis
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS=1
|
||||
<toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS=1
|
||||
<toolset>msvc:<cxxflags>"/wd4100 /wd4251 /bigobj"
|
||||
<toolset>msvc:<cxxflags>"/permissive- /bigobj"
|
||||
<toolset>msvc:<variant>release:<cxxflags>"/Ob2 /Oi /Ot"
|
||||
<os>LINUX:<define>_XOPEN_SOURCE=600
|
||||
<os>LINUX:<define>_GNU_SOURCE=1
|
||||
@@ -125,4 +112,4 @@ project beast
|
||||
;
|
||||
|
||||
build-project test ;
|
||||
build-project examples ;
|
||||
build-project example ;
|
||||
|
||||
@@ -1,63 +1,50 @@
|
||||
<img width="880" height = "80" alt = "Beast"
|
||||
src="https://raw.githubusercontent.com/vinniefalco/Beast/master/doc/images/readme.png">
|
||||
|
||||
[](https://gitter.im/vinniefalco/Beast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://travis-ci.org/vinniefalco/Beast) [](https://codecov.io/gh/vinniefalco/Beast) [](https://coveralls.io/github/vinniefalco/Beast?branch=master) [](http://vinniefalco.github.io/beast/) [](LICENSE_1_0.txt)
|
||||
|
||||
# HTTP and WebSocket built on Boost.Asio in C++11
|
||||
|
||||
---
|
||||
|
||||
## Appearances
|
||||
|
||||
| <a href="http://cppcast.com/2017/01/vinnie-falco/">CppCast 2017</a> | <a href="https://raw.githubusercontent.com/vinniefalco/Beast/master/doc/images/CppCon2016.pdf">CppCon 2016</a> |
|
||||
| ------------ | ----------- |
|
||||
| <a href="http://cppcast.com/2017/01/vinnie-falco/"><img width="180" height="180" alt="Vinnie Falco" src="https://avatars1.githubusercontent.com/u/1503976?v=3&u=76c56d989ef4c09625256662eca2775df78a16ad&s=180"></a> | <a href="https://www.youtube.com/watch?v=uJZgRcvPFwI"><img width="320" height = "180" alt="Beast" src="https://raw.githubusercontent.com/vinniefalco/Beast/master/doc/images/CppCon2016.png"></a> |
|
||||
|
||||
---
|
||||
Branch | Build | Coverage | Documentation
|
||||
------------|---------------|----------------|---------------
|
||||
[master](https://github.com/vinniefalco/Beast/tree/master) | [](https://travis-ci.org/vinniefalco/Beast) [](https://ci.appveyor.com/project/vinniefalco/beast/branch/master) | [](https://codecov.io/gh/vinniefalco/Beast/branch/master) | [](http://vinniefalco.github.io/beast/)
|
||||
[develop](https://github.com/vinniefalco/Beast/tree/develop) | [](https://travis-ci.org/vinniefalco/Beast) [](https://ci.appveyor.com/project/vinniefalco/beast/branch/develop) | [](https://codecov.io/gh/vinniefalco/Beast/branch/develop) | [](http://vinniefalco.github.io/stage/beast/develop)
|
||||
|
||||
## Contents
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Appearances](#appearances)
|
||||
- [Description](#description)
|
||||
- [Requirements](#requirements)
|
||||
- [Building](#building)
|
||||
- [Usage](#usage)
|
||||
- [Licence](#licence)
|
||||
- [Contact](#contact)
|
||||
- [Contributing](#Contributing)
|
||||
|
||||
## Introduction
|
||||
|
||||
Beast is a header-only, cross-platform C++ library built on Boost.Asio and
|
||||
Boost, containing two modules implementing widely used network protocols.
|
||||
Beast.HTTP offers a universal model for describing, sending, and receiving
|
||||
HTTP messages while Beast.WebSocket provides a complete implementation of
|
||||
the WebSocket protocol. Their design achieves these goals:
|
||||
Beast is a C++ header-only library serving as a foundation for writing
|
||||
interoperable networking libraries by providing **low-level HTTP/1,
|
||||
WebSocket, and networking protocol** vocabulary types and algorithms
|
||||
using the consistent asynchronous model of Boost.Asio.
|
||||
|
||||
* **Symmetry.** Interfaces are role-agnostic; the same interfaces can be
|
||||
used to build clients, servers, or both.
|
||||
This library is designed for:
|
||||
|
||||
* **Ease of Use.** HTTP messages are modeled using simple, readily
|
||||
accessible objects. Functions and classes used to send and receive HTTP
|
||||
or WebSocket messages are designed to resemble Boost.Asio as closely as
|
||||
possible. Users familiar with Boost.Asio will be immediately comfortable
|
||||
using this library.
|
||||
* **Symmetry:** Algorithms are role-agnostic; build clients, servers, or both.
|
||||
|
||||
* **Flexibility.** Interfaces do not mandate specific implementation
|
||||
strategies; important decisions such as buffer or thread management are
|
||||
left to users of the library.
|
||||
* **Ease of Use:** Boost.Asio users will immediately understand Beast.
|
||||
|
||||
* **Performance.** The implementation performs competitively, making it a
|
||||
realistic choice for building high performance network servers.
|
||||
* **Flexibility:** Users make the important decisions such as buffer or
|
||||
thread management.
|
||||
|
||||
* **Scalability.** Development of network applications that scale to thousands
|
||||
of concurrent connections is possible with the implementation.
|
||||
* **Performance:** Build applications handling thousands of connections or more.
|
||||
|
||||
* **Basis for further abstraction.** The interfaces facilitate the
|
||||
development of other libraries that provide higher levels of abstraction.
|
||||
* **Basis for Further Abstraction.** Components are well-suited for building upon.
|
||||
|
||||
Beast is used in [rippled](https://github.com/ripple/rippled), an
|
||||
open source server application that implements a decentralized
|
||||
cryptocurrency system.
|
||||
## Appearances
|
||||
|
||||
| <a href="http://cppcast.com/2017/01/vinnie-falco/">CppCast 2017</a> | <a href="https://raw.githubusercontent.com/vinniefalco/Beast/master/doc/images/CppCon2016.pdf">CppCon 2016</a> |
|
||||
| ------------ | ----------- |
|
||||
| <a href="http://cppcast.com/2017/01/vinnie-falco/"><img width="180" height="180" alt="Vinnie Falco" src="https://avatars1.githubusercontent.com/u/1503976?v=3&u=76c56d989ef4c09625256662eca2775df78a16ad&s=180"></a> | <a href="https://www.youtube.com/watch?v=uJZgRcvPFwI"><img width="320" height = "180" alt="Beast" src="https://raw.githubusercontent.com/vinniefalco/Beast/master/doc/images/CppCon2016.png"></a> |
|
||||
|
||||
## Description
|
||||
|
||||
@@ -73,17 +60,20 @@ The library has been submitted to the
|
||||
|
||||
## Requirements
|
||||
|
||||
* Boost 1.58 or later
|
||||
* C++11 or later
|
||||
This library is for programmers familiar with Boost.Asio. Users
|
||||
who wish to use asynchronous interfaces should already know how to
|
||||
create concurrent network programs using callbacks or coroutines.
|
||||
|
||||
* **C++11:** Robust support for most language features.
|
||||
* **Boost:** Boost.Asio and some other parts of Boost.
|
||||
* **OpenSSL:** Optional, for using TLS/Secure sockets.
|
||||
|
||||
When using Microsoft Visual C++, Visual Studio 2015 Update 3 or later is required.
|
||||
|
||||
These components are optionally required in order to build the
|
||||
tests and examples:
|
||||
These components are required in order to build the tests and examples:
|
||||
|
||||
* OpenSSL (optional)
|
||||
* CMake 3.7.2 or later (optional)
|
||||
* Properly configured bjam/b2 (optional)
|
||||
* CMake 3.7.2 or later
|
||||
* Properly configured bjam/b2
|
||||
|
||||
## Building
|
||||
|
||||
@@ -106,24 +96,21 @@ instructions on how to do this for your particular build system.
|
||||
|
||||
For the examples and tests, Beast provides build scripts for Boost.Build (bjam)
|
||||
and CMake. It is possible to generate Microsoft Visual Studio or Apple
|
||||
Developers using Microsoft Visual Studio can generate Visual Studio
|
||||
project files by executing these commands from the root of the repository:
|
||||
Xcode project files using CMake by executing these commands from
|
||||
the root of the repository:
|
||||
|
||||
```
|
||||
mkdir bin
|
||||
cd bin
|
||||
cmake .. # for 32-bit Windows builds
|
||||
|
||||
cd ../bin64
|
||||
cmake .. # for Linux/Mac builds, OR
|
||||
cmake -G"Visual Studio 14 2015 Win64" .. # for 64-bit Windows builds
|
||||
```
|
||||
|
||||
When using Apple Xcode it is possible to generate Xcode project files
|
||||
using these commands:
|
||||
|
||||
```
|
||||
cd bin
|
||||
cmake -G Xcode .. # for Apple Xcode builds
|
||||
|
||||
cd ..
|
||||
mkdir bin64
|
||||
cd bin64
|
||||
cmake -G"Visual Studio 14 2015 Win64" .. # for 64-bit Windows builds (VS2015)
|
||||
cmake -G"Visual Studio 15 2017 Win64" .. # for 64-bit Windows builds (VS2017)
|
||||
|
||||
```
|
||||
|
||||
To build with Boost.Build, it is necessary to have the bjam executable
|
||||
@@ -141,13 +128,13 @@ The files in the repository are laid out thusly:
|
||||
|
||||
```
|
||||
./
|
||||
bin/ Holds executables and project files
|
||||
bin64/ Holds 64-bit Windows executables and project files
|
||||
bin/ Create this to hold executables and project files
|
||||
bin64/ Create this to hold 64-bit Windows executables and project files
|
||||
doc/ Source code and scripts for the documentation
|
||||
include/ Add this to your compiler includes
|
||||
beast/
|
||||
extras/ Additional APIs, may change
|
||||
examples/ Self contained example programs
|
||||
example/ Self contained example programs
|
||||
test/ Unit tests and benchmarks
|
||||
```
|
||||
|
||||
@@ -155,76 +142,9 @@ The files in the repository are laid out thusly:
|
||||
## Usage
|
||||
|
||||
These examples are complete, self-contained programs that you can build
|
||||
and run yourself (they are in the `examples` directory).
|
||||
and run yourself (they are in the `example` directory).
|
||||
|
||||
Example WebSocket program:
|
||||
```C++
|
||||
#include <beast/core/to_string.hpp>
|
||||
#include <beast/websocket.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "echo.websocket.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r{ios};
|
||||
boost::asio::ip::tcp::socket sock{ios};
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
|
||||
|
||||
// WebSocket connect and send message using beast
|
||||
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
|
||||
ws.handshake(host, "/");
|
||||
ws.write(boost::asio::buffer(std::string("Hello, world!")));
|
||||
|
||||
// Receive WebSocket message, print and close using beast
|
||||
beast::streambuf sb;
|
||||
beast::websocket::opcode op;
|
||||
ws.read(op, sb);
|
||||
ws.close(beast::websocket::close_code::normal);
|
||||
std::cout << beast::to_string(sb.data()) << "\n";
|
||||
}
|
||||
```
|
||||
|
||||
Example HTTP program:
|
||||
```C++
|
||||
#include <beast/http.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "boost.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r{ios};
|
||||
boost::asio::ip::tcp::socket sock{ios};
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
|
||||
|
||||
// Send HTTP request using beast
|
||||
beast::http::request<beast::http::empty_body> req;
|
||||
req.method = "GET";
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.fields.replace("Host", host + ":" +
|
||||
boost::lexical_cast<std::string>(sock.remote_endpoint().port()));
|
||||
req.fields.replace("User-Agent", "Beast");
|
||||
beast::http::prepare(req);
|
||||
beast::http::write(sock, req);
|
||||
|
||||
// Receive and print HTTP response using beast
|
||||
beast::streambuf sb;
|
||||
beast::http::response<beast::http::streambuf_body> resp;
|
||||
beast::http::read(sock, sb, resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
```
|
||||
http://vinniefalco.github.io/beast/beast/quick_start.html
|
||||
|
||||
## License
|
||||
|
||||
@@ -236,3 +156,51 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
Please report issues or questions here:
|
||||
https://github.com/vinniefalco/Beast/issues
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Contributing (We Need Your Help!)
|
||||
|
||||
If you would like to contribute to Beast and help us maintain high
|
||||
quality, consider performing code reviews on active pull requests.
|
||||
Any feedback from users and stakeholders, even simple questions about
|
||||
how things work or why they were done a certain way, carries value
|
||||
and can be used to improve the library. Code review provides these
|
||||
benefits:
|
||||
|
||||
* Identify bugs
|
||||
* Documentation proof-reading
|
||||
* Adjust interfaces to suit use-cases
|
||||
* Simplify code
|
||||
|
||||
You can look through the Closed pull requests to get an idea of how
|
||||
reviews are performed. To give a code review just sign in with your
|
||||
GitHub account and then add comments to any open pull requests below,
|
||||
don't be shy!
|
||||
<p>https://github.com/vinniefalco/Beast/pulls</p>
|
||||
|
||||
Here are some resources to learn more about
|
||||
code reviews:
|
||||
|
||||
* <a href="https://blog.scottnonnenberg.com/top-ten-pull-request-review-mistakes/">Top 10 Pull Request Review Mistakes</a>
|
||||
* <a href="https://smartbear.com/SmartBear/media/pdfs/best-kept-secrets-of-peer-code-review.pdf">Best Kept Secrets of Peer Code Review (pdf)</a>
|
||||
* <a href="http://support.smartbear.com/support/media/resources/cc/11_Best_Practices_for_Peer_Code_Review.pdf">11 Best Practices for Peer Code Review (pdf)</a>
|
||||
* <a href="http://www.evoketechnologies.com/blog/code-review-checklist-perform-effective-code-reviews/">Code Review Checklist – To Perform Effective Code Reviews</a>
|
||||
* <a href="https://www.codeproject.com/Articles/524235/Codeplusreviewplusguidelines">Code review guidelines</a>
|
||||
* <a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md">C++ Core Guidelines</a>
|
||||
* <a href="https://doc.lagout.org/programmation/C/CPP101.pdf">C++ Coding Standards (Sutter & Andrescu)</a>
|
||||
|
||||
Beast thrives on code reviews and any sort of feedback from users and
|
||||
stakeholders about its interfaces. Even if you just have questions,
|
||||
asking them in the code review or in issues provides valuable information
|
||||
that can be used to improve the library - do not hesitate, no question
|
||||
is insignificant or unimportant!
|
||||
|
||||
While code reviews are the preferred form of donation, if you simply
|
||||
must donate money to support the library, please do so
|
||||
using <a href="https://bitcoin.org">Bitcoin</a> sent to this address:
|
||||
<a href="bitcoin:1DaPsDvv6MjFUSnsxXSHzeYKSjzrWrQY7T?amount=0.03&label=Beast%20Library"><b>1DaPsDvv6MjFUSnsxXSHzeYKSjzrWrQY7T</b></a>
|
||||
|
||||
<a href="bitcoin:1DaPsDvv6MjFUSnsxXSHzeYKSjzrWrQY7T?amount=0.03&label=Beast%20Library">
|
||||
<img src="https://raw.githubusercontent.com/vinniefalco/Beast/master/doc/images/btc_qr2.png" width="490" height="100"></a>
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
* Add writer::prepare(msg&) interface to set Content-Type
|
||||
|
||||
Boost.Http
|
||||
* Use enum instead of bool in isRequest
|
||||
|
||||
Docs:
|
||||
* Include Example program listings in the docs
|
||||
* Fix index in docs
|
||||
* melpon sandbox?
|
||||
* Implement cleanup-param to remove spaces around template arguments
|
||||
e.g. in basic_streambuf move constructor members
|
||||
* Don't put using namespace at file scope in examples,
|
||||
do something like "using ba = boost::asio" instead.
|
||||
|
||||
Core:
|
||||
* Replace Jamroot with Jamfile
|
||||
* Fix bidirectional buffers iterators operator->()
|
||||
* Complete allocator testing in basic_streambuf
|
||||
|
||||
WebSocket:
|
||||
* Minimize sizeof(websocket::stream)
|
||||
* Move check for message size limit to account for compression
|
||||
* more invokable unit test coverage
|
||||
* More control over the HTTP request and response during handshakes
|
||||
* optimized versions of key/masking, choose prepared_key size
|
||||
* Give callers control over the http request/response used during handshake
|
||||
* Investigate poor autobahn results in Debug builds
|
||||
* Fall through composed operation switch cases
|
||||
* Use close_code::no_code instead of close_code::none
|
||||
* Make request_type, response_type public APIs,
|
||||
use in stream member function signatures
|
||||
|
||||
HTTP:
|
||||
* Define Parser concept in HTTP
|
||||
- Need parse version of read() so caller can set parser options
|
||||
like maximum size of headers, maximum body size, etc
|
||||
* add bool should_close(message_v1 const&) to replace the use
|
||||
of eof return value from write and async_write
|
||||
* More fine grained parser errors
|
||||
* HTTP parser size limit with test (configurable?)
|
||||
* HTTP parser trailers with test
|
||||
* Decode chunk encoding parameters
|
||||
* URL parser, strong URL character checking in HTTP parser
|
||||
* Fix prepare() calling content_length() without init()
|
||||
* Complete allocator testing in basic_streambuf, basic_headers
|
||||
* Custom HTTP error codes for various situations
|
||||
* Branch prediction hints in parser
|
||||
* Check basic_parser_v1 against rfc7230 for leading message whitespace
|
||||
* Fix the order of message constructor parameters:
|
||||
body first then headers (since body is constructed with arguments more often)
|
||||
* Unit tests for char tables
|
||||
* Remove status_code() from API when isRequest==true, et. al.
|
||||
* Permit sending trailers and parameters in chunk-encoding chunks
|
||||
|
||||
Future:
|
||||
|
||||
* SOCKS proxy client and server implementations
|
||||
|
||||
102
src/beast/appveyor.yml
Normal file
102
src/beast/appveyor.yml
Normal file
@@ -0,0 +1,102 @@
|
||||
# Copyright 2016 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#version: 1.0.{build}-{branch}
|
||||
version: "{branch} (#{build})"
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
platform:
|
||||
#- x86
|
||||
- x64
|
||||
|
||||
configuration:
|
||||
#- Debug
|
||||
- Release
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone https://github.com/boostorg/boost.git boost
|
||||
- cd boost
|
||||
# - git checkout boost-1.64.0
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\beast\
|
||||
- git submodule update --init tools/build
|
||||
- git submodule update --init libs/config
|
||||
- git submodule update --init tools/boostdep
|
||||
# - python tools/boostdep/depinst/depinst.py beast
|
||||
- git submodule update --init libs/any
|
||||
- git submodule update --init libs/asio
|
||||
- git submodule update --init libs/algorithm
|
||||
- git submodule update --init libs/array
|
||||
- git submodule update --init libs/assert
|
||||
- git submodule update --init libs/atomic
|
||||
- git submodule update --init libs/bind
|
||||
- git submodule update --init libs/chrono
|
||||
- git submodule update --init libs/concept_check
|
||||
- git submodule update --init libs/config
|
||||
- git submodule update --init libs/container
|
||||
- git submodule update --init libs/context
|
||||
- git submodule update --init libs/conversion
|
||||
- git submodule update --init libs/core
|
||||
- git submodule update --init libs/coroutine
|
||||
- git submodule update --init libs/date_time
|
||||
- git submodule update --init libs/detail
|
||||
- git submodule update --init libs/endian
|
||||
- git submodule update --init libs/exception
|
||||
- git submodule update --init libs/filesystem
|
||||
- git submodule update --init libs/foreach
|
||||
- git submodule update --init libs/function
|
||||
- git submodule update --init libs/function_types
|
||||
- git submodule update --init libs/functional
|
||||
- git submodule update --init libs/fusion
|
||||
- git submodule update --init libs/integer
|
||||
- git submodule update --init libs/intrusive
|
||||
- git submodule update --init libs/io
|
||||
- git submodule update --init libs/iostreams
|
||||
- git submodule update --init libs/iterator
|
||||
- git submodule update --init libs/lambda
|
||||
- git submodule update --init libs/lexical_cast
|
||||
- git submodule update --init libs/locale
|
||||
- git submodule update --init libs/logic
|
||||
- git submodule update --init libs/math
|
||||
- git submodule update --init libs/move
|
||||
- git submodule update --init libs/mpl
|
||||
- git submodule update --init libs/numeric/conversion
|
||||
- git submodule update --init libs/optional
|
||||
# - git submodule update --init libs/phoenix
|
||||
- git submodule update --init libs/pool
|
||||
- git submodule update --init libs/predef
|
||||
- git submodule update --init libs/preprocessor
|
||||
- git submodule update --init libs/program_options
|
||||
- git submodule update --init libs/proto
|
||||
- git submodule update --init libs/random
|
||||
- git submodule update --init libs/range
|
||||
- git submodule update --init libs/ratio
|
||||
- git submodule update --init libs/rational
|
||||
- git submodule update --init libs/regex
|
||||
- git submodule update --init libs/serialization
|
||||
- git submodule update --init libs/smart_ptr
|
||||
# - git submodule update --init libs/spirit
|
||||
- git submodule update --init libs/static_assert
|
||||
- git submodule update --init libs/system
|
||||
- git submodule update --init libs/thread
|
||||
- git submodule update --init libs/throw_exception
|
||||
- git submodule update --init libs/tokenizer
|
||||
- git submodule update --init libs/tti
|
||||
- git submodule update --init libs/tuple
|
||||
- git submodule update --init libs/type_index
|
||||
- git submodule update --init libs/type_traits
|
||||
- git submodule update --init libs/typeof
|
||||
- git submodule update --init libs/unordered
|
||||
- git submodule update --init libs/utility
|
||||
- git submodule update --init libs/variant
|
||||
- git submodule update --init libs/winapi
|
||||
- bootstrap
|
||||
- b2 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- b2 libs/beast/example toolset=msvc-14.0
|
||||
- b2 libs/beast/test toolset=msvc-14.0
|
||||
113
src/beast/doc/0_main.qbk
Normal file
113
src/beast/doc/0_main.qbk
Normal file
@@ -0,0 +1,113 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[library Beast
|
||||
[quickbook 1.6]
|
||||
[copyright 2013 - 2017 Vinnie Falco]
|
||||
[purpose Networking Protocol Library]
|
||||
[license
|
||||
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])
|
||||
]
|
||||
[authors [Falco, Vinnie]]
|
||||
[category template]
|
||||
[category generic]
|
||||
]
|
||||
|
||||
[template mdash[] '''— ''']
|
||||
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
|
||||
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
|
||||
[template repo_file[path] '''<ulink url="https://github.com/vinniefalco/Beast/blob/master/'''[path]'''">'''[path]'''</ulink>''']
|
||||
[template include_file[path][^<'''<ulink url="https://github.com/vinniefalco/Beast/blob/master/include/'''[path]'''">'''[path]'''</ulink>'''>]]
|
||||
|
||||
[def __N3747__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf [*N3747]]]
|
||||
[def __N4588__ [@http://cplusplus.github.io/networking-ts/draft.pdf [*N4588]]]
|
||||
[def __rfc6455__ [@https://tools.ietf.org/html/rfc6455 rfc6455]]
|
||||
[def __rfc7230__ [@https://tools.ietf.org/html/rfc7230 rfc7230]]
|
||||
|
||||
[def __Asio__ [@http://www.boost.org/doc/html/boost_asio.html Boost.Asio]]
|
||||
|
||||
[def __asio_handler_invoke__ [@http://www.boost.org/doc/html/boost_asio/reference/asio_handler_invoke.html `asio_handler_invoke`]]
|
||||
[def __asio_handler_allocate__ [@http://www.boost.org/doc/html/boost_asio/reference/asio_handler_allocate.html `asio_handler_allocate`]]
|
||||
[def __io_service__ [@http://www.boost.org/doc/html/boost_asio/reference/io_service.html `io_service`]]
|
||||
[def __socket__ [@http://www.boost.org/doc/html/boost_asio/reference/ip__tcp/socket.html `boost::asio::ip::tcp::socket`]]
|
||||
[def __ssl_stream__ [@http://www.boost.org/doc/html/boost_asio/reference/ssl__stream.html `boost::asio::ssl::stream`]]
|
||||
[def __streambuf__ [@http://www.boost.org/doc/html/boost_asio/reference/streambuf.html `boost::asio::streambuf`]]
|
||||
[def __use_future__ [@http://www.boost.org/doc/html/boost_asio/reference/use_future_t.html `boost::asio::use_future`]]
|
||||
[def __void_or_deduced__ [@http://www.boost.org/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]]
|
||||
[def __yield_context__ [@http://www.boost.org/doc/html/boost_asio/reference/yield_context.html `boost::asio::yield_context`]]
|
||||
|
||||
[def __AsyncReadStream__ [@http://www.boost.org/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]]
|
||||
[def __AsyncWriteStream__ [@http://www.boost.org/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]]
|
||||
[def __CompletionHandler__ [@http://www.boost.org/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]]
|
||||
[def __ConstBufferSequence__ [@http://www.boost.org/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]]
|
||||
[def __Handler__ [@http://www.boost.org/doc/html/boost_asio/reference/Handler.html [*Handler]]]
|
||||
[def __MutableBufferSequence__ [@http://www.boost.org/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]]
|
||||
[def __SyncReadStream__ [@http://www.boost.org/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]]
|
||||
[def __SyncWriteStream__ [@http://www.boost.org/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]]
|
||||
|
||||
[def __async_initfn__ [@http://www.boost.org/doc/html/boost_asio/reference/asynchronous_operations.html initiating function]]
|
||||
|
||||
[def __AsyncStream__ [link beast.concept.streams.AsyncStream [*AsyncStream]]]
|
||||
[def __Body__ [link beast.concept.Body [*Body]]]
|
||||
[def __BodyReader__ [link beast.concept.BodyReader [*BodyReader]]]
|
||||
[def __BodyWriter__ [link beast.concept.BodyWriter [*BodyWriter]]]
|
||||
[def __DynamicBuffer__ [link beast.concept.DynamicBuffer [*DynamicBuffer]]]
|
||||
[def __Fields__ [link beast.concept.Fields [*Fields]]]
|
||||
[def __FieldsReader__ [link beast.concept.FieldsReader [*FieldsReader]]]
|
||||
[def __File__ [link beast.concept.File [*File]]]
|
||||
[def __Stream__ [link beast.concept.streams [*Stream]]]
|
||||
[def __SyncStream__ [link beast.concept.streams.SyncStream [*SyncStream]]]
|
||||
|
||||
[def __basic_fields__ [link beast.ref.beast__http__basic_fields `basic_fields`]]
|
||||
[def __basic_multi_buffer__ [link beast.ref.beast__basic_multi_buffer `basic_multi_buffer`]]
|
||||
[def __basic_parser__ [link beast.ref.beast__http__basic_parser `basic_parser`]]
|
||||
[def __buffer_body__ [link beast.ref.beast__http__buffer_body `buffer_body`]]
|
||||
[def __fields__ [link beast.ref.beast__http__fields `fields`]]
|
||||
[def __flat_buffer__ [link beast.ref.beast__flat_buffer `flat_buffer`]]
|
||||
[def __header__ [link beast.ref.beast__http__header `header`]]
|
||||
[def __message__ [link beast.ref.beast__http__message `message`]]
|
||||
[def __multi_buffer__ [link beast.ref.beast__multi_buffer `multi_buffer`]]
|
||||
[def __parser__ [link beast.ref.beast__http__parser `parser`]]
|
||||
[def __serializer__ [link beast.ref.beast__http__serializer `serializer`]]
|
||||
[def __static_buffer__ [link beast.ref.beast__static_buffer `static_buffer`]]
|
||||
[def __static_buffer_n__ [link beast.ref.beast__static_buffer_n `static_buffer_n`]]
|
||||
|
||||
[import ../example/common/detect_ssl.hpp]
|
||||
[import ../example/doc/http_examples.hpp]
|
||||
[import ../example/echo-op/echo_op.cpp]
|
||||
[import ../example/http-client/http_client.cpp]
|
||||
[import ../example/websocket-client/websocket_client.cpp]
|
||||
|
||||
[import ../include/beast/http/file_body.hpp]
|
||||
|
||||
[import ../test/exemplars.cpp]
|
||||
[import ../test/core/doc_snippets.cpp]
|
||||
[import ../test/http/doc_snippets.cpp]
|
||||
[import ../test/websocket/doc_snippets.cpp]
|
||||
|
||||
[include 1_intro.qbk]
|
||||
[include 2_examples.qbk]
|
||||
[include 3_0_core.qbk]
|
||||
[include 5_00_http.qbk]
|
||||
[include 6_0_http_examples.qbk]
|
||||
[include 7_0_websocket.qbk]
|
||||
[include 8_concepts.qbk]
|
||||
[include 9_0_design.qbk]
|
||||
|
||||
[section:quickref Reference]
|
||||
[xinclude quickref.xml]
|
||||
[endsect]
|
||||
|
||||
[block'''<reference id="hidden"><title>This Page Intentionally Left Blank 1/2</title>''']
|
||||
[section:ref This Page Intentionally Left Blank 2/2]
|
||||
[include reference.qbk]
|
||||
[endsect]
|
||||
[block'''</reference>''']
|
||||
|
||||
[xinclude index.xml]
|
||||
96
src/beast/doc/1_intro.qbk
Normal file
96
src/beast/doc/1_intro.qbk
Normal file
@@ -0,0 +1,96 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:intro Introduction]
|
||||
|
||||
Beast is a C++ header-only library serving as a foundation for writing
|
||||
interoperable networking libraries by providing [*low-level HTTP/1,
|
||||
WebSocket, and networking protocol] vocabulary types and algorithms
|
||||
using the consistent asynchronous model of __Asio__.
|
||||
|
||||
This library is designed for:
|
||||
|
||||
* [*Symmetry:] Algorithms are role-agnostic; build clients, servers, or both.
|
||||
|
||||
* [*Ease of Use:] __Asio__ users will immediately understand Beast.
|
||||
|
||||
* [*Flexibility:] Users make the important decisions such as buffer or
|
||||
thread management.
|
||||
|
||||
* [*Performance:] Build applications handling thousands of connections or more.
|
||||
|
||||
* [*Basis for Further Abstraction.] Components are well-suited for building upon.
|
||||
|
||||
Beast is not an HTTP client or HTTP server, but it can be used to build
|
||||
those things.
|
||||
|
||||
[heading Motivation]
|
||||
|
||||
Beast empowers users to create their own libraries, clients, and servers
|
||||
using HTTP/1 and WebSocket. Code will be easier and faster to implement,
|
||||
understand, and maintain, because Beast takes care of the low-level
|
||||
protocol details.
|
||||
The HTTP and WebSocket protocols drive most of the World Wide Web.
|
||||
Every web browser implements these protocols to load webpages and
|
||||
to enable client side programs (often written in JavaScript) to
|
||||
communicate interactively. C++ benefits greatly from having a
|
||||
standardized implementation of these protocols.
|
||||
|
||||
[heading Requirements]
|
||||
|
||||
[important
|
||||
This library is for programmers familiar with __Asio__. Users who
|
||||
wish to use asynchronous interfaces should already know how to
|
||||
create concurrent network programs using callbacks or coroutines.
|
||||
]
|
||||
|
||||
Beast requires:
|
||||
|
||||
* [*C++11:] Robust support for most language features.
|
||||
* [*Boost:] Beast only works with Boost, not stand-alone Asio
|
||||
* [*OpenSSL:] Optional, for using TLS/Secure sockets.
|
||||
|
||||
Supported compilers: msvc-14+, gcc 4.8+, clang 3.6+
|
||||
|
||||
Sources are [*header-only]. To link a program using Beast successfully, add the
|
||||
[@http://www.boost.org/libs/system/doc/reference.html Boost.System]
|
||||
library to the list of linked libraries. If you use coroutines
|
||||
you'll also need the
|
||||
[@http://www.boost.org/libs/coroutine/doc/html/index.html Boost.Coroutine]
|
||||
library. Please visit the
|
||||
[@http://www.boost.org/doc/ Boost documentation]
|
||||
for instructions on how to do this for your particular build system.
|
||||
|
||||
[heading Credits]
|
||||
|
||||
Boost.Asio is the inspiration behind which all of the interfaces and
|
||||
implementation strategies are built. Some parts of the documentation are
|
||||
written to closely resemble the wording and presentation of Boost.Asio
|
||||
documentation. Credit goes to
|
||||
[@https://github.com/chriskohlhoff Christopher Kohlhoff]
|
||||
for his wonderful Asio library and the ideas in __N4588__ which power Beast.
|
||||
|
||||
Beast would not be possible without the support of
|
||||
[@https://www.ripple.com Ripple]
|
||||
during the library's early development, or the ideas, time and patience
|
||||
contributed by
|
||||
[@https://github.com/JoelKatz David Schwartz],
|
||||
[@https://github.com/ximinez Edward Hennis],
|
||||
[@https://github.com/howardhinnant Howard Hinnant],
|
||||
[@https://github.com/miguelportilla Miguel Portilla],
|
||||
[@https://github.com/nbougalis Nik Bougalis],
|
||||
[@https://github.com/seelabs Scott Determan],
|
||||
[@https://github.com/scottschurr Scott Schurr],
|
||||
Many thanks to
|
||||
[@https://github.com/K-ballo Agustín Bergé],
|
||||
[@http://www.boost.org/users/people/glen_fernandes.html Glen Fernandes],
|
||||
and
|
||||
[@https://github.com/pdimov Peter Dimov]
|
||||
for tirelessly answering questions on
|
||||
[@https://cpplang.slack.com/ Cpplang-Slack].
|
||||
|
||||
[endsect]
|
||||
192
src/beast/doc/2_examples.qbk
Normal file
192
src/beast/doc/2_examples.qbk
Normal file
@@ -0,0 +1,192 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:quickstart Quick Start]
|
||||
[block'''<?dbhtml stop-chunking?>''']
|
||||
|
||||
These complete programs are intended to quickly impress upon readers
|
||||
the flavor of the library. Source code and build scripts for them are
|
||||
located in the example/ directory.
|
||||
|
||||
[section HTTP Client]
|
||||
|
||||
Use HTTP to make a GET request to a website and print the response:
|
||||
|
||||
File: [repo_file example/http-client/http_client.cpp]
|
||||
|
||||
[example_http_client]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section WebSocket Client]
|
||||
|
||||
Establish a WebSocket connection, send a message and receive the reply:
|
||||
|
||||
File: [repo_file example/websocket-client/websocket_client.cpp]
|
||||
|
||||
[example_websocket_client]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:examples Examples]
|
||||
[block'''<?dbhtml stop-chunking?>''']
|
||||
|
||||
Source code and build scripts for these programs are located
|
||||
in the example/ directory.
|
||||
|
||||
|
||||
|
||||
[section HTTP Crawl]
|
||||
|
||||
This example retrieves the page at each of the most popular domains
|
||||
as measured by Alexa.
|
||||
|
||||
* [repo_file example/http-crawl/http_crawl.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section HTTP Client (with SSL)]
|
||||
|
||||
This example demonstrates sending and receiving HTTP messages
|
||||
over a TLS connection. Requires OpenSSL to build.
|
||||
|
||||
* [repo_file example/http-client-ssl/http_client_ssl.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section HTTP Server (Fast)]
|
||||
|
||||
This example implements a very simple HTTP server with
|
||||
some optimizations suitable for calculating benchmarks.
|
||||
|
||||
* [repo_file example/http-server-fast/fields_alloc.hpp]
|
||||
* [repo_file example/http-server-fast/http_server_fast.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section HTTP Server (Small)]
|
||||
|
||||
This example implements a very simple HTTP server
|
||||
suitable as a starting point on an embedded device.
|
||||
|
||||
* [repo_file example/http-server-small/http_server_small.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section HTTP Server (Threaded)]
|
||||
|
||||
This example implements a very simple HTTP server using
|
||||
synchronous interfaces and using one thread per connection:
|
||||
|
||||
* [repo_file example/http-server-threaded/http_server_threaded.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section WebSocket Client (with SSL)]
|
||||
|
||||
Establish a WebSocket connection over an encrypted TLS connection,
|
||||
send a message and receive the reply. Requires OpenSSL to build.
|
||||
|
||||
* [repo_file example/websocket-client-ssl/websocket_client_ssl.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section WebSocket Server (Asynchronous)]
|
||||
|
||||
This program implements a WebSocket echo server using asynchronous
|
||||
interfaces and a configurable number of threads.
|
||||
|
||||
* [repo_file example/websocket-server-async/websocket_server_async.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section Documentation Samples]
|
||||
|
||||
Here are all of the example functions and classes presented
|
||||
throughout the documentation, they can be included and used
|
||||
in your program without modification
|
||||
|
||||
* [repo_file example/doc/http_examples.hpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section Composed Operations]
|
||||
|
||||
This program shows how to use Beast's network foundations to build a
|
||||
composable asynchronous initiation function with associated composed
|
||||
operation implementation. This is a complete, runnable version of
|
||||
the example described in the Core Foundations document section.
|
||||
|
||||
* [repo_file example/echo-op/echo_op.cpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section Common Code]
|
||||
|
||||
This code is reused between some of the examples. The header files
|
||||
stand alone can be directly included in your projects.
|
||||
|
||||
* [repo_file example/common/detect_ssl.hpp]
|
||||
* [repo_file example/common/helpers.hpp]
|
||||
* [repo_file example/common/mime_types.hpp]
|
||||
* [repo_file example/common/rfc7231.hpp]
|
||||
* [repo_file example/common/ssl_stream.hpp]
|
||||
* [repo_file example/common/write_msg.hpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section Server Framework]
|
||||
|
||||
This is a complete program and framework of classes implementing
|
||||
a general purpose server that users may copy to use as the basis
|
||||
for writing their own servers. It serves both HTTP and WebSocket.
|
||||
|
||||
* [repo_file example/server-framework/file_service.hpp]
|
||||
* [repo_file example/server-framework/framework.hpp]
|
||||
* [repo_file example/server-framework/http_async_port.hpp]
|
||||
* [repo_file example/server-framework/http_base.hpp]
|
||||
* [repo_file example/server-framework/http_sync_port.hpp]
|
||||
* [repo_file example/server-framework/https_ports.hpp]
|
||||
* [repo_file example/server-framework/main.cpp]
|
||||
* [repo_file example/server-framework/multi_port.hpp]
|
||||
* [repo_file example/server-framework/server.hpp]
|
||||
* [repo_file example/server-framework/service_list.hpp]
|
||||
* [repo_file example/server-framework/ssl_certificate.hpp]
|
||||
* [repo_file example/server-framework/ws_async_port.hpp]
|
||||
* [repo_file example/server-framework/ws_sync_port.hpp]
|
||||
* [repo_file example/server-framework/ws_upgrade_service.hpp]
|
||||
* [repo_file example/server-framework/wss_ports.hpp]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
33
src/beast/doc/3_0_core.qbk
Normal file
33
src/beast/doc/3_0_core.qbk
Normal file
@@ -0,0 +1,33 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:using_io Using I/O]
|
||||
|
||||
This library makes I/O primitives used by the implementation publicly
|
||||
available so users can take advantage of them in their own libraries.
|
||||
These primitives include traits, buffers, buffer algorithms, files,
|
||||
and helpers for implementing asynchronous operations compatible with
|
||||
__Asio__ and described in __N3747__. This section lists these facilities
|
||||
by group, with descriptions.
|
||||
|
||||
[important
|
||||
This documentation assumes familiarity with __Asio__. Sample
|
||||
code and identifiers used throughout are written as if the
|
||||
following declarations are in effect:
|
||||
|
||||
[snippet_core_1a]
|
||||
[snippet_core_1b]
|
||||
]
|
||||
|
||||
[include 3_1_asio.qbk]
|
||||
[include 3_2_streams.qbk]
|
||||
[include 3_3_buffers.qbk]
|
||||
[include 3_4_files.qbk]
|
||||
[include 3_5_composed.qbk]
|
||||
[include 3_6_detect_ssl.qbk]
|
||||
|
||||
[endsect]
|
||||
62
src/beast/doc/3_1_asio.qbk
Normal file
62
src/beast/doc/3_1_asio.qbk
Normal file
@@ -0,0 +1,62 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Asio Refresher]
|
||||
|
||||
[warning
|
||||
Beast does not manage sockets, make outgoing connections,
|
||||
accept incoming connections, handle timeouts, close endpoints,
|
||||
do name lookups, deal with TLS certificates, perform authentication,
|
||||
or otherwise handle any aspect of connection management. This is
|
||||
left to the interfaces already existing on the underlying streams.
|
||||
]
|
||||
|
||||
Library stream algorithms require a __socket__, __ssl_stream__, or other
|
||||
__Stream__ object that has already established communication with an
|
||||
endpoint. This example is provided as a reminder of how to work with
|
||||
sockets:
|
||||
|
||||
[snippet_core_2]
|
||||
|
||||
Throughout this documentation identifiers with the following names have
|
||||
special meaning:
|
||||
|
||||
[table Global Variables
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/io_service.html [*`ios`]]
|
||||
][
|
||||
A variable of type
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/io_service.html `boost::asio::io_service`]
|
||||
which is running on one separate thread, and upon which a
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/io_service__work.html `boost::asio::io_service::work`]
|
||||
object has been constructed.
|
||||
]]
|
||||
[[
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/ip__tcp/socket.html [*`sock`]]
|
||||
][
|
||||
A variable of type
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/ip__tcp/socket.html `boost::asio::ip::tcp::socket`]
|
||||
which has already been connected to a remote host.
|
||||
]]
|
||||
[[
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/ssl__stream.html [*`ssl_sock`]]
|
||||
][
|
||||
A variable of type
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/ssl__stream.html `boost::asio::ssl::stream<boost::asio::ip::tcp::socket>`]
|
||||
which is already connected and has handshaked with a remote host.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__websocket__stream [*`ws`]]
|
||||
][
|
||||
A variable of type
|
||||
[link beast.ref.beast__websocket__stream `websocket::stream<boost::asio::ip::tcp::socket>`]
|
||||
which is already connected with a remote host.
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
120
src/beast/doc/3_2_streams.qbk
Normal file
120
src/beast/doc/3_2_streams.qbk
Normal file
@@ -0,0 +1,120 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Stream Types]
|
||||
|
||||
A __Stream__ is a communication channel where data is transferred as
|
||||
an ordered sequence of octet buffers. Streams are either synchronous
|
||||
or asynchronous, and may allow reading, writing, or both. Note that
|
||||
a particular type may model more than one concept. For example, the
|
||||
Asio types __socket__ and __ssl_stream__ support both __SyncStream__
|
||||
and __AsyncStream__. All stream algorithms in Beast are declared as
|
||||
template functions using these concepts:
|
||||
|
||||
[table Stream Concepts
|
||||
[[Concept][Description]]
|
||||
[
|
||||
[__SyncReadStream__]
|
||||
[
|
||||
Supports buffer-oriented blocking reads.
|
||||
]
|
||||
][
|
||||
[__SyncWriteStream__]
|
||||
[
|
||||
Supports buffer-oriented blocking writes.
|
||||
]
|
||||
][
|
||||
[__SyncStream__]
|
||||
[
|
||||
A stream supporting buffer-oriented blocking reads and writes.
|
||||
]
|
||||
][
|
||||
[__AsyncReadStream__]
|
||||
[
|
||||
Supports buffer-oriented asynchronous reads.
|
||||
]
|
||||
][
|
||||
[__AsyncWriteStream__]
|
||||
[
|
||||
Supports buffer-oriented asynchronous writes.
|
||||
]
|
||||
][
|
||||
[__AsyncStream__]
|
||||
[
|
||||
A stream supporting buffer-oriented asynchronous reads and writes.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
These template metafunctions check whether a given type meets the
|
||||
requirements for the various stream concepts, and some additional
|
||||
useful utilities. The library uses these type checks internally
|
||||
and also provides them as public interfaces so users may use the
|
||||
same techniques to augment their own code. The use of these type
|
||||
checks helps provide more concise errors during compilation:
|
||||
|
||||
[table Stream Type Checks
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__get_lowest_layer `get_lowest_layer`]
|
||||
][
|
||||
Returns `T::lowest_layer_type` if it exists, else returns `T`.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__has_get_io_service `has_get_io_service`]
|
||||
][
|
||||
Determine if the `get_io_service` member function is present,
|
||||
and returns an __io_service__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_async_read_stream `is_async_read_stream`]
|
||||
][
|
||||
Determine if a type meets the requirements of __AsyncReadStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_async_stream `is_async_stream`]
|
||||
][
|
||||
Determine if a type meets the requirements of both __AsyncReadStream__
|
||||
and __AsyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_async_write_stream `is_async_write_stream`]
|
||||
][
|
||||
Determine if a type meets the requirements of __AsyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_completion_handler `is_completion_handler`]
|
||||
][
|
||||
Determine if a type meets the requirements of __CompletionHandler__,
|
||||
and is callable with a specified signature.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_sync_read_stream `is_sync_read_stream`]
|
||||
][
|
||||
Determine if a type meets the requirements of __SyncReadStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_sync_stream `is_sync_stream`]
|
||||
][
|
||||
Determine if a type meets the requirements of both __SyncReadStream__
|
||||
and __SyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_sync_write_stream `is_sync_write_stream`]
|
||||
][
|
||||
Determine if a type meets the requirements of __SyncWriteStream__.
|
||||
]]
|
||||
]
|
||||
|
||||
Using the type checks with `static_assert` on function or class template
|
||||
types will provide users with helpful error messages and prevent undefined
|
||||
behaviors. This example shows how a template function which writes to a
|
||||
synchronous stream may check its argument:
|
||||
|
||||
[snippet_core_3]
|
||||
|
||||
[endsect]
|
||||
161
src/beast/doc/3_3_buffers.qbk
Normal file
161
src/beast/doc/3_3_buffers.qbk
Normal file
@@ -0,0 +1,161 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Buffer Types]
|
||||
|
||||
__Asio__ provides the __ConstBufferSequence__ and __MutableBufferSequence__
|
||||
concepts, whose models provide ranges of buffers, as well as the __streambuf__
|
||||
class which encapsulates memory storage that may be automatically resized as
|
||||
required, where the memory is divided into an input sequence followed by an
|
||||
output sequence. The Networking TS (__N4588__) generalizes this `streambuf`
|
||||
interface into the __DynamicBuffer__ concept. Beast algorithms which require
|
||||
resizable buffers accept dynamic buffer objects as templated parameters.
|
||||
These metafunctions check if types match the buffer concepts:
|
||||
|
||||
[table Buffer Type Checks
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__is_dynamic_buffer `is_dynamic_buffer`]
|
||||
][
|
||||
Determine if a type meets the requirements of __DynamicBuffer__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_const_buffer_sequence `is_const_buffer_sequence`]
|
||||
][
|
||||
Determine if a type meets the requirements of __ConstBufferSequence__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__is_mutable_buffer_sequence `is_mutable_buffer_sequence`]
|
||||
][
|
||||
Determine if a type meets the requirements of __MutableBufferSequence__.
|
||||
]]
|
||||
]
|
||||
|
||||
Beast provides several dynamic buffer implementations for a variety
|
||||
of scenarios:
|
||||
|
||||
[table Dynamic Buffer Implementations
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__buffers_adapter `buffers_adapter`]
|
||||
][
|
||||
This wrapper adapts any __MutableBufferSequence__ into a
|
||||
__DynamicBuffer__ with an upper limit on the total size of the input and
|
||||
output areas equal to the size of the underlying mutable buffer sequence.
|
||||
The implementation does not perform heap allocations.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__drain_buffer `drain_buffer`]
|
||||
][
|
||||
A drain buffer has a small internal buffer and maximum size that
|
||||
uses no dynamic allocation. It always has a size of zero, and
|
||||
silently discards its input. This buffer may be passed to functions
|
||||
which store data in a dynamic buffer when the caller wishes to
|
||||
efficiently discard the data.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__flat_buffer `flat_buffer`]
|
||||
[link beast.ref.beast__basic_flat_buffer `basic_flat_buffer`]
|
||||
][
|
||||
Guarantees that input and output areas are buffer sequences with
|
||||
length one. Upon construction an optional upper limit to the total
|
||||
size of the input and output areas may be set. The basic container
|
||||
is an
|
||||
[@http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer [*AllocatorAwareContainer]].
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__multi_buffer `multi_buffer`]
|
||||
[link beast.ref.beast__basic_multi_buffer `basic_multi_buffer`]
|
||||
][
|
||||
Uses a sequence of one or more character arrays of varying sizes.
|
||||
Additional character array objects are appended to the sequence to
|
||||
accommodate changes in the size of the character sequence. The basic
|
||||
container is an
|
||||
[@http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer [*AllocatorAwareContainer]].
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__static_buffer `static_buffer`]
|
||||
[link beast.ref.beast__static_buffer `static_buffer_n`]
|
||||
][
|
||||
Provides the facilities of a dynamic buffer, subject to an upper
|
||||
limit placed on the total size of the input and output areas defined
|
||||
by a constexpr template parameter. The storage for the sequences are
|
||||
kept in the class; the implementation does not perform heap allocations.
|
||||
]]
|
||||
]
|
||||
|
||||
Network applications frequently need to manipulate buffer sequences. To
|
||||
facilitate working with buffers the library treats these sequences as
|
||||
a special type of range. Algorithms and wrappers are provided which
|
||||
transform these ranges efficiently using lazy evaluation. No memory
|
||||
allocations are used in the transformations; instead, they create
|
||||
lightweight iterators over the existing, unmodified memory buffers.
|
||||
Control of buffers is retained by the caller; ownership is not
|
||||
transferred.
|
||||
|
||||
[table Buffer Algorithms and Types
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__buffer_cat `buffer_cat`]
|
||||
][
|
||||
This functions returns a new buffer sequence which, when iterated,
|
||||
traverses the sequence which would be formed if all of the input buffer
|
||||
sequences were concatenated. With this routine, multiple calls to a
|
||||
stream's `write_some` function may be combined into one, eliminating
|
||||
expensive system calls.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__buffer_cat_view `buffer_cat_view`]
|
||||
][
|
||||
This class represents the buffer sequence formed by concatenating
|
||||
two or more buffer sequences. This is type of object returned by
|
||||
[link beast.ref.beast__buffer_cat `buffer_cat`].
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__buffer_prefix `buffer_prefix`]
|
||||
][
|
||||
This function returns a new buffer or buffer sequence which represents
|
||||
a prefix of the original buffers.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__buffer_prefix_view `buffer_prefix_view`]
|
||||
][
|
||||
This class represents the buffer sequence formed from a prefix of
|
||||
an existing buffer sequence. This is the type of buffer returned by
|
||||
[link beast.ref.beast__buffer_prefix.overload3 `buffer_prefix`].
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__consuming_buffers `consuming_buffers`]
|
||||
][
|
||||
This class wraps the underlying memory of an existing buffer sequence
|
||||
and presents a suffix of the original sequence. The length of the suffix
|
||||
may be progressively shortened. This lets callers work with sequential
|
||||
increments of a buffer sequence.
|
||||
]]
|
||||
]
|
||||
|
||||
These two functions facilitate buffer interoperability with standard
|
||||
output streams.
|
||||
|
||||
[table Buffer Output Streams
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__buffers `buffers`]
|
||||
][
|
||||
This function wraps a __ConstBufferSequence__ so it may be
|
||||
used with `operator<<` and `std::ostream`.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__ostream `ostream`]
|
||||
][
|
||||
This function returns a `std::ostream` which wraps a dynamic buffer.
|
||||
Characters sent to the stream using `operator<<` are stored in the
|
||||
dynamic buffer.
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
38
src/beast/doc/3_4_files.qbk
Normal file
38
src/beast/doc/3_4_files.qbk
Normal file
@@ -0,0 +1,38 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:files Files]
|
||||
|
||||
Often when implementing network algorithms such as servers, it is necessary
|
||||
to interact with files on the system. Beast defines the __File__ concept
|
||||
and several models to facilitate cross-platform interaction with the
|
||||
underlying filesystem:
|
||||
|
||||
[table File Types
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__file_stdio `file_stdio`]
|
||||
][
|
||||
This implementation of __File__ uses the C++ standard library
|
||||
facilities obtained by including `<cstdio>`.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__file_win32 `file_win32`]
|
||||
][
|
||||
This implements a __File__ for the Win32 API. It provides low level
|
||||
access to the native file handle when necessary.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__file_posix `file_posix`]
|
||||
][
|
||||
For POSIX systems, this class provides a suitable implementation
|
||||
of __File__ which wraps the native file descriptor and provides
|
||||
it if necessary.
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
236
src/beast/doc/3_5_composed.qbk
Normal file
236
src/beast/doc/3_5_composed.qbk
Normal file
@@ -0,0 +1,236 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Writing Composed Operations]
|
||||
[block'''<?dbhtml stop-chunking?>''']
|
||||
|
||||
Asynchronous operations are started by calling a free function or member
|
||||
function known as an asynchronous ['__async_initfn__]. This function accepts
|
||||
parameters specific to the operation as well as a "completion token." The
|
||||
token is either a completion handler, or a type defining how the caller is
|
||||
informed of the asynchronous operation result. __Asio__ comes with the
|
||||
special tokens __use_future__ and __yield_context__ for using futures
|
||||
and coroutines respectively. This system of customizing the return value
|
||||
and method of completion notification is known as the
|
||||
['Extensible Asynchronous Model] described in __N3747__, and a built in
|
||||
to __N4588__. Here is an example of an initiating function which reads a
|
||||
line from the stream and echoes it back. This function is developed
|
||||
further in the next section:
|
||||
|
||||
[example_core_echo_op_1]
|
||||
|
||||
Authors using Beast can reuse the library's primitives to create their
|
||||
own initiating functions for performing a series of other, intermediate
|
||||
asynchronous operations before invoking a final completion handler.
|
||||
The set of intermediate actions produced by an initiating function is
|
||||
known as a
|
||||
[@http://blog.think-async.com/2009/08/composed-operations-coroutines-and-code.html ['composed operation]].
|
||||
To ensure full interoperability and well-defined behavior, __Asio__ imposes
|
||||
requirements on the implementation of composed operations. These classes
|
||||
and functions make it easier to develop initiating functions and their
|
||||
composed operations:
|
||||
|
||||
[table Asynchronous Helpers
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__async_completion `async_completion`]
|
||||
][
|
||||
This class aggregates the completion handler customization point and
|
||||
the asynchronous initiation function return value customization point
|
||||
into a single object which exposes the appropriate output types for the
|
||||
given input types, and also contains boilerplate that is necessary to
|
||||
implement an initiation function using the Extensible Model.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__async_return_type `async_return_type`]
|
||||
][
|
||||
This template alias determines the return value of an asynchronous
|
||||
initiation function given the completion token and signature. It is used
|
||||
by asynchronous initiation functions to meet the requirements of the
|
||||
Extensible Asynchronous Model.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__bind_handler `bind_handler`]
|
||||
][
|
||||
This function returns a new, nullary completion handler which when
|
||||
invoked with no arguments invokes the original completion handler with a
|
||||
list of bound arguments. The invocation is made from the same implicit
|
||||
or explicit strand as that which would be used to invoke the original
|
||||
handler. This is accomplished by using the correct overload of
|
||||
`asio_handler_invoke` associated with the original completion handler.
|
||||
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__handler_alloc `handler_alloc`]
|
||||
][
|
||||
This class meets the requirements of [*Allocator], and uses any custom
|
||||
memory allocation and deallocation hooks associated with a given handler.
|
||||
It is useful for when a composed operation requires temporary dynamic
|
||||
allocations to achieve its result. Memory allocated using this allocator
|
||||
must be freed before the final completion handler is invoked.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__handler_ptr `handler_ptr`]
|
||||
][
|
||||
This is a smart pointer container used to manage the internal state of a
|
||||
composed operation. It is useful when the state is non trivial. For example
|
||||
when the state has non-copyable or expensive to copy types. The container
|
||||
takes ownership of the final completion handler, and provides boilerplate
|
||||
to invoke the final handler in a way that also deletes the internal state.
|
||||
The internal state is allocated using the final completion handler's
|
||||
associated allocator, benefiting from all handler memory management
|
||||
optimizations transparently.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__handler_type `handler_type`]
|
||||
][
|
||||
This template alias converts a completion token and signature to the
|
||||
correct completion handler type. It is used in the implementation of
|
||||
asynchronous initiation functions to meet the requirements of the
|
||||
Extensible Asynchronous Model.
|
||||
]]
|
||||
]
|
||||
|
||||
|
||||
|
||||
[section Echo]
|
||||
|
||||
This example develops an initiating function called [*echo].
|
||||
The operation will read up to the first newline on a stream, and
|
||||
then write the same line including the newline back on the stream.
|
||||
The implementation performs both reading and writing, and has a
|
||||
non-trivially-copyable state.
|
||||
First we define the input parameters and results, then declare our
|
||||
initiation function. For our echo operation the only inputs are the
|
||||
stream and the completion token. The output is the error code which
|
||||
is usually included in all completion handler signatures.
|
||||
|
||||
[example_core_echo_op_2]
|
||||
|
||||
Now that we have a declaration, we will define the body of the function.
|
||||
We want to achieve the following goals: perform static type checking on
|
||||
the input parameters, set up the return value as per __N3747__, and launch
|
||||
the composed operation by constructing the object and invoking it.
|
||||
|
||||
[example_core_echo_op_3]
|
||||
|
||||
The initiating function contains a few relatively simple parts. There is
|
||||
the customization of the return value type, static type checking, building
|
||||
the return value type using the helper, and creating and launching the
|
||||
composed operation object. The [*`echo_op`] object does most of the work
|
||||
here, and has a somewhat non-trivial structure. This structure is necessary
|
||||
to meet the stringent requirements of composed operations (described in more
|
||||
detail in the __Asio__ documentation). We will touch on these requirements
|
||||
without explaining them in depth.
|
||||
|
||||
Here is the boilerplate present in all composed operations written
|
||||
in this style:
|
||||
|
||||
[example_core_echo_op_4]
|
||||
|
||||
Next is to implement the function call operator. Our strategy is to make our
|
||||
composed object meet the requirements of a completion handler by being copyable
|
||||
(also movable), and by providing the function call operator with the correct
|
||||
signature. Rather than using `std::bind` or `boost::bind`, which destroys
|
||||
the type information and therefore breaks the allocation and invocation
|
||||
hooks, we will simply pass `std::move(*this)` as the completion handler
|
||||
parameter for any operations that we initiate. For the move to work correctly,
|
||||
care must be taken to ensure that no access to data members are made after the
|
||||
move takes place. Here is the implementation of the function call operator for
|
||||
this echo operation:
|
||||
|
||||
[example_core_echo_op_5]
|
||||
|
||||
This is the most important element of writing a composed operation, and
|
||||
the part which is often neglected or implemented incorrectly. It is the
|
||||
declaration and definition of the "handler hooks". There are four hooks:
|
||||
|
||||
[table Handler Hooks
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/asio_handler_invoke.html `asio_handler_invoke`]
|
||||
][
|
||||
Default invoke function for handlers. This hooking function ensures
|
||||
that the invoked method used for the final handler is accessible at
|
||||
each intermediate step.
|
||||
]]
|
||||
[[
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/asio_handler_allocate.html `asio_handler_allocate`]
|
||||
][
|
||||
Default allocation function for handlers. Implement `asio_handler_allocate`
|
||||
and `asio_handler_deallocate` for your own handlers to provide custom
|
||||
allocation for temporary objects.
|
||||
]]
|
||||
[[
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/asio_handler_deallocate.html `asio_handler_deallocate`]
|
||||
][
|
||||
Default deallocation function for handlers. Implement `asio_handler_allocate`
|
||||
and `asio_handler_deallocate` for your own handlers to provide custom
|
||||
allocation for temporary objects.
|
||||
]]
|
||||
[[
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/asio_handler_is_continuation.html `asio_handler_is_continuation`]
|
||||
][
|
||||
Default continuation function for handlers. Implement
|
||||
`asio_handler_is_continuation` for your own handlers to indicate when
|
||||
a handler represents a continuation.
|
||||
]]
|
||||
]
|
||||
|
||||
Our composed operation stores the final handler and performs its own
|
||||
intermediate asynchronous operations. To ensure that I/O objects, in this
|
||||
case the stream, are accessed safely it is important to use the same method
|
||||
to invoke intermediate handlers as that used to invoke the final handler.
|
||||
Similarly, for the memory allocation hooks our composed operation should use
|
||||
the same hooks as those used by the final handler. And finally for the
|
||||
`asio_is_continuation` hook, we want to return `true` for any intermediate
|
||||
asynchronous operations we perform after the first one, since those represent
|
||||
continuations. For the first asynchronous operation we perform, the hook should
|
||||
return `true` only if the final handler also represents a continuation. Our
|
||||
implementation of the hooks will forward the call to the corresponding
|
||||
overloads of the final handler:
|
||||
|
||||
[example_core_echo_op_6]
|
||||
|
||||
There are some common mistakes that should be avoided when writing
|
||||
composed operations:
|
||||
|
||||
* Type erasing the final handler. This will cause undefined behavior.
|
||||
|
||||
* Not using `std::addressof` to get the address of the handler.
|
||||
|
||||
* Forgetting to include a return statement after calling an
|
||||
initiating function.
|
||||
|
||||
* Calling a synchronous function by accident. In general composed
|
||||
operations should not block for long periods of time, since this
|
||||
ties up a thread running on the __io_service__.
|
||||
|
||||
* Forgetting to overload `asio_handler_invoke` for the composed
|
||||
operation. This will cause undefined behavior if someone calls
|
||||
the initiating function with a strand-wrapped function object,
|
||||
and there is more than thread running on the `io_service`.
|
||||
|
||||
* For operations which complete immediately (i.e. without calling an
|
||||
intermediate initiating function), forgetting to use `io_service::post`
|
||||
to invoke the final handler. This breaks the following initiating
|
||||
function guarantee: ['Regardless of whether the asynchronous operation
|
||||
completes immediately or not, the handler will not be invoked from
|
||||
within this function. Invocation of the handler will be performed
|
||||
in a manner equivalent to using `boost::asio::io_service::post`].
|
||||
The function
|
||||
[link beast.ref.beast__bind_handler `bind_handler`]
|
||||
is provided for this purpose.
|
||||
|
||||
A complete, runnable version of this example may be found in the examples
|
||||
directory.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
67
src/beast/doc/3_6_detect_ssl.qbk
Normal file
67
src/beast/doc/3_6_detect_ssl.qbk
Normal file
@@ -0,0 +1,67 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Example: Detect SSL]
|
||||
|
||||
In this example we will build a simple function to detect the presence
|
||||
of the SSL handshake given an input buffer sequence. Then we build on
|
||||
the example by adding a synchronous stream algorithm. Finally, we
|
||||
implemement an asynchronous detection function using a composed operation.
|
||||
This SSL detector may be used to allow a server to accept both SSL/TLS and
|
||||
unencrypted connections at the same port.
|
||||
|
||||
Here is the declaration for a function to detect the SSL client handshake.
|
||||
The input to the function is simply a buffer sequence, no stream. This
|
||||
allows the detection algorithm to be used elsewhere.
|
||||
|
||||
[example_core_detect_ssl_1]
|
||||
|
||||
The implementation checks the buffer for the presence of the SSL
|
||||
Handshake message octet sequence and returns an apporopriate value:
|
||||
|
||||
[example_core_detect_ssl_2]
|
||||
|
||||
Now we define a stream operation. We start with the simple,
|
||||
synchronous version which takes the stream and buffer as input:
|
||||
|
||||
[example_core_detect_ssl_3]
|
||||
|
||||
The synchronous algorithm is the model for building the asynchronous
|
||||
operation which has more boilerplate. First, we declare the asynchronous
|
||||
initiating function:
|
||||
|
||||
[example_core_detect_ssl_4]
|
||||
|
||||
The implementation of the initiating function is straightforward
|
||||
and contains mostly boilerplate. It is to construct the return
|
||||
type customization helper to obtain the actual handler, and
|
||||
then create the composed operation and launch it. The actual
|
||||
code for interacting with the stream is in the composed operation,
|
||||
which is written as a separate class.
|
||||
|
||||
[example_core_detect_ssl_5]
|
||||
|
||||
Now we will declare our composed operation. There is a considerable
|
||||
amount of necessary boilerplate to get this right, but the result
|
||||
is worth the effort.
|
||||
|
||||
[example_core_detect_ssl_6]
|
||||
|
||||
The boilerplate is all done, and now we need to implement the function
|
||||
call operator that turns this composed operation a completion handler
|
||||
with the signature `void(error_code, std::size_t)` which is exactly
|
||||
the signature needed when performing asynchronous reads. This function
|
||||
is a transformation of the synchronous version of `detect_ssl` above,
|
||||
but with the inversion of flow that characterizes code written in the
|
||||
callback style:
|
||||
|
||||
[example_core_detect_ssl_7]
|
||||
|
||||
This SSL detector is used by the server framework in the example
|
||||
directory.
|
||||
|
||||
[endsect]
|
||||
91
src/beast/doc/5_00_http.qbk
Normal file
91
src/beast/doc/5_00_http.qbk
Normal file
@@ -0,0 +1,91 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Using HTTP]
|
||||
|
||||
[warning
|
||||
Higher level functions such as Basic
|
||||
Authentication, mime/multipart encoding, cookies, automatic handling
|
||||
of redirects, gzipped transfer encodings, caching, or proxying (to name
|
||||
a few) are not directly provided, but nothing stops users from creating
|
||||
these features using Beast's HTTP message types.
|
||||
]
|
||||
|
||||
This library offers programmers simple and performant models of HTTP messages
|
||||
and their associated operations including synchronous, asynchronous, and
|
||||
buffer-oriented parsing and serialization of messages in the HTTP/1 wire
|
||||
format using __Asio__. Specifically, the library provides:
|
||||
|
||||
[variablelist
|
||||
[
|
||||
[Message Containers]
|
||||
[
|
||||
Complete HTTP messages are modeled using the __message__ class,
|
||||
with possible user customizations.
|
||||
]
|
||||
][
|
||||
[Stream Reading]
|
||||
[
|
||||
The functions
|
||||
[link beast.ref.beast__http__read `read`],
|
||||
[link beast.ref.beast__http__read_header `read_header`],
|
||||
[link beast.ref.beast__http__read_some `read_some`],
|
||||
[link beast.ref.beast__http__async_read `async_read`],
|
||||
[link beast.ref.beast__http__async_read_header `async_read_header`], and
|
||||
[link beast.ref.beast__http__async_read_some `async_read_some`]
|
||||
read HTTP/1 message data from a
|
||||
[link beast.concept.streams stream].
|
||||
]
|
||||
][
|
||||
[Stream Writing]
|
||||
[
|
||||
The functions
|
||||
[link beast.ref.beast__http__write `write`],
|
||||
[link beast.ref.beast__http__write_header `write_header`],
|
||||
[link beast.ref.beast__http__write_some `write_some`],
|
||||
[link beast.ref.beast__http__async_write `async_write`],
|
||||
[link beast.ref.beast__http__async_write_header `async_write_header`], and
|
||||
[link beast.ref.beast__http__async_write_some `async_write_some`]
|
||||
write HTTP/1 message data to a
|
||||
[link beast.concept.streams stream].
|
||||
]
|
||||
][
|
||||
[Serialization]
|
||||
[
|
||||
The __serializer__ produces a series of octet buffers
|
||||
conforming to the __rfc7230__ wire representation of
|
||||
a __message__.
|
||||
]
|
||||
][
|
||||
[Parsing]
|
||||
[
|
||||
The __parser__ attempts to convert a series of octet
|
||||
buffers into a __message__.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[note
|
||||
This documentation assumes some familiarity with __Asio__ and
|
||||
the HTTP protocol specification described in __rfc7230__. Sample
|
||||
code and identifiers mentioned in this section is written as if
|
||||
these declarations are in effect:
|
||||
|
||||
[http_snippet_1]
|
||||
]
|
||||
|
||||
[include 5_01_primer.qbk]
|
||||
[include 5_02_message.qbk]
|
||||
[include 5_03_streams.qbk]
|
||||
[include 5_04_serializer_streams.qbk]
|
||||
[include 5_05_parser_streams.qbk]
|
||||
[include 5_06_serializer_buffers.qbk]
|
||||
[include 5_07_parser_buffers.qbk]
|
||||
[include 5_08_custom_body.qbk]
|
||||
[include 5_09_custom_parsers.qbk]
|
||||
|
||||
[endsect]
|
||||
153
src/beast/doc/5_01_primer.qbk
Normal file
153
src/beast/doc/5_01_primer.qbk
Normal file
@@ -0,0 +1,153 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Protocol Primer]
|
||||
|
||||
The HTTP protocol defines the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-2.1 client and server roles]:
|
||||
clients send requests and servers send back responses. When a client and
|
||||
server have established a connection, the client sends a series of requests
|
||||
while the server sends back at least one response for each received request
|
||||
in the order those requests were received.
|
||||
|
||||
A request or response is an
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3 HTTP message]
|
||||
(referred to hereafter as "message") having two parts:
|
||||
a header with structured metadata and an optional variable-length body
|
||||
holding arbitrary data. A serialized header is one or more text lines
|
||||
where each line ends in a carriage return followed by linefeed (`"\r\n"`).
|
||||
An empty line marks the end of the header. The first line in the header
|
||||
is called the ['start-line]. The contents of the start line contents are
|
||||
different for requests and responses.
|
||||
|
||||
Every message contains a set of zero or more field name/value pairs,
|
||||
collectively called "fields". The names and values are represented using
|
||||
text strings with various requirements. A serialized field contains the
|
||||
field name, then a colon followed by a space (`": "`), and finally the field
|
||||
value with a trailing CRLF.
|
||||
|
||||
[heading Requests]
|
||||
|
||||
Clients send requests, which contain a
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.1.1 method]
|
||||
and
|
||||
[@https://tools.ietf.org/html/rfc7230#section-5.3 request-target],
|
||||
and
|
||||
[@https://tools.ietf.org/html/rfc7230#section-2.6 HTTP-version].
|
||||
The method identifies the operation to be performed while the target
|
||||
identifies the object on the server to which the operation applies.
|
||||
The version is almost always 1.1, but older programs sometimes use 1.0.
|
||||
|
||||
[table
|
||||
[[Serialized Request][Description]]
|
||||
[[
|
||||
```
|
||||
GET / HTTP/1.1\r\n
|
||||
User-Agent: Beast\r\n
|
||||
\r\n
|
||||
```
|
||||
][
|
||||
This request has a method of "GET", a target of "/", and indicates
|
||||
HTTP version 1.1. It contains a single field called "User-Agent"
|
||||
whose value is "Beast". There is no message body.
|
||||
]]
|
||||
]
|
||||
|
||||
[heading Responses]
|
||||
|
||||
Servers send responses, which contain a
|
||||
[@https://tools.ietf.org/html/rfc7231#section-6 status-code],
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.1.2 reason-phrase], and
|
||||
[@https://tools.ietf.org/html/rfc7230#section-2.6 HTTP-version].
|
||||
The reason phrase is
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.1.2 obsolete]:
|
||||
clients SHOULD ignore the reason-phrase content. Here is a response which
|
||||
includes a body. The special
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.3.2 Content-Length]
|
||||
field informs the remote host of the size of the body which follows.
|
||||
|
||||
[table
|
||||
[[Serialized Response][Description]]
|
||||
[[
|
||||
```
|
||||
HTTP/1.1 200 OK\r\n
|
||||
Server: Beast\r\n
|
||||
Content-Length: 13\r\n
|
||||
\r\n
|
||||
Hello, world!
|
||||
```
|
||||
][
|
||||
This response has a
|
||||
[@https://tools.ietf.org/html/rfc7231#section-6 200 status code]
|
||||
meaning the operation requested completed successfully. The obsolete
|
||||
reason phrase is "OK". It specifies HTTP version 1.1, and contains
|
||||
a body 13 octets in size with the text "Hello, world!".
|
||||
]]
|
||||
]
|
||||
|
||||
[heading Body]
|
||||
|
||||
Messages may optionally carry a body. The size of the message body
|
||||
is determined by the semantics of the message and the special fields
|
||||
Content-Length and Transfer-Encoding.
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.3 rfc7230 section 3.3]
|
||||
provides a comprehensive description for how the body length is
|
||||
determined.
|
||||
|
||||
[heading Special Fields]
|
||||
|
||||
Certain fields appearing in messages are special. The library understands
|
||||
these fields when performing serialization and parsing, taking automatic
|
||||
action as needed when the fields are parsed in a message and also setting
|
||||
the fields if the caller requests it.
|
||||
|
||||
[table Special Fields
|
||||
[[Field][Description]]
|
||||
[
|
||||
[
|
||||
[@https://tools.ietf.org/html/rfc7230#section-6.1 [*`Connection`]]
|
||||
|
||||
[@https://tools.ietf.org/html/rfc7230#appendix-A.1.2 [*`Proxy-Connection`]]
|
||||
][
|
||||
This field allows the sender to indicate desired control options
|
||||
for the current connection. Common values include "close",
|
||||
"keep-alive", and "upgrade".
|
||||
]
|
||||
][
|
||||
[
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.3.2 [*`Content-Length`]]
|
||||
][
|
||||
When present, this field informs the recipient about the exact
|
||||
size in bytes of the body which follows the message header.
|
||||
]
|
||||
][
|
||||
[
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.3.1 [*`Transfer-Encoding`]]
|
||||
][
|
||||
This optional field lists the names of the sequence of transfer codings
|
||||
that have been (or will be) applied to the content payload to form
|
||||
the message body.
|
||||
|
||||
Beast understands the "chunked" coding scheme when it is the last
|
||||
(outermost) applied coding. The library will automatically apply
|
||||
chunked encoding when the content length is not known ahead of time
|
||||
during serialization, and the library will automatically remove chunked
|
||||
encoding from parsed messages when present.
|
||||
]
|
||||
][
|
||||
[
|
||||
[@https://tools.ietf.org/html/rfc7230#section-6.7 [*`Upgrade`]]
|
||||
][
|
||||
The Upgrade header field provides a mechanism to transition from
|
||||
HTTP/1.1 to another protocol on the same connection. For example, it
|
||||
is the mechanism used by WebSocket's initial HTTP handshake to
|
||||
establish a WebSocket connection.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
231
src/beast/doc/5_02_message.qbk
Normal file
231
src/beast/doc/5_02_message.qbk
Normal file
@@ -0,0 +1,231 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Message Containers]
|
||||
|
||||
Beast provides a single class template __message__ and some aliases which
|
||||
model HTTP/1 and
|
||||
[@https://tools.ietf.org/html/rfc7540 HTTP/2]
|
||||
messages:
|
||||
|
||||
[table Message
|
||||
[[Name][Description]]
|
||||
[[
|
||||
__message__
|
||||
][
|
||||
```
|
||||
/// An HTTP message
|
||||
template<
|
||||
bool isRequest, // `true` for requests, `false` for responses
|
||||
class Body, // Controls the container and algorithms used for the body
|
||||
class Fields = fields> // The type of container to store the fields
|
||||
class message;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__request `request`]
|
||||
][
|
||||
```
|
||||
/// A typical HTTP request
|
||||
template<class Body, class Fields = fields>
|
||||
using request = message<true, Body, Fields>;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__response `response`]
|
||||
][
|
||||
```
|
||||
/// A typical HTTP response
|
||||
template<class Body, class Fields = fields>
|
||||
using response = message<false, Body, Fields>;
|
||||
```
|
||||
]]
|
||||
]
|
||||
|
||||
The container offers value semantics including move and copy if supported
|
||||
by __Body__ and __Fields__. User defined template function parameters can
|
||||
accept any message, or can use partial specialization to accept just
|
||||
requests or responses. The default __fields__ is a provided associative
|
||||
container using the standard allocator and supporting modification and
|
||||
inspection of fields. As per __rfc7230__, a non-case-sensitive comparison
|
||||
is used for field names. User defined types for fields are possible.
|
||||
The `Body` type determines the type of the container used to represent the
|
||||
body as well as the algorithms for transferring buffers to and from the
|
||||
the container. The library comes with a collection of common body types.
|
||||
As with fields, user defined body types are possible.
|
||||
|
||||
Sometimes it is desired to only work with a header. Beast provides a single
|
||||
class template __header__ and some aliases to model HTTP/1 and HTTP/2 headers:
|
||||
|
||||
[table Header
|
||||
[[Name][Description]]
|
||||
[[
|
||||
__header__
|
||||
][
|
||||
```
|
||||
/// An HTTP header
|
||||
template<
|
||||
bool isRequest, // `true` for requests, `false` for responses
|
||||
class Fields = fields> // The type of container to store the fields
|
||||
class header;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__request_header `request_header`]
|
||||
][
|
||||
```
|
||||
/// A typical HTTP request header
|
||||
template<class Fields>
|
||||
using request_header = header<true, Fields>;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__response_header `response_header`]
|
||||
][
|
||||
```
|
||||
/// A typical HTTP response header
|
||||
template<class Fields>
|
||||
using response_header = header<false, Fields>;
|
||||
```
|
||||
]]
|
||||
]
|
||||
|
||||
Requests and responses share the version, fields, and body but have
|
||||
a few members unique to the type. This is implemented by declaring the
|
||||
header classes as partial specializations of `isRequest`. __message__
|
||||
is derived from __header__; a message may be passed as an argument to
|
||||
a function taking a suitably typed header as a parameter. Additionally,
|
||||
`header` is publicly derived from `Fields`; a message inherits all the
|
||||
member functions of `Fields`. This diagram shows the inheritance
|
||||
relationship between header and message, along with some of the
|
||||
notable differences in members in each partial specialization:
|
||||
|
||||
[$images/message.png [width 730px] [height 410px]]
|
||||
|
||||
[heading:body Body Types]
|
||||
|
||||
Beast defines the __Body__ concept, which determines both the type of
|
||||
the [link beast.ref.beast__http__message.body `message::body`] member
|
||||
(as seen in the diagram above) and may also include algorithms for
|
||||
transferring buffers in and out. These algorithms are used during
|
||||
parsing and serialization. Users may define their own body types which
|
||||
meet the requirements, or use the ones that come with the library:
|
||||
|
||||
[table
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__http__buffer_body `buffer_body`]
|
||||
][
|
||||
A body whose
|
||||
[link beast.ref.beast__http__buffer_body__value_type `value_type`]
|
||||
holds a raw pointer and size to a caller-provided buffer.
|
||||
This allows for serialization of body data coming from
|
||||
external sources, and incremental parsing of message body
|
||||
content using a fixed size buffer.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__dynamic_body `dynamic_body`]
|
||||
|
||||
[link beast.ref.beast__http__basic_dynamic_body `basic_dynamic_body`]
|
||||
][
|
||||
A body whose `value_type` is a __DynamicBuffer__. It inherits
|
||||
the insertion complexity of the underlying choice of dynamic buffer.
|
||||
Messages with this body type may be serialized and parsed.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__empty_body `empty_body`]
|
||||
][
|
||||
A special body with an empty `value_type` indicating that the
|
||||
message has no body. Messages with this body may be serialized
|
||||
and parsed; however, body octets received while parsing a message
|
||||
with this body will generate a unique error.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__file_body `file_body`]
|
||||
][
|
||||
This body is represented by a file opened for either reading or
|
||||
writing. Messages with this body may be serialized and parsed.
|
||||
HTTP algorithms will use the open file for reading and writing,
|
||||
for streaming and incremental sends and receives.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__span_body `span_body`]
|
||||
][
|
||||
A body whose `value_type` is a
|
||||
[link beast.ref.beast__span `span`],
|
||||
a non-owning reference to a single linear buffer of bytes.
|
||||
Messages with this body type may be serialized and parsed.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__basic_string_body `basic_string_body`]
|
||||
|
||||
[link beast.ref.beast__http__string_body `string_body`]
|
||||
][
|
||||
A body whose `value_type` is `std::basic_string` or `std::string`.
|
||||
Insertion complexity is amortized constant time, while capacity
|
||||
grows geometrically. Messages with this body type may be serialized
|
||||
and parsed. This is the type of body used in the examples.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__vector_body `vector_body`]
|
||||
][
|
||||
A body whose `value_type` is `std::vector`. Insertion complexity
|
||||
is amortized constant time, while capacity grows geometrically.
|
||||
Messages with this body type may be serialized and parsed.
|
||||
]]
|
||||
]
|
||||
|
||||
[heading Usage]
|
||||
|
||||
These examples show how to create and fill in request and response
|
||||
objects: Here we build an
|
||||
[@https://tools.ietf.org/html/rfc7231#section-4.3.1 HTTP GET]
|
||||
request with an empty message body:
|
||||
|
||||
[table Create Request
|
||||
[[Statements] [Serialized Result]]
|
||||
[[
|
||||
[http_snippet_2]
|
||||
][
|
||||
```
|
||||
GET /index.htm HTTP/1.1\r\n
|
||||
Accept: text/html\r\n
|
||||
User-Agent: Beast\r\n
|
||||
\r\n
|
||||
```
|
||||
]]
|
||||
]
|
||||
|
||||
In this code we create an HTTP response with a status code indicating success.
|
||||
This message has a body with a non-zero length. The function
|
||||
[link beast.ref.beast__http__message.prepare_payload `message::prepare_payload`]
|
||||
automatically sets the Content-Length or Transfer-Encoding field
|
||||
depending on the content and type of the `body` member. Use of this function
|
||||
is optional; these fields may also be set explicitly.
|
||||
|
||||
[table Create Response
|
||||
[[Statements] [Serialized Result]]
|
||||
[[
|
||||
[http_snippet_3]
|
||||
][
|
||||
```
|
||||
HTTP/1.1 200 OK\r\n
|
||||
Server: Beast\r\n
|
||||
Content-Length: 13\r\n
|
||||
\r\n
|
||||
Hello, world!
|
||||
```
|
||||
]]
|
||||
]
|
||||
|
||||
The implementation will automatically fill in the obsolete
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.1.2 reason-phrase]
|
||||
from the status code when serializing a message. Or it may
|
||||
be set directly using
|
||||
[link beast.ref.beast__http__header.reason.overload2 `header::reason`].
|
||||
|
||||
[endsect]
|
||||
107
src/beast/doc/5_03_streams.qbk
Normal file
107
src/beast/doc/5_03_streams.qbk
Normal file
@@ -0,0 +1,107 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Message Stream Operations]
|
||||
|
||||
Beast provides synchronous and asynchronous algorithms to parse and
|
||||
serialize HTTP/1 wire format messages on streams. These functions form
|
||||
the message-oriented stream interface:
|
||||
|
||||
[table Message Stream Operations
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__http__read.overload3 [*read]]
|
||||
][
|
||||
Read a __message__ from a __SyncReadStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_read.overload2 [*async_read]]
|
||||
][
|
||||
Read a __message__ from an __AsyncReadStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__write.overload1 [*write]]
|
||||
][
|
||||
Write a __message__ to a __SyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_write [*async_write]]
|
||||
][
|
||||
Write a __message__ to an __AsyncWriteStream__.
|
||||
]]
|
||||
]
|
||||
|
||||
All synchronous stream operations come in two varieties. One which throws
|
||||
an exception upon error, and another which accepts as the last parameter an
|
||||
argument of type [link beast.ref.beast__error_code `error_code&`]. If an error
|
||||
occurs this argument will be set to contain the error code.
|
||||
|
||||
|
||||
|
||||
[heading Reading]
|
||||
|
||||
Because a serialized header is not length-prefixed, algorithms which
|
||||
parse messages from a stream may read past the end of a message for
|
||||
efficiency. To hold this surplus data, all stream read operations use
|
||||
a passed-in __DynamicBuffer__ which must be persisted between calls.
|
||||
Each read operation may consume bytes remaining in the buffer, and
|
||||
leave behind new bytes. In this example we declare the buffer and a
|
||||
message variable, then read a complete HTTP request synchronously:
|
||||
|
||||
[http_snippet_4]
|
||||
|
||||
This example uses __flat_buffer__. Beast's __basic_parser__ is
|
||||
optimized for structured HTTP data located in a single contiguous
|
||||
(['flat]) memory buffer. When not using a flat buffer the implementation
|
||||
may perform an additional memory allocations to restructure the input
|
||||
into a single buffer for parsing.
|
||||
|
||||
[tip
|
||||
Other Implementations of __DynamicBuffer__ may avoid parser
|
||||
memory allocation by always returning buffer sequences of
|
||||
length one.
|
||||
]
|
||||
|
||||
Messages may also be read asynchronously. When performing asynchronous
|
||||
stream read operations the stream, buffer, and message variables must
|
||||
remain valid until the operation has completed. Beast asynchronous
|
||||
initiation functions use Asio's completion handler model. This call
|
||||
reads a message asynchronously and report the error code upon
|
||||
completion:
|
||||
|
||||
[http_snippet_5]
|
||||
|
||||
If a read stream algorithm cannot complete its operation without exceeding
|
||||
the maximum specified size of the dynamic buffer provided, the error
|
||||
[link beast.ref.beast__http__error `buffer_overflow`]
|
||||
is returned. This may be used to impose a limit on the maximum size of an
|
||||
HTTP message header for protection from buffer overflow attacks. The
|
||||
following code will print the error message:
|
||||
|
||||
[http_snippet_6]
|
||||
|
||||
|
||||
|
||||
[heading Writing]
|
||||
|
||||
A set of free functions allow serialization of an entire HTTP message to
|
||||
a stream. If a response has no declared content length and no chunked
|
||||
transfer encoding, then the end of the message is indicated by the server
|
||||
closing the connection. When sending such a response, Beast will return the
|
||||
[link beast.ref.beast__http__error `error::end_of_stream`]
|
||||
from the write algorithm to indicate
|
||||
to the caller that the connection should be closed. This example
|
||||
constructs and sends a response whose body length is determined by
|
||||
the number of octets received prior to the server closing the connection:
|
||||
|
||||
[http_snippet_7]
|
||||
|
||||
The asynchronous version could be used instead:
|
||||
|
||||
[http_snippet_8]
|
||||
|
||||
[endsect]
|
||||
150
src/beast/doc/5_04_serializer_streams.qbk
Normal file
150
src/beast/doc/5_04_serializer_streams.qbk
Normal file
@@ -0,0 +1,150 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Serializer Stream Operations]
|
||||
|
||||
Non-trivial algorithms need to do more than send entire messages
|
||||
at once, such as:
|
||||
|
||||
* Send the header first, and the body later.
|
||||
|
||||
* Set chunk extensions or trailers using a chunk decorator.
|
||||
|
||||
* Send a message incrementally: bounded work in each I/O cycle.
|
||||
|
||||
* Use a series of caller-provided buffers to represent the body.
|
||||
|
||||
These tasks may be performed by using the serializer stream interfaces.
|
||||
To use these interfaces, first construct a suitable object with
|
||||
the message to be sent:
|
||||
|
||||
[table Serializer
|
||||
[[Name][Description]]
|
||||
[[
|
||||
__serializer__
|
||||
][
|
||||
```
|
||||
/// Provides buffer oriented HTTP message serialization functionality.
|
||||
template<
|
||||
bool isRequest,
|
||||
class Body,
|
||||
class Fields = fields,
|
||||
class ChunkDecorator = no_chunk_decorator
|
||||
>
|
||||
class serializer;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__request_serializer `request_serializer`]
|
||||
][
|
||||
```
|
||||
/// A serializer for HTTP/1 requests
|
||||
template<
|
||||
class Body,
|
||||
class Fields = fields,
|
||||
class ChunkDecorator = no_chunk_decorator>
|
||||
using request_serializer = serializer<true, Body, Fields, ChunkDecorator>;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__response_serializer `response_serializer`]
|
||||
][
|
||||
```
|
||||
/// A serializer for HTTP/1 responses
|
||||
template<
|
||||
class Body,
|
||||
class Fields = fields,
|
||||
class ChunkDecorator = no_chunk_decorator>
|
||||
using response_serializer = serializer<false, Body, Fields, ChunkDecorator>;
|
||||
```
|
||||
]]
|
||||
]
|
||||
|
||||
The choices for template types must match the message passed on construction.
|
||||
This code creates an HTTP response and the corresponding serializer:
|
||||
|
||||
[http_snippet_10]
|
||||
|
||||
The stream operations which work on serializers are:
|
||||
|
||||
[table Serializer Stream Operations
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__http__write.overload1 [*write]]
|
||||
][
|
||||
Send everything in a __serializer__ to a __SyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_write.overload1 [*async_write]]
|
||||
][
|
||||
Send everything in a __serializer__ asynchronously to an __AsyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__write_header.overload1 [*write_header]]
|
||||
][
|
||||
Send only the header from a __serializer__ to a __SyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_write_header [*async_write_header]]
|
||||
][
|
||||
Send only the header from a __serializer__ asynchronously to an __AsyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__write_some.overload1 [*write_some]]
|
||||
][
|
||||
Send part of a __serializer__ to a __SyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_write_some [*async_write_some]]
|
||||
][
|
||||
Send part of a __serializer__ asynchronously to an __AsyncWriteStream__.
|
||||
]]
|
||||
]
|
||||
|
||||
Here is an example of using a serializer to send a message on a stream
|
||||
synchronously. This performs the same operation as calling `write(stream, m)`:
|
||||
|
||||
[http_snippet_12]
|
||||
|
||||
[heading Chunk Decorators]
|
||||
|
||||
When the message used to construct the serializer indicates the chunked
|
||||
transfer encoding, the serializer will automatically generate the proper
|
||||
encoding in the output buffers. __rfc7230__ defines additional fields
|
||||
called the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-4.1.1 chunk extensions]
|
||||
in chunks with body octets, and the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-4.1.2 chunked trailer part]
|
||||
for the final chunk. Applications that wish to emit chunk extensions
|
||||
and trailers may instantiate the serializer with a "chunk decorator" type,
|
||||
and pass an instance of the type upon construction. This decorator is
|
||||
a function object which, when invoked with a __ConstBufferSequence__,
|
||||
returns a
|
||||
[link beast.ref.beast__string_view `string_view`] containing either the extensions
|
||||
or the trailer. For chunks containing body data, the passed buffer will
|
||||
contain one or more corresponding body octets. The decorator may use this
|
||||
information as needed. For example, to compute a digest on the data and
|
||||
store it as a chunk extension. For the trailers, the serializer will
|
||||
invoke the decorator with a buffer sequence of size zero. Or more
|
||||
specifically, with an object of type
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/null_buffers.html `boost::asio::null_buffers`].
|
||||
|
||||
For body chunks the string returned by the decorator must follow the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-4.1.1 correct syntax]
|
||||
for the entire chunk extension. For the trailer, the returned string
|
||||
should consist of zero or more lines ending in a CRLF and containing
|
||||
a field name/value pair in the format prescribed by __rfc7230__. It
|
||||
is the responsibility of the decorator to manage returned string buffers.
|
||||
The implementation guarantees it will not reference previous strings
|
||||
after subsequent calls.
|
||||
|
||||
This defines a decorator which sets an extension variable `x` equal
|
||||
to the size of the chunk in bytes, and returns a single trailer field:
|
||||
|
||||
[http_snippet_17]
|
||||
|
||||
[endsect]
|
||||
138
src/beast/doc/5_05_parser_streams.qbk
Normal file
138
src/beast/doc/5_05_parser_streams.qbk
Normal file
@@ -0,0 +1,138 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Parser Stream Operations]
|
||||
|
||||
Non-trivial algorithms need to do more than receive entire messages
|
||||
at once, such as:
|
||||
|
||||
|
||||
* Receive the header first and body later.
|
||||
|
||||
* Receive a large body using a fixed-size buffer.
|
||||
|
||||
* Receive a message incrementally: bounded work in each I/O cycle.
|
||||
|
||||
* Defer the commitment to a __Body__ type until after reading the header.
|
||||
|
||||
These types of operations require callers to manage the lifetime of
|
||||
associated state, by constructing a class derived from __basic_parser__.
|
||||
Beast comes with the derived instance __parser__ which creates complete
|
||||
__message__ objects using the __basic_fields__ Fields container.
|
||||
|
||||
[table Parser
|
||||
[[Name][Description]]
|
||||
[[
|
||||
__parser__
|
||||
][
|
||||
```
|
||||
/// An HTTP/1 parser for producing a message.
|
||||
template<
|
||||
bool isRequest, // `true` to parse an HTTP request
|
||||
class Body, // The Body type for the resulting message
|
||||
class Allocator = std::allocator<char>> // The type of allocator for the header
|
||||
class parser
|
||||
: public basic_parser<...>;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__request_parser `request_parser`]
|
||||
][
|
||||
```
|
||||
/// An HTTP/1 parser for producing a request message.
|
||||
template<class Body, class Allocator = std::allocator<char>>
|
||||
using request_parser = parser<true, Body, Allocator>;
|
||||
```
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__response_parser `response_parser`]
|
||||
][
|
||||
```
|
||||
/// An HTTP/1 parser for producing a response message.
|
||||
template<class Body, class Allocator = std::allocator<char>>
|
||||
using response_parser = parser<false, Body, Allocator>;
|
||||
```
|
||||
]]
|
||||
]
|
||||
|
||||
[note
|
||||
The __basic_parser__ and classes derived from it handle octet streams
|
||||
serialized in the HTTP/1 format described in __rfc7230__.
|
||||
]
|
||||
|
||||
The stream operations which work on parsers are:
|
||||
|
||||
[table Parser Stream Operations
|
||||
[[Name][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__http__read.overload1 [*read]]
|
||||
][
|
||||
Read everything into a parser from a __SyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_read.overload1 [*async_read]]
|
||||
][
|
||||
Read everything into a parser asynchronously from an __AsyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__read_header.overload1 [*read_header]]
|
||||
][
|
||||
Read only the header octets into a parser from a __SyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_read_header [*async_read_header]]
|
||||
][
|
||||
Read only the header octets into a parser asynchronously from an __AsyncWriteStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__read_some.overload1 [*read_some]]
|
||||
][
|
||||
Read some octets into a parser from a __SyncReadStream__.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__async_read_some [*async_read_some]]
|
||||
][
|
||||
Read some octets into a parser asynchronously from an __AsyncWriteStream__.
|
||||
]]
|
||||
]
|
||||
|
||||
As with message stream operations, parser stream operations require a
|
||||
persisted __DynamicBuffer__ for holding unused octets from the stream.
|
||||
The basic parser implementation is optimized for the case where this dynamic
|
||||
buffer stores its input sequence in a single contiguous memory buffer. It is
|
||||
advised to use an instance of __flat_buffer__, __static_buffer__, or
|
||||
__static_buffer_n__ for this purpose, although a user defined instance of
|
||||
__DynamicBuffer__ which produces input sequences of length one is also suitable.
|
||||
|
||||
The parser contains a message constructed internally. Arguments passed
|
||||
to the parser's constructor are forwarded into the message container.
|
||||
The caller can access the message inside the parser by calling
|
||||
[link beast.ref.beast__http__parser.get `parser::get`].
|
||||
If the `Fields` and `Body` types are [*MoveConstructible], the caller
|
||||
can take ownership of the message by calling
|
||||
[link beast.ref.beast__http__parser.release `parser::release`]. In this example
|
||||
we read an HTTP response with a string body using a parser, then print
|
||||
the response:
|
||||
|
||||
[http_snippet_13]
|
||||
|
||||
|
||||
|
||||
[section Incremental Read]
|
||||
|
||||
This function uses
|
||||
[link beast.ref.beast__http__buffer_body `buffer_body`]
|
||||
and parser stream operations to read a message body progressively
|
||||
using a small, fixed-size buffer:
|
||||
|
||||
[example_incremental_read]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
79
src/beast/doc/5_06_serializer_buffers.qbk
Normal file
79
src/beast/doc/5_06_serializer_buffers.qbk
Normal file
@@ -0,0 +1,79 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Buffer-Oriented Serializing]
|
||||
[block'''<?dbhtml stop-chunking?>''']
|
||||
|
||||
An instance of __serializer__ can be invoked directly, without using
|
||||
the provided stream operations. This could be useful for implementing
|
||||
algorithms on objects whose interface does not conform to __Stream__.
|
||||
For example, a
|
||||
[@https://github.com/libuv/libuv *libuv* socket].
|
||||
The serializer interface is interactive; the caller invokes it repeatedly
|
||||
to produce buffers until all of the buffers have been generated. Then the
|
||||
serializer is destroyed.
|
||||
|
||||
To obtain the serialized next buffer sequence, call
|
||||
[link beast.ref.beast__http__serializer.next `serializer::next`].
|
||||
Then, call
|
||||
[link beast.ref.beast__http__serializer.consume `serializer::consume`]
|
||||
to indicate the number of bytes consumed. This updates the next
|
||||
set of buffers to be returned, if any.
|
||||
`serializer::next` takes an error code parameter and invokes a visitor
|
||||
argument with the error code and buffer of unspecified type. In C++14
|
||||
this is easily expressed with a generic lambda. The function
|
||||
[link beast.ref.beast__http__serializer.is_done `serializer::is_done`]
|
||||
will return `true` when all the buffers have been produced. This C++14
|
||||
example prints the buffers to standard output:
|
||||
|
||||
[http_snippet_14]
|
||||
|
||||
Generic lambda expressions are only available in C++14 or later. A functor
|
||||
with a templated function call operator is necessary to use C++11 as shown:
|
||||
|
||||
[http_snippet_15]
|
||||
|
||||
[heading Split Serialization]
|
||||
|
||||
In some cases, such as the handling of the
|
||||
[@https://tools.ietf.org/html/rfc7231#section-5.1.1 Expect: 100-continue]
|
||||
field, it may be desired to first serialize the header, perform some other
|
||||
action, and then continue with serialization of the body. This is
|
||||
accomplished by calling
|
||||
[link beast.ref.beast__http__serializer.split `serializer::split`]
|
||||
with a boolean indicating that when buffers are produced, the last buffer
|
||||
containing serialized header octets will not contain any octets corresponding
|
||||
to the body. The function
|
||||
[link beast.ref.beast__http__serializer.is_header_done `serializer::is_header_done`]
|
||||
informs the caller whether the header been serialized fully. In this
|
||||
C++14 example we print the header first, followed by the body:
|
||||
|
||||
[http_snippet_16]
|
||||
|
||||
|
||||
|
||||
[section Write To std::ostream]
|
||||
|
||||
The standard library provides the type `std::ostream` for performing high
|
||||
level write operations on character streams. The variable `std::cout` is
|
||||
based on this output stream. This example uses the buffer oriented interface
|
||||
of __serializer__ to write an HTTP message to a `std::ostream`:
|
||||
|
||||
[example_http_write_ostream]
|
||||
|
||||
[tip
|
||||
Serializing to a `std::ostream` could be implemented using an alternate
|
||||
strategy: adapt the `std::ostream` interface to a __SyncWriteStream__,
|
||||
enabling use with the library's existing stream algorithms. This is
|
||||
left as an exercise for the reader.
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
107
src/beast/doc/5_07_parser_buffers.qbk
Normal file
107
src/beast/doc/5_07_parser_buffers.qbk
Normal file
@@ -0,0 +1,107 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Buffer-Oriented Parsing]
|
||||
[block'''<?dbhtml stop-chunking?>''']
|
||||
|
||||
A subclass of __basic_parser__ can be invoked directly, without using
|
||||
the provided stream operations. This could be useful for implementing
|
||||
algorithms on objects whose interface does not conform to __Stream__.
|
||||
For example, a
|
||||
[@http://zeromq.org/ *ZeroMQ* socket].
|
||||
The basic parser interface is interactive; the caller invokes the function
|
||||
[link beast.ref.beast__http__basic_parser.put `basic_parser::put`]
|
||||
repeatedly with buffers until an error occurs or the parsing is done. The
|
||||
function
|
||||
[link beast.ref.beast__http__basic_parser.put_eof `basic_parser::put_eof`]
|
||||
Is used when the caller knows that there will never be more data (for example,
|
||||
if the underlying connection is closed),
|
||||
|
||||
[heading Parser Options]
|
||||
|
||||
The parser provides a few options which may be set before parsing begins:
|
||||
|
||||
[table Parser Options
|
||||
[[Name][Default][Description]]
|
||||
[[
|
||||
[link beast.ref.beast__http__basic_parser.eager.overload2 `eager`]
|
||||
][
|
||||
`false`
|
||||
][
|
||||
Normally the parser returns after successfully parsing a structured
|
||||
element (header, chunk header, or chunk body) even if there are octets
|
||||
remaining in the input. This is necessary when attempting to parse the
|
||||
header first, or when the caller wants to inspect information which may
|
||||
be invalidated by subsequent parsing, such as a chunk extension. The
|
||||
`eager` option controls whether the parser keeps going after parsing
|
||||
structured element if there are octets remaining in the buffer and no
|
||||
error occurs. This option is automatically set or cleared during certain
|
||||
stream operations to improve performance with no change in functionality.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__basic_parser.skip.overload2 `skip`]
|
||||
][
|
||||
`false`
|
||||
][
|
||||
This option controls whether or not the parser expects to see an HTTP
|
||||
body, regardless of the presence or absence of certain fields such as
|
||||
Content-Length or a chunked Transfer-Encoding. Depending on the request,
|
||||
some responses do not carry a body. For example, a 200 response to a
|
||||
[@https://tools.ietf.org/html/rfc7231#section-4.3.6 CONNECT] request
|
||||
from a tunneling proxy, or a response to a
|
||||
[@https://tools.ietf.org/html/rfc7231#section-4.3.2 HEAD] request.
|
||||
In these cases, callers may use this function inform the parser that
|
||||
no body is expected. The parser will consider the message complete
|
||||
after the header has been received.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__basic_parser.body_limit `body_limit`]
|
||||
][
|
||||
1MB/8MB
|
||||
][
|
||||
This function sets the maximum allowed size of the content body.
|
||||
When a body larger than the specified size is detected, an error
|
||||
is generated and parsing terminates. This setting helps protect
|
||||
servers from resource exhaustion attacks. The default limit when
|
||||
parsing requests is 1MB, and for parsing responses 8MB.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref.beast__http__basic_parser.header_limit `header_limit`]
|
||||
][
|
||||
8KB
|
||||
][
|
||||
This function sets the maximum allowed size of the header
|
||||
including all field name, value, and delimiter characters
|
||||
and also including the CRLF sequences in the serialized
|
||||
input.
|
||||
]]
|
||||
]
|
||||
|
||||
|
||||
|
||||
[section Read From std::istream]
|
||||
|
||||
The standard library provides the type `std::istream` for performing high
|
||||
level read operations on character streams. The variable `std::cin` is based
|
||||
on this input stream. This example uses the buffer oriented interface of
|
||||
__basic_parser__ to build a stream operation which parses an HTTP message
|
||||
from a `std::istream`:
|
||||
|
||||
[example_http_read_istream]
|
||||
|
||||
[tip
|
||||
Parsing from a `std::istream` could be implemented using an alternate
|
||||
strategy: adapt the `std::istream` interface to a __SyncReadStream__,
|
||||
enabling use with the library's existing stream algorithms. This is
|
||||
left as an exercise for the reader.
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
158
src/beast/doc/5_08_custom_body.qbk
Normal file
158
src/beast/doc/5_08_custom_body.qbk
Normal file
@@ -0,0 +1,158 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Custom Body Types]
|
||||
[block'''<?dbhtml stop-chunking?>''']
|
||||
|
||||
User-defined types are possible for the message body, where the type meets the
|
||||
__Body__ requirements. This simplified class declaration
|
||||
shows the customization points available to user-defined body types:
|
||||
```
|
||||
/// Defines a Body type
|
||||
struct body
|
||||
{
|
||||
/// This determines the type of the `message::body` member
|
||||
using value_type = ...;
|
||||
|
||||
/// An optional function, returns the body's payload size
|
||||
static
|
||||
std::uint64_t
|
||||
size(value_type const& v);
|
||||
|
||||
/// The algorithm used for extracting buffers
|
||||
class reader;
|
||||
|
||||
/// The algorithm used for inserting buffers
|
||||
class writer;
|
||||
}
|
||||
```
|
||||
|
||||
The meaning of the nested types is as follows
|
||||
|
||||
[table Body Type Members
|
||||
[[Name][Description]]
|
||||
[
|
||||
[`value_type`]
|
||||
[
|
||||
Determines the type of the
|
||||
[link beast.ref.beast__http__message.body `message::body`]
|
||||
member.
|
||||
]
|
||||
][
|
||||
[`reader`]
|
||||
[
|
||||
An optional nested type meeting the requirements of __BodyReader__,
|
||||
which provides the algorithm for converting the body representation
|
||||
to a forward range of buffer sequences.
|
||||
If present this body type may be used with a __serializer__.
|
||||
]
|
||||
][
|
||||
[`writer`]
|
||||
[
|
||||
An optional nested type meeting the requirements of __BodyWriter__,
|
||||
which provides the algorithm for storing a forward range of buffer
|
||||
sequences in the body representation.
|
||||
If present, this body type may be used with a __parser__.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[heading Value Type]
|
||||
|
||||
The `value_type` nested type allows the body to define the declaration of
|
||||
the body type as it appears in the message. This can be any type. For
|
||||
example, a body's value type may specify `std::vector<char>` or even
|
||||
`std::list<std::string>`. A custom body may even set the value type to
|
||||
something that is not a container for body octets, such as a
|
||||
[@http://www.boost.org/libs/filesystem/doc/reference.html#class-path `boost::filesystem::path`].
|
||||
Or, a more structured container may be chosen. This declares a body's
|
||||
value type as a JSON tree structure produced from a
|
||||
[@http://www.boost.org/doc/html/property_tree/parsers.html#property_tree.parsers.json_parser `json_parser`]:
|
||||
```
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
struct Body
|
||||
{
|
||||
using value_type = boost::property_tree::ptree;
|
||||
|
||||
class reader;
|
||||
|
||||
class writer;
|
||||
|
||||
// Optional member
|
||||
static
|
||||
std::uint64_t
|
||||
size(value_type const&);
|
||||
};
|
||||
```
|
||||
|
||||
As long as a suitable reader or writer is available to provide the
|
||||
algorithm for transferring buffers in and out of the value type,
|
||||
those bodies may be serialized or parsed.
|
||||
|
||||
|
||||
|
||||
[section File Body]
|
||||
|
||||
Use of the flexible __Body__ concept customization point enables authors to
|
||||
preserve the self-contained nature of the __message__ object while allowing
|
||||
domain specific behaviors. Common operations for HTTP servers include sending
|
||||
responses which deliver file contents, and allowing for file uploads. In this
|
||||
example we build the `basic_file_body` type which supports both reading and
|
||||
writing to a file on the file system. The interface is a class templated
|
||||
on the type of file used to access the file system, which must meet the
|
||||
requirements of __File__.
|
||||
|
||||
First we declare the type with its nested types:
|
||||
|
||||
[example_http_file_body_1]
|
||||
|
||||
We will start with the definition of the `value_type`. Our strategy
|
||||
will be to store the file object directly in the message container
|
||||
through the `value_type` field. To use this body it will be necessary
|
||||
to call `msg.body.file().open()` first with the required information
|
||||
such as the path and open mode. This ensures that the file exists
|
||||
throughout the operation and prevent the race condition where the
|
||||
file is removed from the file system in between calls.
|
||||
|
||||
[example_http_file_body_2]
|
||||
|
||||
Our implementation of __BodyReader__ will contain a small buffer
|
||||
from which the file contents are read. The buffer is provided to
|
||||
the implementation on each call until everything has been read in.
|
||||
|
||||
[example_http_file_body_3]
|
||||
|
||||
And here are the definitions for the functions we have declared:
|
||||
|
||||
[example_http_file_body_4]
|
||||
|
||||
Files can be read now, and the next step is to allow writing to files
|
||||
by implementing the __BodyWriter__. The style is similar to the reader,
|
||||
except that buffers are incoming instead of outgoing. Here's the
|
||||
declaration:
|
||||
|
||||
[example_http_file_body_5]
|
||||
|
||||
Finally, here is the implementation of the writer member functions:
|
||||
|
||||
[example_http_file_body_6]
|
||||
|
||||
We have created a full featured body type capable of reading and
|
||||
writing files on the filesystem, integrating seamlessly with the
|
||||
HTTP algorithms and message container. The body type works with
|
||||
any file implementation meeting the requirements of __File__ so
|
||||
it may be transparently used with solutions optimized for particular
|
||||
platforms. Example HTTP servers which use file bodies are available
|
||||
in the example directory.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
39
src/beast/doc/5_09_custom_parsers.qbk
Normal file
39
src/beast/doc/5_09_custom_parsers.qbk
Normal file
@@ -0,0 +1,39 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Custom Parsers]
|
||||
|
||||
While the parsers included in the library will handle a broad number of
|
||||
use-cases, the __basic_parser__ interface can be subclassed to implement
|
||||
custom parsing strategies: the basic parser processes the incoming octets
|
||||
into elements according to the HTTP/1 protocol specification, while the
|
||||
derived class decides what to do with those elements. In particular, users
|
||||
who create exotic containers for [*Fields] may need to also create their
|
||||
own parser. Custom parsers will work with all of the stream read operations
|
||||
that work on parsers, as those algorithms use only the basic parser
|
||||
interface. Some use cases for implementing custom parsers are:
|
||||
|
||||
* Inspect incoming header fields and keep or discard them.
|
||||
|
||||
* Use a container provided by an external interface.
|
||||
|
||||
* Store header data in a user-defined __Fields__ type.
|
||||
|
||||
The basic parser uses the Curiously Recurring Template Pattern
|
||||
([@https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern CRTP]).
|
||||
To declare your user defined parser, derive it from __basic_parser__.
|
||||
The interface to the parser is event-driven. Member functions of the derived
|
||||
class (termed "callbacks" in this context) are invoked with parsed elements
|
||||
as they become available, requiring either the `friend` declaration as shown
|
||||
above or that the member functions are declared public (not recommended).
|
||||
Buffers provided by the parser are non-owning references; it is the
|
||||
responsibility of the derived class to copy any information it needs before
|
||||
returning from the callback.
|
||||
|
||||
[example_http_custom_parser]
|
||||
|
||||
[endsect]
|
||||
143
src/beast/doc/6_0_http_examples.qbk
Normal file
143
src/beast/doc/6_0_http_examples.qbk
Normal file
@@ -0,0 +1,143 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section More Examples]
|
||||
|
||||
These examples in this section are working functions that may be found
|
||||
in the examples directory. They demonstrate the usage of the library for
|
||||
a variety of scenarios.
|
||||
|
||||
|
||||
|
||||
[section Change Body Type]
|
||||
|
||||
Sophisticated servers may wish to defer the choice of the Body template type
|
||||
until after the header is available. Then, a body type may be chosen
|
||||
depending on the header contents. For example, depending on the verb,
|
||||
target path, or target query parameters. To accomplish this, a parser
|
||||
is declared to read in the header only, using a trivial body type such as
|
||||
[link beast.ref.beast__http__empty_body `empty_body`]. Then, a new parser is constructed
|
||||
from this existing parser where the body type is conditionally determined
|
||||
by information from the header or elsewhere.
|
||||
|
||||
This example illustrates how a server may make the commitment of a body
|
||||
type depending on the method verb:
|
||||
|
||||
[example_http_defer_body]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section Expect 100-continue (Client)]
|
||||
|
||||
The Expect field with the value "100-continue" in a request is special. It
|
||||
indicates that the after sending the message header, a client desires an
|
||||
immediate informational response before sending the the message body, which
|
||||
presumably may be expensive to compute or large. This behavior is described in
|
||||
[@https://tools.ietf.org/html/rfc7231#section-5.1.1 rfc7231 section 5.1.1].
|
||||
Invoking the 100-continue behavior is implemented easily in a client by
|
||||
constructing a __serializer__ to send the header first, then receiving
|
||||
the server response, and finally conditionally send the body using the same
|
||||
serializer instance. A synchronous, simplified version (no timeout) of
|
||||
this client action looks like this:
|
||||
|
||||
[example_http_send_expect_100_continue]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section Expect 100-continue (Server)]
|
||||
|
||||
The Expect field with the value "100-continue" in a request is special. It
|
||||
indicates that the after sending the message header, a client desires an
|
||||
immediate informational response before sending the the message body, which
|
||||
presumably may be expensive to compute or large. This behavior is described in
|
||||
[@https://tools.ietf.org/html/rfc7231#section-5.1.1 rfc7231 section 5.1.1].
|
||||
Handling the Expect field can be implemented easily in a server by constructing
|
||||
a __parser__ to read the header first, then send an informational HTTP
|
||||
response, and finally read the body using the same parser instance. A
|
||||
synchronous version of this server action looks like this:
|
||||
|
||||
[example_http_receive_expect_100_continue]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section HEAD request (Client)]
|
||||
|
||||
The
|
||||
[@https://tools.ietf.org/html/rfc7231#section-4.3.2 HEAD request]
|
||||
method indicates to the server that the client wishes to receive the
|
||||
entire header that would be delivered if the method was GET, except
|
||||
that the body is omitted.
|
||||
|
||||
[example_http_do_head_request]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section HEAD response (Server)]
|
||||
|
||||
When a server receives a
|
||||
[@https://tools.ietf.org/html/rfc7231#section-4.3.2 HEAD request],
|
||||
the response should contain the entire header that would be delivered
|
||||
if the method was GET, except that the body is omitted.
|
||||
|
||||
[example_http_do_head_response]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section HTTP Relay]
|
||||
|
||||
An HTTP proxy acts as a relay between client and server. The proxy reads a
|
||||
request from the client and sends it to the server, possibly adjusting some
|
||||
of the headers and representation of the body along the way. Then, the
|
||||
proxy reads a response from the server and sends it back to the client,
|
||||
also with the possibility of changing the headers and body representation.
|
||||
|
||||
The example that follows implements a synchronous HTTP relay. It uses a
|
||||
fixed size buffer, to avoid reading in the entire body so that the upstream
|
||||
connection sees a header without unnecessary latency. This example brings
|
||||
together all of the concepts discussed so far, it uses both a __serializer__
|
||||
and a __parser__ to achieve its goal:
|
||||
|
||||
[example_http_relay]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section Send Child Process Output]
|
||||
|
||||
Sometimes it is necessary to send a message whose body is not conveniently
|
||||
described by a single container. For example, when implementing an HTTP relay
|
||||
function a robust implementation needs to present body buffers individually
|
||||
as they become available from the downstream host. These buffers should be
|
||||
fixed in size, otherwise creating the unnecessary and inefficient burden of
|
||||
reading the complete message body before forwarding it to the upstream host.
|
||||
|
||||
To enable these use-cases, the body type __buffer_body__ is provided. This
|
||||
body uses a caller-provided pointer and size instead of an owned container.
|
||||
To use this body, instantiate an instance of the serializer and fill in
|
||||
the pointer and size fields before calling a stream write function.
|
||||
|
||||
This example reads from a child process and sends the output back in an
|
||||
HTTP response. The output of the process is sent as it becomes available:
|
||||
|
||||
[example_http_send_cgi_response]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
38
src/beast/doc/7_0_websocket.qbk
Normal file
38
src/beast/doc/7_0_websocket.qbk
Normal file
@@ -0,0 +1,38 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Using WebSocket]
|
||||
|
||||
The WebSocket Protocol enables two-way communication between a client
|
||||
running untrusted code in a controlled environment to a remote host that has
|
||||
opted-in to communications from that code. The protocol consists of an opening
|
||||
handshake followed by basic message framing, layered over TCP. The goal of
|
||||
this technology is to provide a mechanism for browser-based applications
|
||||
needing two-way communication with servers without relying on opening multiple
|
||||
HTTP connections.
|
||||
|
||||
Beast provides developers with a robust WebSocket implementation built on
|
||||
Boost.Asio with a consistent asynchronous model using a modern C++ approach.
|
||||
|
||||
[note
|
||||
This documentation assumes familiarity with __Asio__ and
|
||||
the protocol specification described in __rfc6455__.
|
||||
Sample code and identifiers appearing in this section is written
|
||||
as if these declarations are in effect:
|
||||
|
||||
[ws_snippet_1]
|
||||
]
|
||||
|
||||
[include 7_1_streams.qbk]
|
||||
[include 7_2_connect.qbk]
|
||||
[include 7_3_client.qbk]
|
||||
[include 7_4_server.qbk]
|
||||
[include 7_5_messages.qbk]
|
||||
[include 7_6_control.qbk]
|
||||
[include 7_7_notes.qbk]
|
||||
|
||||
[endsect]
|
||||
64
src/beast/doc/7_1_streams.qbk
Normal file
64
src/beast/doc/7_1_streams.qbk
Normal file
@@ -0,0 +1,64 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Creating Streams]
|
||||
|
||||
The interface to the WebSocket implementation is a single template class
|
||||
[link beast.ref.beast__websocket__stream `stream`]
|
||||
which wraps an existing network transport object or other type of
|
||||
octet oriented stream. The wrapped object is called the "next layer"
|
||||
and must meet the requirements of __SyncStream__ if synchronous
|
||||
operations are performed, __AsyncStream__ if asynchronous operations
|
||||
are performed, or both. Any arguments supplied during construction of
|
||||
the stream wrapper are passed to next layer's constructor.
|
||||
|
||||
Here we declare a websocket stream over a TCP/IP socket with ownership
|
||||
of the socket. The `io_service` argument is forwarded to the wrapped
|
||||
socket's constructor:
|
||||
|
||||
[ws_snippet_2]
|
||||
|
||||
[heading Using SSL]
|
||||
|
||||
To use WebSockets over SSL, use an instance of the `boost::asio::ssl::stream`
|
||||
class template as the template type for the stream. The required `io_service`
|
||||
and `ssl::context` arguments are forwarded to the wrapped stream's constructor:
|
||||
|
||||
[wss_snippet_1]
|
||||
[wss_snippet_2]
|
||||
|
||||
[important
|
||||
Code which declares websocket stream objects using Asio SSL types
|
||||
must include the file [include_file beast/websocket/ssl.hpp].
|
||||
]
|
||||
|
||||
[heading Non-owning References]
|
||||
|
||||
If a socket type supports move construction, a websocket stream may be
|
||||
constructed around the already existing socket by invoking the move
|
||||
constructor signature:
|
||||
|
||||
[ws_snippet_3]
|
||||
|
||||
Or, the wrapper can be constructed with a non-owning reference. In
|
||||
this case, the caller is responsible for managing the lifetime of the
|
||||
underlying socket being wrapped:
|
||||
|
||||
[ws_snippet_4]
|
||||
|
||||
Once the WebSocket stream wrapper is created, the wrapped object may be
|
||||
accessed by calling
|
||||
[link beast.ref.beast__websocket__stream.next_layer.overload1 `stream::next_layer`]:
|
||||
|
||||
[ws_snippet_5]
|
||||
|
||||
[warning
|
||||
Initiating operations on the next layer while websocket
|
||||
operations are being performed may result in undefined behavior.
|
||||
]
|
||||
|
||||
[endsect]
|
||||
32
src/beast/doc/7_2_connect.qbk
Normal file
32
src/beast/doc/7_2_connect.qbk
Normal file
@@ -0,0 +1,32 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Establishing Connections]
|
||||
|
||||
Connections are established by invoking functions directly on the next layer
|
||||
object. For example, to make an outgoing connection using a standard TCP/IP
|
||||
socket:
|
||||
|
||||
[ws_snippet_6]
|
||||
|
||||
Similarly, to accept an incoming connection using a standard TCP/IP
|
||||
socket, pass the next layer object to the acceptor:
|
||||
|
||||
[ws_snippet_7]
|
||||
|
||||
When using SSL, which itself wraps a next layer object that is usually a
|
||||
TCP/IP socket, multiple calls to retrieve the next layer may be required.
|
||||
In this example, the websocket stream wraps the SSL stream which wraps
|
||||
the TCP/IP socket:
|
||||
|
||||
[wss_snippet_3]
|
||||
|
||||
[note
|
||||
Examples use synchronous interfaces for clarity of exposition.
|
||||
]
|
||||
|
||||
[endsect]
|
||||
95
src/beast/doc/7_3_client.qbk
Normal file
95
src/beast/doc/7_3_client.qbk
Normal file
@@ -0,0 +1,95 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Handshaking (Clients)]
|
||||
|
||||
A WebSocket session begins when a client sends the HTTP/1
|
||||
[@https://tools.ietf.org/html/rfc7230#section-6.7 Upgrade]
|
||||
request for
|
||||
[@https://tools.ietf.org/html/rfc6455#section-1.3 websocket],
|
||||
and the server sends an appropriate response indicating that
|
||||
the request was accepted and that the connection has been upgraded.
|
||||
The Upgrade request must include the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-5.4 Host]
|
||||
field, and the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-5.3 target]
|
||||
of the resource to request. The stream member functions
|
||||
[link beast.ref.beast__websocket__stream.handshake.overload1 `handshake`] and
|
||||
[link beast.ref.beast__websocket__stream.async_handshake.overload1 `async_handshake`]
|
||||
are used to send the request with the required host and target strings.
|
||||
|
||||
[ws_snippet_8]
|
||||
|
||||
The implementation will create and send a request that typically
|
||||
looks like this:
|
||||
|
||||
[table WebSocket Upgrade HTTP Request
|
||||
[[Serialized Octets][Description]]
|
||||
[[
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Host: localhost
|
||||
Upgrade: websocket
|
||||
Connection: upgrade
|
||||
Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA==
|
||||
Sec-WebSocket-Version: 13
|
||||
User-Agent: Beast
|
||||
```
|
||||
][
|
||||
The host and target parameters become part of the Host field
|
||||
and request-target in the resulting HTTP request. The key is
|
||||
generated by the implementation. Callers may add fields or
|
||||
modify fields by providing a ['decorator], described below.
|
||||
]]]
|
||||
|
||||
[heading Decorators]
|
||||
|
||||
If the caller wishes to add or modify fields, the member functions
|
||||
[link beast.ref.beast__websocket__stream.handshake_ex `handshake_ex`] and
|
||||
[link beast.ref.beast__websocket__stream.async_handshake_ex `async_handshake_ex`]
|
||||
are provided which allow an additional function object, called a
|
||||
['decorator], to be passed. The decorator is invoked to modify
|
||||
the HTTP Upgrade request as needed. This example sets a subprotocol
|
||||
on the request:
|
||||
|
||||
[ws_snippet_9]
|
||||
|
||||
The HTTP Upgrade request produced by the previous call will look thusly:
|
||||
|
||||
[table Decorated WebSocket Upgrade HTTP Request
|
||||
[[Serialized Octets][Description]]
|
||||
[[
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Host: localhost
|
||||
Upgrade: websocket
|
||||
Connection: upgrade
|
||||
Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA==
|
||||
Sec-WebSocket-Version: 13
|
||||
Sec-WebSocket-Protocol: xmpp;ws-chat
|
||||
User-Agent: Beast
|
||||
```
|
||||
][
|
||||
Undefined behavior results if the decorator modifies the fields
|
||||
specific to perform the WebSocket Upgrade , such as the Upgrade
|
||||
and Connection fields.
|
||||
]]]
|
||||
|
||||
[heading Filtering]
|
||||
|
||||
When a client receives an HTTP Upgrade response from the server indicating
|
||||
a successful upgrade, the caller may wish to perform additional validation
|
||||
on the received HTTP response message. For example, to check that the
|
||||
response to a basic authentication challenge is valid. To achieve this,
|
||||
overloads of the handshake member function allow the caller to store the
|
||||
received HTTP message in an output reference argument as
|
||||
[link beast.ref.beast__websocket__response_type `response_type`]
|
||||
as follows:
|
||||
|
||||
[ws_snippet_10]
|
||||
|
||||
[endsect]
|
||||
116
src/beast/doc/7_4_server.qbk
Normal file
116
src/beast/doc/7_4_server.qbk
Normal file
@@ -0,0 +1,116 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Handshaking (Servers)]
|
||||
|
||||
A
|
||||
[link beast.ref.beast__websocket__stream `stream`]
|
||||
automatically handles receiving and processing the HTTP response to the
|
||||
handshake request. The call to handshake is successful if a HTTP response
|
||||
is received with the 101 "Switching Protocols" status code. On failure,
|
||||
an error is returned or an exception is thrown. Depending on the keep alive
|
||||
setting, the connection may remain open for a subsequent handshake attempt.
|
||||
|
||||
Performing a handshake for an incoming websocket upgrade request operates
|
||||
similarly. If the handshake fails, an error is returned or exception thrown:
|
||||
|
||||
[ws_snippet_11]
|
||||
|
||||
Successful WebSocket Upgrade responses generated by the implementation will
|
||||
typically look like this:
|
||||
|
||||
[table Decorated WebSocket Upgrade HTTP Request
|
||||
[[Serialized Octets][Description]]
|
||||
[[
|
||||
```
|
||||
HTTP/1.1 101 Switching Protocols
|
||||
Upgrade: websocket
|
||||
Connection: upgrade
|
||||
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
||||
Server: Beast/40
|
||||
```
|
||||
][
|
||||
The Sec-WebSocket-Accept field value is generated from the
|
||||
request in a fashion specified by the WebSocket protocol.
|
||||
]]]
|
||||
|
||||
[heading Decorators]
|
||||
|
||||
If the caller wishes to add or modify fields, the member functions
|
||||
[link beast.ref.beast__websocket__stream.accept_ex `accept_ex`] and
|
||||
[link beast.ref.beast__websocket__stream.async_accept_ex `async_accept_ex`]
|
||||
are provided which allow an additional function object, called a
|
||||
['decorator], to be passed. The decorator is invoked to modify
|
||||
the HTTP Upgrade request as needed. This example sets the Server
|
||||
field on the response:
|
||||
|
||||
[ws_snippet_12]
|
||||
|
||||
The HTTP Upgrade response produced by the previous call looks like this:
|
||||
|
||||
[table Decorated WebSocket Upgrade HTTP Request
|
||||
[[Serialized Octets][Description]]
|
||||
[[
|
||||
```
|
||||
HTTP/1.1 101 Switching Protocols
|
||||
Upgrade: websocket
|
||||
Connection: upgrade
|
||||
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
|
||||
Server: AcmeServer
|
||||
```
|
||||
][
|
||||
When the Upgrade request fails, the implementation will still invoke
|
||||
the decorator to modify the response. In this case, the response
|
||||
object will have a status code other than 101.
|
||||
|
||||
Undefined behavior results when the upgrade request is successful
|
||||
and the decorator modifies the fields specific to perform the
|
||||
WebSocket Upgrade, such as the Upgrade and Connection fields.
|
||||
]]]
|
||||
|
||||
[heading Passing HTTP Requests]
|
||||
|
||||
When implementing an HTTP server that also supports WebSocket, the
|
||||
server usually reads the HTTP request from the client. To detect when
|
||||
the incoming HTTP request is a WebSocket Upgrade request, the function
|
||||
[link beast.ref.beast__websocket__is_upgrade `is_upgrade`] may be used.
|
||||
|
||||
Once the caller determines that the HTTP request is a WebSocket Upgrade,
|
||||
additional overloads of
|
||||
[link beast.ref.beast__websocket__stream.accept `accept`],
|
||||
[link beast.ref.beast__websocket__stream.accept_ex `accept_ex`],
|
||||
[link beast.ref.beast__websocket__stream.async_accept `async_accept`], and
|
||||
[link beast.ref.beast__websocket__stream.async_accept_ex `async_accept_ex`]
|
||||
are provided which receive the entire HTTP request header as an object
|
||||
to perform the handshake. In this example, the request is first read
|
||||
in using the HTTP algorithms, and then passed to a newly constructed
|
||||
stream:
|
||||
|
||||
[ws_snippet_13]
|
||||
|
||||
[heading Buffered Handshakes]
|
||||
|
||||
Sometimes a server implementation wishes to read octets on the stream
|
||||
in order to route the incoming request. For example, a server may read
|
||||
the first 6 octets after accepting an incoming connection to determine
|
||||
if a TLS protocol is being negotiated, and choose a suitable implementation
|
||||
at run-time. In the case where the server wishes to accept the incoming
|
||||
request as an HTTP WebSocket Upgrade request, additional overloads of
|
||||
[link beast.ref.beast__websocket__stream.accept `accept`],
|
||||
[link beast.ref.beast__websocket__stream.accept_ex `accept_ex`],
|
||||
[link beast.ref.beast__websocket__stream.async_accept `async_accept`], and
|
||||
[link beast.ref.beast__websocket__stream.async_accept_ex `async_accept_ex`]
|
||||
are provided which receive the additional buffered octets and consume
|
||||
them as part of the handshake.
|
||||
|
||||
In this example, the server reads the initial HTTP message into the
|
||||
specified dynamic buffer as an octet sequence in the buffer's output
|
||||
area, and later uses those octets to attempt an HTTP WebSocket Upgrade:
|
||||
|
||||
[ws_snippet_14]
|
||||
|
||||
[endsect]
|
||||
36
src/beast/doc/7_5_messages.qbk
Normal file
36
src/beast/doc/7_5_messages.qbk
Normal file
@@ -0,0 +1,36 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Send and Receive Messages]
|
||||
|
||||
After the WebSocket handshake is accomplished, callers may send and receive
|
||||
messages using the message oriented interface. This interface requires that
|
||||
all of the buffers representing the message are known ahead of time:
|
||||
|
||||
[ws_snippet_15]
|
||||
|
||||
[important
|
||||
Calls to [link beast.ref.beast__websocket__stream.set_option `set_option`]
|
||||
must be made from the same implicit or explicit strand as that used
|
||||
to perform other operations.
|
||||
]
|
||||
|
||||
[heading Frames]
|
||||
|
||||
Some use-cases make it impractical or impossible to buffer the entire
|
||||
message ahead of time:
|
||||
|
||||
* Streaming multimedia to an endpoint.
|
||||
* Sending a message that does not fit in memory at once.
|
||||
* Providing incremental results as they become available.
|
||||
|
||||
For these cases, the frame oriented interface may be used. This
|
||||
example reads and echoes a complete message using this interface:
|
||||
|
||||
[ws_snippet_16]
|
||||
|
||||
[endsect]
|
||||
113
src/beast/doc/7_6_control.qbk
Normal file
113
src/beast/doc/7_6_control.qbk
Normal file
@@ -0,0 +1,113 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Control Frames]
|
||||
|
||||
Control frames are small (less than 128 bytes) messages entirely contained
|
||||
in an individual WebSocket frame. They may be sent at any time by either
|
||||
peer on an established connection, and can appear in between continuation
|
||||
frames for a message. There are three types of control frames: ping, pong,
|
||||
and close.
|
||||
|
||||
A sent ping indicates a request that the sender wants to receive a pong. A
|
||||
pong is a response to a ping. Pongs may be sent unsolicited, at any time.
|
||||
One use for an unsolicited pong is to inform the remote peer that the
|
||||
session is still active after a long period of inactivity. A close frame
|
||||
indicates that the remote peer wishes to close the WebSocket connection.
|
||||
The connection is considered gracefully closed when each side has sent
|
||||
and received a close frame.
|
||||
|
||||
During read operations, Beast automatically reads and processes control
|
||||
frames. If a control callback is registered, the callback is notified of
|
||||
the incoming control frame. The implementation will respond to pings
|
||||
automatically. The receipt of a close frame initiates the WebSocket
|
||||
close procedure, eventually resulting in the error code
|
||||
[link beast.ref.beast__websocket__error `error::closed`]
|
||||
being delivered to the caller in a subsequent read operation, assuming
|
||||
no other error takes place.
|
||||
|
||||
A consequence of this automatic behavior is that caller-initiated read
|
||||
operations can cause socket writes. However, these writes will not
|
||||
compete with caller-initiated write operations. For the purposes of
|
||||
correctness with respect to the stream invariants, caller-initiated
|
||||
read operations still only count as a read. This means that callers can
|
||||
have a simultaneously active read, write, and ping/pong operation in
|
||||
progress, while the implementation also automatically handles control
|
||||
frames.
|
||||
|
||||
[heading Control Callback]
|
||||
|
||||
Ping, pong, and close messages are control frames which may be sent at
|
||||
any time by either peer on an established WebSocket connection. They
|
||||
are sent using the functions
|
||||
[link beast.ref.beast__websocket__stream.ping `ping`],
|
||||
[link beast.ref.beast__websocket__stream.pong `pong`].
|
||||
and
|
||||
[link beast.ref.beast__websocket__stream.close `close`].
|
||||
To be notified of control frames, callers may register a
|
||||
['control callback] using
|
||||
[link beast.ref.beast__websocket__stream.control_callback `control_callback`].
|
||||
The object provided with this option should be callable with the following
|
||||
signature:
|
||||
|
||||
[ws_snippet_17]
|
||||
|
||||
When a control callback is registered, it will be invoked for all pings,
|
||||
pongs, and close frames received through either synchronous read functions
|
||||
or asynchronous read functions. The type of frame and payload text are
|
||||
passed as parameters to the control callback. If the frame is a close
|
||||
frame, the close reason may be obtained by calling
|
||||
[link beast.ref.beast__websocket__stream.reason `reason`].
|
||||
|
||||
Unlike regular completion handlers used in calls to asynchronous initiation
|
||||
functions, the control callback only needs to be set once. The callback is
|
||||
not reset after being called. The same callback is used for both synchronous
|
||||
and asynchronous reads. The callback is passive; in order to be called,
|
||||
a stream read operation must be active.
|
||||
|
||||
[note
|
||||
When an asynchronous read function receives a control frame, the
|
||||
control callback is invoked in the same manner as that used to
|
||||
invoke the final completion handler of the corresponding read
|
||||
function.
|
||||
]
|
||||
|
||||
[heading Close Frames]
|
||||
|
||||
The WebSocket protocol defines a procedure and control message for initiating
|
||||
a close of the session. Handling of close initiated by the remote end of the
|
||||
connection is performed automatically. To manually initiate a close, use
|
||||
the
|
||||
[link beast.ref.beast__websocket__stream.close `close`] function:
|
||||
|
||||
[ws_snippet_18]
|
||||
|
||||
When the remote peer initiates a close by sending a close frame, Beast
|
||||
will handle it for you by causing the next read to return `error::closed`.
|
||||
When this error code is delivered, it indicates to the application that
|
||||
the WebSocket connection has been closed cleanly, and that the TCP/IP
|
||||
connection has been closed. After initiating a close, it is necessary to
|
||||
continue reading messages until receiving the error `error::closed`. This
|
||||
is because the remote peer may still be sending message and control frames
|
||||
before it receives and responds to the close frame.
|
||||
|
||||
[important
|
||||
To receive the
|
||||
[link beast.ref.beast__websocket__error `error::closed`]
|
||||
error, a read operation is required.
|
||||
]
|
||||
|
||||
[heading Auto-fragment]
|
||||
|
||||
To ensure timely delivery of control frames, large messages can be broken up
|
||||
into smaller sized frames. The automatic fragment option turns on this
|
||||
feature, and the write buffer size option determines the maximum size of
|
||||
the fragments:
|
||||
|
||||
[ws_snippet_19]
|
||||
|
||||
[endsect]
|
||||
55
src/beast/doc/7_7_notes.qbk
Normal file
55
src/beast/doc/7_7_notes.qbk
Normal file
@@ -0,0 +1,55 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Notes]
|
||||
|
||||
Because calls to read data may return a variable amount of bytes, the
|
||||
interface to calls that read data require an object that meets the requirements
|
||||
of __DynamicBuffer__. This concept is modeled on __streambuf__.
|
||||
|
||||
The implementation does not perform queueing or buffering of messages. If
|
||||
desired, these features should be provided by callers. The impact of this
|
||||
design is that library users are in full control of the allocation strategy
|
||||
used to store data and the back-pressure applied on the read and write side
|
||||
of the underlying TCP/IP connection.
|
||||
|
||||
[heading Asynchronous Operations]
|
||||
|
||||
Asynchronous versions are available for all functions:
|
||||
|
||||
[ws_snippet_20]
|
||||
|
||||
Calls to asynchronous initiation functions support the extensible asynchronous
|
||||
model developed by the Boost.Asio author, allowing for traditional completion
|
||||
handlers, stackful or stackless coroutines, and even futures:
|
||||
|
||||
[ws_snippet_21]
|
||||
|
||||
[heading The io_service]
|
||||
|
||||
The creation and operation of the __io_service__ associated with the
|
||||
underlying stream is left to the callers, permitting any implementation
|
||||
strategy including one that does not require threads for environments
|
||||
where threads are unavailable. Beast WebSocket itself does not use
|
||||
or require threads.
|
||||
|
||||
[heading Thread Safety]
|
||||
|
||||
Like a regular __Asio__ socket, a
|
||||
[link beast.ref.beast__websocket__stream `stream`]
|
||||
is not thread safe. Callers are responsible for synchronizing operations on
|
||||
the socket using an implicit or explicit strand, as per the Asio documentation.
|
||||
The asynchronous interface supports one active read and one active write
|
||||
simultaneously. Undefined behavior results if two or more reads or two or
|
||||
more writes are attempted concurrently. Caller initiated WebSocket ping, pong,
|
||||
and close operations each count as an active write.
|
||||
|
||||
The implementation uses composed asynchronous operations internally; a high
|
||||
level read can cause both reads and writes to take place on the underlying
|
||||
stream. This behavior is transparent to callers.
|
||||
|
||||
[endsect]
|
||||
22
src/beast/doc/8_concepts.qbk
Normal file
22
src/beast/doc/8_concepts.qbk
Normal file
@@ -0,0 +1,22 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:concept Concepts]
|
||||
|
||||
This section describes all of the concepts defined by the library.
|
||||
|
||||
[include concept/Body.qbk]
|
||||
[include concept/BodyReader.qbk]
|
||||
[include concept/BodyWriter.qbk]
|
||||
[include concept/BufferSequence.qbk]
|
||||
[include concept/DynamicBuffer.qbk]
|
||||
[include concept/Fields.qbk]
|
||||
[include concept/FieldsReader.qbk]
|
||||
[include concept/File.qbk]
|
||||
[include concept/Streams.qbk]
|
||||
|
||||
[endsect]
|
||||
58
src/beast/doc/9_0_design.qbk
Normal file
58
src/beast/doc/9_0_design.qbk
Normal file
@@ -0,0 +1,58 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Design Choices]
|
||||
|
||||
The implementations were originally driven by business needs of cryptocurrency
|
||||
server applications (e.g. [@https://github.com/ripple/rippled rippled]),
|
||||
written in C++. These needs were not met by existing solutions so Beast
|
||||
was written from scratch as a solution. Beast's design philosophy avoids
|
||||
flaws exhibited by other libraries:
|
||||
|
||||
* Don't try to do too much.
|
||||
|
||||
* Don't sacrifice performance.
|
||||
|
||||
* Mimic __Asio__; familiarity breeds confidence.
|
||||
|
||||
* Role-symmetric interfaces; client and server the same (or close to it).
|
||||
|
||||
* Leave important decisions, such as allocating memory or
|
||||
managing flow control, to the user.
|
||||
|
||||
Beast uses the __DynamicBuffer__ concept presented in the Networking TS
|
||||
(__N4588__), and relies heavily on the __ConstBufferSequence__ and
|
||||
__MutableBufferSequence__ concepts for passing buffers to functions.
|
||||
The authors have found the dynamic buffer and buffer sequence interfaces to
|
||||
be optimal for interacting with Asio, and for other tasks such as incremental
|
||||
parsing of data in buffers (for example, parsing websocket frames stored
|
||||
in a [link beast.ref.beast__static_buffer `static_buffer`]).
|
||||
|
||||
During the development of Beast the authors have studied other software
|
||||
packages and in particular the comments left during the Boost Review process
|
||||
of other packages offering similar functionality. In this section and the
|
||||
FAQs that follow we attempt to answer those questions that are also applicable
|
||||
to Beast.
|
||||
|
||||
For HTTP we model the message to maximize flexibility of implementation
|
||||
strategies while allowing familiar verbs such as [*`read`] and [*`write`].
|
||||
The HTTP interface is further driven by the needs of the WebSocket module,
|
||||
as a WebSocket session requires a HTTP Upgrade handshake exchange at the
|
||||
start. Other design goals:
|
||||
|
||||
* Keep it simple.
|
||||
|
||||
* Stay low level; don't invent a whole web server or client.
|
||||
|
||||
* Allow for customizations, if the user needs it.
|
||||
|
||||
[include 9_1_http_message.qbk]
|
||||
[include 9_2_http_comparison.qbk]
|
||||
[include 9_3_websocket_zaphoyd.qbk]
|
||||
[include 9_4_faq.qbk]
|
||||
|
||||
[endsect]
|
||||
340
src/beast/doc/9_1_http_message.qbk
Normal file
340
src/beast/doc/9_1_http_message.qbk
Normal file
@@ -0,0 +1,340 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section HTTP Message Container]
|
||||
|
||||
In this section we describe the problem of modeling HTTP messages and explain
|
||||
how the library arrived at its solution, with a discussion of the benefits
|
||||
and drawbacks of the design choices. The goal for creating a message model
|
||||
is to create a container with value semantics, possibly movable and/or
|
||||
copyable, that contains all the information needed to serialize, or all
|
||||
of the information captured during parsing. More formally, given:
|
||||
|
||||
* `m` is an instance of an HTTP message container
|
||||
|
||||
* `x` is a series of octets describing a valid HTTP message in
|
||||
the serialized format described in __rfc7230__.
|
||||
|
||||
* `S(m)` is a serialization function which produces a series of octets
|
||||
from a message container.
|
||||
|
||||
* `P(x)` is a parsing function which produces a message container from
|
||||
a series of octets.
|
||||
|
||||
These relations are true:
|
||||
|
||||
* `S(m) == x`
|
||||
|
||||
* `P(S(m)) == m`
|
||||
|
||||
We would also like our message container to have customization points
|
||||
permitting the following: allocator awareness, user-defined containers
|
||||
to represent header fields, and user-defined types and algorithms to
|
||||
represent the body. And finally, because requests and responses have
|
||||
different fields in the ['start-line], we would like the containers for
|
||||
requests and responses to be represented by different types for function
|
||||
overloading.
|
||||
|
||||
Here is our first attempt at declaring some message containers:
|
||||
|
||||
[table
|
||||
[[
|
||||
```
|
||||
/// An HTTP request
|
||||
template<class Fields, class Body>
|
||||
struct request
|
||||
{
|
||||
int version;
|
||||
std::string method;
|
||||
std::string target;
|
||||
Fields fields;
|
||||
|
||||
typename Body::value_type body;
|
||||
};
|
||||
```
|
||||
][
|
||||
```
|
||||
/// An HTTP response
|
||||
template<class Fields, class Body>
|
||||
struct response
|
||||
{
|
||||
int version;
|
||||
int status;
|
||||
std::string reason;
|
||||
Fields fields;
|
||||
|
||||
typename Body::value_type body;
|
||||
};
|
||||
```
|
||||
]]
|
||||
]
|
||||
|
||||
These containers are capable of representing everything in the model
|
||||
of HTTP requests and responses described in __rfc7230__. Request and
|
||||
response objects are different types. The user can choose the container
|
||||
used to represent the fields. And the user can choose the [*Body] type,
|
||||
which is a concept defining not only the type of `body` member but also
|
||||
the algorithms used to transfer information in and out of that member
|
||||
when performing serialization and parsing.
|
||||
|
||||
However, a problem arises. How do we write a function which can accept
|
||||
an object that is either a request or a response? As written, the only
|
||||
obvious solution is to make the message a template type. Additional traits
|
||||
classes would then be needed to make sure that the passed object has a
|
||||
valid type which meets the requirements. These unnecessary complexities
|
||||
are bypassed by making each container a partial specialization:
|
||||
```
|
||||
/// An HTTP message
|
||||
template<bool isRequest, class Fields, class Body>
|
||||
struct message;
|
||||
|
||||
/// An HTTP request
|
||||
template<class Fields, class Body>
|
||||
struct message<true, Fields, Body>
|
||||
{
|
||||
int version;
|
||||
std::string method;
|
||||
std::string target;
|
||||
Fields fields;
|
||||
|
||||
typename Body::value_type body;
|
||||
};
|
||||
|
||||
/// An HTTP response
|
||||
template<bool isRequest, class Fields, class Body>
|
||||
struct message<false, Fields, Body>
|
||||
{
|
||||
int version;
|
||||
int status;
|
||||
std::string reason;
|
||||
Fields fields;
|
||||
|
||||
typename Body::value_type body;
|
||||
};
|
||||
```
|
||||
|
||||
Now we can declare a function which takes any message as a parameter:
|
||||
```
|
||||
template<bool isRequest, class Fields, class Body>
|
||||
void f(message<isRequest, Fields, Body>& msg);
|
||||
```
|
||||
|
||||
This function can manipulate the fields common to requests and responses.
|
||||
If it needs to access the other fields, it can use overloads with
|
||||
partial specialization, or in C++17 a `constexpr` expression:
|
||||
```
|
||||
template<bool isRequest, class Fields, class Body>
|
||||
void f(message<isRequest, Fields, Body>& msg)
|
||||
{
|
||||
if constexpr(isRequest)
|
||||
{
|
||||
// call msg.method(), msg.target()
|
||||
}
|
||||
else
|
||||
{
|
||||
// call msg.result(), msg.reason()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Often, in non-trivial HTTP applications, we want to read the HTTP header
|
||||
and examine its contents before choosing a type for [*Body]. To accomplish
|
||||
this, there needs to be a way to model the header portion of a message.
|
||||
And we'd like to do this in a way that allows functions which take the
|
||||
header as a parameter, to also accept a type representing the whole
|
||||
message (the function will see just the header part). This suggests
|
||||
inheritance, by splitting a new base class off of the message:
|
||||
```
|
||||
/// An HTTP message header
|
||||
template<bool isRequest, class Fields>
|
||||
struct header;
|
||||
```
|
||||
|
||||
Code which accesses the fields has to laboriously mention the `fields`
|
||||
member, so we'll not only make `header` a base class but we'll make
|
||||
a quality of life improvement and derive the header from the fields
|
||||
for notational convenience. In order to properly support all forms
|
||||
of construction of [*Fields] there will need to be a set of suitable
|
||||
constructor overloads (not shown):
|
||||
```
|
||||
/// An HTTP request header
|
||||
template<class Fields>
|
||||
struct header<true, Fields> : Fields
|
||||
{
|
||||
int version;
|
||||
std::string method;
|
||||
std::string target;
|
||||
};
|
||||
|
||||
/// An HTTP response header
|
||||
template<class Fields>
|
||||
struct header<false, Fields> : Fields
|
||||
{
|
||||
int version;
|
||||
int status;
|
||||
std::string reason;
|
||||
};
|
||||
|
||||
/// An HTTP message
|
||||
template<bool isRequest, class Fields, class Body>
|
||||
struct message : header<isRequest, Fields>
|
||||
{
|
||||
typename Body::value_type body;
|
||||
|
||||
/// Construct from a `header`
|
||||
message(header<isRequest, Fields>&& h);
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
Note that the `message` class now has a constructor allowing messages
|
||||
to be constructed from a similarly typed `header`. This handles the case
|
||||
where the user already has the header and wants to make a commitment to the
|
||||
type for [*Body]. A function can be declared which accepts any header:
|
||||
```
|
||||
template<bool isRequest, class Fields>
|
||||
void f(header<isRequest, Fields>& msg);
|
||||
```
|
||||
|
||||
Until now we have not given significant consideration to the constructors
|
||||
of the `message` class. But to achieve all our goals we will need to make
|
||||
sure that there are enough constructor overloads to not only provide for
|
||||
the special copy and move members if the instantiated types support it,
|
||||
but also allow the fields container and body container to be constructed
|
||||
with arbitrary variadic lists of parameters. This allows the container
|
||||
to fully support allocators.
|
||||
|
||||
The solution used in the library is to treat the message like a `std::pair`
|
||||
for the purposes of construction, except that instead of `first` and `second`
|
||||
we have the `Fields` base class and `message::body` member. This means that
|
||||
single-argument constructors for those fields should be accessible as they
|
||||
are with `std::pair`, and that a mechanism identical to the pair's use of
|
||||
`std::piecewise_construct` should be provided. Those constructors are too
|
||||
complex to repeat here, but interested readers can view the declarations
|
||||
in the corresponding header file.
|
||||
|
||||
There is now significant progress with our message container but a stumbling
|
||||
block remains. There is no way to control the allocator for the `std::string`
|
||||
members. We could add an allocator to the template parameter list of the
|
||||
header and message classes, use it for those strings. This is unsatisfying
|
||||
because of the combinatorial explosion of constructor variations needed to
|
||||
support the scheme. It also means that request messages could have [*four]
|
||||
different allocators: two for the fields and body, and two for the method
|
||||
and target strings. A better solution is needed.
|
||||
|
||||
To get around this we make an interface modification and then add
|
||||
a requirement to the [*Fields] type. First, the interface change:
|
||||
```
|
||||
/// An HTTP request header
|
||||
template<class Fields>
|
||||
struct header<true, Fields> : Fields
|
||||
{
|
||||
int version;
|
||||
|
||||
verb method() const;
|
||||
string_view method_string() const;
|
||||
void method(verb);
|
||||
void method(string_view);
|
||||
|
||||
string_view target(); const;
|
||||
void target(string_view);
|
||||
|
||||
private:
|
||||
verb method_;
|
||||
};
|
||||
|
||||
/// An HTTP response header
|
||||
template<class Fields>
|
||||
struct header<false, Fields> : Fields
|
||||
{
|
||||
int version;
|
||||
int result;
|
||||
string_view reason() const;
|
||||
void reason(string_view);
|
||||
};
|
||||
```
|
||||
|
||||
The start-line data members are replaced traditional accessors using
|
||||
non-owning references to string buffers. The method is stored using
|
||||
a simple integer instead of the entire string, for the case where
|
||||
the method is recognized from the set of known verb strings.
|
||||
|
||||
Now we add a requirement to the fields type: management of the
|
||||
corresponding string is delegated to the [*Fields] container, which can
|
||||
already be allocator aware and constructed with the necessary allocator
|
||||
parameter via the provided constructor overloads for `message`. The
|
||||
delegation implementation looks like this (only the response header
|
||||
specialization is shown):
|
||||
```
|
||||
/// An HTTP response header
|
||||
template<class Fields>
|
||||
struct header<false, Fields> : Fields
|
||||
{
|
||||
int version;
|
||||
int status;
|
||||
|
||||
string_view
|
||||
reason() const
|
||||
{
|
||||
return this->reason_impl(); // protected member of Fields
|
||||
}
|
||||
|
||||
void
|
||||
reason(string_view s)
|
||||
{
|
||||
this->reason_impl(s); // protected member of Fields
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Now that we've accomplished our initial goals and more, there are a few
|
||||
more quality of life improvements to make. Users will choose different
|
||||
types for `Body` far more often than they will for `Fields`. Thus, we
|
||||
swap the order of these types and provide a default. Then, we provide
|
||||
type aliases for requests and responses to soften the impact of using
|
||||
`bool` to choose the specialization:
|
||||
|
||||
```
|
||||
/// An HTTP header
|
||||
template<bool isRequest, class Body, class Fields = fields>
|
||||
struct header;
|
||||
|
||||
/// An HTTP message
|
||||
template<bool isRequest, class Body, class Fields = fields>
|
||||
struct message;
|
||||
|
||||
/// An HTTP request
|
||||
template<class Body, class Fields = fields>
|
||||
using request = message<true, Body, Fields>;
|
||||
|
||||
/// An HTTP response
|
||||
template<class Body, class Fields = fields>
|
||||
using response = message<false, Body, Fields>;
|
||||
```
|
||||
|
||||
This allows concise specification for the common cases, while
|
||||
allowing for maximum customization for edge cases:
|
||||
```
|
||||
request<string_body> req;
|
||||
|
||||
response<file_body> res;
|
||||
```
|
||||
|
||||
This container is also capable of representing complete HTTP/2 messages.
|
||||
Not because it was explicitly designed for, but because the IETF wanted to
|
||||
preserve message compatibility with HTTP/1. Aside from version specific
|
||||
fields such as Connection, the contents of HTTP/1 and HTTP/2 messages are
|
||||
identical even though their serialized representation is considerably
|
||||
different. The message model presented in this library is ready for HTTP/2.
|
||||
|
||||
In conclusion, this representation for the message container is well thought
|
||||
out, provides comprehensive flexibility, and avoids the necessity of defining
|
||||
additional traits classes. User declarations of functions that accept headers
|
||||
or messages as parameters are easy to write in a variety of ways to accomplish
|
||||
different results, without forcing cumbersome SFINAE declarations everywhere.
|
||||
|
||||
[endsect]
|
||||
454
src/beast/doc/9_2_http_comparison.qbk
Normal file
454
src/beast/doc/9_2_http_comparison.qbk
Normal file
@@ -0,0 +1,454 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section HTTP Comparison to Other Libraries]
|
||||
|
||||
There are a few C++ published libraries which implement some of the HTTP
|
||||
protocol. We analyze the message model chosen by those libraries and discuss
|
||||
the advantages and disadvantages relative to Beast.
|
||||
|
||||
The general strategy used by the author to evaluate external libraries is
|
||||
as follows:
|
||||
|
||||
* Review the message model. Can it represent a complete request or
|
||||
response? What level of allocator support is present? How much
|
||||
customization is possible?
|
||||
|
||||
* Review the stream abstraction. This is the type of object, such as
|
||||
a socket, which may be used to parse or serialize (i.e. read and write).
|
||||
Can user defined types be specified? What's the level of conformance to
|
||||
to Asio or Networking-TS concepts?
|
||||
|
||||
* Check treatment of buffers. Does the library manage the buffers
|
||||
or can users provide their own buffers?
|
||||
|
||||
* How does the library handle corner cases such as trailers,
|
||||
Expect: 100-continue, or deferred commitment of the body type?
|
||||
|
||||
[note
|
||||
Declarations examples from external libraries have been edited:
|
||||
portions have been removed for simplification.
|
||||
]
|
||||
|
||||
|
||||
|
||||
[heading cpp-netlib]
|
||||
|
||||
[@https://github.com/cpp-netlib/cpp-netlib/tree/092cd570fb179d029d1865aade9f25aae90d97b9 [*cpp-netlib]]
|
||||
is a network programming library previously intended for Boost but not
|
||||
having gone through formal review. As of this writing it still uses the
|
||||
Boost name, namespace, and directory structure although the project states
|
||||
that Boost acceptance is no longer a goal. The library is based on Boost.Asio
|
||||
and bills itself as ['"a collection of network related routines/implementations
|
||||
geared towards providing a robust cross-platform networking library"]. It
|
||||
cites ['"Common Message Type"] as a feature. As of the branch previous
|
||||
linked, it uses these declarations:
|
||||
```
|
||||
template <class Tag>
|
||||
struct basic_message {
|
||||
public:
|
||||
typedef Tag tag;
|
||||
|
||||
typedef typename headers_container<Tag>::type headers_container_type;
|
||||
typedef typename headers_container_type::value_type header_type;
|
||||
typedef typename string<Tag>::type string_type;
|
||||
|
||||
headers_container_type& headers() { return headers_; }
|
||||
headers_container_type const& headers() const { return headers_; }
|
||||
|
||||
string_type& body() { return body_; }
|
||||
string_type const& body() const { return body_; }
|
||||
|
||||
string_type& source() { return source_; }
|
||||
string_type const& source() const { return source_; }
|
||||
|
||||
string_type& destination() { return destination_; }
|
||||
string_type const& destination() const { return destination_; }
|
||||
|
||||
private:
|
||||
friend struct detail::directive_base<Tag>;
|
||||
friend struct detail::wrapper_base<Tag, basic_message<Tag> >;
|
||||
|
||||
mutable headers_container_type headers_;
|
||||
mutable string_type body_;
|
||||
mutable string_type source_;
|
||||
mutable string_type destination_;
|
||||
};
|
||||
```
|
||||
|
||||
This container is the base class template used to represent HTTP messages.
|
||||
It uses a "tag" type style specializations for a variety of trait classes,
|
||||
allowing for customization of the various parts of the message. For example,
|
||||
a user specializes `headers_container<T>` to determine what container type
|
||||
holds the header fields. We note some problems with the container declaration:
|
||||
|
||||
* The header and body containers may only be default-constructed.
|
||||
|
||||
* No stateful allocator support.
|
||||
|
||||
* There is no way to defer the commitment of the type for `body_` to
|
||||
after the headers are read in.
|
||||
|
||||
* The message model includes a "source" and "destination." This is
|
||||
extraneous metadata associated with the connection which is not part
|
||||
of the HTTP protocol specification and belongs elsewhere.
|
||||
|
||||
* The use of `string_type` (a customization point) for source,
|
||||
destination, and body suggests that `string_type` models a
|
||||
[*ForwardRange] whose `value_type` is `char`. This representation
|
||||
is less than ideal, considering that the library is built on
|
||||
Boost.Asio. Adapting a __DynamicBuffer__ to the required forward
|
||||
range destroys information conveyed by the __ConstBufferSequence__
|
||||
and __MutableBufferSequence__ used in dynamic buffers. The consequence
|
||||
is that cpp-netlib implementations will be less efficient than an
|
||||
equivalent __N4588__ conforming implementation.
|
||||
|
||||
* The library uses specializations of `string<Tag>` to change the type
|
||||
of string used everywhere, including the body, field name and value
|
||||
pairs, and extraneous metadata such as source and destination. The
|
||||
user may only choose a single type: field name, field values, and
|
||||
the body container will all use the same string type. This limits
|
||||
utility of the customization point. The library's use of the string
|
||||
trait is limited to selecting between `std::string` and `std::wstring`.
|
||||
We do not find this use-case compelling given the limitations.
|
||||
|
||||
* The specialized trait classes generate a proliferation of small
|
||||
additional framework types. To specialize traits, users need to exit
|
||||
their namespace and intrude into the `boost::network::http` namespace.
|
||||
The way the traits are used in the library limits the usefulness
|
||||
of the traits to trivial purpose.
|
||||
|
||||
* The `string<Tag> customization point constrains user defined body types
|
||||
to few possible strategies. There is no way to represent an HTTP message
|
||||
body as a filename with accompanying algorithms to store or retrieve data
|
||||
from the file system.
|
||||
|
||||
The design of the message container in this library is cumbersome
|
||||
with its system of customization using trait specializations. The
|
||||
use of these customizations is extremely limited due to the way they
|
||||
are used in the container declaration, making the design overly
|
||||
complex without corresponding benefit.
|
||||
|
||||
|
||||
|
||||
[heading Boost.HTTP]
|
||||
|
||||
[@https://github.com/BoostGSoC14/boost.http/tree/45fc1aa828a9e3810b8d87e669b7f60ec100bff4 [*boost.http]]
|
||||
is a library resulting from the 2014 Google Summer of Code. It was submitted
|
||||
for a Boost formal review and rejected in 2015. It is based on Boost.Asio,
|
||||
and development on the library has continued to the present. As of the branch
|
||||
previously linked, it uses these message declarations:
|
||||
```
|
||||
template<class Headers, class Body>
|
||||
struct basic_message
|
||||
{
|
||||
typedef Headers headers_type;
|
||||
typedef Body body_type;
|
||||
|
||||
headers_type &headers();
|
||||
|
||||
const headers_type &headers() const;
|
||||
|
||||
body_type &body();
|
||||
|
||||
const body_type &body() const;
|
||||
|
||||
headers_type &trailers();
|
||||
|
||||
const headers_type &trailers() const;
|
||||
|
||||
private:
|
||||
headers_type headers_;
|
||||
body_type body_;
|
||||
headers_type trailers_;
|
||||
};
|
||||
|
||||
typedef basic_message<boost::http::headers, std::vector<std::uint8_t>> message;
|
||||
|
||||
template<class Headers, class Body>
|
||||
struct is_message<basic_message<Headers, Body>>: public std::true_type {};
|
||||
```
|
||||
|
||||
* This container cannot model a complete message. The ['start-line] items
|
||||
(method and target for requests, reason-phrase for responses) are
|
||||
communicated out of band, as is the ['http-version]. A function that
|
||||
operates on the message including the start line requires additional
|
||||
parameters. This is evident in one of the
|
||||
[@https://github.com/BoostGSoC14/boost.http/blob/45fc1aa828a9e3810b8d87e669b7f60ec100bff4/example/basic_router.cpp#L81 example programs].
|
||||
The `500` and `"OK"` arguments represent the response ['status-code] and
|
||||
['reason-phrase] respectively:
|
||||
```
|
||||
...
|
||||
http::message reply;
|
||||
...
|
||||
self->socket.async_write_response(500, string_ref("OK"), reply, yield);
|
||||
```
|
||||
|
||||
* `headers_`, `body_`, and `trailers_` may only be default-constructed,
|
||||
since there are no explicitly declared constructors.
|
||||
|
||||
* There is no way to defer the commitment of the [*Body] type to after
|
||||
the headers are read in. This is related to the previous limitation
|
||||
on default-construction.
|
||||
|
||||
* No stateful allocator support. This follows from the previous limitation
|
||||
on default-construction. Buffers for start-line strings must be
|
||||
managed externally from the message object since they are not members.
|
||||
|
||||
* The trailers are stored in a separate object. Aside from the combinatorial
|
||||
explosion of the number of additional constructors necessary to fully
|
||||
support arbitrary forwarded parameter lists for each of the headers, body,
|
||||
and trailers members, the requirement to know in advance whether a
|
||||
particular HTTP field will be located in the headers or the trailers
|
||||
poses an unnecessary complication for general purpose functions that
|
||||
operate on messages.
|
||||
|
||||
* The declarations imply that `std::vector` is a model of [*Body].
|
||||
More formally, that a body is represented by the [*ForwardRange]
|
||||
concept whose `value_type` is an 8-bit integer. This representation
|
||||
is less than ideal, considering that the library is built on
|
||||
Boost.Asio. Adapting a __DynamicBuffer__ to the required forward range
|
||||
destroys information conveyed by the __ConstBufferSequence__ and
|
||||
__MutableBufferSequence__ used in dynamic buffers. The consequence is
|
||||
that Boost.HTTP implementations will be less efficient when dealing
|
||||
with body containers than an equivalent __N4588__ conforming
|
||||
implementation.
|
||||
|
||||
* The [*Body] customization point constrains user defined types to
|
||||
very limited implementation strategies. For example, there is no way
|
||||
to represent an HTTP message body as a filename with accompanying
|
||||
algorithms to store or retrieve data from the file system.
|
||||
|
||||
This representation addresses a narrow range of use cases. It has
|
||||
limited potential for customization and performance. It is more difficult
|
||||
to use because it excludes the start line fields from the model.
|
||||
|
||||
|
||||
|
||||
[heading C++ REST SDK (cpprestsdk)]
|
||||
|
||||
[@https://github.com/Microsoft/cpprestsdk/tree/381f5aa92d0dfb59e37c0c47b4d3771d8024e09a [*cpprestsdk]]
|
||||
is a Microsoft project which ['"...aims to help C++ developers connect to and
|
||||
interact with services"]. It offers the most functionality of the libraries
|
||||
reviewed here, including support for Websocket services using its websocket++
|
||||
dependency. It can use native APIs such as HTTP.SYS when building Windows
|
||||
based applications, and it can use Boost.Asio. The WebSocket module uses
|
||||
Boost.Asio exclusively.
|
||||
|
||||
As cpprestsdk is developed by a large corporation, it contains quite a bit
|
||||
of functionality and necessarily has more interfaces. We will break down
|
||||
the interfaces used to model messages into more manageable pieces. This
|
||||
is the container used to store the HTTP header fields:
|
||||
```
|
||||
class http_headers
|
||||
{
|
||||
public:
|
||||
...
|
||||
|
||||
private:
|
||||
std::map<utility::string_t, utility::string_t, _case_insensitive_cmp> m_headers;
|
||||
};
|
||||
```
|
||||
|
||||
This declaration is quite bare-bones. We note the typical problems of
|
||||
most field containers:
|
||||
|
||||
* The container may only be default-constructed.
|
||||
|
||||
* No support for allocators, stateful or otherwise.
|
||||
|
||||
* There are no customization points at all.
|
||||
|
||||
Now we analyze the structure of
|
||||
the larger message container. The library uses a handle/body idiom. There
|
||||
are two public message container interfaces, one for requests (`http_request`)
|
||||
and one for responses (`http_response`). Each interface maintains a private
|
||||
shared pointer to an implementation class. Public member function calls
|
||||
are routed to the internal implementation. This is the first implementation
|
||||
class, which forms the base class for both the request and response
|
||||
implementations:
|
||||
```
|
||||
namespace details {
|
||||
|
||||
class http_msg_base
|
||||
{
|
||||
public:
|
||||
http_headers &headers() { return m_headers; }
|
||||
|
||||
_ASYNCRTIMP void set_body(const concurrency::streams::istream &instream, const utf8string &contentType);
|
||||
|
||||
/// Set the stream through which the message body could be read
|
||||
void set_instream(const concurrency::streams::istream &instream) { m_inStream = instream; }
|
||||
|
||||
/// Set the stream through which the message body could be written
|
||||
void set_outstream(const concurrency::streams::ostream &outstream, bool is_default) { m_outStream = outstream; m_default_outstream = is_default; }
|
||||
|
||||
const pplx::task_completion_event<utility::size64_t> & _get_data_available() const { return m_data_available; }
|
||||
|
||||
protected:
|
||||
/// Stream to read the message body.
|
||||
concurrency::streams::istream m_inStream;
|
||||
|
||||
/// stream to write the msg body
|
||||
concurrency::streams::ostream m_outStream;
|
||||
|
||||
http_headers m_headers;
|
||||
bool m_default_outstream;
|
||||
|
||||
/// <summary> The TCE is used to signal the availability of the message body. </summary>
|
||||
pplx::task_completion_event<utility::size64_t> m_data_available;
|
||||
};
|
||||
```
|
||||
|
||||
To understand these declarations we need to first understand that cpprestsdk
|
||||
uses the asynchronous model defined by Microsoft's
|
||||
[@https://msdn.microsoft.com/en-us/library/dd504870.aspx [*Concurrency Runtime]].
|
||||
Identifiers from the [@https://msdn.microsoft.com/en-us/library/jj987780.aspx [*`pplx` namespace]]
|
||||
define common asynchronous patterns such as tasks and events. The
|
||||
`concurrency::streams::istream` parameter and `m_data_available` data member
|
||||
indicates a lack of separation of concerns. The representation of HTTP messages
|
||||
should not be conflated with the asynchronous model used to serialize or
|
||||
parse those messages in the message declarations.
|
||||
|
||||
The next declaration forms the complete implementation class referenced by the
|
||||
handle in the public interface (which follows after):
|
||||
```
|
||||
/// Internal representation of an HTTP request message.
|
||||
class _http_request final : public http::details::http_msg_base, public std::enable_shared_from_this<_http_request>
|
||||
{
|
||||
public:
|
||||
_ASYNCRTIMP _http_request(http::method mtd);
|
||||
|
||||
_ASYNCRTIMP _http_request(std::unique_ptr<http::details::_http_server_context> server_context);
|
||||
|
||||
http::method &method() { return m_method; }
|
||||
|
||||
const pplx::cancellation_token &cancellation_token() const { return m_cancellationToken; }
|
||||
|
||||
_ASYNCRTIMP pplx::task<void> reply(const http_response &response);
|
||||
|
||||
private:
|
||||
|
||||
// Actual initiates sending the response, without checking if a response has already been sent.
|
||||
pplx::task<void> _reply_impl(http_response response);
|
||||
|
||||
http::method m_method;
|
||||
|
||||
std::shared_ptr<progress_handler> m_progress_handler;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
```
|
||||
|
||||
As before, we note that the implementation class for HTTP requests concerns
|
||||
itself more with the mechanics of sending the message asynchronously than
|
||||
it does with actually modeling the HTTP message as described in __rfc7230__:
|
||||
|
||||
* The constructor accepting `std::unique_ptr<http::details::_http_server_context`
|
||||
breaks encapsulation and separation of concerns. This cannot be extended
|
||||
for user defined server contexts.
|
||||
|
||||
* The "cancellation token" is stored inside the message. This breaks the
|
||||
separation of concerns.
|
||||
|
||||
* The `_reply_impl` function implies that the message implementation also
|
||||
shares responsibility for the means of sending back an HTTP reply. This
|
||||
would be better if it was completely separate from the message container.
|
||||
|
||||
Finally, here is the public class which represents an HTTP request:
|
||||
```
|
||||
class http_request
|
||||
{
|
||||
public:
|
||||
const http::method &method() const { return _m_impl->method(); }
|
||||
|
||||
void set_method(const http::method &method) const { _m_impl->method() = method; }
|
||||
|
||||
/// Extract the body of the request message as a string value, checking that the content type is a MIME text type.
|
||||
/// A body can only be extracted once because in some cases an optimization is made where the data is 'moved' out.
|
||||
pplx::task<utility::string_t> extract_string(bool ignore_content_type = false)
|
||||
{
|
||||
auto impl = _m_impl;
|
||||
return pplx::create_task(_m_impl->_get_data_available()).then([impl, ignore_content_type](utility::size64_t) { return impl->extract_string(ignore_content_type); });
|
||||
}
|
||||
|
||||
/// Extracts the body of the request message into a json value, checking that the content type is application/json.
|
||||
/// A body can only be extracted once because in some cases an optimization is made where the data is 'moved' out.
|
||||
pplx::task<json::value> extract_json(bool ignore_content_type = false) const
|
||||
{
|
||||
auto impl = _m_impl;
|
||||
return pplx::create_task(_m_impl->_get_data_available()).then([impl, ignore_content_type](utility::size64_t) { return impl->_extract_json(ignore_content_type); });
|
||||
}
|
||||
|
||||
/// Sets the body of the message to the contents of a byte vector. If the 'Content-Type'
|
||||
void set_body(const std::vector<unsigned char> &body_data);
|
||||
|
||||
/// Defines a stream that will be relied on to provide the body of the HTTP message when it is
|
||||
/// sent.
|
||||
void set_body(const concurrency::streams::istream &stream, const utility::string_t &content_type = _XPLATSTR("application/octet-stream"));
|
||||
|
||||
/// Defines a stream that will be relied on to hold the body of the HTTP response message that
|
||||
/// results from the request.
|
||||
void set_response_stream(const concurrency::streams::ostream &stream);
|
||||
{
|
||||
return _m_impl->set_response_stream(stream);
|
||||
}
|
||||
|
||||
/// Defines a callback function that will be invoked for every chunk of data uploaded or downloaded
|
||||
/// as part of the request.
|
||||
void set_progress_handler(const progress_handler &handler);
|
||||
|
||||
private:
|
||||
friend class http::details::_http_request;
|
||||
friend class http::client::http_client;
|
||||
|
||||
std::shared_ptr<http::details::_http_request> _m_impl;
|
||||
};
|
||||
```
|
||||
|
||||
It is clear from this declaration that the goal of the message model in
|
||||
this library is driven by its use-case (interacting with REST servers)
|
||||
and not to model HTTP messages generally. We note problems similar to
|
||||
the other declarations:
|
||||
|
||||
* There are no compile-time customization points at all. The only
|
||||
customization is in the `concurrency::streams::istream` and
|
||||
`concurrency::streams::ostream` reference parameters. Presumably,
|
||||
these are abstract interfaces which may be subclassed by users
|
||||
to achieve custom behaviors.
|
||||
|
||||
* The extraction of the body is conflated with the asynchronous model.
|
||||
|
||||
* No way to define an allocator for the container used when extracting
|
||||
the body.
|
||||
|
||||
* A body can only be extracted once, limiting the use of this container
|
||||
when using a functional programming style.
|
||||
|
||||
* Setting the body requires either a vector or a `concurrency::streams::istream`.
|
||||
No user defined types are possible.
|
||||
|
||||
* The HTTP request container conflates HTTP response behavior (see the
|
||||
`set_response_stream` member). Again this is likely purpose-driven but
|
||||
the lack of separation of concerns limits this library to only the
|
||||
uses explicitly envisioned by the authors.
|
||||
|
||||
The general theme of the HTTP message model in cpprestsdk is "no user
|
||||
definable customizations". There is no allocator support, and no
|
||||
separation of concerns. It is designed to perform a specific set of
|
||||
behaviors. In other words, it does not follow the open/closed principle.
|
||||
|
||||
Tasks in the Concurrency Runtime operate in a fashion similar to
|
||||
`std::future`, but with some improvements such as continuations which
|
||||
are not yet in the C++ standard. The costs of using a task based
|
||||
asynchronous interface instead of completion handlers is well
|
||||
documented: synchronization points along the call chain of composed
|
||||
task operations which cannot be optimized away. See:
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf
|
||||
[*A Universal Model for Asynchronous Operations]] (Kohlhoff).
|
||||
|
||||
[endsect]
|
||||
445
src/beast/doc/9_3_websocket_zaphoyd.qbk
Normal file
445
src/beast/doc/9_3_websocket_zaphoyd.qbk
Normal file
@@ -0,0 +1,445 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section Comparison to Zaphoyd Studios WebSocket++]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[
|
||||
How does this compare to [@https://www.zaphoyd.com/websocketpp websocketpp],
|
||||
an alternate header-only WebSocket implementation?
|
||||
][
|
||||
[variablelist
|
||||
|
||||
[[1. Synchronous Interface][
|
||||
|
||||
Beast offers full support for WebSockets using a synchronous interface. It
|
||||
uses the same style of interfaces found in Boost.Asio: versions that throw
|
||||
exceptions, or versions that return the error code in a reference parameter:
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L774 Beast]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
read(DynamicBuffer& dynabuf)
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
[[2. Connection Model][
|
||||
|
||||
websocketpp supports multiple transports by utilizing a trait, the `config::transport_type`
|
||||
([@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/asio/connection.hpp#L60 asio transport example])
|
||||
To get an idea of the complexity involved with implementing a transport,
|
||||
compare the asio transport to the
|
||||
[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/iostream/connection.hpp#L59 `iostream` transport]
|
||||
(a layer that allows websocket communication over a `std::iostream`).
|
||||
|
||||
In contrast, Beast abstracts the transport by defining just one [*`NextLayer`]
|
||||
template argument The type requirements for [*`NextLayer`] are
|
||||
already familiar to users as they are documented in Asio:
|
||||
__AsyncReadStream__, __AsyncWriteStream__, __SyncReadStream__, __SyncWriteStream__.
|
||||
|
||||
The type requirements for instantiating `beast::websocket::stream` versus
|
||||
`websocketpp::connection` with user defined types are vastly reduced
|
||||
(18 functions versus 2). Note that websocketpp connections are passed by
|
||||
`shared_ptr`. Beast does not use `shared_ptr` anywhere in its public interface.
|
||||
A `beast::websocket::stream` is constructible and movable in a manner identical
|
||||
to a `boost::asio::ip::tcp::socket`. Callers can put such objects in a
|
||||
`shared_ptr` if they want to, but there is no requirement to do so.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L234 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template<class NextLayer>
|
||||
class stream
|
||||
{
|
||||
NextLayer next_layer_;
|
||||
...
|
||||
}
|
||||
```]
|
||||
[```
|
||||
template <typename config>
|
||||
class connection
|
||||
: public config::transport_type::transport_con_type
|
||||
, public config::connection_base
|
||||
{
|
||||
public:
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
...
|
||||
}
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[3. Client and Server Role][
|
||||
|
||||
websocketpp provides multi-role support through a hierarchy of
|
||||
different classes. A `beast::websocket::stream` is role-agnostic, it
|
||||
offers member functions to perform both client and server handshakes
|
||||
in the same class. The same types are used for client and server
|
||||
streams.
|
||||
|
||||
[table
|
||||
[
|
||||
[Beast]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/roles/server_endpoint.hpp#L39 websocketpp],
|
||||
[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/roles/client_endpoint.hpp#L42 also]]
|
||||
][
|
||||
[
|
||||
/<not needed>/
|
||||
]
|
||||
[```
|
||||
template <typename config>
|
||||
class client : public endpoint<connection<config>,config>;
|
||||
template <typename config>
|
||||
class server : public endpoint<connection<config>,config>;
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[4. Thread Safety][
|
||||
|
||||
websocketpp uses mutexes to protect shared data from concurrent
|
||||
access. In contrast, Beast does not use mutexes anywhere in its
|
||||
implementation. Instead, it follows the Asio pattern. Calls to
|
||||
asynchronous initiation functions use the same method to invoke
|
||||
intermediate handlers as the method used to invoke the final handler,
|
||||
through the __asio_handler_invoke__ mechanism.
|
||||
|
||||
The only requirement in Beast is that calls to asynchronous initiation
|
||||
functions are made from the same implicit or explicit strand. For
|
||||
example, if the `io_service` associated with a `beast::websocket::stream`
|
||||
is single threaded, this counts as an implicit strand and no performance
|
||||
costs associated with mutexes are incurred.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/impl/read_frame_op.ipp#L118 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/iostream/connection.hpp#L706 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template <class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, read_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::invoke(f, op->d_->h);
|
||||
}
|
||||
```]
|
||||
[```
|
||||
mutex_type m_read_mutex;
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[5. Callback Model][
|
||||
|
||||
websocketpp requires a one-time call to set the handler for each event
|
||||
in its interface (for example, upon message receipt). The handler is
|
||||
represented by a `std::function` equivalent. Its important to recognize
|
||||
that the websocketpp interface performs type-erasure on this handler.
|
||||
|
||||
In comparison, Beast handlers are specified in a manner identical to
|
||||
Boost.Asio. They are function objects which can be copied or moved but
|
||||
most importantly they are not type erased. The compiler can see
|
||||
through the type directly to the implementation, permitting
|
||||
optimization. Furthermore, Beast follows the Asio rules for treatment
|
||||
of handlers. It respects any allocation, continuation, or invocation
|
||||
customizations associated with the handler through the use of argument
|
||||
dependent lookup overloads of functions such as `asio_handler_allocate`.
|
||||
|
||||
The Beast completion handler is provided at the call site. For each
|
||||
call to an asynchronous initiation function, it is guaranteed that
|
||||
there will be exactly one final call to the handler. This functions
|
||||
exactly the same way as the asynchronous initiation functions found in
|
||||
Boost.Asio, allowing the composition of higher level abstractions.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L834 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L281 websocketpp],
|
||||
[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L473 also]]
|
||||
][
|
||||
[```
|
||||
template<
|
||||
class DynamicBuffer, // Supports user defined types
|
||||
class ReadHandler // Handler is NOT type-erased
|
||||
>
|
||||
typename async_completion< // Return value customization
|
||||
ReadHandler, // supports futures and coroutines
|
||||
void(error_code)
|
||||
>::result_type
|
||||
async_read(
|
||||
DynamicBuffer& dynabuf,
|
||||
ReadHandler&& handler);
|
||||
```]
|
||||
[```
|
||||
typedef lib::function<
|
||||
void(connection_hdl,message_ptr)
|
||||
> message_handler;
|
||||
void set_message_handler(message_handler h);
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[6. Extensible Asynchronous Model][
|
||||
|
||||
Beast fully supports the
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3896.pdf Extensible Asynchronous Model]
|
||||
developed by Christopher Kohlhoff, author of Boost.Asio (see Section 8).
|
||||
|
||||
Beast websocket asynchronous interfaces may be used seamlessly with
|
||||
`std::future` stackful/stackless coroutines, or user defined customizations.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/impl/stream.ipp#L378 Beast]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
beast::async_completion<
|
||||
ReadHandler,
|
||||
void(error_code)> completion{handler};
|
||||
read_op<
|
||||
DynamicBuffer, decltype(completion.handler)>{
|
||||
completion.handler, *this, op, buffer};
|
||||
|
||||
return completion.result.get(); // Customization point
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
[[7. Message Buffering][
|
||||
|
||||
websocketpp defines a message buffer, passed in arguments by
|
||||
`shared_ptr`, and an associated message manager which permits
|
||||
aggregation and reuse of memory. The implementation of
|
||||
`websocketpp::message` uses a `std::string` to hold the payload. If an
|
||||
incoming message is broken up into multiple frames, the string may be
|
||||
reallocated for each continuation frame. The `std::string` always uses
|
||||
the standard allocator, it is not possible to customize the choice of
|
||||
allocator.
|
||||
|
||||
Beast allows callers to specify the object for receiving the message
|
||||
or frame data, which is of any type meeting the requirements of
|
||||
__DynamicBuffer__ (modeled after `boost::asio::streambuf`).
|
||||
|
||||
Beast comes with the class __basic_multi_buffer__, an efficient
|
||||
implementation of the __DynamicBuffer__ concept which makes use of multiple
|
||||
allocated octet arrays. If an incoming message is broken up into
|
||||
multiple pieces, no reallocation occurs. Instead, new allocations are
|
||||
appended to the sequence when existing allocations are filled. Beast
|
||||
does not impose any particular memory management model on callers. The
|
||||
__basic_multi_buffer__ provided by beast supports standard allocators through
|
||||
a template argument. Use the __DynamicBuffer__ that comes with beast,
|
||||
customize the allocator if you desire, or provide your own type that
|
||||
meets the requirements.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L774 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/message_buffer/message.hpp#L78 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template<class DynamicBuffer>
|
||||
read(DynamicBuffer& dynabuf);
|
||||
```]
|
||||
[```
|
||||
template <template<class> class con_msg_manager>
|
||||
class message {
|
||||
public:
|
||||
typedef lib::shared_ptr<message> ptr;
|
||||
...
|
||||
std::string m_payload;
|
||||
...
|
||||
};
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[8. Sending Messages][
|
||||
|
||||
When sending a message, websocketpp requires that the payload is
|
||||
packaged in a `websocketpp::message` object using `std::string` as the
|
||||
storage, or it requires a copy of the caller provided buffer by
|
||||
constructing a new message object. Messages are placed onto an
|
||||
outgoing queue. An asynchronous write operation runs in the background
|
||||
to clear the queue. No user facing handler can be registered to be
|
||||
notified when messages or frames have completed sending.
|
||||
|
||||
Beast doesn't allocate or make copies of buffers when sending data. The
|
||||
caller's buffers are sent in-place. You can use any object meeting the
|
||||
requirements of
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/ConstBufferSequence.html ConstBufferSequence],
|
||||
permitting efficient scatter-gather I/O.
|
||||
|
||||
The [*ConstBufferSequence] interface allows callers to send data from
|
||||
memory-mapped regions (not possible in websocketpp). Callers can also
|
||||
use the same buffers to send data to multiple streams, for example
|
||||
broadcasting common subscription data to many clients at once. For
|
||||
each call to `async_write` the completion handler is called once when
|
||||
the data finishes sending, in a manner identical to `boost::asio::async_write`.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L1048 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L672 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template<class ConstBufferSequence>
|
||||
void
|
||||
write(ConstBufferSequence const& buffers);
|
||||
```]
|
||||
[```
|
||||
lib::error_code send(std::string const & payload,
|
||||
frame::opcode::value op = frame::opcode::text);
|
||||
...
|
||||
lib::error_code send(message_ptr msg);
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[9. Streaming Messages][
|
||||
|
||||
websocketpp requires that the entire message fit into memory, and that
|
||||
the size is known ahead of time.
|
||||
|
||||
Beast allows callers to compose messages in individual frames. This is
|
||||
useful when the size of the data is not known ahead of time or if it
|
||||
is not desired to buffer the entire message in memory at once before
|
||||
sending it. For example, sending periodic output of a database query
|
||||
running on a coroutine. Or sending the contents of a file in pieces,
|
||||
without bringing it all into memory.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L1151 Beast]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
template<class ConstBufferSequence>
|
||||
void
|
||||
write_frame(bool fin,
|
||||
ConstBufferSequence const& buffers);
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
[[10. Flow Control][
|
||||
|
||||
The websocketpp read implementation continuously reads asynchronously
|
||||
from the network and buffers message data. To prevent unbounded growth
|
||||
and leverage TCP/IP's flow control mechanism, callers can periodically
|
||||
turn this 'read pump' off and back on.
|
||||
|
||||
In contrast a `beast::websocket::stream` does not independently begin
|
||||
background activity, nor does it buffer messages. It receives data only
|
||||
when there is a call to an asynchronous initiation function (for
|
||||
example `beast::websocket::stream::async_read`) with an associated handler.
|
||||
Applications do not need to implement explicit logic to regulate the
|
||||
flow of data. Instead, they follow the traditional model of issuing a
|
||||
read, receiving a read completion, processing the message, then
|
||||
issuing a new read and repeating the process.
|
||||
|
||||
[table
|
||||
[
|
||||
[Beast]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L728 websocketpp]]
|
||||
][
|
||||
[
|
||||
/<implicit>/
|
||||
]
|
||||
[```
|
||||
lib::error_code pause_reading();
|
||||
lib::error_code resume_reading();
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[11. Connection Establishment][
|
||||
|
||||
websocketpp offers the `endpoint` class which can handle binding and
|
||||
listening to a port, and spawning connection objects.
|
||||
|
||||
Beast does not reinvent the wheel here, callers use the interfaces
|
||||
already in `boost::asio` for receiving incoming connections resolving
|
||||
host names, or establishing outgoing connections. After the socket (or
|
||||
`boost::asio::ssl::stream`) is connected, the `beast::websocket::stream`
|
||||
is constructed around it and the WebSocket handshake can be performed.
|
||||
|
||||
Beast users are free to implement their own "connection manager", but
|
||||
there is no requirement to do so.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@http://www.boost.org/doc/html/boost_asio/reference/async_connect.html Beast],
|
||||
[@http://www.boost.org/doc/html/boost_asio/reference/basic_socket_acceptor/async_accept.html also]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/asio/endpoint.hpp#L52 websocketpp]]
|
||||
][
|
||||
[```
|
||||
#include <boost/asio.hpp>
|
||||
```]
|
||||
[```
|
||||
template <typename config>
|
||||
class endpoint : public config::socket_type;
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[12. WebSocket Handshaking][
|
||||
|
||||
Callers invoke `beast::websocket::accept` to perform the WebSocket
|
||||
handshake, but there is no requirement to use this function. Advanced
|
||||
users can perform the WebSocket handshake themselves. Beast WebSocket
|
||||
provides the tools for composing the request or response, and the
|
||||
Beast HTTP interface provides the container and algorithms for sending
|
||||
and receiving HTTP/1 messages including the necessary HTTP Upgrade
|
||||
request for establishing the WebSocket session.
|
||||
|
||||
Beast allows the caller to pass the incoming HTTP Upgrade request for
|
||||
the cases where the caller has already received an HTTP message.
|
||||
This flexibility permits novel and robust implementations. For example,
|
||||
a listening socket that can handshake in multiple protocols on the
|
||||
same port.
|
||||
|
||||
Sometimes callers want to read some bytes on the socket before reading
|
||||
the WebSocket HTTP Upgrade request. Beast allows these already-received
|
||||
bytes to be supplied to an overload of the accepting function to permit
|
||||
sophisticated features. For example, a listening socket that can
|
||||
accept both regular WebSocket and Secure WebSocket (SSL) connections.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L501 Beast],
|
||||
[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L401 also]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
template<class ConstBufferSequence>
|
||||
void
|
||||
accept(ConstBufferSequence const& buffers);
|
||||
|
||||
template<class Allocator>
|
||||
void
|
||||
accept(http::header<true, http::basic_fields<Allocator>> const& req);
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
]
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
283
src/beast/doc/9_4_faq.qbk
Normal file
283
src/beast/doc/9_4_faq.qbk
Normal file
@@ -0,0 +1,283 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section FAQ]
|
||||
|
||||
To set realistic expectations and prevent a litany of duplicate review
|
||||
statements, these notes address the most common questions and comments
|
||||
about Beast and other HTTP libraries that have gone through formal review.
|
||||
|
||||
[variablelist
|
||||
[[
|
||||
"Beast requires too much user code to do anything!"
|
||||
][
|
||||
It is not the intention of the library to provide turn-key
|
||||
solutions for specific HTTP or WebSocket use-cases.
|
||||
Instead, it is a sensible protocol layering on top of
|
||||
Boost.Asio which retains the Boost.Asio memory
|
||||
management style and asynchronous model.
|
||||
]]
|
||||
[[
|
||||
"Beast does not offer an HTTP server?"
|
||||
][
|
||||
Beast has a functional HTTP server in the example directory. The
|
||||
server supports both HTTP and WebSocket using synchronous and
|
||||
asynchronous shared or dedicated ports. In addition, the server
|
||||
supports encrypted TLS connections if OpenSSL is available, on
|
||||
dedicated ports. And the server comes with a "multi-port", a
|
||||
flexible single port which supports both encrypted and unencrypted
|
||||
connections, both HTTP and WebSocket, all on the same port. The
|
||||
server is not part of Beast's public interfaces, as that
|
||||
functionality is outside the scope of the library. The author
|
||||
feels that attempting to broaden the scope of the library will
|
||||
reduce its appeal for standardization.
|
||||
]]
|
||||
[[
|
||||
"Beast does not offer an HTTP client?"
|
||||
][
|
||||
"I just want to download a resource using HTTP" is a common
|
||||
cry from users and reviewers. Such functionality is beyond
|
||||
the scope of Beast. Building a full featured HTTP client is
|
||||
a difficult task and large enough to deserve its own library.
|
||||
There are many things to deal with such as the various message
|
||||
body encodings, complex parsing of headers, difficult header
|
||||
semantics such as Range and Cache-Control, redirection,
|
||||
Expect:100-continue, connection retrying, domain name
|
||||
resolution, TLS, and much, much more. It is the author's
|
||||
position that Boost first needs a common set of nouns and
|
||||
verbs for manipulating HTTP at the protocol level; Beast
|
||||
provides that language.
|
||||
]]
|
||||
[[
|
||||
"There's no HTTP/2 support yet!"
|
||||
][
|
||||
Many reviewers feel that HTTP/2 support is an essential feature of
|
||||
a HTTP library. The authors agree that HTTP/2 is important but also
|
||||
feel that the most sensible implementation is one that does not re-use
|
||||
the same network reading and writing interface for 2 as that for 1.0
|
||||
and 1.1.
|
||||
|
||||
The Beast HTTP message model was designed with the new protocol
|
||||
in mind and should be evaluated in that context. There are plans
|
||||
to add HTTP/2 in the future, but there is no rush to do so.
|
||||
Users can work with HTTP/1 now; we should not deny them that
|
||||
functionality today to wait for a newer protocol tomorrow.
|
||||
It is the author's position that there is sufficient value in
|
||||
Beast's HTTP/1-only implementation that the lack of HTTP/2
|
||||
should not be a barrier to acceptance.
|
||||
|
||||
The Beast HTTP message model is suitable for HTTP/2 and can be re-used.
|
||||
The IETF HTTP Working Group adopted message compatibility with HTTP/1.x
|
||||
as an explicit goal. A parser can simply emit full headers after
|
||||
decoding the compressed HTTP/2 headers. The stream ID is not logically
|
||||
part of the message but rather message metadata and should be
|
||||
communicated out-of-band (see below). HTTP/2 sessions begin with a
|
||||
traditional HTTP/1.1 Upgrade similar in fashion to the WebSocket
|
||||
upgrade. An HTTP/2 implementation can use existing Beast.HTTP primitives
|
||||
to perform this handshake.
|
||||
]]
|
||||
[[
|
||||
"This should work with standalone-Asio!"
|
||||
][
|
||||
Beast uses more than Boost.Asio, it depends on various other parts
|
||||
of Boost. The standalone Asio is currently farther ahead than the
|
||||
Boost version. Keeping Beast maintained against both versions of
|
||||
Asio is beyond the resources of the author at the present time.
|
||||
Compatibility with non-Boost libraries should not be an acceptance
|
||||
criteria. Beast is currently designed to be a part of Boost:
|
||||
nothing more, nothing less. Looking at the bigger picture, it
|
||||
is the author's goal to propose this library for standardization.
|
||||
A logical track for achieving this is as follows:
|
||||
|
||||
[ordered_list
|
||||
[
|
||||
Boost library acceptance.
|
||||
][
|
||||
Port to the Boost.Asio version of Networking-TS (This has to wait
|
||||
until Boost's version of Asio is updated).
|
||||
][
|
||||
Wait for Networking-TS to become an official part of C++.
|
||||
][
|
||||
Port to the standard library versions of networking (gcc, clang, msvc).
|
||||
][
|
||||
Develop proposed language (This can happen concurrently with steps 3 and 4)
|
||||
]]
|
||||
]]
|
||||
[[
|
||||
"You need benchmarks!"
|
||||
][
|
||||
The energy invested in Beast went into the design of the interfaces,
|
||||
not performance. That said, the most sensitive parts of Beast have
|
||||
been optimized or designed with optimization in mind. The slow parts
|
||||
of WebSocket processing have been optimized, and the HTTP parser design
|
||||
is lifted from another extremely popular project which has performance
|
||||
as a design goal (see [@https://github.com/h2o/picohttpparser]).
|
||||
|
||||
From: [@http://www.boost.org/development/requirements.html]
|
||||
|
||||
"Aim first for clarity and correctness; optimization should
|
||||
be only a secondary concern in most Boost libraries."
|
||||
|
||||
As the library matures it will undergo optimization passes; benchmarks
|
||||
will logically accompany this process. There is a small benchmarking
|
||||
program included in the tests which compares the performance of
|
||||
Beast's parser to the NodeJS reference parser, as well as some
|
||||
benchmarks which compare the performance of various Beast dynamic
|
||||
buffer implementations against Asio's.
|
||||
]]
|
||||
[[
|
||||
"Beast is a terrible name!"
|
||||
][
|
||||
The name "Boost.Http" or "Boost.WebSocket" would mislead users into
|
||||
believing they could perform an HTTP request on a URL or put up a
|
||||
WebSocket client or server in a couple of lines of code. Where
|
||||
would the core utilities go? Very likely it would step on the
|
||||
owner of Boost.Asio's toes to put things in the boost/asio
|
||||
directory; at the very least, it would create unrequested,
|
||||
additional work for the foreign repository.
|
||||
|
||||
"Beast" is sufficiently vague as to not suggest any particular
|
||||
functionality, while acting as a memorable umbrella term for a
|
||||
family of low level containers and algorithms. People in the know
|
||||
or with a need for low-level network protocol operations will
|
||||
have no trouble finding it, and the chances of luring a novice
|
||||
into a bad experience are greatly reduced.
|
||||
There is precedent for proper names: "Hana", "Fusion", "Phoenix",
|
||||
and "Spirit" come to mind. Is "Beast" really any worse than say,
|
||||
"mp11" for example?
|
||||
Beast also already has a growing body of users and attention from
|
||||
the open source community, the name Beast comes up in reddit posts
|
||||
and StackOverflow as the answer to questions about which HTTP or
|
||||
WebSocket library to use.
|
||||
]]
|
||||
|
||||
|
||||
|
||||
[[
|
||||
"Some more advanced examples, e.g. including TLS with client/server
|
||||
certificates would help."
|
||||
][
|
||||
The server-framework example demonstrates how to implement a server
|
||||
that supports TLS using certificates. There are also websocket and
|
||||
HTTP client examples which use TLS. Furthermore, management of
|
||||
certificates is beyond the scope of the public interfaces of the
|
||||
library. Asio already provides documentation, interfaces, and
|
||||
examples for performing these tasks - Beast does not intend to
|
||||
reinvent them or to redundantly provide this information.
|
||||
]]
|
||||
|
||||
[[
|
||||
"A built-in HTTP router?"
|
||||
][
|
||||
We presume this means a facility to match expressions against the URI
|
||||
in HTTP requests, and dispatch them to calling code. The authors feel
|
||||
that this is a responsibility of higher level code. Beast does
|
||||
not try to offer a web server. That said, the server-framework
|
||||
example has a concept of request routing called a Service. Two
|
||||
services are provided, one for serving files and the other for
|
||||
handling WebSocket upgrade requests.
|
||||
]]
|
||||
|
||||
[[
|
||||
"HTTP Cookies? Forms/File Uploads?"
|
||||
][
|
||||
Cookies, or managing these types of HTTP headers in general, is the
|
||||
responsibility of higher levels. Beast just tries to get complete
|
||||
messages to and from the calling code. It deals in the HTTP headers just
|
||||
enough to process the message body and leaves the rest to callers. However,
|
||||
for forms and file uploads the symmetric interface of the message class
|
||||
allows HTTP requests to include arbitrary body types including those needed
|
||||
to upload a file or fill out a form.
|
||||
]]
|
||||
|
||||
[[
|
||||
"...supporting TLS (is this a feature? If not this would be a show-stopper),
|
||||
etc."
|
||||
][
|
||||
Beast works with the Stream concept, so it automatically works with the
|
||||
`boost::asio::ssl::stream` that you have already set up through Asio.
|
||||
]]
|
||||
|
||||
[[
|
||||
"There should also be more examples of how to integrate the http service
|
||||
with getting files from the file system, generating responses CGI-style"
|
||||
][
|
||||
The design goal for the library is to not try to invent a web server.
|
||||
We feel that there is a strong need for a basic implementation that
|
||||
models the HTTP message and provides functions to send and receive them
|
||||
over Asio. Such an implementation should serve as a building block upon
|
||||
which higher abstractions such as the aforementioned HTTP service or
|
||||
cgi-gateway can be built.
|
||||
|
||||
There are several HTTP servers in the example directory which deliver
|
||||
files, as well as some tested and compiled code snippets which can be
|
||||
used as a starting point for interfacing with other processes.
|
||||
]]
|
||||
|
||||
[[
|
||||
"You should send a 100-continue to ask for the rest of the body if required."
|
||||
][
|
||||
Deciding on whether to send the "Expect: 100-continue" header or
|
||||
how to handle it on the server side is the caller's responsibility;
|
||||
Beast provides the functionality to send or inspect the header before
|
||||
sending or reading the body.
|
||||
]]
|
||||
|
||||
|
||||
|
||||
[[
|
||||
"I would also like to see instances of this library being used
|
||||
in production. That would give some evidence that the design
|
||||
works in practice."
|
||||
][
|
||||
Beast has already been on public servers receiving traffic and handling
|
||||
hundreds of millions of dollars' worth of financial transactions daily.
|
||||
The servers run [*rippled], open source software
|
||||
([@https://github.com/ripple/rippled repository])
|
||||
implementing the
|
||||
[@https://ripple.com/files/ripple_consensus_whitepaper.pdf [*Ripple Consensus Protocol]],
|
||||
technology provided by [@http://ripple.com Ripple].
|
||||
|
||||
Furthermore, the repository has grown significantly in popularity in
|
||||
2017. There are many users, and some of them participate directly in
|
||||
the repository by reporting issues, performing testing, and in some
|
||||
cases submitting pull requests with code contributions.
|
||||
]]
|
||||
|
||||
|
||||
|
||||
[[
|
||||
What about WebSocket message compression?
|
||||
][
|
||||
Beast WebSocket supports the permessage-deflate extension described in
|
||||
[@https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-00 draft-ietf-hybi-permessage-compression-00].
|
||||
The library comes with a header-only, C++11 port of ZLib's "deflate" codec
|
||||
used in the implementation of the permessage-deflate extension.
|
||||
]]
|
||||
[[
|
||||
Where is the WebSocket TLS/SSL interface?
|
||||
][
|
||||
The `websocket::stream` wraps the socket or stream that you provide
|
||||
(for example, a `boost::asio::ip::tcp::socket` or a
|
||||
`boost::asio::ssl::stream`). You establish your TLS connection using the
|
||||
interface on `ssl::stream` like shown in all of the Asio examples, then
|
||||
construct your `websocket::stream` around it. It works perfectly fine;
|
||||
Beast comes with an `ssl_stream` wrapper in the example directory which
|
||||
allows the SSL stream to be moved, overcoming an Asio limitation.
|
||||
|
||||
The WebSocket implementation [*does] provide support for shutting down
|
||||
the TLS connection through the use of the ADL compile-time virtual functions
|
||||
[link beast.ref.beast__websocket__teardown `teardown`] and
|
||||
[link beast.ref.beast__websocket__async_teardown `async_teardown`]. These will
|
||||
properly close the connection as per rfc6455 and overloads are available
|
||||
for TLS streams. Callers may provide their own overloads of these functions
|
||||
for user-defined next layer types.
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
@@ -17,13 +17,13 @@ using doxygen ;
|
||||
|
||||
import quickbook ;
|
||||
|
||||
path-constant here : . ;
|
||||
path-constant out : . ;
|
||||
|
||||
install stylesheets
|
||||
:
|
||||
$(broot)/doc/src/boostbook.css
|
||||
:
|
||||
<location>$(here)/html
|
||||
<location>$(out)/html
|
||||
;
|
||||
|
||||
explicit stylesheets ;
|
||||
@@ -32,10 +32,9 @@ install images
|
||||
:
|
||||
[ glob $(broot)/doc/src/images/*.png ]
|
||||
images/beast.png
|
||||
images/body.png
|
||||
images/message.png
|
||||
:
|
||||
<location>$(here)/html/images
|
||||
<location>$(out)/html/images
|
||||
;
|
||||
|
||||
explicit images ;
|
||||
@@ -44,28 +43,14 @@ install callouts
|
||||
:
|
||||
[ glob $(broot)/doc/src/images/callouts/*.png ]
|
||||
:
|
||||
<location>$(here)/html/images/callouts
|
||||
<location>$(out)/html/images/callouts
|
||||
;
|
||||
|
||||
explicit callout ;
|
||||
|
||||
install examples
|
||||
:
|
||||
[ glob
|
||||
../examples/*.cpp
|
||||
../examples/*.hpp
|
||||
../examples/ssl/*.cpp
|
||||
../examples/ssl/*.hpp
|
||||
]
|
||||
:
|
||||
<location>$(here)/html/examples
|
||||
;
|
||||
|
||||
explicit examples ;
|
||||
|
||||
xml doc
|
||||
:
|
||||
master.qbk
|
||||
0_main.qbk
|
||||
:
|
||||
<location>temp
|
||||
<include>$(broot)/tools/boostbook/dtd
|
||||
@@ -86,11 +71,10 @@ boostbook boostdoc
|
||||
<xsl:param>toc.section.depth=8 # How deep should recursive sections appear in the TOC?
|
||||
<xsl:param>toc.max.depth=8 # How many levels should be created for each TOC?
|
||||
<xsl:param>generate.section.toc.level=8 # Control depth of TOC generation in sections
|
||||
<xsl:param>generate.toc="chapter nop section nop"
|
||||
<xsl:param>generate.toc="chapter toc,title section nop reference nop"
|
||||
<include>$(broot)/tools/boostbook/dtd
|
||||
:
|
||||
<location>temp
|
||||
<dependency>examples
|
||||
<dependency>images
|
||||
<dependency>stylesheets
|
||||
;
|
||||
@@ -1,72 +0,0 @@
|
||||
# Building documentation
|
||||
|
||||
## Specifying Files
|
||||
|
||||
To specify the source files for which to build documentation, modify `INPUT`
|
||||
and its related fields in `doc/source.dox`. Note that the `INPUT` paths are
|
||||
relative to the `doc/` directory.
|
||||
|
||||
## Install Dependencies
|
||||
|
||||
### Windows
|
||||
|
||||
Install these dependencies:
|
||||
|
||||
1. Install [Doxygen](http://www.stack.nl/~dimitri/doxygen/download.html)
|
||||
2. Download the following zip files from [xsltproc](https://www.zlatkovic.com/pub/libxml/)
|
||||
(Alternate download: ftp://ftp.zlatkovic.com/libxml/),
|
||||
and extract the `bin\` folder contents into any folder in your path.
|
||||
* iconv
|
||||
* libxml2
|
||||
* libxslt
|
||||
* zlib
|
||||
3. Download [Boost](http://www.boost.org/users/download/)
|
||||
1. Extract the compressed file contents to your (new) `$BOOST_ROOT` location.
|
||||
2. Open a command prompt or shell in the `$BOOST_ROOT`.
|
||||
3. `./bootstrap.bat`
|
||||
4. If it is not already there, add your `$BOOST_ROOT` to your environment `$PATH`.
|
||||
|
||||
### MacOS
|
||||
|
||||
1. Install doxygen:
|
||||
* Use homebrew to install: `brew install doxygen`. The executable will be
|
||||
installed in `/usr/local/bin` which is already in your path.
|
||||
* Alternatively, install from here: [doxygen](http://www.stack.nl/~dimitri/doxygen/download.html).
|
||||
You'll then need to make doxygen available to your command line. You can
|
||||
do this by adding a symbolic link from `/usr/local/bin` to the doxygen
|
||||
executable. For example, `$ ln -s /Applications/Doxygen.app/Contents/Resources/doxygen /usr/local/bin/doxygen`
|
||||
2. Install [Boost](http://www.boost.org/users/download/)
|
||||
1. Extract the compressed file contents to your (new) `$BOOST_ROOT` location.
|
||||
2. Open a command prompt or shell in the `$BOOST_ROOT`.
|
||||
3. `$ ./bootstrap.bat`
|
||||
4. If it is not already there, add your `$BOOST_ROOT` to your environment
|
||||
`$PATH`. This makes the `b2` command available to the command line.
|
||||
3. That should be all that's required. In OS X 10.11, at least, libxml2 and
|
||||
libxslt come pre-installed.
|
||||
|
||||
### Linux
|
||||
|
||||
1. Install [Docker](https://docs.docker.com/engine/installation/)
|
||||
2. Build Docker image. From the Beast root folder:
|
||||
```
|
||||
sudo docker build -t beast-docs doc/
|
||||
```
|
||||
|
||||
## Do it
|
||||
|
||||
### Windows & MacOS
|
||||
|
||||
From the Beast root folder:
|
||||
```
|
||||
cd doc
|
||||
./makeqbk.sh && b2
|
||||
```
|
||||
The output will be in `doc/html`.
|
||||
|
||||
### Linux
|
||||
|
||||
From the Beast root folder:
|
||||
```
|
||||
sudo docker run -v $PWD:/opt/beast --rm beast-docs
|
||||
```
|
||||
The output will be in `doc/html`.
|
||||
105
src/beast/doc/concept/Body.qbk
Normal file
105
src/beast/doc/concept/Body.qbk
Normal file
@@ -0,0 +1,105 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:Body Body]
|
||||
|
||||
A [*Body] type is supplied as a template argument to the __message__ class. It
|
||||
controls both the type of the data member of the resulting message object, and
|
||||
the algorithms used during parsing and serialization.
|
||||
|
||||
In this table:
|
||||
|
||||
* `X` is a type meeting the requirements of [*Body].
|
||||
|
||||
* `m` is a value of type `message<b, X, F>` where `b` is a `bool` value
|
||||
and `F` is a type meeting the requirements of [*Fields].
|
||||
|
||||
[table Body requirements
|
||||
[[expression] [type] [semantics, pre/post-conditions]]
|
||||
[
|
||||
[`X::value_type`]
|
||||
[]
|
||||
[
|
||||
The type of the `message::body` member.
|
||||
If this is not movable or not copyable, the containing message
|
||||
will be not movable or not copyable.
|
||||
]
|
||||
][
|
||||
[`X::writer`]
|
||||
[]
|
||||
[
|
||||
If present, indicates that the body can hold a message body
|
||||
parsing result. The type must meet the requirements of
|
||||
__BodyWriter__. The implementation constructs an object of
|
||||
this type to obtain buffers into which parsed body octets
|
||||
are placed.
|
||||
]
|
||||
][
|
||||
[`X::reader`]
|
||||
[]
|
||||
[
|
||||
If present, indicates that the body is serializable. The type
|
||||
must meet the requirements of __BodyReader__. The implementation
|
||||
constructs an object of this type to obtain buffers representing
|
||||
the message body for serialization.
|
||||
]
|
||||
][
|
||||
[`X::size(X::value_type v)`]
|
||||
[`std::uint64_t`]
|
||||
[
|
||||
This static member function is optional. It returns the payload
|
||||
size of `v` not including any chunked transfer encoding. The
|
||||
function shall not exit via an exception.
|
||||
|
||||
When this function is present:
|
||||
|
||||
* The function shall not fail
|
||||
|
||||
* A call to
|
||||
[link beast.ref.beast__http__message.payload_size `message::payload_size`]
|
||||
will return the same value as `size`.
|
||||
|
||||
* A call to
|
||||
[link beast.ref.beast__http__message.prepare_payload `message::prepare_payload`]
|
||||
will remove "chunked" from the Transfer-Encoding field if it appears
|
||||
as the last encoding, and will set the Content-Length field to the
|
||||
returned value.
|
||||
|
||||
Otherwise, when the function is omitted:
|
||||
|
||||
* A call to
|
||||
[link beast.ref.beast__http__message.payload_size `message::payload_size`]
|
||||
will return `boost::none`.
|
||||
|
||||
* A call to
|
||||
[link beast.ref.beast__http__message.prepare_payload `message::prepare_payload`]
|
||||
will erase the Content-Length field, and add "chunked" as the last
|
||||
encoding in the Transfer-Encoding field if it is not already present.
|
||||
]
|
||||
][
|
||||
[`is_body<X>`]
|
||||
[`std::true_type`]
|
||||
[
|
||||
An alias for `std::true_type` for `X`, otherwise an alias
|
||||
for `std::false_type`.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[heading Exemplar]
|
||||
|
||||
[concept_Body]
|
||||
|
||||
[heading Models]
|
||||
|
||||
* [link beast.ref.beast__http__basic_dynamic_body `basic_dynamic_body`]
|
||||
* [link beast.ref.beast__http__buffer_body `buffer_body`]
|
||||
* [link beast.ref.beast__http__dynamic_body `dynamic_body`]
|
||||
* [link beast.ref.beast__http__empty_body `empty_body`]
|
||||
* [link beast.ref.beast__http__string_body `string_body`]
|
||||
|
||||
[endsect]
|
||||
117
src/beast/doc/concept/BodyReader.qbk
Normal file
117
src/beast/doc/concept/BodyReader.qbk
Normal file
@@ -0,0 +1,117 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:BodyReader BodyReader]
|
||||
|
||||
A [*BodyReader] provides an online algorithm to obtain a sequence of zero
|
||||
or more buffers from a body during serialization. The implementation creates
|
||||
an instance of this type when needed, and calls into it one or more times to
|
||||
retrieve buffers holding body octets. The interface of [*BodyReader] is
|
||||
intended to obtain buffers for these scenarios:
|
||||
|
||||
* A body that does not entirely fit in memory.
|
||||
* A body produced incrementally from coroutine output.
|
||||
* A body represented by zero or more buffers already in memory.
|
||||
* A body whose size is not known ahead of time.
|
||||
* Body data generated dynamically from other threads.
|
||||
* Body data computed algorithmically.
|
||||
|
||||
In this table:
|
||||
|
||||
* `X` denotes a type meeting the requirements of [*BodyReader].
|
||||
|
||||
* `B` denotes a __Body__ where
|
||||
`std::is_same<X, B::reader>::value == true`.
|
||||
|
||||
* `a` denotes a value of type `X`.
|
||||
|
||||
* `m` denotes a possibly const value of type `message&` where
|
||||
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
|
||||
|
||||
* `ec` is a value of type [link beast.ref.beast__error_code `error_code&`].
|
||||
|
||||
* `R<T>` is the type `boost::optional<std::pair<T, bool>>`.
|
||||
|
||||
[heading Associated Types]
|
||||
|
||||
* __Body__
|
||||
|
||||
* [link beast.ref.beast__http__is_body_reader `is_body_reader`]
|
||||
|
||||
[heading BodyReader requirements]
|
||||
[table Valid Expressions
|
||||
[[Expression] [Type] [Semantics, Pre/Post-conditions]]
|
||||
[
|
||||
[`X::const_buffers_type`]
|
||||
[]
|
||||
[
|
||||
A type which meets the requirements of __ConstBufferSequence__.
|
||||
This is the type of buffer returned by `X::get`.
|
||||
]
|
||||
][
|
||||
[`X(m);`]
|
||||
[]
|
||||
[
|
||||
Constructible from `m`. The lifetime of `m` is guaranteed
|
||||
to end no earlier than after the `X` is destroyed.
|
||||
The reader shall not access the contents of `m` before the
|
||||
first call to `init`, permitting lazy construction of the
|
||||
message.
|
||||
|
||||
The constructor may optionally require that `m` is const, which
|
||||
has these consequences:
|
||||
|
||||
* If `X` requires that `m` is a const reference, then serializers
|
||||
constructed for messages with this body type will also require a
|
||||
const reference to a message, otherwise:
|
||||
|
||||
* If `X` requires that `m` is a non-const reference, then serializers
|
||||
constructed for messages with this body type will aso require
|
||||
a non-const reference to a message.
|
||||
]
|
||||
][
|
||||
[`a.init(ec)`]
|
||||
[]
|
||||
[
|
||||
Called once to fully initialize the object before any calls to
|
||||
`get`. The message body becomes valid before entering this function,
|
||||
and remains valid until the reader is destroyed.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if there was one.
|
||||
]
|
||||
][
|
||||
[`a.get(ec)`]
|
||||
[`R<X::const_buffers_type>`]
|
||||
[
|
||||
Called one or more times after `init` succeeds. This function
|
||||
returns `boost::none` if all buffers representing the body have
|
||||
been returned in previous calls or if it sets `ec` to indicate an
|
||||
error. Otherwise, if there are buffers remaining the function
|
||||
should return a pair with the first element containing a non-zero
|
||||
length buffer sequence representing the next set of octets in
|
||||
the body, while the second element is a `bool` meaning `true`
|
||||
if there may be additional buffers returned on a subsequent call,
|
||||
or `false` if the buffer returned on this call is the last
|
||||
buffer representing the body.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if there was one.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[heading Exemplar]
|
||||
|
||||
[concept_BodyReader]
|
||||
|
||||
[heading Models]
|
||||
|
||||
* [link beast.ref.beast__http__basic_dynamic_body.reader `basic_dynamic_body::reader`]
|
||||
* [link beast.ref.beast__http__basic_file_body__reader `basic_file_body::reader`]
|
||||
* [link beast.ref.beast__http__basic_string_body.reader `basic_string_body::reader`]
|
||||
* [link beast.ref.beast__http__empty_body.reader `empty_body::reader`]
|
||||
|
||||
[endsect]
|
||||
119
src/beast/doc/concept/BodyWriter.qbk
Normal file
119
src/beast/doc/concept/BodyWriter.qbk
Normal file
@@ -0,0 +1,119 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:BodyWriter BodyWriter]
|
||||
|
||||
A [*BodyWriter] provides an online algorithm to transfer a series of zero
|
||||
or more buffers containing parsed body octets into a message container. The
|
||||
__parser__ creates an instance of this type when needed, and calls into
|
||||
it zero or more times to transfer buffers. The interface of [*BodyWriter]
|
||||
is intended to allow the conversion of buffers into these scenarios for
|
||||
representation:
|
||||
|
||||
* Storing a body in a dynamic buffer
|
||||
* Storing a body in a user defined container with a custom allocator
|
||||
* Transformation of incoming body data before storage, for example
|
||||
to compress it first.
|
||||
* Saving body data to a file
|
||||
|
||||
In this table:
|
||||
|
||||
* `X` denotes a type meeting the requirements of [*BodyWriter].
|
||||
|
||||
* `B` denotes a __Body__ where
|
||||
`std::is_same<X, B::writer>::value == true`.
|
||||
|
||||
* `a` denotes a value of type `X`.
|
||||
|
||||
* `b` is an object whose type meets the requirements of __ConstBufferSequence__
|
||||
|
||||
* `m` denotes a value of type `message&` where
|
||||
`std::is_same<decltype(m.body), Body::value_type>::value == true`.
|
||||
|
||||
* `n` is a value of type `boost::optional<std::uint64_t>`.
|
||||
|
||||
* `ec` is a value of type [link beast.ref.beast__error_code `error_code&`].
|
||||
|
||||
[heading Associated Types]
|
||||
|
||||
* __Body__
|
||||
* [link beast.ref.beast__http__is_body_writer `is_body_writer`]
|
||||
|
||||
[table Writer requirements
|
||||
[[expression] [type] [semantics, pre/post-conditions]]
|
||||
[
|
||||
[`X(m);`]
|
||||
[]
|
||||
[
|
||||
Constructible from `m`. The lifetime of `m` is guaranteed to
|
||||
end no earlier than after the `X` is destroyed. The constructor
|
||||
will be called after a complete header is stored in `m`, and
|
||||
before parsing body octets for messages indicating that a body
|
||||
is present The writer shall not access the contents of `m` before
|
||||
the first call to `init`, permitting lazy construction of the
|
||||
message.
|
||||
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if there was one.
|
||||
]
|
||||
][
|
||||
[`a.init(n, ec)`]
|
||||
[]
|
||||
[
|
||||
Called once to fully initialize the object before any calls to
|
||||
`put`. The message body is valid before entering this function,
|
||||
and remains valid until the writer is destroyed.
|
||||
The value of `n` will be set to the content length of the
|
||||
body if known, otherwise `n` will be equal to `boost::none`.
|
||||
Implementations of [*BodyWriter] may use this information to
|
||||
optimize allocation.
|
||||
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if there was one.
|
||||
]
|
||||
][
|
||||
[`a.put(b,ec)`]
|
||||
[`std::size_t`]
|
||||
[
|
||||
This function is called to append some or all of the buffers
|
||||
specified by `b` into the body representation. The number of
|
||||
bytes inserted from `b` is returned. If the number of bytes
|
||||
inserted is less than the total input, the remainder of the
|
||||
input will be presented in the next call to `put`.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if there was one.
|
||||
]
|
||||
][
|
||||
[`a.finish(ec)`]
|
||||
[]
|
||||
[
|
||||
This function is called when no more body octets are remaining.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if there was one.
|
||||
]
|
||||
][
|
||||
[`is_body_writer<B>`]
|
||||
[`std::true_type`]
|
||||
[
|
||||
An alias for `std::true_type` for `B`, otherwise an alias
|
||||
for `std::false_type`.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[heading Exemplar]
|
||||
|
||||
[concept_BodyWriter]
|
||||
|
||||
[heading Models]
|
||||
|
||||
* [link beast.ref.beast__http__basic_dynamic_body.writer `basic_dynamic_body::writer`]
|
||||
* [link beast.ref.beast__http__basic_file_body__reader `basic_file_body::writer`]
|
||||
* [link beast.ref.beast__http__basic_string_body.writer `basic_string_body::writer`]
|
||||
* [link beast.ref.beast__http__empty_body.writer `empty_body::writer`]
|
||||
|
||||
[endsect]
|
||||
15
src/beast/doc/concept/BufferSequence.qbk
Normal file
15
src/beast/doc/concept/BufferSequence.qbk
Normal file
@@ -0,0 +1,15 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:BufferSequence BufferSequence]
|
||||
|
||||
A [*BufferSequence] is a type meeting either of the following requirements:
|
||||
|
||||
* __ConstBufferSequence__
|
||||
* __MutableBufferSequence__
|
||||
|
||||
[endsect]
|
||||
@@ -5,7 +5,7 @@
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section:DynamicBuffer DynamicBuffer requirements]
|
||||
[section:DynamicBuffer DynamicBuffer]
|
||||
|
||||
A dynamic buffer encapsulates memory storage that may be automatically resized
|
||||
as required, where the memory is divided into an input sequence followed by an
|
||||
@@ -19,7 +19,8 @@ The interface to this concept is intended to permit the following
|
||||
implementation strategies:
|
||||
|
||||
* A single contiguous octet array, which is reallocated as necessary to
|
||||
accommodate changes in the size of the octet sequence.
|
||||
accommodate changes in the size of the octet sequence. This is the
|
||||
implementation approach currently offered by __flat_buffer__.
|
||||
|
||||
* A sequence of one or more octet arrays, where each array is of the same
|
||||
size. Additional octet array objects are appended to the sequence to
|
||||
@@ -28,19 +29,19 @@ implementation strategies:
|
||||
* A sequence of one or more octet arrays of varying sizes. Additional octet
|
||||
array objects are appended to the sequence to accommodate changes in the
|
||||
size of the character sequence. This is the implementation approach
|
||||
currently offered by [link beast.ref.basic_streambuf `basic_streambuf`].
|
||||
currently offered by __multi_buffer__.
|
||||
|
||||
In the table below:
|
||||
In this table:
|
||||
|
||||
* `X` denotes a dynamic buffer class.
|
||||
* `a` denotes a value of type `X`.
|
||||
* `c` denotes a (possibly const) value of type `X`.
|
||||
* `n` denotes a value of type `std::size_t`.
|
||||
* `T` denotes a type meeting the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html `ConstBufferSequence`].
|
||||
* `U` denotes a type meeting the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html `MutableBufferSequence`].
|
||||
* `T` denotes a type meeting the requirements for __ConstBufferSequence__.
|
||||
* `U` denotes a type meeting the requirements for __MutableBufferSequence__.
|
||||
|
||||
[table DynamicBuffer requirements
|
||||
[[operation] [type] [semantics, pre/post-conditions]]
|
||||
[[expression] [type] [semantics, pre/post-conditions]]
|
||||
[
|
||||
[`X::const_buffers_type`]
|
||||
[`T`]
|
||||
@@ -122,4 +123,14 @@ In the table below:
|
||||
]
|
||||
]
|
||||
|
||||
[heading Models]
|
||||
|
||||
* [link beast.ref.beast__basic_flat_buffer `basic_flat_buffer`]
|
||||
* [link beast.ref.beast__basic_multi_buffer `basic_multi_buffer`]
|
||||
* [link beast.ref.beast__drain_buffer `drain_buffer`]
|
||||
* [link beast.ref.beast__flat_buffer `flat_buffer`]
|
||||
* [link beast.ref.beast__multi_buffer `multi_buffer`]
|
||||
* [link beast.ref.beast__static_buffer `static_buffer`]
|
||||
* [link beast.ref.beast__static_buffer_n `static_buffer_n`]
|
||||
|
||||
[endsect]
|
||||
225
src/beast/doc/concept/Fields.qbk
Normal file
225
src/beast/doc/concept/Fields.qbk
Normal file
@@ -0,0 +1,225 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:Fields Fields]
|
||||
|
||||
An instance of [*Fields] is a container for holding HTTP header fields
|
||||
and their values. The implementation also calls upon the container to
|
||||
store the request target and non-standard strings for method and obsolete
|
||||
reason phrase as needed. Types which meet these requirements can always
|
||||
be serialized.
|
||||
|
||||
[heading Associated Types]
|
||||
|
||||
* __FieldsReader__
|
||||
|
||||
* [link beast.ref.beast__http__is_fields `is_fields`]
|
||||
|
||||
[heading Requirements]
|
||||
|
||||
In this table:
|
||||
|
||||
* `F` denotes a type that meets the requirements of [*Fields].
|
||||
|
||||
* `R` denotes a type meeting the requirements of __FieldsReader__.
|
||||
|
||||
* `a` denotes a value of type `F`.
|
||||
|
||||
* `c` denotes a (possibly const) value of type `F`.
|
||||
|
||||
* `b` is a value of type `bool`
|
||||
|
||||
* `n` is a value of type `boost::optional<std::uint64_t>`.
|
||||
|
||||
* `s` is a value of type [link beast.ref.beast__string_view `string_view`].
|
||||
|
||||
* `v` is a value of type `unsigned int` representing the HTTP-version.
|
||||
|
||||
[table Valid expressions
|
||||
[[Expression] [Type] [Semantics, Pre/Post-conditions]]
|
||||
[
|
||||
[`F::reader`]
|
||||
[`R`]
|
||||
[
|
||||
A type which meets the requirements of __FieldsReader__.
|
||||
]
|
||||
][
|
||||
[`c.get_method_impl()`]
|
||||
[`string_view`]
|
||||
[
|
||||
Returns the method text.
|
||||
The implementation only calls this function for request
|
||||
headers when retrieving the method text previously set
|
||||
with a call to `set_method_impl` using a non-empty string.
|
||||
]
|
||||
][
|
||||
[`c.get_target_impl()`]
|
||||
[`string_view`]
|
||||
[
|
||||
Returns the target string.
|
||||
The implementation only calls this function for request headers.
|
||||
]
|
||||
][
|
||||
[`c.get_reason_impl()`]
|
||||
[`string_view`]
|
||||
[
|
||||
Returns the obsolete request text.
|
||||
The implementation only calls this for response headers when
|
||||
retrieving the reason text previously set with a call to
|
||||
`set_reason_impl` using a non-empty string.
|
||||
]
|
||||
][
|
||||
[`c.get_chunked_impl()`]
|
||||
[`bool`]
|
||||
[
|
||||
Returns `true` if the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.3.1 [*Transfer-Encoding]]
|
||||
field value indicates that the payload is chunk encoded. Both
|
||||
of these conditions must be true:
|
||||
[itemized_list
|
||||
[
|
||||
The Transfer-Encoding field is present in the message.
|
||||
][
|
||||
The last item the value of the field is "chunked".
|
||||
]]
|
||||
]
|
||||
][
|
||||
[`c.get_keep_alive_impl(v)`]
|
||||
[`bool`]
|
||||
[
|
||||
Returns `true` if the semantics of the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-6.1 [*Connection]]
|
||||
field and version indicate that the connection should remain
|
||||
open after the corresponding response is transmitted or received:
|
||||
|
||||
[itemized_list
|
||||
[
|
||||
If `(v < 11)` the function returns `true` if the "keep-alive"
|
||||
token is present in the Connection field value. Otherwise the
|
||||
function returns `false`.
|
||||
][
|
||||
If `(v == 11)`, the function returns `false` if the "close"
|
||||
token is present in the Connection field value. Otherwise the
|
||||
function returns `true`.
|
||||
]]
|
||||
]
|
||||
][
|
||||
[`a.set_method_impl(s)`]
|
||||
[]
|
||||
[
|
||||
Stores a copy of `s` as the method text, or erases the previously
|
||||
stored value if `s` is empty.
|
||||
The implementation only calls this function for request headers.
|
||||
This function may throw `std::invalid_argument` if the operation
|
||||
is not supported by the container.
|
||||
]
|
||||
][
|
||||
[`a.set_target_impl(s)`]
|
||||
[]
|
||||
[
|
||||
Stores a copy of `s` as the target, or erases the previously
|
||||
stored value if `s` is empty.
|
||||
The implementation only calls this function for request headers.
|
||||
This function may throw `std::invalid_argument` if the operation
|
||||
is not supported by the container.
|
||||
]
|
||||
][
|
||||
[`a.set_reason_impl(s)`]
|
||||
[]
|
||||
[
|
||||
Stores a copy of `s` as the reason text, or erases the previously
|
||||
stored value of the reason text if `s` is empty.
|
||||
The implementation only calls this function for request headers.
|
||||
This function may throw `std::invalid_argument` if the operation
|
||||
is not supported by the container.
|
||||
]
|
||||
][
|
||||
[`a.set_chunked_impl(b)`]
|
||||
[]
|
||||
[
|
||||
Adjusts the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.3.1 [*Transfer-Encoding]]
|
||||
field as follows:
|
||||
|
||||
[itemized_list
|
||||
[
|
||||
If `b` is `true`, the "chunked" token is appended
|
||||
to the list of encodings if it does not already appear
|
||||
last in the list.
|
||||
If the Transfer-Encoding field is absent, the field will
|
||||
be inserted to the container with the value "chunked".
|
||||
][
|
||||
If `b` is `false, the "chunked" token is removed from the
|
||||
list of encodings if it appears last in the list.
|
||||
If the result of the removal leaves the list of encodings
|
||||
empty, the Transfer-Encoding field shall not appear when
|
||||
the associated __FieldsReader__ serializes the fields.
|
||||
]]
|
||||
]
|
||||
|
||||
][
|
||||
[`a.set_content_length_impl(n)`]
|
||||
[]
|
||||
[
|
||||
Adjusts the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-3.3.2 [*Content-Length]]
|
||||
field as follows:
|
||||
|
||||
[itemized_list
|
||||
[
|
||||
If `n` contains a value, the Content-Length field
|
||||
will be set to the text representation of the value.
|
||||
Any previous Content-Length fields are removed from
|
||||
the container.
|
||||
][
|
||||
If `n` does not contain a value, any present Content-Length
|
||||
fields are removed from the container.
|
||||
]]
|
||||
]
|
||||
|
||||
][
|
||||
[`a.set_keep_alive_impl(v,b)`]
|
||||
[]
|
||||
[
|
||||
Adjusts the
|
||||
[@https://tools.ietf.org/html/rfc7230#section-6.1 [*Connection]]
|
||||
field value depending on the values of `v` and `b`. The field
|
||||
value is treated as
|
||||
[@https://tools.ietf.org/html/rfc7230#section-6.1 ['connection-option]]
|
||||
(rfc7230).
|
||||
|
||||
[itemized_list
|
||||
[
|
||||
If `(v < 11 && b)`, then all "close" tokens present in the
|
||||
value are removed, and the "keep-alive" token is added to
|
||||
the valueif it is not already present.
|
||||
][
|
||||
If `(v < 11 && ! b)`, then all "close" and "keep-alive"
|
||||
tokens present in the value are removed.
|
||||
|
||||
][
|
||||
If `(v == 11 && b)`, then all "keep-alive" and "close"
|
||||
tokens present in the value are removed.
|
||||
][
|
||||
If `(v == 11 && ! b)`, then all "keep-alive" tokens present
|
||||
in the value are removed, and the "close" token is added to
|
||||
the value if it is not already present.
|
||||
]]
|
||||
]
|
||||
|
||||
]]
|
||||
|
||||
[heading Exemplar]
|
||||
|
||||
[concept_Fields]
|
||||
|
||||
[heading Models]
|
||||
|
||||
* [link beast.ref.beast__http__basic_fields `basic_fields`]
|
||||
* [link beast.ref.beast__http__fields `fields`]
|
||||
|
||||
[endsect]
|
||||
84
src/beast/doc/concept/FieldsReader.qbk
Normal file
84
src/beast/doc/concept/FieldsReader.qbk
Normal file
@@ -0,0 +1,84 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:FieldsReader FieldsReader]
|
||||
|
||||
A [*FieldsReader] provides a algorithm to obtain a sequence of buffers
|
||||
representing the complete serialized HTTP/1 header for a set of fields.
|
||||
The implementation constructs an instance of this type when needed, and
|
||||
calls into it once to retrieve the buffers.
|
||||
|
||||
[heading Associated Types]
|
||||
|
||||
* __FieldsReader__
|
||||
|
||||
[heading Requirements]
|
||||
|
||||
In this table:
|
||||
|
||||
* `X` denotes a type that meets the requirements of [*FieldsReader].
|
||||
|
||||
* `F` denotes a __Fields__ where
|
||||
`std::is_same<X, F::reader>::value == true`.
|
||||
|
||||
* `a` is a value of type `X`.
|
||||
|
||||
* `f` is a value of type `F`.
|
||||
|
||||
* `v` is an `unsigned` value representing the HTTP version.
|
||||
|
||||
* `c` is an `unsigned` representing the HTTP status-code.
|
||||
|
||||
* `m` is a value of type [link beast.ref.beast__http__verb `verb`].
|
||||
|
||||
[table Valid expressions
|
||||
[[expression][type][semantics, pre/post-conditions]]
|
||||
[
|
||||
[`X::const_buffers_type`]
|
||||
[]
|
||||
[
|
||||
A type which meets the requirements of __ConstBufferSequence__.
|
||||
This is the type of buffer returned by `X::get`.
|
||||
]
|
||||
][
|
||||
[`X(f,v,m)`]
|
||||
[]
|
||||
[
|
||||
The implementation calls this constructor to indicate
|
||||
that the fields being serialized form part of an HTTP
|
||||
request. The lifetime of `f` is guaranteed
|
||||
to end no earlier than after the `X` is destroyed.
|
||||
]
|
||||
][
|
||||
[`X(f,v,c)`]
|
||||
[]
|
||||
[
|
||||
The implementation calls this constructor to indicate
|
||||
that the fields being serialized form part of an HTTP
|
||||
response. The lifetime of `f` is guaranteed
|
||||
to end no earlier than after the `X` is destroyed.
|
||||
]
|
||||
][
|
||||
[`a.get()`]
|
||||
[`X::const_buffers_type`]
|
||||
[
|
||||
Called once after construction, this function returns
|
||||
a constant buffer sequence containing the serialized
|
||||
representation of the HTTP request or response including
|
||||
the final carriage return linefeed sequence (`"\r\n"`).
|
||||
]
|
||||
]]
|
||||
|
||||
[heading Exemplar]
|
||||
|
||||
[concept_FieldsReader]
|
||||
|
||||
[heading Models]
|
||||
|
||||
* [link beast.ref.beast__http__basic_fields.reader `basic_fields::reader`]
|
||||
|
||||
[endsect]
|
||||
173
src/beast/doc/concept/File.qbk
Normal file
173
src/beast/doc/concept/File.qbk
Normal file
@@ -0,0 +1,173 @@
|
||||
[/
|
||||
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:File File]
|
||||
|
||||
The [*File] concept abstracts access to files in the underlying file system.
|
||||
To support other platform interfaces, users may author their own [*File]
|
||||
types which meet these requirements.
|
||||
|
||||
In this table:
|
||||
|
||||
* `F` is a [*File] type
|
||||
* `f` is an instance of `F`
|
||||
* `p` is a value of type `char const*` which points to a null
|
||||
terminated utf-8 encoded string.
|
||||
* `m` is an instance of [link beast.ref.beast__file_mode `file_mode`]
|
||||
* `n` is a number of bytes, convertible to `std::size_t`
|
||||
* `o` is a byte offset in the file, convertible to `std::uint64_t`
|
||||
* `b` is any non-const pointer to memory
|
||||
* `c` is any possibly-const pointer to memory
|
||||
* `ec` is a reference of type [link beast.ref.beast__error_code `error_code`]
|
||||
|
||||
[heading Associated Types]
|
||||
|
||||
* [link beast.ref.beast__file_mode `file_mode`]
|
||||
* [link beast.ref.beast__is_file `is_file`]
|
||||
|
||||
[heading File Requirements]
|
||||
[table Valid Expressions
|
||||
[[Operation] [Return Type] [Semantics, Pre/Post-conditions]]
|
||||
[
|
||||
[`F()`]
|
||||
[ ]
|
||||
[
|
||||
Default constructable
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.~F()`]
|
||||
[ ]
|
||||
[
|
||||
Destructible.
|
||||
If `f` refers to an open file, it is first closed
|
||||
as if by a call to `close` with the error ignored.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.is_open()`]
|
||||
[`bool`]
|
||||
[
|
||||
Returns `true` if `f` refers to an open file, `false` otherwise.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.close(ec)`]
|
||||
[]
|
||||
[
|
||||
If `f` refers to an open file, thie function attempts to
|
||||
close the file.
|
||||
Regardless of whether an error occurs or not, a subsequent
|
||||
call to `f.is_open()` will return `false`.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if an error
|
||||
occurred.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.open(p,m,ec)`]
|
||||
[]
|
||||
[
|
||||
Attempts to open the file at the path specified by `p`
|
||||
with the mode specified by `m`.
|
||||
Upon success, a subsequent call to `f.is_open()` will
|
||||
return `true`.
|
||||
If `f` refers to an open file, it is first closed
|
||||
as if by a call to `close` with the error ignored.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if an error
|
||||
occurred.
|
||||
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.size(ec)`]
|
||||
[`std::uint64_t`]
|
||||
[
|
||||
If `f` refers to an open file, this function attempts to
|
||||
determine the file size and return its value.
|
||||
If `f` does not refer to an open file, the function will
|
||||
set `ec` to `errc::invalid_argument` and return 0.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if an error
|
||||
occurred.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.pos(ec)`]
|
||||
[`std::uint64_t`]
|
||||
[
|
||||
If `f` refers to an open file, this function attempts to
|
||||
determine the current file offset and return it.
|
||||
If `f` does not refer to an open file, the function will
|
||||
set `ec` to `errc::invalid_argument` and return 0.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if an error
|
||||
occurred.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.seek(o,ec)`]
|
||||
[]
|
||||
[
|
||||
Attempts to reposition the current file offset to the value
|
||||
`o`, which represents a byte offset relative to the beginning
|
||||
of the file.
|
||||
If `f` does not refer to an open file, the function will
|
||||
set `ec` to `errc::invalid_argument` and return immediately.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if an error
|
||||
occurred.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.read(b,n,ec)`]
|
||||
[`std::size_t`]
|
||||
[
|
||||
Attempts to read `n` bytes starting at the current file offset
|
||||
from the open file referred to by `f`.
|
||||
Bytes read are stored in the memory buffer at address `b` which
|
||||
must be at least `n` bytes in size.
|
||||
The function advances the file offset by the amount read, and
|
||||
returns the number of bytes actually read, which may be less
|
||||
than `n`.
|
||||
If `f` does not refer to an open file, the function will
|
||||
set `ec` to `errc::invalid_argument` and return immediately.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if an error
|
||||
occurred.
|
||||
]
|
||||
]
|
||||
[
|
||||
[`f.write(c,n,ec)`]
|
||||
[`std::size_t`]
|
||||
[
|
||||
Attempts to write `n` bytes from the buffer pointed to by `c` to
|
||||
the current file offset of the open file referred to by `f`.
|
||||
The memory buffer at `c` must point to storage of at least `n`
|
||||
bytes meant to be copied to the file.
|
||||
The function advances the file offset by the amount written,
|
||||
and returns the number of bytes actually written, which may be
|
||||
less than `n`.
|
||||
If `f` does not refer to an open file, the function will
|
||||
set `ec` to `errc::invalid_argument` and return immediately.
|
||||
The function will ensure that `!ec` is `true` if there was
|
||||
no error or set to the appropriate error code if an error
|
||||
occurred.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
[heading Exemplar]
|
||||
|
||||
[concept_File]
|
||||
|
||||
[heading Models]
|
||||
|
||||
* [link beast.ref.beast__file_stdio `file_stdio`]
|
||||
|
||||
[endsect]
|
||||
34
src/beast/doc/concept/Streams.qbk
Normal file
34
src/beast/doc/concept/Streams.qbk
Normal file
@@ -0,0 +1,34 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:streams Stream]
|
||||
|
||||
Stream types represent objects capable of performing synchronous or
|
||||
asynchronous I/O. They are based on concepts from `boost::asio`.
|
||||
|
||||
[heading:Stream Stream]
|
||||
|
||||
A type modeling [*Stream] meets either or both of the following requirements:
|
||||
|
||||
* [*AsyncStream]
|
||||
* [*SyncStream]
|
||||
|
||||
[heading:AsyncStream AsyncStream]
|
||||
|
||||
A type modeling [*AsyncStream] meets the following requirements:
|
||||
|
||||
* __AsyncReadStream__
|
||||
* __AsyncWriteStream__
|
||||
|
||||
[heading:SyncStream SyncStream]
|
||||
|
||||
A type modeling [*SyncStream] meets the following requirements:
|
||||
|
||||
* __SyncReadStream__
|
||||
* __SyncWriteStream__
|
||||
|
||||
[endsect]
|
||||
@@ -1,654 +0,0 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:design Design Choices]
|
||||
|
||||
[block '''
|
||||
<informaltable frame="all"><tgroup cols="1"><colspec colname="a"/><tbody><row><entry valign="top"><simplelist>
|
||||
<member><link linkend="beast.design.http">HTTP FAQ</link></member>
|
||||
<member><link linkend="beast.design.websocket">WebSocket FAQ</link></member>
|
||||
<member><link linkend="beast.design.websocketpp">Comparison to Zaphoyd Studios WebSocket++</link></member>
|
||||
</simplelist></entry></row></tbody></tgroup></informaltable>
|
||||
''']
|
||||
|
||||
The implementations are driven by business needs of cryptocurrency server
|
||||
applications (e.g. [@https://ripple.com Ripple]) written in C++. These
|
||||
needs were not met by existing solutions so Beast was written from scratch
|
||||
as a solution. Beast's design philosophy avoids flaws exhibited by other
|
||||
libraries:
|
||||
|
||||
* Don't try to do too much.
|
||||
|
||||
* Don't sacrifice performance.
|
||||
|
||||
* Mimic Boost.Asio; familiarity breeds confidence.
|
||||
|
||||
* Role-symmetric interfaces; client and server the same (or close to it).
|
||||
|
||||
* Leave important decisions to the user, such as allocating memory or
|
||||
managing flow control.
|
||||
|
||||
Beast uses the __DynamicBuffer__ concept presented in the Networking TS
|
||||
(__N4588__), and relies heavily on the Boost.Asio __ConstBufferSequence__
|
||||
and __MutableBufferSequence__ concepts for passing buffers to functions.
|
||||
The authors have found the dynamic buffer and buffer sequence interfaces to
|
||||
be optimal for interacting with Asio, and for other tasks such as incremental
|
||||
parsing of data in buffers (for example, parsing websocket frames stored
|
||||
in a [link beast.ref.static_streambuf `static_streambuf`]).
|
||||
|
||||
During the development of Beast the authors have studied other software
|
||||
packages and in particular the comments left during the Boost Review process
|
||||
of other packages offering similar functionality. In this section and the
|
||||
FAQs that follow we attempt to answer those questions that are also applicable
|
||||
to Beast.
|
||||
|
||||
[variablelist
|
||||
[[
|
||||
"I would also like to see instances of this library being used
|
||||
in production. That would give some evidence that the design
|
||||
works in practice."
|
||||
][
|
||||
Beast.HTTP and Beast.WebSocket are production ready and currently
|
||||
running on public servers receiving traffic and handling millions of
|
||||
dollars worth of financial transactions daily. The servers run [*rippled],
|
||||
open source software ([@https://github.com/ripple/rippled repository])
|
||||
implementing the
|
||||
[@https://ripple.com/files/ripple_consensus_whitepaper.pdf [*Ripple Consensus Protocol]],
|
||||
technology provided by [@http://ripple.com Ripple].
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
[section:http HTTP FAQ]
|
||||
|
||||
For HTTP we model the message to maximize flexibility of implementation
|
||||
strategies while allowing familiar verbs such as [*`read`] and [*`write`].
|
||||
The HTTP interface is further driven by the needs of the WebSocket module,
|
||||
as a WebSocket session requires a HTTP Upgrade handshake exchange at the
|
||||
start. Other design goals:
|
||||
|
||||
* Keep it simple.
|
||||
|
||||
* Stay low level; don't invent a whole web server or client.
|
||||
|
||||
* Allow for customizations, if the user needs it.
|
||||
|
||||
[variablelist
|
||||
|
||||
[[
|
||||
"Some more advanced examples, e.g. including TLS with client/server
|
||||
certificates would help."
|
||||
][
|
||||
The HTTP interface doesn't try to reinvent the wheel, it just uses
|
||||
the `boost::asio::ip::tcp::socket` or `boost::asio::ssl::stream` that
|
||||
you set up beforehand. Callers use the interfaces already existing
|
||||
on those objects to make outgoing connections, accept incoming connections,
|
||||
or establish TLS sessions with certificates. We find the available Asio
|
||||
examples for performing these tasks sufficient.
|
||||
]]
|
||||
|
||||
[[
|
||||
"A built-in router?"
|
||||
][
|
||||
We presume this means a facility to match expressions against the URI
|
||||
in HTTP requests, and dispatch them to calling code. The authors feel
|
||||
that this is a responsibility of higher level code. Beast.HTTP does
|
||||
not try to offer a web server.
|
||||
]]
|
||||
|
||||
[[
|
||||
"Cookies? Forms/File Uploads?"
|
||||
][
|
||||
Cookies, or managing these types of HTTP headers in general, is the
|
||||
responsibility of higher levels. Beast.HTTP just tries to get complete
|
||||
messages to and from the calling code. It deals in the HTTP headers just
|
||||
enough to process the message body and leaves the rest to callers. However,
|
||||
for forms and file uploads the symmetric interface of the message class
|
||||
allows HTTP requests to include arbitrary body types including those needed
|
||||
to upload a file or fill out a form.
|
||||
]]
|
||||
|
||||
[[
|
||||
"...supporting TLS (is this a feature? If not this would be a show-stopper),
|
||||
etc."
|
||||
][
|
||||
Beast.HTTP does not provide direct facilities for implementing TLS
|
||||
connections; however, the interfaces already existing on the
|
||||
`boost::asio::ssl::stream` are available and can be used to establish
|
||||
secure connections. Then, functions like `http::read` or `http::async_write`
|
||||
can work with those encrypted connections with no problem.
|
||||
]]
|
||||
|
||||
[[
|
||||
"There should also be more examples of how to integrate the http service
|
||||
with getting files from the file system, generating responses CGI-style"
|
||||
][
|
||||
The design goal for the library is to not try to invent a web server.
|
||||
We feel that there is a strong need for a basic implementation that
|
||||
models the HTTP message and provides functions to send and receive them
|
||||
over Asio. Such an implementation should serve as a building block upon
|
||||
which higher abstractions such as the aforementioned HTTP service or
|
||||
cgi-gateway can be built.
|
||||
|
||||
One of the example programs implements a simple HTTP server that
|
||||
delivers files from the filesystem.
|
||||
]]
|
||||
|
||||
[[
|
||||
"You should send a 100-continue to ask for the rest of the body if required."
|
||||
][
|
||||
The Beast interface needs to support this functionality (by allowing this
|
||||
special case of partial message parsing and serialization). Specifically,
|
||||
it should let callers read the request up to just before the body,
|
||||
and let callers write the request up to just before the body. However,
|
||||
making use of this behavior should be up to callers (since Beast is low
|
||||
level).
|
||||
]]
|
||||
|
||||
[[
|
||||
"What about HTTP/2?"
|
||||
][
|
||||
Many reviewers feel that HTTP/2 support is an essential feature of
|
||||
a HTTP library. The authors agree that HTTP/2 is important but also
|
||||
feel that the most sensible implementation is one that does not re-use
|
||||
the same network reading and writing interface for 2 as that for 1.0
|
||||
and 1.1.
|
||||
|
||||
The Beast.HTTP message model is suitable for HTTP/2 and can be re-used.
|
||||
The IETF HTTP Working Group adopted message compatiblity with HTTP/1.x
|
||||
as an explicit goal. A parser can simply emit full headers after
|
||||
decoding the compressed HTTP/2 headers. The stream ID is not logically
|
||||
part of the message but rather message metadata and should be
|
||||
communicated out-of-band (see below). HTTP/2 sessions begin with a
|
||||
traditional HTTP/1.1 Upgrade similar in fashion to the WebSocket
|
||||
upgrade. An HTTP/2 implementation can use existing Beast.HTTP primitives
|
||||
to perform this handshake.
|
||||
|
||||
Free functions for HTTP/2 sessions are not possible because of the
|
||||
requirement to maintain per-session state. For example, to decode the
|
||||
compressed headers. Or to remember and respect the remote peer's window
|
||||
settings. The authors propose that a HTTP/2 implementation be written
|
||||
as a separate class template, similar to the `websocket::stream` but with
|
||||
additional interfaces to support version 2 features. We feel that
|
||||
Beast.HTTP offers enough useful functionality to justify inclusion,
|
||||
so that developers can take advantage of it right away instead of
|
||||
waiting.
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:websocket WebSocket FAQ]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[
|
||||
What about message compression?
|
||||
][
|
||||
Beast WebSocket supports the permessage-deflate extension described in
|
||||
[@https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-00 draft-ietf-hybi-permessage-compression-00].
|
||||
The library comes with a header-only, C++11 port of ZLib's "deflate" codec
|
||||
used in the implementation of the permessage-deflate extension.
|
||||
]]
|
||||
|
||||
[[
|
||||
Where is the TLS/SSL interface?
|
||||
][
|
||||
The `websocket::stream` wraps the socket or stream that you provide
|
||||
(for example, a `boost::asio::ip::tcp::socket` or a
|
||||
`boost::asio::ssl::stream`). You establish your TLS connection using the
|
||||
interface on `ssl::stream` like shown in all of the Asio examples, then
|
||||
construct your `websocket::stream` around it. It works perfectly fine;
|
||||
Beast.WebSocket doesn't try to reinvent the wheel or put a fresh coat of
|
||||
interface paint on the `ssl::stream`.
|
||||
|
||||
The WebSocket implementation [*does] provide support for shutting down
|
||||
the TLS connection through the use of the ADL compile-time virtual functions
|
||||
[link beast.ref.websocket__teardown `teardown`] and
|
||||
[link beast.ref.websocket__async_teardown `async_teardown`]. These will
|
||||
properly close the connection as per rfc6455 and overloads are available
|
||||
for TLS streams. Callers may provide their own overloads of these functions
|
||||
for user-defined next layer types.
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:websocketpp Comparison to Zaphoyd Studios WebSocket++]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[
|
||||
How does this compare to [@https://www.zaphoyd.com/websocketpp websocketpp],
|
||||
an alternate header-only WebSocket implementation?
|
||||
][
|
||||
[variablelist
|
||||
|
||||
[[1. Synchronous Interface][
|
||||
|
||||
Beast offers full support for WebSockets using a synchronous interface. It
|
||||
uses the same style of interfaces found in Boost.Asio: versions that throw
|
||||
exceptions, or versions that return the error code in a reference parameter:
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L774 Beast]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
read(opcode& op, DynamicBuffer& dynabuf)
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
[[2. Connection Model][
|
||||
|
||||
websocketpp supports multiple transports by utilizing a trait, the `config::transport_type`
|
||||
([@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/asio/connection.hpp#L60 asio transport example])
|
||||
To get an idea of the complexity involved with implementing a transport,
|
||||
compare the asio transport to the
|
||||
[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/iostream/connection.hpp#L59 `iostream` transport]
|
||||
(a layer that allows websocket communication over a `std::iostream`).
|
||||
|
||||
In contrast, Beast abstracts the transport by defining just one [*`NextLayer`]
|
||||
template argument The type requirements for [*`NextLayer`] are
|
||||
already familiar to users as they are documented in Asio:
|
||||
__AsyncReadStream__, __AsyncWriteStream__, __SyncReadStream__, __SyncWriteStream__.
|
||||
|
||||
The type requirements for instantiating `beast::websocket::stream` versus
|
||||
`websocketpp::connection` with user defined types are vastly reduced
|
||||
(18 functions versus 2). Note that websocketpp connections are passed by
|
||||
`shared_ptr`. Beast does not use `shared_ptr` anywhere in its public interface.
|
||||
A `beast::websocket::stream` is constructible and movable in a manner identical
|
||||
to a `boost::asio::ip::tcp::socket`. Callers can put such objects in a
|
||||
`shared_ptr` if they want to, but there is no requirement to do so.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L234 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template<class NextLayer>
|
||||
class stream
|
||||
{
|
||||
NextLayer next_layer_;
|
||||
...
|
||||
}
|
||||
```]
|
||||
[```
|
||||
template <typename config>
|
||||
class connection
|
||||
: public config::transport_type::transport_con_type
|
||||
, public config::connection_base
|
||||
{
|
||||
public:
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
...
|
||||
}
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[3. Client and Server Role][
|
||||
|
||||
websocketpp provides multi-role support through a hierarchy of
|
||||
different classes. A `beast::websocket::stream` is role-agnostic, it
|
||||
offers member functions to perform both client and server handshakes
|
||||
in the same class. The same types are used for client and server
|
||||
streams.
|
||||
|
||||
[table
|
||||
[
|
||||
[Beast]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/roles/server_endpoint.hpp#L39 websocketpp],
|
||||
[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/roles/client_endpoint.hpp#L42 also]]
|
||||
][
|
||||
[
|
||||
/<not needed>/
|
||||
]
|
||||
[```
|
||||
template <typename config>
|
||||
class client : public endpoint<connection<config>,config>;
|
||||
template <typename config>
|
||||
class server : public endpoint<connection<config>,config>;
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[4. Thread Safety][
|
||||
|
||||
websocketpp uses mutexes to protect shared data from concurrent
|
||||
access. In contrast, Beast does not use mutexes anywhere in its
|
||||
implementation. Instead, it follows the Asio pattern. Calls to
|
||||
asynchronous initiation functions use the same method to invoke
|
||||
intermediate handlers as the method used to invoke the final handler,
|
||||
through the __asio_handler_invoke__ mechanism.
|
||||
|
||||
The only requirement in Beast is that calls to asynchronous initiation
|
||||
functions are made from the same implicit or explicit strand. For
|
||||
example, if the `io_service` associated with a `beast::websocket::stream`
|
||||
is single threaded, this counts as an implicit strand and no performance
|
||||
costs associated with mutexes are incurred.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/impl/read_frame_op.ipp#L118 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/iostream/connection.hpp#L706 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template <class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, read_frame_op* op)
|
||||
{
|
||||
return boost_asio_handler_invoke_helpers::invoke(f, op->d_->h);
|
||||
}
|
||||
```]
|
||||
[```
|
||||
mutex_type m_read_mutex;
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[5. Callback Model][
|
||||
|
||||
websocketpp requires a one-time call to set the handler for each event
|
||||
in its interface (for example, upon message receipt). The handler is
|
||||
represented by a `std::function` equivalent. Its important to recognize
|
||||
that the websocketpp interface performs type-erasure on this handler.
|
||||
|
||||
In comparison, Beast handlers are specified in a manner identical to
|
||||
Boost.Asio. They are function objects which can be copied or moved but
|
||||
most importantly they are not type erased. The compiler can see
|
||||
through the type directly to the implementation, permitting
|
||||
optimization. Furthermore, Beast follows the Asio rules for treatment
|
||||
of handlers. It respects any allocation, continuation, or invocation
|
||||
customizations associated with the handler through the use of argument
|
||||
dependent lookup overloads of functions such as `asio_handler_allocate`.
|
||||
|
||||
The Beast completion handler is provided at the call site. For each
|
||||
call to an asynchronous initiation function, it is guaranteed that
|
||||
there will be exactly one final call to the handler. This functions
|
||||
exactly the same way as the asynchronous initiation functions found in
|
||||
Boost.Asio, allowing the composition of higher level abstractions.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L834 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L281 websocketpp],
|
||||
[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L473 also]]
|
||||
][
|
||||
[```
|
||||
template<class DynamicBuffer, class ReadHandler>
|
||||
typename async_completion<ReadHandler, void(error_code)>::result_type
|
||||
async_read(opcode& op, DynamicBuffer& dynabuf, ReadHandler&& handler);
|
||||
```]
|
||||
[```
|
||||
typedef lib::function<void(connection_hdl,message_ptr)> message_handler;
|
||||
void set_message_handler(message_handler h);
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[6. Extensible Asynchronous Model][
|
||||
|
||||
Beast fully supports the
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3896.pdf Extensible Asynchronous Model]
|
||||
developed by Christopher Kohlhoff, author of Boost.Asio (see Section 8).
|
||||
|
||||
Beast websocket asynchronous interfaces may be used seamlessly with
|
||||
`std::future` stackful/stackless coroutines, or user defined customizations.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/impl/stream.ipp#L378 Beast]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
beast::async_completion<ReadHandler, void(error_code)> completion(handler);
|
||||
read_op<DynamicBuffer, decltype(completion.handler)>{
|
||||
completion.handler, *this, op, streambuf};
|
||||
return completion.result.get();
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
[[7. Message Buffering][
|
||||
|
||||
websocketpp defines a message buffer, passed in arguments by
|
||||
`shared_ptr`, and an associated message manager which permits
|
||||
aggregation and reuse of memory. The implementation of
|
||||
`websocketpp::message` uses a `std::string` to hold the payload. If an
|
||||
incoming message is broken up into multiple frames, the string may be
|
||||
reallocated for each continuation frame. The `std::string` always uses
|
||||
the standard allocator, it is not possible to customize the choice of
|
||||
allocator.
|
||||
|
||||
Beast allows callers to specify the object for receiving the message
|
||||
or frame data, which is of any type meeting the requirements of
|
||||
__DynamicBuffer__ (modeled after `boost::asio::streambuf`).
|
||||
|
||||
Beast comes with the class __basic_streambuf__, an efficient
|
||||
implementation of the __DynamicBuffer__ concept which makes use of multiple
|
||||
allocated octet arrays. If an incoming message is broken up into
|
||||
multiple pieces, no reallocation occurs. Instead, new allocations are
|
||||
appended to the sequence when existing allocations are filled. Beast
|
||||
does not impose any particular memory management model on callers. The
|
||||
__basic_streambuf__ provided by beast supports standard allocators through
|
||||
a template argument. Use the __DynamicBuffer__ that comes with beast,
|
||||
customize the allocator if you desire, or provide your own type that
|
||||
meets the requirements.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L774 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/message_buffer/message.hpp#L78 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template<class DynamicBuffer>
|
||||
read(opcode& op, DynamicBuffer& dynabuf);
|
||||
```]
|
||||
[```
|
||||
template <template<class> class con_msg_manager>
|
||||
class message {
|
||||
public:
|
||||
typedef lib::shared_ptr<message> ptr;
|
||||
...
|
||||
std::string m_payload;
|
||||
...
|
||||
};
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[8. Sending Messages][
|
||||
|
||||
When sending a message, websocketpp requires that the payload is
|
||||
packaged in a `websocketpp::message` object using `std::string` as the
|
||||
storage, or it requires a copy of the caller provided buffer by
|
||||
constructing a new message object. Messages are placed onto an
|
||||
outgoing queue. An asynchronous write operation runs in the background
|
||||
to clear the queue. No user facing handler can be registered to be
|
||||
notified when messages or frames have completed sending.
|
||||
|
||||
Beast doesn't allocate or make copies of buffers when sending data. The
|
||||
caller's buffers are sent in-place. You can use any object meeting the
|
||||
requirements of
|
||||
[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html ConstBufferSequence],
|
||||
permitting efficient scatter-gather I/O.
|
||||
|
||||
The [*ConstBufferSequence] interface allows callers to send data from
|
||||
memory-mapped regions (not possible in websocketpp). Callers can also
|
||||
use the same buffers to send data to multiple streams, for example
|
||||
broadcasting common subscription data to many clients at once. For
|
||||
each call to `async_write` the completion handler is called once when
|
||||
the data finishes sending, in a manner identical to `boost::asio::async_write`.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L1048 Beast]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L672 websocketpp]]
|
||||
][
|
||||
[```
|
||||
template<class ConstBufferSequence>
|
||||
void
|
||||
write(ConstBufferSequence const& buffers);
|
||||
```]
|
||||
[```
|
||||
lib::error_code send(std::string const & payload,
|
||||
frame::opcode::value op = frame::opcode::text);
|
||||
...
|
||||
lib::error_code send(message_ptr msg);
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[9. Streaming Messages][
|
||||
|
||||
websocketpp requires that the entire message fit into memory, and that
|
||||
the size is known ahead of time.
|
||||
|
||||
Beast allows callers to compose messages in individual frames. This is
|
||||
useful when the size of the data is not known ahead of time or if it
|
||||
is not desired to buffer the entire message in memory at once before
|
||||
sending it. For example, sending periodic output of a database query
|
||||
running on a coroutine. Or sending the contents of a file in pieces,
|
||||
without bringing it all into memory.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L1151 Beast]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
template<class ConstBufferSequence>
|
||||
void
|
||||
write_frame(bool fin,
|
||||
ConstBufferSequence const& buffers);
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
[[10. Flow Control][
|
||||
|
||||
The websocketpp read implementation continuously reads asynchronously
|
||||
from the network and buffers message data. To prevent unbounded growth
|
||||
and leverage TCP/IP's flow control mechanism, callers can periodically
|
||||
turn this 'read pump' off and back on.
|
||||
|
||||
In contrast a `beast::websocket::stream` does not independently begin
|
||||
background activity, nor does it buffer messages. It receives data only
|
||||
when there is a call to an asynchronous initiation function (for
|
||||
example `beast::websocket::stream::async_read`) with an associated handler.
|
||||
Applications do not need to implement explicit logic to regulate the
|
||||
flow of data. Instead, they follow the traditional model of issuing a
|
||||
read, receiving a read completion, processing the message, then
|
||||
issuing a new read and repeating the process.
|
||||
|
||||
[table
|
||||
[
|
||||
[Beast]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/connection.hpp#L728 websocketpp]]
|
||||
][
|
||||
[
|
||||
/<implicit>/
|
||||
]
|
||||
[```
|
||||
lib::error_code pause_reading();
|
||||
lib::error_code resume_reading();
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[11. Connection Establishment][
|
||||
|
||||
websocketpp offers the `endpoint` class which can handle binding and
|
||||
listening to a port, and spawning connection objects.
|
||||
|
||||
Beast does not reinvent the wheel here, callers use the interfaces
|
||||
already in `boost::asio` for receiving incoming connections resolving
|
||||
host names, or establishing outgoing connections. After the socket (or
|
||||
`boost::asio::ssl::stream`) is connected, the `beast::websocket::stream`
|
||||
is constructed around it and the WebSocket handshake can be performed.
|
||||
|
||||
Beast users are free to implement their own "connection manager", but
|
||||
there is no requirement to do so.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/async_connect.html Beast],
|
||||
[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/basic_socket_acceptor/async_accept.html also]]
|
||||
[[@https://github.com/zaphoyd/websocketpp/blob/378437aecdcb1dfe62096ffd5d944bf1f640ccc3/websocketpp/transport/asio/endpoint.hpp#L52 websocketpp]]
|
||||
][
|
||||
[```
|
||||
#include <boost/asio.hpp>
|
||||
```]
|
||||
[```
|
||||
template <typename config>
|
||||
class endpoint : public config::socket_type;
|
||||
```]
|
||||
]]]]
|
||||
|
||||
[[12. WebSocket Handshaking][
|
||||
|
||||
Callers invoke `beast::websocket::accept` to perform the WebSocket
|
||||
handshake, but there is no requirement to use this function. Advanced
|
||||
users can perform the WebSocket handshake themselves. Beast WebSocket
|
||||
provides the tools for composing the request or response, and the
|
||||
Beast HTTP interface provides the container and algorithms for sending
|
||||
and receiving HTTP/1 messages including the necessary HTTP Upgrade
|
||||
request for establishing the WebSocket session.
|
||||
|
||||
Beast allows the caller to pass the incoming HTTP Upgrade request for
|
||||
the cases where the caller has already received an HTTP message.
|
||||
This flexibility permits novel and robust implementations. For example,
|
||||
a listening socket that can handshake in multiple protocols on the
|
||||
same port.
|
||||
|
||||
Sometimes callers want to read some bytes on the socket before reading
|
||||
the WebSocket HTTP Upgrade request. Beast allows these already-received
|
||||
bytes to be supplied to an overload of the accepting function to permit
|
||||
sophisticated features. For example, a listening socket that can
|
||||
accept both regular WebSocket and Secure WebSocket (SSL) connections.
|
||||
|
||||
[table
|
||||
[
|
||||
[[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L501 Beast],
|
||||
[@https://github.com/vinniefalco/Beast/blob/6c8b4b2f8dde72b01507e4ac7fde4ffea57ebc99/include/beast/websocket/stream.hpp#L401 also]]
|
||||
[websocketpp]
|
||||
][
|
||||
[```
|
||||
template<class ConstBufferSequence>
|
||||
void
|
||||
accept(ConstBufferSequence const& buffers);
|
||||
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
accept(http::request_v1<Body, Headers> const& request);
|
||||
```]
|
||||
[
|
||||
/<not available>/
|
||||
]
|
||||
]]]]
|
||||
|
||||
]
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
4
src/beast/doc/docca/README.md
Normal file
4
src/beast/doc/docca/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# docca
|
||||
Boost.Book XSLT C++ documentation system
|
||||
|
||||
[Example Documentation](http://vinniefalco.github.io/docca/)
|
||||
5
src/beast/doc/docca/example/.gitignore
vendored
Normal file
5
src/beast/doc/docca/example/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
bin
|
||||
html
|
||||
temp
|
||||
reference.qbk
|
||||
out.txt
|
||||
65
src/beast/doc/docca/example/Jamfile
Normal file
65
src/beast/doc/docca/example/Jamfile
Normal file
@@ -0,0 +1,65 @@
|
||||
#
|
||||
# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
|
||||
import os ;
|
||||
|
||||
local broot = [ os.environ BOOST_ROOT ] ;
|
||||
|
||||
project docca/doc ;
|
||||
|
||||
using boostbook ;
|
||||
using quickbook ;
|
||||
using doxygen ;
|
||||
|
||||
xml docca_bb : main.qbk ;
|
||||
|
||||
path-constant out : . ;
|
||||
|
||||
install stylesheets
|
||||
:
|
||||
$(broot)/doc/src/boostbook.css
|
||||
:
|
||||
<location>$(out)/html
|
||||
;
|
||||
|
||||
explicit stylesheets ;
|
||||
|
||||
install images
|
||||
:
|
||||
[ glob $(broot)/doc/src/images/*.png ]
|
||||
:
|
||||
<location>$(out)/html/images
|
||||
;
|
||||
|
||||
explicit images ;
|
||||
|
||||
install callouts
|
||||
:
|
||||
[ glob $(broot)/doc/src/images/callouts/*.png ]
|
||||
:
|
||||
<location>$(out)/html/images/callouts
|
||||
;
|
||||
|
||||
explicit callout ;
|
||||
|
||||
boostbook doc
|
||||
:
|
||||
docca_bb
|
||||
:
|
||||
<xsl:param>chapter.autolabel=0
|
||||
<xsl:param>boost.root=$(broot)
|
||||
<xsl:param>chapter.autolabel=0
|
||||
<xsl:param>chunk.first.sections=1 # Chunk the first top-level section?
|
||||
<xsl:param>chunk.section.depth=8 # Depth to which sections should be chunked
|
||||
<xsl:param>generate.section.toc.level=1 # Control depth of TOC generation in sections
|
||||
<xsl:param>toc.max.depth=2 # How many levels should be created for each TOC?
|
||||
<xsl:param>toc.section.depth=2 # How deep should recursive sections appear in the TOC?
|
||||
:
|
||||
<location>temp
|
||||
<dependency>stylesheets
|
||||
<dependency>images
|
||||
;
|
||||
439
src/beast/doc/docca/example/boostbook.dtd
Normal file
439
src/beast/doc/docca/example/boostbook.dtd
Normal file
@@ -0,0 +1,439 @@
|
||||
<!--
|
||||
BoostBook DTD - development version
|
||||
|
||||
For further information, see: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Boost_Documentation_Format
|
||||
|
||||
Copyright (c) 2002 by Peter Simons <simons@cryp.to>
|
||||
Copyright (c) 2003-2004 by Douglas Gregor <doug.gregor -at- gmail.com>
|
||||
Copyright (c) 2007 by Frank Mori Hess <fmhess@users.sourceforge.net>
|
||||
|
||||
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)
|
||||
|
||||
The latest stable DTD module is identified by the PUBLIC and SYSTEM identifiers:
|
||||
|
||||
PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
|
||||
SYSTEM "http://www.boost.org/tools/boostbook/dtd/1.1/boostbook.dtd"
|
||||
|
||||
$Revision$
|
||||
$Date$
|
||||
-->
|
||||
|
||||
<!--========== Define XInclude features. ==========-->
|
||||
<!-- This is not really integrated into the DTD yet. Needs more
|
||||
research. -->
|
||||
<!--
|
||||
<!ELEMENT xi:include (xi:fallback)?>
|
||||
<!ATTLIST xi:include
|
||||
xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude"
|
||||
href CDATA #REQUIRED
|
||||
parse (xml|text) "xml"
|
||||
encoding CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT xi:fallback ANY>
|
||||
<!ATTLIST xi:fallback
|
||||
xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude">
|
||||
-->
|
||||
|
||||
<!ENTITY % local.common.attrib "last-revision CDATA #IMPLIED">
|
||||
|
||||
<!--========== Define the BoostBook extensions ==========-->
|
||||
<!ENTITY % boost.common.attrib "%local.common.attrib;
|
||||
id CDATA #IMPLIED">
|
||||
|
||||
<!ENTITY % boost.namespace.mix
|
||||
"class|class-specialization|struct|struct-specialization|
|
||||
union|union-specialization|typedef|enum|
|
||||
free-function-group|function|overloaded-function|
|
||||
namespace">
|
||||
|
||||
<!ENTITY % boost.template.mix
|
||||
"template-type-parameter|template-nontype-parameter|template-varargs">
|
||||
|
||||
<!ENTITY % boost.class.members
|
||||
"static-constant|typedef|enum|
|
||||
copy-assignment|constructor|destructor|method-group|
|
||||
method|overloaded-method|data-member|class|class-specialization|struct|
|
||||
struct-specialization|union|union-specialization">
|
||||
|
||||
<!ENTITY % boost.class.mix
|
||||
"%boost.class.members;|free-function-group|function|overloaded-function">
|
||||
|
||||
<!ENTITY % boost.class.content
|
||||
"template?, inherit*, purpose?, description?,
|
||||
(%boost.class.mix;|access)*">
|
||||
|
||||
<!ENTITY % boost.class-specialization.content
|
||||
"template?, specialization?, inherit?, purpose?, description?,
|
||||
(%boost.class.mix;|access)*">
|
||||
|
||||
<!ENTITY % boost.function.semantics
|
||||
"purpose?, description?, requires?, effects?, postconditions?,
|
||||
returns?, throws?, complexity?, notes?, rationale?">
|
||||
|
||||
<!ENTITY % library.content
|
||||
"libraryinfo, (title, ((section|library-reference|testsuite))+)?">
|
||||
|
||||
<!ELEMENT library (%library.content;)>
|
||||
<!ATTLIST library
|
||||
name CDATA #REQUIRED
|
||||
dirname CDATA #REQUIRED
|
||||
html-only CDATA #IMPLIED
|
||||
url CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT boostbook (title, (chapter|library)*)>
|
||||
<!ATTLIST boostbook %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT libraryinfo (author+, copyright*, legalnotice*, librarypurpose, librarycategory*)>
|
||||
<!ATTLIST libraryinfo %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT librarypurpose (#PCDATA|code|ulink|functionname|methodname|classname|macroname|headername|enumname|globalname)*>
|
||||
<!ATTLIST librarypurpose %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT librarycategory (#PCDATA)>
|
||||
<!ATTLIST librarycategory
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT libraryname (#PCDATA)>
|
||||
<!ATTLIST libraryname %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT library-reference ANY>
|
||||
<!ATTLIST library-reference
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT librarylist EMPTY>
|
||||
<!ATTLIST librarylist %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT librarycategorylist (librarycategorydef)*>
|
||||
<!ATTLIST librarycategorylist %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT librarycategorydef (#PCDATA)>
|
||||
<!ATTLIST librarycategorydef
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT header ANY>
|
||||
<!ATTLIST header
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT namespace (%boost.namespace.mix;)*>
|
||||
<!ATTLIST namespace
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT class (%boost.class.content;)>
|
||||
<!ATTLIST class
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT struct (%boost.class.content;)>
|
||||
<!ATTLIST struct
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT union (%boost.class.content;)>
|
||||
<!ATTLIST union
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT class-specialization (%boost.class-specialization.content;)>
|
||||
<!ATTLIST class-specialization
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT struct-specialization (%boost.class-specialization.content;)>
|
||||
<!ATTLIST struct-specialization
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT union-specialization (%boost.class-specialization.content;)>
|
||||
<!ATTLIST union-specialization
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT access (%boost.class.members;)+>
|
||||
<!ATTLIST access
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!--========= C++ Templates =========-->
|
||||
<!ELEMENT template (%boost.template.mix;)*>
|
||||
<!ATTLIST template %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT template-type-parameter (default?, purpose?)>
|
||||
<!ATTLIST template-type-parameter
|
||||
name CDATA #REQUIRED
|
||||
pack CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT template-nontype-parameter (type, default?, purpose?)>
|
||||
<!ATTLIST template-nontype-parameter
|
||||
name CDATA #REQUIRED
|
||||
pack CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT template-varargs EMPTY>
|
||||
<!ATTLIST template-varargs %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT specialization (template-arg)*>
|
||||
<!ATTLIST specialization %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT template-arg ANY>
|
||||
<!ATTLIST template-arg
|
||||
pack CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT default ANY>
|
||||
<!ATTLIST default %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT inherit (type, purpose?)>
|
||||
<!ATTLIST inherit
|
||||
access CDATA #IMPLIED
|
||||
pack CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT purpose ANY>
|
||||
<!ATTLIST purpose %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT description ANY>
|
||||
<!ATTLIST description %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT type ANY>
|
||||
<!ATTLIST type %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT typedef (type, purpose?, description?)>
|
||||
<!ATTLIST typedef
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT enum (enumvalue*, purpose?, description?)>
|
||||
<!ATTLIST enum
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT enumvalue (default?, purpose?, description?)>
|
||||
<!ATTLIST enumvalue
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT static-constant (type, default, purpose?, description?)>
|
||||
<!ATTLIST static-constant
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT data-member (type, purpose?, description?)>
|
||||
<!ATTLIST data-member
|
||||
name CDATA #REQUIRED
|
||||
specifiers CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT paramtype ANY>
|
||||
<!ATTLIST paramtype %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT effects ANY>
|
||||
<!ATTLIST effects %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT postconditions ANY>
|
||||
<!ATTLIST postconditions %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT method-group (method|overloaded-method)*>
|
||||
<!ATTLIST method-group
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT constructor (template?, parameter*, %boost.function.semantics;)>
|
||||
<!ATTLIST constructor
|
||||
specifiers CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT destructor (%boost.function.semantics;)>
|
||||
<!ATTLIST destructor
|
||||
specifiers CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT method (template?, type, parameter*, %boost.function.semantics;)>
|
||||
<!ATTLIST method
|
||||
name CDATA #REQUIRED
|
||||
cv CDATA #IMPLIED
|
||||
specifiers CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT function (template?, type, parameter*, %boost.function.semantics;)>
|
||||
<!ATTLIST function
|
||||
name CDATA #REQUIRED
|
||||
specifiers CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT overloaded-method (signature*, %boost.function.semantics;)>
|
||||
<!ATTLIST overloaded-method
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT overloaded-function (signature*, %boost.function.semantics;)>
|
||||
<!ATTLIST overloaded-function
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT signature (template?, type, parameter*)>
|
||||
<!ATTLIST signature
|
||||
cv CDATA #IMPLIED
|
||||
specifiers CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT requires ANY>
|
||||
<!ATTLIST requires %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT returns ANY>
|
||||
<!ATTLIST returns %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT throws ANY>
|
||||
<!ATTLIST throws %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT complexity ANY>
|
||||
<!ATTLIST complexity %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT notes ANY>
|
||||
<!ATTLIST notes %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT rationale ANY>
|
||||
<!ATTLIST rationale %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT functionname (#PCDATA)>
|
||||
<!ATTLIST functionname
|
||||
alt CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT enumname (#PCDATA)>
|
||||
<!ATTLIST enumname
|
||||
alt CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT macroname (#PCDATA)>
|
||||
<!ATTLIST macroname
|
||||
alt CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT headername (#PCDATA)>
|
||||
<!ATTLIST headername
|
||||
alt CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT globalname (#PCDATA)>
|
||||
<!ATTLIST globalname
|
||||
alt CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT copy-assignment
|
||||
(template?, type?, parameter*, %boost.function.semantics;)>
|
||||
<!ATTLIST copy-assignment
|
||||
cv CDATA #IMPLIED
|
||||
specifiers CDATA #IMPLIED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT free-function-group (function|overloaded-function)*>
|
||||
<!ATTLIST free-function-group
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT precondition ANY>
|
||||
<!ATTLIST precondition %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT code ANY>
|
||||
<!ATTLIST code %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT using-namespace EMPTY>
|
||||
<!ATTLIST using-namespace
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!ELEMENT using-class EMPTY>
|
||||
<!ATTLIST using-class
|
||||
name CDATA #REQUIRED
|
||||
%boost.common.attrib;>
|
||||
|
||||
<!--========== Boost Testsuite Extensions ==========-->
|
||||
<!ENTITY % boost.testsuite.tests
|
||||
"compile-test|link-test|run-test|
|
||||
compile-fail-test|link-fail-test|run-fail-test">
|
||||
<!ENTITY % boost.testsuite.test.content
|
||||
"source*, lib*, requirement*, purpose, if-fails?">
|
||||
|
||||
<!ELEMENT testsuite ((%boost.testsuite.tests;)+)>
|
||||
<!ATTLIST testsuite %boost.common.attrib;>
|
||||
|
||||
<!ELEMENT compile-test (%boost.testsuite.test.content;)>
|
||||
<!ATTLIST compile-test
|
||||
filename CDATA #REQUIRED
|
||||
name CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT link-test (%boost.testsuite.test.content;)>
|
||||
<!ATTLIST link-test
|
||||
filename CDATA #REQUIRED
|
||||
name CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT run-test (%boost.testsuite.test.content;)>
|
||||
<!ATTLIST run-test
|
||||
filename CDATA #REQUIRED
|
||||
name CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT compile-fail-test (%boost.testsuite.test.content;)>
|
||||
<!ATTLIST compile-fail-test
|
||||
filename CDATA #REQUIRED
|
||||
name CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT link-fail-test (%boost.testsuite.test.content;)>
|
||||
<!ATTLIST link-fail-test
|
||||
filename CDATA #REQUIRED
|
||||
name CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT run-fail-test (%boost.testsuite.test.content;)>
|
||||
<!ATTLIST run-fail-test
|
||||
filename CDATA #REQUIRED
|
||||
name CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT source (#PCDATA|snippet)*>
|
||||
|
||||
<!ELEMENT snippet EMPTY>
|
||||
<!ATTLIST snippet
|
||||
name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT lib (#PCDATA)>
|
||||
|
||||
<!ELEMENT requirement (#PCDATA)>
|
||||
<!ATTLIST requirement
|
||||
name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT if-fails ANY>
|
||||
|
||||
<!ELEMENT parameter (paramtype, default?, description?)>
|
||||
<!ATTLIST parameter
|
||||
name CDATA #IMPLIED
|
||||
pack CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT programlisting ANY>
|
||||
<!ATTLIST programlisting
|
||||
name CDATA #IMPLIED>
|
||||
|
||||
<!--========== Customize the DocBook DTD ==========-->
|
||||
<!ENTITY % local.tech.char.class "|functionname|libraryname|enumname|headername|macroname|code">
|
||||
<!ENTITY % local.para.class
|
||||
"|using-namespace|using-class|librarylist|librarycategorylist">
|
||||
<!ENTITY % local.descobj.class "|libraryinfo">
|
||||
<!ENTITY % local.classname.attrib "alt CDATA #IMPLIED">
|
||||
<!ENTITY % local.methodname.attrib "alt CDATA #IMPLIED">
|
||||
<!ENTITY % local.refentry.class "|library-reference|testsuite">
|
||||
<!ENTITY % local.title.char.mix "">
|
||||
<!ENTITY % programlisting.module "IGNORE">
|
||||
<!ENTITY % parameter.module "IGNORE">
|
||||
<!ENTITY % function.module "IGNORE">
|
||||
<!ENTITY % type.module "IGNORE">
|
||||
|
||||
<!--========== Import DocBook DTD ==========-->
|
||||
<!ENTITY % DocBook PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
|
||||
%DocBook;
|
||||
851
src/beast/doc/docca/example/include/docca/example.hpp
Normal file
851
src/beast/doc/docca/example/include/docca/example.hpp
Normal file
@@ -0,0 +1,851 @@
|
||||
//
|
||||
// Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// 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 EXAMPLE_HPP
|
||||
#define EXAMPLE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
// This is a sample header file to show docca XLST results
|
||||
//
|
||||
// namespace, enum, type alias, global, static global,
|
||||
// function, static function, struct/class
|
||||
|
||||
namespace example {
|
||||
|
||||
/** Enum
|
||||
|
||||
Description
|
||||
*/
|
||||
enum enum_t
|
||||
{
|
||||
/// 0
|
||||
zero,
|
||||
|
||||
/// 1
|
||||
one,
|
||||
|
||||
/// 2
|
||||
two
|
||||
};
|
||||
|
||||
/** Enum class
|
||||
|
||||
Description
|
||||
*/
|
||||
enum class enum_c
|
||||
{
|
||||
/// aaa
|
||||
aaa,
|
||||
|
||||
/// bbb
|
||||
bbb,
|
||||
|
||||
/// ccc
|
||||
ccc
|
||||
};
|
||||
|
||||
/** Type alias
|
||||
|
||||
Description
|
||||
*/
|
||||
using type = std::string;
|
||||
|
||||
/** Template type alias
|
||||
|
||||
Description
|
||||
*/
|
||||
template<class T>
|
||||
using t_type = std::vector<T>;
|
||||
|
||||
/** Void or deduced
|
||||
|
||||
Description
|
||||
*/
|
||||
using vod = void_or_deduced;
|
||||
|
||||
/** Implementation-defined
|
||||
|
||||
Description
|
||||
*/
|
||||
using impdef = implementation_defined;
|
||||
|
||||
/** Variable
|
||||
|
||||
Description
|
||||
*/
|
||||
extern std::size_t var;
|
||||
|
||||
/** Static variable
|
||||
|
||||
Description
|
||||
*/
|
||||
static std::size_t s_var = 0;
|
||||
|
||||
/** Brief with @b bold text.
|
||||
|
||||
Function returning @ref type.
|
||||
|
||||
@return The type
|
||||
|
||||
@see t_func.
|
||||
|
||||
@throw std::exception on error
|
||||
@throw std::domain_error on bad parameters
|
||||
|
||||
@par Thread Safety
|
||||
|
||||
Cannot be called concurrently.
|
||||
|
||||
@note Additional notes.
|
||||
|
||||
@param arg1 Function parameter 1
|
||||
@param arg2 Function parameter 2
|
||||
*/
|
||||
type
|
||||
func(int arg1, std::string arg2);
|
||||
|
||||
/** Brief for function starting with _
|
||||
|
||||
@return @ref type
|
||||
|
||||
@see func
|
||||
*/
|
||||
type
|
||||
_func(float arg1, std::size arg2);
|
||||
|
||||
/** Brief.
|
||||
|
||||
Function description.
|
||||
|
||||
See @ref func.
|
||||
|
||||
@tparam T Template parameter 1
|
||||
@tparam U Template parameter 2
|
||||
@tparam V Template parameter 3
|
||||
|
||||
@param t Function parameter 1
|
||||
@param u Function parameter 2
|
||||
@param v Function parameter 3
|
||||
|
||||
@return nothing
|
||||
*/
|
||||
template<class T, class U>
|
||||
void
|
||||
t_func(T t, U const& u, V&& v);
|
||||
|
||||
/** Overloaded function 1
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
*/
|
||||
void
|
||||
overload(int arg1);
|
||||
|
||||
/** Overloaded function 2
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
@param arg2 Parameter 2
|
||||
*/
|
||||
void
|
||||
overload(int arg1, int arg2);
|
||||
|
||||
/** Overloaded function 3
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
@param arg2 Parameter 2
|
||||
@param arg3 Parameter 3
|
||||
*/
|
||||
void
|
||||
overload(int arg1, int arg2, int arg3);
|
||||
|
||||
/** Markdown examples
|
||||
|
||||
@par List
|
||||
|
||||
1. Lists with extra long lines that can *span* multiple lines
|
||||
and overflow even the longest of buffers.
|
||||
2. With Numbers
|
||||
+ Or not
|
||||
+ Nesting
|
||||
1. Deeply
|
||||
+ And returning `here`.
|
||||
|
||||
Another list I enjoy:
|
||||
|
||||
-# 1
|
||||
- 1.a
|
||||
-# 1.a.1
|
||||
-# 1.a.2
|
||||
- 1.b
|
||||
-# 2
|
||||
- 2.a
|
||||
- 2.b
|
||||
-# 2.b.1
|
||||
-# 2.b.2
|
||||
- 2.b.2.a
|
||||
- 2.b.2.b
|
||||
|
||||
@par Table
|
||||
|
||||
First Header | Second Header
|
||||
------------- | -------------
|
||||
Content Cell | Content Cell
|
||||
Content Cell | Content Cell
|
||||
*/
|
||||
void markdown();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** Detail class
|
||||
|
||||
Description
|
||||
*/
|
||||
struct detail_type
|
||||
{
|
||||
};
|
||||
|
||||
/** Detail function
|
||||
|
||||
Description
|
||||
*/
|
||||
void
|
||||
detail_function();
|
||||
|
||||
} // detail
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/// Nested namespace
|
||||
namespace nested {
|
||||
|
||||
/** Enum
|
||||
|
||||
Description
|
||||
*/
|
||||
enum enum_t
|
||||
{
|
||||
/// 0
|
||||
zero,
|
||||
|
||||
/// 1
|
||||
one,
|
||||
|
||||
/// 2
|
||||
two
|
||||
};
|
||||
|
||||
/** Enum class
|
||||
|
||||
Description
|
||||
*/
|
||||
enum class enum_c
|
||||
{
|
||||
/// aaa
|
||||
aaa,
|
||||
|
||||
/// bbb
|
||||
bbb,
|
||||
|
||||
/// ccc
|
||||
ccc
|
||||
};
|
||||
|
||||
/** Type alias
|
||||
|
||||
Description
|
||||
*/
|
||||
using type = std::string;
|
||||
|
||||
/** Template type alias
|
||||
|
||||
Description
|
||||
*/
|
||||
template<class T>
|
||||
using t_type = std::vector<T>;
|
||||
|
||||
/** Variable
|
||||
|
||||
Description
|
||||
*/
|
||||
extern std::size_t var;
|
||||
|
||||
/** Static variable
|
||||
|
||||
Description
|
||||
*/
|
||||
static std::size_t s_var = 0;
|
||||
|
||||
/** Brief with @b bold text.
|
||||
|
||||
Function returning @ref type.
|
||||
|
||||
@return The type
|
||||
|
||||
@see t_func.
|
||||
|
||||
@throw std::exception on error
|
||||
@throw std::domain_error on bad parameters
|
||||
|
||||
@par Thread Safety
|
||||
|
||||
Cannot be called concurrently.
|
||||
|
||||
@note Additional notes.
|
||||
|
||||
@param arg1 Function parameter 1
|
||||
@param arg2 Function parameter 2
|
||||
*/
|
||||
type
|
||||
func(int arg1, std::string arg2);
|
||||
|
||||
/** Brief for function starting with _
|
||||
|
||||
@return @ref type
|
||||
|
||||
@see func
|
||||
*/
|
||||
type
|
||||
_func(float arg1, std::size arg2);
|
||||
|
||||
/** Brief.
|
||||
|
||||
Function description.
|
||||
|
||||
See @ref func.
|
||||
|
||||
@tparam T Template parameter 1
|
||||
@tparam U Template parameter 2
|
||||
@tparam V Template parameter 3
|
||||
|
||||
@param t Function parameter 1
|
||||
@param u Function parameter 2
|
||||
@param v Function parameter 3
|
||||
|
||||
@return nothing
|
||||
*/
|
||||
template<class T, class U>
|
||||
void
|
||||
t_func(T t, U const& u, V&& v);
|
||||
|
||||
/** Overloaded function 1
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
*/
|
||||
void
|
||||
overload(int arg1);
|
||||
|
||||
/** Overloaded function 2
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
@param arg2 Parameter 2
|
||||
*/
|
||||
void
|
||||
overload(int arg1, int arg2);
|
||||
|
||||
/** Overloaded function 3
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
@param arg2 Parameter 2
|
||||
@param arg3 Parameter 3
|
||||
*/
|
||||
void
|
||||
overload(int arg1, int arg2, int arg3);
|
||||
|
||||
} // nested
|
||||
|
||||
/// Overloads operators
|
||||
struct Num
|
||||
{
|
||||
|
||||
/// Addition
|
||||
friend
|
||||
Num
|
||||
operator +(Num, Num);
|
||||
|
||||
/// Subtraction
|
||||
friend
|
||||
Num
|
||||
operator -(Num, Num);
|
||||
|
||||
/// Multiplication
|
||||
friend
|
||||
Num
|
||||
operator *(Num, Num);
|
||||
|
||||
/// Division
|
||||
friend
|
||||
Num
|
||||
operator /(Num, Num);
|
||||
|
||||
};
|
||||
|
||||
/// @ref Num addition
|
||||
Num
|
||||
operator +(Num, Num);
|
||||
|
||||
/// @ref Num subtraction
|
||||
Num
|
||||
operator -(Num, Num);
|
||||
|
||||
/// @ref Num multiplication
|
||||
Num
|
||||
operator *(Num, Num);
|
||||
|
||||
/// @ref Num division
|
||||
Num
|
||||
operator /(Num, Num);
|
||||
|
||||
/** Template class type.
|
||||
|
||||
Description.
|
||||
|
||||
@tparam T Template parameter 1
|
||||
@tparam U Template parameter 2
|
||||
*/
|
||||
template<class T, class U>
|
||||
class class_type
|
||||
{
|
||||
public:
|
||||
/** Enum
|
||||
|
||||
Description
|
||||
*/
|
||||
enum enum_t
|
||||
{
|
||||
/// 0
|
||||
zero,
|
||||
|
||||
/// 1
|
||||
one,
|
||||
|
||||
/// 2
|
||||
two,
|
||||
|
||||
/// _3
|
||||
_three
|
||||
};
|
||||
|
||||
/** Enum class
|
||||
|
||||
Description
|
||||
*/
|
||||
enum class enum_c
|
||||
{
|
||||
/// aaa
|
||||
aaa,
|
||||
|
||||
/// bbb
|
||||
bbb,
|
||||
|
||||
/// ccc
|
||||
ccc,
|
||||
|
||||
/// _ddd
|
||||
_ddd
|
||||
};
|
||||
|
||||
/** Type alias
|
||||
|
||||
Description
|
||||
*/
|
||||
using type = std::string;
|
||||
|
||||
/** Template type alias
|
||||
|
||||
Description
|
||||
*/
|
||||
template<class T>
|
||||
using t_type = std::vector<T>;
|
||||
|
||||
/** Variable
|
||||
|
||||
Description
|
||||
*/
|
||||
extern std::size_t var;
|
||||
|
||||
/** Static variable
|
||||
|
||||
Description
|
||||
*/
|
||||
static std::size_t s_var = 0;
|
||||
|
||||
/** Default Ctor
|
||||
|
||||
Description
|
||||
*/
|
||||
class_type();
|
||||
|
||||
/** Dtor
|
||||
|
||||
Description
|
||||
*/
|
||||
~class_type();
|
||||
|
||||
/** Brief with @b bold text.
|
||||
|
||||
Function returning @ref type.
|
||||
|
||||
@return The type
|
||||
|
||||
@see t_func.
|
||||
|
||||
@throw std::exception on error
|
||||
@throw std::domain_error on bad parameters
|
||||
|
||||
@par Thread Safety
|
||||
|
||||
Cannot be called concurrently.
|
||||
|
||||
@note Additional notes.
|
||||
|
||||
@param arg1 Function parameter 1
|
||||
@param arg2 Function parameter 2
|
||||
*/
|
||||
type
|
||||
func(int arg1, std::string arg2);
|
||||
|
||||
/** Brief.
|
||||
|
||||
Function description.
|
||||
|
||||
See @ref func.
|
||||
|
||||
@tparam T Template parameter 1
|
||||
@tparam U Template parameter 2
|
||||
@tparam V Template parameter 3
|
||||
|
||||
@param t Function parameter 1
|
||||
@param u Function parameter 2
|
||||
@param v Function parameter 3
|
||||
|
||||
@return nothing
|
||||
*/
|
||||
template<class T, class U>
|
||||
void
|
||||
t_func(T t, U const& u, V&& v);
|
||||
|
||||
/** Overloaded function 1
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
*/
|
||||
void
|
||||
overload(int arg1);
|
||||
|
||||
/** Overloaded function 2
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
@param arg2 Parameter 2
|
||||
*/
|
||||
void
|
||||
overload(int arg1, int arg2);
|
||||
|
||||
/** Overloaded function 3
|
||||
|
||||
Description
|
||||
|
||||
@param arg1 Parameter 1
|
||||
@param arg2 Parameter 2
|
||||
@param arg3 Parameter 3
|
||||
*/
|
||||
void
|
||||
overload(int arg1, int arg2, int arg3);
|
||||
|
||||
/** Less-than operator
|
||||
|
||||
Description
|
||||
*/
|
||||
bool
|
||||
operator< (class_type const& rhs) const;
|
||||
|
||||
/** Greater-than operator
|
||||
|
||||
Description
|
||||
*/
|
||||
bool
|
||||
operator> (class_type const& rhs) const;
|
||||
|
||||
/** Less-than-or-equal-to operator
|
||||
|
||||
Description
|
||||
*/
|
||||
bool
|
||||
operator<= (class_type const& rhs) const;
|
||||
|
||||
/** Greater-than-or-equal-to operator
|
||||
|
||||
Description
|
||||
*/
|
||||
bool
|
||||
operator>= (class_type const& rhs) const;
|
||||
|
||||
/** Equality operator
|
||||
|
||||
Description
|
||||
*/
|
||||
bool
|
||||
operator== (class_type const& rhs) const;
|
||||
|
||||
/** Inequality operator
|
||||
|
||||
Description
|
||||
*/
|
||||
bool
|
||||
operator!= (class_type const& rhs) const;
|
||||
|
||||
/** Arrow operator
|
||||
|
||||
Description
|
||||
*/
|
||||
std::size_t operator->() const;
|
||||
|
||||
/** Index operator
|
||||
|
||||
Description
|
||||
*/
|
||||
enum_c& operator[](std::size_t);
|
||||
|
||||
/** Index operator
|
||||
|
||||
Description
|
||||
*/
|
||||
enum_c operator[](std::size_t) const;
|
||||
|
||||
/// Public data
|
||||
std::size_t pub_data_;
|
||||
|
||||
/// Public static data
|
||||
static std::size_t pub_sdata_;
|
||||
|
||||
protected:
|
||||
/** Protected data
|
||||
|
||||
Description
|
||||
*/
|
||||
std::size_t prot_data_;
|
||||
|
||||
/** Protected enum
|
||||
|
||||
Description
|
||||
*/
|
||||
enum_c _prot_enum;
|
||||
|
||||
/** Static protected data
|
||||
|
||||
Description
|
||||
*/
|
||||
static std::size_t prot_sdata_;
|
||||
|
||||
/** Protected type
|
||||
|
||||
Description
|
||||
*/
|
||||
struct prot_type
|
||||
{
|
||||
};
|
||||
|
||||
/** Protected function
|
||||
|
||||
Description
|
||||
*/
|
||||
void prot_memfn();
|
||||
|
||||
/** Protected function returning @ref prot_type
|
||||
|
||||
Description
|
||||
*/
|
||||
prot_type prot_rvmemfn();
|
||||
|
||||
/** Protected static member function
|
||||
|
||||
Description
|
||||
*/
|
||||
static void static_prot_memfn();
|
||||
|
||||
private:
|
||||
/** Private data
|
||||
|
||||
Description
|
||||
*/
|
||||
std::size_t priv_data_;
|
||||
|
||||
/** Static private data
|
||||
|
||||
Description
|
||||
*/
|
||||
static std::size_t priv_sdata_;
|
||||
|
||||
/** Private type
|
||||
|
||||
Description
|
||||
*/
|
||||
struct priv_type
|
||||
{
|
||||
};
|
||||
|
||||
/** Private function
|
||||
|
||||
Description
|
||||
*/
|
||||
void priv_memfn();
|
||||
|
||||
/** Private function returning *ref priv_type
|
||||
|
||||
Description
|
||||
*/
|
||||
priv_type priv_rvmemfn();
|
||||
|
||||
/** Static private member function
|
||||
|
||||
Description
|
||||
*/
|
||||
static void static_priv_memfn();
|
||||
|
||||
/** Friend class
|
||||
|
||||
Description
|
||||
*/
|
||||
friend friend_class;
|
||||
};
|
||||
|
||||
/// Other base class 1
|
||||
class other_base_class1
|
||||
{
|
||||
};
|
||||
|
||||
/// Other base class 2
|
||||
class other_base_class2
|
||||
{
|
||||
};
|
||||
|
||||
/** Derived type
|
||||
|
||||
Description
|
||||
*/
|
||||
template<class T, class U>
|
||||
class derived_type :
|
||||
public class_type<T, U>,
|
||||
protected other_base_class1,
|
||||
private other_base_class2
|
||||
{
|
||||
};
|
||||
|
||||
/** References to all identifiers:
|
||||
|
||||
Description one @ref one
|
||||
|
||||
@par See Also
|
||||
|
||||
@li @ref type
|
||||
|
||||
@li @ref t_type
|
||||
|
||||
@li @ref vod
|
||||
|
||||
@li @ref impdef
|
||||
|
||||
@li @ref var
|
||||
|
||||
@li @ref s_var
|
||||
|
||||
@li @ref func
|
||||
|
||||
@li @ref t_func
|
||||
|
||||
@li @ref overload
|
||||
|
||||
@li @ref nested::enum_t : @ref nested::zero @ref nested::one @ref nested::two
|
||||
|
||||
@li @ref nested::enum_c : nested::enum_c::aaa @ref nested::enum_c::bbb @ref nested::enum_c::ccc
|
||||
|
||||
@li @ref nested::type
|
||||
|
||||
@li @ref nested::t_type
|
||||
|
||||
@li @ref nested::var
|
||||
|
||||
@li @ref nested::s_var
|
||||
|
||||
@li @ref nested::func
|
||||
|
||||
@li @ref nested::t_func
|
||||
|
||||
@li @ref nested::overload
|
||||
|
||||
@li @ref class_type
|
||||
|
||||
@li @ref class_type::enum_t : @ref class_type::zero @ref class_type::one @ref class_type::two @ref class_type::_three
|
||||
|
||||
@li @ref class_type::enum_c : class_type::enum_c::aaa @ref class_type::enum_c::bbb @ref class_type::enum_c::ccc class_type::enum_c::_ddd
|
||||
|
||||
@li @ref class_type::type
|
||||
|
||||
@li @ref class_type::t_type
|
||||
|
||||
@li @ref class_type::var
|
||||
|
||||
@li @ref class_type::s_var
|
||||
|
||||
@li @ref class_type::class_type
|
||||
|
||||
@li @ref class_type::func
|
||||
|
||||
@li @ref class_type::t_func
|
||||
|
||||
@li @ref class_type::overload
|
||||
|
||||
@li @ref class_type::pub_data_
|
||||
|
||||
@li @ref class_type::pub_sdata_
|
||||
|
||||
@li @ref class_type::_prot_enum
|
||||
|
||||
@li @ref class_type::prot_type
|
||||
|
||||
@li @ref class_type::priv_type
|
||||
|
||||
@li @ref derived_type
|
||||
|
||||
@li @ref Num
|
||||
|
||||
*/
|
||||
void all_ref();
|
||||
|
||||
} // example
|
||||
|
||||
namespace other {
|
||||
|
||||
/// other function
|
||||
void func();
|
||||
|
||||
/// other class
|
||||
struct class_type
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
} // other
|
||||
|
||||
#endif
|
||||
14
src/beast/doc/docca/example/index.xml
Normal file
14
src/beast/doc/docca/example/index.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "boostbook.dtd">
|
||||
|
||||
<!--
|
||||
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
-->
|
||||
|
||||
<section id="docca.index">
|
||||
<title>Index</title>
|
||||
<index/>
|
||||
</section>
|
||||
28
src/beast/doc/docca/example/main.qbk
Normal file
28
src/beast/doc/docca/example/main.qbk
Normal file
@@ -0,0 +1,28 @@
|
||||
[/
|
||||
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[library docca
|
||||
[quickbook 1.6]
|
||||
[copyright 2016 Vinnie Falco]
|
||||
[purpose Documentation Library]
|
||||
[license
|
||||
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])
|
||||
]
|
||||
[category template]
|
||||
[category generic]
|
||||
]
|
||||
|
||||
[template mdash[] '''— ''']
|
||||
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
|
||||
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
|
||||
|
||||
[section:ref Reference]
|
||||
[include reference.qbk]
|
||||
[endsect]
|
||||
[xinclude index.xml]
|
||||
13
src/beast/doc/docca/example/makeqbk.sh
Normal file
13
src/beast/doc/docca/example/makeqbk.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
#
|
||||
# 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)
|
||||
|
||||
mkdir -p temp
|
||||
doxygen source.dox
|
||||
cd temp
|
||||
xsltproc combine.xslt index.xml > all.xml
|
||||
xsltproc ../reference.xsl all.xml > ../reference.qbk
|
||||
|
||||
14
src/beast/doc/docca/example/reference.xsl
Normal file
14
src/beast/doc/docca/example/reference.xsl
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
|
||||
<!-- Variables (Edit for your project) -->
|
||||
<xsl:variable name="doc-ref" select="'docca.ref.'"/>
|
||||
<xsl:variable name="doc-ns" select="'example'"/>
|
||||
<xsl:variable name="debug" select="0"/>
|
||||
<xsl:variable name="private" select="0"/>
|
||||
<!-- End Variables -->
|
||||
|
||||
<xsl:include href="../include/docca/doxygen.xsl"/>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
333
src/beast/doc/docca/example/source.dox
Normal file
333
src/beast/doc/docca/example/source.dox
Normal file
@@ -0,0 +1,333 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "docca"
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF = Documentation Library
|
||||
PROJECT_LOGO =
|
||||
OUTPUT_DIRECTORY =
|
||||
CREATE_SUBDIRS = NO
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF =
|
||||
ALWAYS_DETAILED_SEC = YES
|
||||
INLINE_INHERITED_MEMB = YES
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH = include/
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = YES
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 4
|
||||
ALIASES =
|
||||
TCL_SUBST =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
EXTENSION_MAPPING =
|
||||
MARKDOWN_SUPPORT = YES
|
||||
AUTOLINK_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
GROUP_NESTED_COMPOUNDS = NO
|
||||
SUBGROUPING = YES
|
||||
INLINE_GROUPED_CLASSES = NO
|
||||
INLINE_SIMPLE_STRUCTS = NO
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_PACKAGE = NO
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
HIDE_COMPOUND_REFERENCE= NO
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
SHOW_GROUPED_MEMB_INC = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = NO
|
||||
SORT_MEMBER_DOCS = NO
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = YES
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
GENERATE_TODOLIST = NO
|
||||
GENERATE_TESTLIST = NO
|
||||
GENERATE_BUGLIST = NO
|
||||
GENERATE_DEPRECATEDLIST= NO
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = NO
|
||||
SHOW_FILES = NO
|
||||
SHOW_NAMESPACES = NO
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
CITE_BIB_FILES =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_AS_ERROR = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = include/docca/example.hpp
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS =
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = YES
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
SOURCE_TOOLTIPS = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
CLANG_OPTIONS =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 1
|
||||
IGNORE_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = NO
|
||||
HTML_OUTPUT = dhtm
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = NO
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
HTML_INDEX_NUM_ENTRIES = 100
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
GENERATE_TREEVIEW = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_FORMAT = HTML-CSS
|
||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
MATHJAX_EXTENSIONS =
|
||||
MATHJAX_CODEFILE =
|
||||
SEARCHENGINE = YES
|
||||
SERVER_BASED_SEARCH = NO
|
||||
EXTERNAL_SEARCH = NO
|
||||
SEARCHENGINE_URL =
|
||||
SEARCHDATA_FILE = searchdata.xml
|
||||
EXTERNAL_SEARCH_ID =
|
||||
EXTRA_SEARCH_MAPPINGS =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
LATEX_FOOTER =
|
||||
LATEX_EXTRA_STYLESHEET =
|
||||
LATEX_EXTRA_FILES =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
LATEX_BIB_STYLE = plain
|
||||
LATEX_TIMESTAMP = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
RTF_SOURCE_CODE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_SUBDIR =
|
||||
MAN_LINKS = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = temp/
|
||||
XML_PROGRAMLISTING = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the DOCBOOK output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_DOCBOOK = NO
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = DOXYGEN \
|
||||
GENERATING_DOCS \
|
||||
_MSC_VER
|
||||
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
EXTERNAL_PAGES = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = NO
|
||||
MSCGEN_PATH =
|
||||
DIA_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
INTERACTIVE_SVG = NO
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DIAFILE_DIRS =
|
||||
PLANTUML_JAR_PATH =
|
||||
PLANTUML_INCLUDE_PATH =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,136 +0,0 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[section:example Examples]
|
||||
|
||||
These usage examples are intended to quickly impress upon readers the
|
||||
flavor of the library. They are complete programs which may be built
|
||||
and run. Source code and build scripts for these programs may be found
|
||||
in the examples directory.
|
||||
|
||||
[heading HTTP GET]
|
||||
|
||||
Use HTTP to request the root page from a website and print the response:
|
||||
|
||||
```
|
||||
#include <beast/http.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "boost.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r{ios};
|
||||
boost::asio::ip::tcp::socket sock{ios};
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
|
||||
|
||||
// Send HTTP request using beast
|
||||
beast::http::request<beast::http::empty_body> req;
|
||||
req.method = "GET";
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.fields.replace("Host", host + ":" +
|
||||
boost::lexical_cast<std::string>(sock.remote_endpoint().port()));
|
||||
req.fields.replace("User-Agent", "Beast");
|
||||
beast::http::prepare(req);
|
||||
beast::http::write(sock, req);
|
||||
|
||||
// Receive and print HTTP response using beast
|
||||
beast::streambuf sb;
|
||||
beast::http::response<beast::http::streambuf_body> resp;
|
||||
beast::http::read(sock, sb, resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
```
|
||||
[heading WebSocket]
|
||||
|
||||
Establish a WebSocket connection, send a message and receive the reply:
|
||||
```
|
||||
#include <beast/core/to_string.hpp>
|
||||
#include <beast/websocket.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "echo.websocket.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r{ios};
|
||||
boost::asio::ip::tcp::socket sock{ios};
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
|
||||
|
||||
// WebSocket connect and send message using beast
|
||||
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
|
||||
ws.handshake(host, "/");
|
||||
ws.write(boost::asio::buffer(std::string("Hello, world!")));
|
||||
|
||||
// Receive WebSocket message, print and close using beast
|
||||
beast::streambuf sb;
|
||||
beast::websocket::opcode op;
|
||||
ws.read(op, sb);
|
||||
ws.close(beast::websocket::close_code::normal);
|
||||
std::cout << beast::to_string(sb.data()) << "\n";
|
||||
}
|
||||
```
|
||||
|
||||
[heading WebSocket Echo Server]
|
||||
|
||||
This example demonstrates both synchronous and asynchronous
|
||||
WebSocket server implementations.
|
||||
|
||||
* [@examples/websocket_async_echo_server.hpp]
|
||||
* [@examples/websocket_sync_echo_server.hpp]
|
||||
* [@examples/websocket_echo.cpp]
|
||||
|
||||
[heading Secure WebSocket]
|
||||
|
||||
Establish a WebSocket connection over an encrypted TLS connection,
|
||||
send a message and receive the reply. Requires OpenSSL to build.
|
||||
|
||||
* [@examples/websocket_ssl_example.cpp]
|
||||
|
||||
[heading HTTPS GET]
|
||||
|
||||
This example demonstrates sending and receiving HTTP messages
|
||||
over a TLS connection. Requires OpenSSL to build.
|
||||
|
||||
* [@examples/http_ssl_example.cpp]
|
||||
|
||||
[heading HTTP Crawl]
|
||||
|
||||
This example retrieves the page at each of the most popular domains
|
||||
as measured by Alexa.
|
||||
|
||||
* [@examples/http_crawl.cpp]
|
||||
|
||||
[heading HTTP Server]
|
||||
|
||||
This example demonstrates both synchronous and asynchronous server
|
||||
implementations. It also provides an example of implementing a [*Body]
|
||||
type, in `file_body`.
|
||||
|
||||
* [@examples/file_body.hpp]
|
||||
* [@examples/http_async_server.hpp]
|
||||
* [@examples/http_sync_server.hpp]
|
||||
* [@examples/http_server.cpp]
|
||||
|
||||
[heading Listings]
|
||||
|
||||
These are stand-alone listings of the HTTP and WebSocket examples.
|
||||
|
||||
* [@examples/http_example.cpp]
|
||||
* [@examples/websocket_example.cpp]
|
||||
|
||||
[endsect]
|
||||
@@ -1,381 +0,0 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[/
|
||||
ideas:
|
||||
- complete send request walkthrough (client)
|
||||
- complete receive response walkthrough (client)
|
||||
- complete receive request walkthrough (server)
|
||||
- complete send response walkthrough (server)
|
||||
|
||||
- Introduce concepts from simple to complex
|
||||
- Smooth progression of new ideas building on the previous ideas
|
||||
|
||||
- do we show a simplified message with collapsed fields?
|
||||
- do we introduce `header` or `message` first?
|
||||
|
||||
|
||||
contents:
|
||||
Message (and header, fields)
|
||||
Create request
|
||||
Create response
|
||||
Algorithms
|
||||
Write
|
||||
Read
|
||||
Parse
|
||||
Examples
|
||||
Send Request
|
||||
Receive Response
|
||||
Receive Request
|
||||
Send Response
|
||||
Advanced
|
||||
Responding to HEAD
|
||||
Expect: 100-continue
|
||||
Body (user defined)
|
||||
|
||||
|
||||
section beast.http.examples Examples
|
||||
|
||||
note
|
||||
In the example code which follows, `socket` refers to an object of type
|
||||
`boost::asio::ip::tcp::socket` which is currently connected to a remote peer.
|
||||
]
|
||||
|
||||
|
||||
|
||||
[section:http Using HTTP]
|
||||
|
||||
[block '''
|
||||
<informaltable frame="all"><tgroup cols="1"><colspec colname="a"/><tbody><row><entry valign="top"><simplelist>
|
||||
<member><link linkend="beast.http.message">Message</link></member>
|
||||
<member><link linkend="beast.http.fields">Fields</link></member>
|
||||
<member><link linkend="beast.http.body">Body</link></member>
|
||||
<member><link linkend="beast.http.algorithms">Algorithms</link></member>
|
||||
</simplelist></entry></row></tbody></tgroup></informaltable>
|
||||
''']
|
||||
|
||||
Beast offers programmers simple and performant models of HTTP messages and
|
||||
their associated operations including synchronous and asynchronous reading and
|
||||
writing of messages and headers in the HTTP/1 wire format using Boost.Asio.
|
||||
|
||||
[note
|
||||
The following documentation assumes familiarity with both Boost.Asio
|
||||
and the HTTP protocol specification described in __rfc7230__. Sample code
|
||||
and identifiers mentioned in this section are written as if the following
|
||||
declarations are in effect:
|
||||
```
|
||||
#include <beast/core.hpp>
|
||||
#include <beast/http.hpp>
|
||||
using namespace beast;
|
||||
using namespace beast::http;
|
||||
```
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[section:message Message]
|
||||
|
||||
The HTTP protocol defines the client and server roles: clients send messages
|
||||
called requests and servers send back messages called responses. A HTTP message
|
||||
(referred to hereafter as "message") contains request or response specific
|
||||
attributes (contained in the "Start Line"), a series of zero or more name/value
|
||||
pairs (collectively termed "Fields"), and an optional series of octets called
|
||||
the message body which may be zero in length. The start line for a HTTP request
|
||||
includes a string called the method, a string called the URL, and a version
|
||||
number indicating HTTP/1.0 or HTTP/1.1. For a response, the start line contains
|
||||
an integer status code and a string called the reason phrase. Alternatively, a
|
||||
HTTP message can be viewed as two parts: a header, followed by a body.
|
||||
|
||||
[note
|
||||
The Reason-Phrase is obsolete as of rfc7230.
|
||||
]
|
||||
|
||||
The __header__ class template models the header for HTTP/1 and HTTP/2 messages.
|
||||
This class template is a family of specializations, one for requests and one
|
||||
for responses, depending on the [*`isRequest`] template value.
|
||||
The [*`Fields`] template type determines the type of associative container
|
||||
used to store the field values. The provided __basic_fields__ class template
|
||||
and __fields__ type alias are typical choices for the [*`Fields`] type, but
|
||||
advanced applications may supply user defined types which meet the requirements.
|
||||
The __message__ class template models the header and optional body for HTTP/1
|
||||
and HTTP/2 requests and responses. It is derived from the __header__ class
|
||||
template with the same shared template parameters, and adds the `body` data
|
||||
member. The message class template requires an additional template argument
|
||||
type [*`Body`]. This type controls the container used to represent the body,
|
||||
if any, as well as the algorithms needed to serialize and parse bodies of
|
||||
that type.
|
||||
|
||||
This illustration shows the declarations and members of the __header__ and
|
||||
__message__ class templates, as well as the inheritance relationship:
|
||||
|
||||
[$images/message.png [width 650px] [height 390px]]
|
||||
|
||||
For notational convenience, these template type aliases are provided which
|
||||
supply typical choices for the [*`Fields`] type:
|
||||
```
|
||||
using request_header = header<true, fields>;
|
||||
using response_header = header<false, fields>;
|
||||
|
||||
template<class Body, class Fields = fields>
|
||||
using request = message<true, Body, Fields>;
|
||||
|
||||
template<class Body, class Fields = fields>
|
||||
using response = message<false, Body, Fields>;
|
||||
```
|
||||
|
||||
The code examples below show how to create and fill in a request and response
|
||||
object:
|
||||
|
||||
[table Create Message
|
||||
[[HTTP Request] [HTTP Response]]
|
||||
[[
|
||||
```
|
||||
request<empty_body> req;
|
||||
req.version = 11; // HTTP/1.1
|
||||
req.method = "GET";
|
||||
req.url = "/index.htm"
|
||||
req.fields.insert("Accept", "text/html");
|
||||
req.fields.insert("Connection", "keep-alive");
|
||||
req.fields.insert("User-Agent", "Beast");
|
||||
```
|
||||
][
|
||||
```
|
||||
response<string_body> res;
|
||||
res.version = 11; // HTTP/1.1
|
||||
res.status = 200;
|
||||
res.reason = "OK";
|
||||
res.fields.insert("Sever", "Beast");
|
||||
res.fields.insert("Content-Length", 4);
|
||||
res.body = "****";
|
||||
```
|
||||
]]]
|
||||
|
||||
In the serialized format of a HTTP message, the header is represented as a
|
||||
series of text lines ending in CRLF (`"\r\n"`). The end of the header is
|
||||
indicated by a line containing only CRLF. Here are examples of serialized HTTP
|
||||
request and response objects. The objects created above will produce these
|
||||
results when serialized. Note that only the response has a body:
|
||||
|
||||
[table Serialized HTTP Request and Response
|
||||
[[HTTP Request] [HTTP Response]]
|
||||
[[
|
||||
```
|
||||
GET /index.htm HTTP/1.1\r\n
|
||||
Accept: text/html\r\n
|
||||
Connection: keep-alive\r\n
|
||||
User-Agent: Beast\r\n
|
||||
\r\n
|
||||
```
|
||||
][
|
||||
```
|
||||
200 OK HTTP/1.1\r\n
|
||||
Server: Beast\r\n
|
||||
Content-Length: 4\r\n
|
||||
\r\n
|
||||
****
|
||||
```
|
||||
]]]
|
||||
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
||||
[section:fields Fields]
|
||||
|
||||
The [*`Fields`] type represents a container that can set or retrieve the
|
||||
fields in a message. Beast provides the
|
||||
[link beast.ref.http__basic_fields `basic_fields`] class which serves
|
||||
the needs for most users. It supports modification and inspection of values.
|
||||
The field names are not case-sensitive.
|
||||
|
||||
These statements change the values of the headers in the message passed:
|
||||
```
|
||||
template<class Body>
|
||||
void set_fields(request<Body>& req)
|
||||
{
|
||||
if(! req.exists("User-Agent"))
|
||||
req.insert("User-Agent", "myWebClient");
|
||||
|
||||
if(req.exists("Accept-Charset"))
|
||||
req.erase("Accept-Charset");
|
||||
|
||||
req.replace("Accept", "text/plain");
|
||||
}
|
||||
```
|
||||
|
||||
User defined [*`Fields`] types are possible. To support serialization, the
|
||||
type must meet the requirements of __FieldSequence__. To support parsing using
|
||||
the provided parser, the type must provide the `insert` member function.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:body Body]
|
||||
|
||||
The message [*`Body`] template parameter controls both the type of the data
|
||||
member of the resulting message object, and the algorithms used during parsing
|
||||
and serialization. Beast provides three very common [*`Body`] types:
|
||||
|
||||
* [link beast.ref.http__empty_body [*`empty_body`:]] An empty message body.
|
||||
Used in GET requests where there is no message body. Example:
|
||||
```
|
||||
request<empty_body> req;
|
||||
req.version = 11;
|
||||
req.method = "GET";
|
||||
req.url = "/index.html";
|
||||
```
|
||||
|
||||
* [link beast.ref.http__string_body [*`string_body`:]] A body with a
|
||||
`value_type` as `std::string`. Useful for quickly putting together a request
|
||||
or response with simple text in the message body (such as an error message).
|
||||
Has the same insertion complexity of `std::string`. This is the type of body
|
||||
used in the examples:
|
||||
```
|
||||
response<string_body> res;
|
||||
static_assert(std::is_same<decltype(res.body), std::string>::value);
|
||||
res.body = "Here is the data you requested";
|
||||
```
|
||||
|
||||
* [link beast.ref.http__streambuf_body [*`streambuf_body`:]] A body with a
|
||||
`value_type` of [link beast.ref.streambuf `streambuf`]: an efficient storage
|
||||
object which uses multiple octet arrays of varying lengths to represent data.
|
||||
|
||||
[heading Advanced]
|
||||
|
||||
User-defined types are possible for the message body, where the type meets the
|
||||
[link beast.ref.Body [*`Body`]] requirements. This simplified class declaration
|
||||
shows the customization points available to user-defined body types:
|
||||
|
||||
[$images/body.png [width 510px] [height 210px]]
|
||||
|
||||
* [*`value_type`]: Determines the type of the
|
||||
[link beast.ref.http__message.body `message::body`] member. If this
|
||||
type defines default construction, move, copy, or swap, then message objects
|
||||
declared with this [*`Body`] will have those operations defined.
|
||||
|
||||
* [*`reader`]: An optional nested type meeting the requirements of
|
||||
[link beast.ref.Reader [*`Reader`]]. If present, this defines the algorithm
|
||||
used for parsing bodies of this type.
|
||||
|
||||
* [*`writer`]: An optional nested type meeting the requirements of
|
||||
[link beast.ref.Writer [*`Writer`]]. If present, this defines the algorithm
|
||||
used for serializing bodies of this type.
|
||||
|
||||
The examples included with this library provide a Body implementation that
|
||||
serializing message bodies that come from a file.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[section:algorithms Algorithms]
|
||||
|
||||
Algorithms are provided to serialize and deserialize HTTP/1 messages on
|
||||
streams.
|
||||
|
||||
* [link beast.ref.http__read [*read]]: Deserialize a HTTP/1 __header__ or __message__ from a stream.
|
||||
* [link beast.ref.http__write [*write]]: Serialize a HTTP/1 __header__ or __message__ to a stream.
|
||||
|
||||
Asynchronous versions of these algorithms are also available:
|
||||
|
||||
* [link beast.ref.http__async_read [*async_read]]: Deserialize a HTTP/1 __header__ or __message__ asynchronously from a stream.
|
||||
* [link beast.ref.http__async_write [*async_write]]: Serialize a HTTP/1 __header__ or __message__ asynchronously to a stream.
|
||||
|
||||
[heading Using Sockets]
|
||||
|
||||
The free function algorithms are modeled after Boost.Asio to send and receive
|
||||
messages on TCP/IP sockets, SSL streams, or any object which meets the
|
||||
Boost.Asio type requirements (__SyncReadStream__, __SyncWriteStream__,
|
||||
__AsyncReadStream__, and __AsyncWriteStream__ depending on the types of
|
||||
operations performed). To send messages synchronously, use one of the
|
||||
[link beast.ref.http__write `write`] functions:
|
||||
```
|
||||
void send_request(boost::asio::ip::tcp::socket& sock)
|
||||
{
|
||||
request<empty_body> req;
|
||||
req.version = 11;
|
||||
req.method = "GET";
|
||||
req.url = "/index.html";
|
||||
...
|
||||
write(sock, req); // Throws exception on error
|
||||
...
|
||||
// Alternatively
|
||||
boost::system::error:code ec;
|
||||
write(sock, req, ec);
|
||||
if(ec)
|
||||
std::cerr << "error writing http message: " << ec.message();
|
||||
}
|
||||
```
|
||||
|
||||
An asynchronous interface is available:
|
||||
```
|
||||
void handle_write(boost::system::error_code);
|
||||
...
|
||||
request<empty_body> req;
|
||||
...
|
||||
async_write(sock, req, std::bind(&handle_write, std::placeholders::_1));
|
||||
```
|
||||
|
||||
When the implementation reads messages from a socket, it can read bytes lying
|
||||
after the end of the message if they are present (the alternative is to read
|
||||
a single byte at a time which is unsuitable for performance reasons). To
|
||||
store and re-use these extra bytes on subsequent messages, the read interface
|
||||
requires an additional parameter: a [link beast.ref.DynamicBuffer [*`DynamicBuffer`]]
|
||||
object. This example reads a message from the socket, with the extra bytes
|
||||
stored in the streambuf parameter for use in a subsequent call to read:
|
||||
```
|
||||
boost::asio::streambuf sb;
|
||||
...
|
||||
response<string_body> res;
|
||||
read(sock, sb, res); // Throws exception on error
|
||||
...
|
||||
// Alternatively
|
||||
boost::system::error:code ec;
|
||||
read(sock, sb, res, ec);
|
||||
if(ec)
|
||||
std::cerr << "error reading http message: " << ec.message();
|
||||
```
|
||||
|
||||
As with the write function, an asynchronous interface is available. The
|
||||
stream buffer parameter must remain valid until the completion handler is
|
||||
called:
|
||||
```
|
||||
void handle_read(boost::system::error_code);
|
||||
...
|
||||
boost::asio::streambuf sb;
|
||||
response<string_body> res;
|
||||
...
|
||||
async_read(sock, res, std::bind(&handle_read, std::placeholders::_1));
|
||||
```
|
||||
|
||||
An alternative to using a `boost::asio::streambuf` is to use a
|
||||
__streambuf__, which meets the requirements of __DynamicBuffer__ and
|
||||
is optimized for performance:
|
||||
```
|
||||
void handle_read(boost::system::error_code);
|
||||
...
|
||||
beast::streambuf sb;
|
||||
response<string_body> res;
|
||||
read(sock, sb, res);
|
||||
```
|
||||
|
||||
The `read` implementation can use any object meeting the requirements of
|
||||
__DynamicBuffer__, allowing callers to define custom
|
||||
memory management strategies used by the implementation.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
BIN
src/beast/doc/images/AlfaSlabOne-Regular.ttf
Normal file
BIN
src/beast/doc/images/AlfaSlabOne-Regular.ttf
Normal file
Binary file not shown.
43
src/beast/doc/images/SIL Open Font License.txt
Normal file
43
src/beast/doc/images/SIL Open Font License.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
Copyright (c) 2011 JM Sole (info@jmsole.cl), with Reserved Font Name "Alfa Slab One"
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.4 KiB |
Binary file not shown.
BIN
src/beast/doc/images/btc_qr2.png
Normal file
BIN
src/beast/doc/images/btc_qr2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 36 KiB |
Binary file not shown.
BIN
src/beast/doc/images/server.png
Normal file
BIN
src/beast/doc/images/server.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
src/beast/doc/images/server.psd
Normal file
BIN
src/beast/doc/images/server.psd
Normal file
Binary file not shown.
@@ -5,9 +5,12 @@
|
||||
# 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)
|
||||
|
||||
mkdir -p ../bin/doc/xml
|
||||
mkdir -p temp
|
||||
doxygen source.dox
|
||||
cd ../bin/doc/xml
|
||||
cd temp
|
||||
xsltproc combine.xslt index.xml > all.xml
|
||||
cd ../../../doc
|
||||
xsltproc reference.xsl ../bin/doc/xml/all.xml > reference.qbk
|
||||
cp ../docca/include/docca/doxygen.xsl doxygen.xsl
|
||||
sed -i -e '/<!-- CLASS_DETAIL_TEMPLATE -->/{r ../xsl/class_detail.xsl' -e 'd}' doxygen.xsl
|
||||
sed -i -e '/<!-- INCLUDES_TEMPLATE -->/{r ../xsl/includes.xsl' -e 'd}' doxygen.xsl
|
||||
sed -i -e '/<!-- INCLUDES_FOOT_TEMPLATE -->/{r ../xsl/includes_foot.xsl' -e 'd}' doxygen.xsl
|
||||
xsltproc ../xsl/reference.xsl all.xml > ../reference.qbk
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
[/
|
||||
Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
[library Beast
|
||||
[quickbook 1.6]
|
||||
[copyright 2013 - 2017 Vinnie Falco]
|
||||
[purpose Networking Protocol Library]
|
||||
[license
|
||||
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])
|
||||
]
|
||||
[authors [Falco, Vinnie]]
|
||||
[category template]
|
||||
[category generic]
|
||||
]
|
||||
|
||||
[template mdash[] '''— ''']
|
||||
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
|
||||
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
|
||||
|
||||
[def __N4588__ [@http://cplusplus.github.io/networking-ts/draft.pdf [*N4588]]]
|
||||
[def __rfc6455__ [@https://tools.ietf.org/html/rfc6455 rfc6455]]
|
||||
[def __rfc7230__ [@https://tools.ietf.org/html/rfc7230 rfc7230]]
|
||||
|
||||
[def __asio_handler_invoke__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_invoke.html `asio_handler_invoke`]]
|
||||
[def __asio_handler_allocate__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asio_handler_allocate.html `asio_handler_allocate`]]
|
||||
[def __void_or_deduced__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]]
|
||||
|
||||
[def __AsyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]]
|
||||
[def __AsyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]]
|
||||
[def __CompletionHandler__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]]
|
||||
[def __ConstBufferSequence__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]]
|
||||
[def __Handler__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/Handler.html [*Handler]]]
|
||||
[def __MutableBufferSequence__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]]
|
||||
[def __SyncReadStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]]
|
||||
[def __SyncWriteStream__ [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]]
|
||||
|
||||
[def __Body__ [link beast.ref.Body [*`Body`]]]
|
||||
[def __DynamicBuffer__ [link beast.ref.DynamicBuffer [*DynamicBuffer]]]
|
||||
[def __FieldSequence__ [link beast.ref.FieldSequence [*FieldSequence]]]
|
||||
[def __Parser__ [link beast.ref.Parser [*`Parser`]]]
|
||||
|
||||
[def __basic_fields__ [link beast.ref.http__basic_fields `basic_fields`]]
|
||||
[def __fields__ [link beast.ref.http__fields `fields`]]
|
||||
[def __header__ [link beast.ref.http__header `header`]]
|
||||
[def __message__ [link beast.ref.http__message `message`]]
|
||||
[def __streambuf__ [link beast.ref.streambuf `streambuf`]]
|
||||
[def __basic_streambuf__ [link beast.ref.basic_streambuf `basic_streambuf`]]
|
||||
|
||||
Beast is a cross-platform, header-only C++ library built on Boost.Asio that
|
||||
provides implementations of the HTTP and WebSocket protocols.
|
||||
|
||||
[variablelist
|
||||
[[
|
||||
[link beast.overview Overview]
|
||||
][
|
||||
An introduction with features, requirements, and credits.
|
||||
]]
|
||||
[[
|
||||
[link beast.http Using HTTP]
|
||||
][
|
||||
How to use Beast's HTTP interfaces in your applications.
|
||||
]]
|
||||
[[
|
||||
[link beast.websocket Using WebSocket]
|
||||
][
|
||||
How to use Beast's WebSocket interfaces in your applications.
|
||||
]]
|
||||
[[
|
||||
[link beast.example Examples]
|
||||
][
|
||||
Examples that illustrate the use of Beast in more complex applications.
|
||||
]]
|
||||
[[
|
||||
[link beast.design Design]
|
||||
][
|
||||
Design rationale, answers to review questions, and
|
||||
other library comparisons.
|
||||
]]
|
||||
[[
|
||||
[link beast.ref Reference]
|
||||
][
|
||||
Detailed class and function reference.
|
||||
]]
|
||||
[[
|
||||
[link beast.index Index]
|
||||
][
|
||||
Book-style text index of Beast documentation.
|
||||
]]
|
||||
]
|
||||
|
||||
[include overview.qbk]
|
||||
[include http.qbk]
|
||||
[include websocket.qbk]
|
||||
[include examples.qbk]
|
||||
[include design.qbk]
|
||||
|
||||
[section:ref Reference]
|
||||
[xinclude quickref.xml]
|
||||
[include types/Body.qbk]
|
||||
[include types/BufferSequence.qbk]
|
||||
[include types/DynamicBuffer.qbk]
|
||||
[include types/Field.qbk]
|
||||
[include types/FieldSequence.qbk]
|
||||
[include types/Parser.qbk]
|
||||
[include types/Reader.qbk]
|
||||
[include types/Streams.qbk]
|
||||
[include types/Writer.qbk]
|
||||
[include reference.qbk]
|
||||
[endsect]
|
||||
|
||||
[xinclude index.xml]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user