Compare commits
455
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dfc144eac | ||
|
|
7f19b6ea95 | ||
|
|
5b99feef7f | ||
|
|
c5510d6de0 | ||
|
|
f931734369 | ||
|
|
af792aeaba | ||
|
|
2af2135d82 | ||
|
|
f2b38d5634 | ||
|
|
1b9e40040c | ||
|
|
8893faff53 | ||
|
|
430fb82e76 | ||
|
|
01d4109ae8 | ||
|
|
4cc678ee93 | ||
|
|
acb53a379c | ||
|
|
c18f210ea3 | ||
|
|
f469b90bfc | ||
|
|
9d95501536 | ||
|
|
9351e73e90 | ||
|
|
b817c4499e | ||
|
|
7829de34a3 | ||
|
|
6973f02d1c | ||
|
|
31b75714bd | ||
|
|
257b5ac8e5 | ||
|
|
769fe89533 | ||
|
|
d670d69c6e | ||
|
|
2c843b9343 | ||
|
|
d076e38e00 | ||
|
|
4331de8a29 | ||
|
|
6dde40d96e | ||
|
|
dc313effa5 | ||
|
|
6300e090ad | ||
|
|
45dfcbec3c | ||
|
|
39dbe3a4e0 | ||
|
|
13f6da6f81 | ||
|
|
ac5d7ea5af | ||
|
|
6f7ecc59cd | ||
|
|
f7cea42c92 | ||
|
|
9efb12e59b | ||
|
|
bcd82bd6f4 | ||
|
|
8f042d95ec | ||
|
|
0278ba7895 | ||
|
|
41c37cfd93 | ||
|
|
4bea90f555 | ||
|
|
ce0300e6dc | ||
|
|
f20b2e573f | ||
|
|
650e4c336b | ||
|
|
31c761a0a9 | ||
|
|
681c2331a1 | ||
|
|
d55f28fe4b | ||
|
|
a8d4a9a66a | ||
|
|
875d420952 | ||
|
|
d792639c20 | ||
|
|
d4e15c89ad | ||
|
|
1d29d48bb8 | ||
|
|
09c5f6505e | ||
|
|
745ed4f77a | ||
|
|
854166364b | ||
|
|
1517d646f9 | ||
|
|
6bb36a28e7 | ||
|
|
96362774a3 | ||
|
|
0a879a6dc2 | ||
|
|
867b323af0 | ||
|
|
9dd99ead25 | ||
|
|
e3884e351b | ||
|
|
23e97bcc11 | ||
|
|
77e2e2fabb | ||
|
|
ef393f8aef | ||
|
|
99f4a66221 | ||
|
|
768472c0d4 | ||
|
|
1f061a920e | ||
|
|
07543a5dde | ||
|
|
ff9af5f8ca | ||
|
|
ffedb97372 | ||
|
|
e1f1c8873b | ||
|
|
922f1c35bc | ||
|
|
3c6c757d93 | ||
|
|
71f88c71d6 | ||
|
|
987f20feda | ||
|
|
27cea4e58f | ||
|
|
e7b2e69ecb | ||
|
|
bc868a244d | ||
|
|
77f1bf593d | ||
|
|
0a47a9a78c | ||
|
|
6578c5852e | ||
|
|
f9ff42c4b0 | ||
|
|
b9d4187e38 | ||
|
|
cbe887524e | ||
|
|
8a9b0beec0 | ||
|
|
18994f7318 | ||
|
|
3f65b2ff98 | ||
|
|
0ad2da2083 | ||
|
|
7404b506db | ||
|
|
b0efc72848 | ||
|
|
beac6e5bb6 | ||
|
|
f6c6552622 | ||
|
|
12700f2bc2 | ||
|
|
8cbe22266d | ||
|
|
c23639d394 | ||
|
|
d3ba1187de | ||
|
|
02b53d979e | ||
|
|
1d598558d8 | ||
|
|
ff3009ed26 | ||
|
|
d1f3eb9516 | ||
|
|
c0dc3c0e5f | ||
|
|
bfbfe2b052 | ||
|
|
1edc8deb01 | ||
|
|
571be82531 | ||
|
|
9ab9941f5e | ||
|
|
7dfe0d5815 | ||
|
|
088625eb53 | ||
|
|
575834b534 | ||
|
|
02dd5150fc | ||
|
|
2917d9262c | ||
|
|
fbc2966cda | ||
|
|
9de0a087b3 | ||
|
|
e9dd9cbbeb | ||
|
|
dc7431c37f | ||
|
|
5fe6f8338d | ||
|
|
19f7886ca4 | ||
|
|
802e34bd2c | ||
|
|
4100fc3ce7 | ||
|
|
6bda8f85d4 | ||
|
|
56cdbcd1da | ||
|
|
4c15d27bf4 | ||
|
|
b3b20ebb04 | ||
|
|
397f5c00bf | ||
|
|
82502a651a | ||
|
|
b46c0fb142 | ||
|
|
e1a0401d25 | ||
|
|
f23abe8e70 | ||
|
|
4309749dd9 | ||
|
|
f06b623767 | ||
|
|
9807283a6b | ||
|
|
83a66f4e3f | ||
|
|
2e7a902ef7 | ||
|
|
55b6cfae90 | ||
|
|
95bfe7c5ba | ||
|
|
f7aeeaaa30 | ||
|
|
55827fc825 | ||
|
|
d7a7112c8b | ||
|
|
d6c9905e80 | ||
|
|
0e66dbfde4 | ||
|
|
e8d25d22bc | ||
|
|
fe6d82e7a3 | ||
|
|
2f64f8d91a | ||
|
|
6da47743e8 | ||
|
|
6c242b205b | ||
|
|
2d2c62c887 | ||
|
|
71a10d83c8 | ||
|
|
fe0310b283 | ||
|
|
8a7beaa86a | ||
|
|
5d0c2f6341 | ||
|
|
122d4e2128 | ||
|
|
e203dbed45 | ||
|
|
ad2932bbff | ||
|
|
3560fa144a | ||
|
|
296f61b595 | ||
|
|
65cc3765a8 | ||
|
|
10be5eee14 | ||
|
|
c39777e4c1 | ||
|
|
af7149ae0a | ||
|
|
7c3eb3e6c2 | ||
|
|
e7ce038207 | ||
|
|
aaed2c4950 | ||
|
|
64fffeda9f | ||
|
|
7137105a81 | ||
|
|
beaa6e98cc | ||
|
|
79c2d09200 | ||
|
|
b92a2b7f61 | ||
|
|
1f73456e25 | ||
|
|
0ca2bae121 | ||
|
|
002d2d0007 | ||
|
|
d8b7cf3fdc | ||
|
|
b358e2cfe8 | ||
|
|
099fdbd4f1 | ||
|
|
19a3713b29 | ||
|
|
cd534ad18e | ||
|
|
7a46203beb | ||
|
|
497bc574da | ||
|
|
0bfb67ef11 | ||
|
|
762c013b93 | ||
|
|
9d237effc7 | ||
|
|
e2b7a4b9f1 | ||
|
|
e154d955ec | ||
|
|
2207348abb | ||
|
|
77495d4076 | ||
|
|
8752687bc8 | ||
|
|
0f3a36a630 | ||
|
|
a63f7d8b7b | ||
|
|
edb26d7721 | ||
|
|
b2d698d3ca | ||
|
|
770b32275c | ||
|
|
9d8eced9a1 | ||
|
|
fd0c62a8e4 | ||
|
|
1a68f4b907 | ||
|
|
c3dfb25181 | ||
|
|
5a5d8321bd | ||
|
|
b805689f9c | ||
|
|
7eedf25500 | ||
|
|
3ca53d0064 | ||
|
|
5e2fadd826 | ||
|
|
840bb6b59e | ||
|
|
fe00a84f7b | ||
|
|
337bf2fb0a | ||
|
|
c5b5492e5c | ||
|
|
af15537205 | ||
|
|
bdeb4ad680 | ||
|
|
faad2ec854 | ||
|
|
dc06049df9 | ||
|
|
3e53c74c3f | ||
|
|
a5a30e554e | ||
|
|
9c8762c961 | ||
|
|
797ce35c5a | ||
|
|
30da3a967b | ||
|
|
e1547bbde8 | ||
|
|
37f69cc19b | ||
|
|
93d9b5f820 | ||
|
|
98fd183210 | ||
|
|
093806f860 | ||
|
|
1da45144e9 | ||
|
|
5f56976290 | ||
|
|
40ed74a141 | ||
|
|
fbc9db2b5d | ||
|
|
f87c9d4360 | ||
|
|
99461184d3 | ||
|
|
9eff0db756 | ||
|
|
86325b1838 | ||
|
|
2d2312a1d7 | ||
|
|
afc28be004 | ||
|
|
b7c5a2e791 | ||
|
|
d36925ce7d | ||
|
|
92dfe9ef97 | ||
|
|
2ab02197fd | ||
|
|
89ac45e60a | ||
|
|
713a05679c | ||
|
|
0fecf023ef | ||
|
|
ffdf5f842b | ||
|
|
d425caea80 | ||
|
|
ce2c1d6e34 | ||
|
|
7ceeaa4f9c | ||
|
|
883410bb77 | ||
|
|
724974c758 | ||
|
|
1622cdde04 | ||
|
|
180543b9e6 | ||
|
|
7c08cae15b | ||
|
|
81e0c44b34 | ||
|
|
722a67a910 | ||
|
|
ba6320ba1c | ||
|
|
d9aa498310 | ||
|
|
47c46a2fbc | ||
|
|
9401cf00ce | ||
|
|
acedd4db49 | ||
|
|
91617150e1 | ||
|
|
c7463afb06 | ||
|
|
ba90910f6e | ||
|
|
bee2c03aa0 | ||
|
|
8e86ddcf5a | ||
|
|
fe85de763e | ||
|
|
ca97dd1fb8 | ||
|
|
c7ec97795a | ||
|
|
6ee7c368bb | ||
|
|
2000746be7 | ||
|
|
c84cc110aa | ||
|
|
09940a5c0b | ||
|
|
bb21e3cf95 | ||
|
|
5f3b92c9e4 | ||
|
|
14074666a7 | ||
|
|
bb431ee0d2 | ||
|
|
373f180638 | ||
|
|
021ac0599c | ||
|
|
e44463583b | ||
|
|
4393a2562b | ||
|
|
780f7683a4 | ||
|
|
8f359e6d35 | ||
|
|
ebb65c81e2 | ||
|
|
c7fda5a960 | ||
|
|
6d4514246f | ||
|
|
c2f2cb951b | ||
|
|
827f3678bb | ||
|
|
57cd0e286e | ||
|
|
87cb5036a4 | ||
|
|
f05f18b384 | ||
|
|
01963a23ea | ||
|
|
18036d2b01 | ||
|
|
17bd89bd80 | ||
|
|
f59f301b91 | ||
|
|
319507f4af | ||
|
|
06cdf43dcf | ||
|
|
f8f945433f | ||
|
|
a4f96cf0c3 | ||
|
|
7032e6940f | ||
|
|
bfd50e1ee1 | ||
|
|
415533f7e7 | ||
|
|
b87bfc068e | ||
|
|
dbb5f963c8 | ||
|
|
a1872c3790 | ||
|
|
8993b34b3d | ||
|
|
7ae83b9efd | ||
|
|
430c49d394 | ||
|
|
3e5404e1b1 | ||
|
|
8524a1a272 | ||
|
|
6f79894ea5 | ||
|
|
5e803b57f7 | ||
|
|
6a3e886f0b | ||
|
|
ac9351f9b3 | ||
|
|
00b5bed0d1 | ||
|
|
0f6e93a13e | ||
|
|
84efd0425a | ||
|
|
f4d3640870 | ||
|
|
6680606523 | ||
|
|
962a090300 | ||
|
|
4d51d990a4 | ||
|
|
362f828767 | ||
|
|
aa74d2b295 | ||
|
|
746389efab | ||
|
|
5894601291 | ||
|
|
17c9831449 | ||
|
|
45a612f44b | ||
|
|
2e3dfe7935 | ||
|
|
1b453e4679 | ||
|
|
72a3bd6e4e | ||
|
|
e73f4cdb10 | ||
|
|
86fe22334c | ||
|
|
71e6babd93 | ||
|
|
8b9fa5db72 | ||
|
|
57d8e5cb6b | ||
|
|
1e97f6c67c | ||
|
|
5c14c8e71e | ||
|
|
933533c623 | ||
|
|
4231edec53 | ||
|
|
4761938600 | ||
|
|
bf5f2852f9 | ||
|
|
e16972b153 | ||
|
|
3d0d28affc | ||
|
|
63cdaec0ba | ||
|
|
43a258efaa | ||
|
|
3d57d412f7 | ||
|
|
97e5e5fc7b | ||
|
|
ed39a6ab1a | ||
|
|
67804061ea | ||
|
|
b934e71ace | ||
|
|
96f7d0f3f2 | ||
|
|
013c2da7e8 | ||
|
|
aebdb26dc6 | ||
|
|
550365df6a | ||
|
|
e91d6f6a45 | ||
|
|
de6d15c9fc | ||
|
|
3035c8dc0a | ||
|
|
c175ec4f42 | ||
|
|
e6319f51a4 | ||
|
|
d17569fa87 | ||
|
|
f22c542a0d | ||
|
|
e9cb0b840f | ||
|
|
bd9c9767e1 | ||
|
|
80133d6d55 | ||
|
|
ac41f467ed | ||
|
|
cab72215aa | ||
|
|
12d240ff09 | ||
|
|
107d3c9bb6 | ||
|
|
49c07296dd | ||
|
|
8475f5f200 | ||
|
|
8ef8372af1 | ||
|
|
4a10d8ddfd | ||
|
|
f02c6f1c75 | ||
|
|
eb9ab6f70f | ||
|
|
a2d92c9a21 | ||
|
|
6e23a6ec3c | ||
|
|
c30d000359 | ||
|
|
ffe59ab078 | ||
|
|
e457467e9b | ||
|
|
485304b438 | ||
|
|
3bab403c1b | ||
|
|
c017331959 | ||
|
|
df828914c7 | ||
|
|
2c879ee797 | ||
|
|
241cf697f6 | ||
|
|
c6f579a52a | ||
|
|
3f08de3d9d | ||
|
|
a9f3821d99 | ||
|
|
2964acd6d7 | ||
|
|
d564189d4c | ||
|
|
ddca46f5d6 | ||
|
|
7f062297de | ||
|
|
1c199aca6e | ||
|
|
b8af39fd82 | ||
|
|
c94621bd29 | ||
|
|
b83b054c7e | ||
|
|
f6bcb86a6c | ||
|
|
28ac69c800 | ||
|
|
b866e4e0ca | ||
|
|
cdaf57cf7d | ||
|
|
2d49035a6d | ||
|
|
686b835f3d | ||
|
|
8f2c4264e1 | ||
|
|
5c608910d5 | ||
|
|
229698dbb0 | ||
|
|
6bd1bfd4f2 | ||
|
|
dbd0fc5372 | ||
|
|
7454bf68f6 | ||
|
|
5b7f4a8c14 | ||
|
|
9dd53d2e28 | ||
|
|
915f5c77a8 | ||
|
|
36cae596db | ||
|
|
407b931395 | ||
|
|
25b530b8a8 | ||
|
|
038a9aee58 | ||
|
|
9749c0a3d5 | ||
|
|
c7b1ddd9fa | ||
|
|
7a0d9c0238 | ||
|
|
cb08f07cb0 | ||
|
|
743cd7a713 | ||
|
|
88fe1bfb1c | ||
|
|
5fd65a934b | ||
|
|
bb1420fe06 | ||
|
|
0264b63fc3 | ||
|
|
256f8325e8 | ||
|
|
ce410a9428 | ||
|
|
573dedcb9d | ||
|
|
4f8b2bdc98 | ||
|
|
330d564ded | ||
|
|
161a5b169a | ||
|
|
7d36965149 | ||
|
|
de5684aef3 | ||
|
|
fd93ad89cb | ||
|
|
6d620aa1e8 | ||
|
|
816fe6410d | ||
|
|
f3c65ab609 | ||
|
|
c938d9fd15 | ||
|
|
0b764bdc62 | ||
|
|
86e2f364de | ||
|
|
54dd4c8084 | ||
|
|
cae30acf91 | ||
|
|
24c1804e40 | ||
|
|
8c6a360600 | ||
|
|
5c35535ffd | ||
|
|
3256c72d98 | ||
|
|
07ab02407f | ||
|
|
edc0057a03 | ||
|
|
9161119b4d | ||
|
|
7db60e3429 | ||
|
|
3c0b8a81b0 | ||
|
|
b812fd001b | ||
|
|
3a43986d9e | ||
|
|
64b1b52297 | ||
|
|
dc048ed021 | ||
|
|
60b167bcb7 | ||
|
|
e680ca1ef4 | ||
|
|
21d79e28c6 | ||
|
|
d25a254e81 | ||
|
|
3e144cfd75 | ||
|
|
096a7dbaa8 | ||
|
|
577591aaa1 | ||
|
|
a401a4448d | ||
|
|
ace76f54f9 | ||
|
|
1eaa1b790f |
No files matched your search
+2
-2
@@ -1,7 +1,7 @@
|
||||
# Lineendings
|
||||
*.sln eol=crlf
|
||||
*.vcproj eol=crlf
|
||||
*.vcxproj* eol=crfl
|
||||
*.vcxproj* eol=crlf
|
||||
|
||||
# Whitespace rules
|
||||
# strict (no trailing, no tabs)
|
||||
@@ -15,4 +15,4 @@
|
||||
*.txt whitespace=trailing-space,space-before-tab,cr-at-eol
|
||||
|
||||
# special files which must ignore whitespace
|
||||
*.patch whitespace=-trailing-space
|
||||
*.patch whitespace=-trailing-space
|
||||
+10
@@ -32,11 +32,15 @@ install_manifest.txt
|
||||
*.ncb
|
||||
*/Debug/*
|
||||
*/*/Debug/*
|
||||
bin/Debug
|
||||
*/Release/*
|
||||
*/*/Release/*
|
||||
*/RelWithDebInfo/*
|
||||
*/*/RelWithDebInfo/*
|
||||
|
||||
# explicitly allow this path with /debug/ in it
|
||||
!websocketpp/transport/debug/*
|
||||
|
||||
objs_shared/
|
||||
objs_static/
|
||||
|
||||
@@ -78,3 +82,9 @@ examples/wsperf/wsperf_client
|
||||
*.out
|
||||
|
||||
*.log
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.user
|
||||
install
|
||||
+5
-2
@@ -2,7 +2,7 @@ language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
before_install:
|
||||
- sudo apt-get install libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y
|
||||
- sudo apt-get install libboost-chrono1.48-dev libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y
|
||||
env:
|
||||
global:
|
||||
- BOOST_INCLUDES=/usr/include
|
||||
@@ -10,11 +10,14 @@ env:
|
||||
script: scons -j 2 && scons test
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- permessage-deflate
|
||||
- experimental
|
||||
- 0.3.x-cmake
|
||||
- develop
|
||||
notifications:
|
||||
recipients:
|
||||
- travis@zaphoyd.com
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_failure: always
|
||||
+19
-12
@@ -9,8 +9,8 @@ project (websocketpp)
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
set (WEBSOCKETPP_MAJOR_VERSION 0)
|
||||
set (WEBSOCKETPP_MINOR_VERSION 2)
|
||||
set (WEBSOCKETPP_PATCH_VERSION 99)
|
||||
set (WEBSOCKETPP_MINOR_VERSION 6)
|
||||
set (WEBSOCKETPP_PATCH_VERSION 0)
|
||||
set (WEBSOCKETPP_VERSION ${WEBSOCKETPP_MAJOR_VERSION}.${WEBSOCKETPP_MINOR_VERSION}.${WEBSOCKETPP_PATCH_VERSION})
|
||||
|
||||
set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files")
|
||||
@@ -70,7 +70,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
|
||||
############ Compiler specific setup
|
||||
|
||||
set (WEBSOCKETPP_PLATFORM_LIBS "")
|
||||
set (WEBSOCKETPP_PLATFORM_TSL_LIBS "")
|
||||
set (WEBSOCKETPP_PLATFORM_TLS_LIBS "")
|
||||
set (WEBSOCKETPP_BOOST_LIBS "")
|
||||
|
||||
# VC9 and C++11 reasoning
|
||||
@@ -87,12 +87,19 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
|
||||
|
||||
# C++11 defines
|
||||
if (ENABLE_CPP11)
|
||||
add_definitions (-D_WEBSOCKETPP_CPP11_STL_)
|
||||
if (MSVC)
|
||||
add_definitions (-D_WEBSOCKETPP_CPP11_FUNCTIONAL_)
|
||||
add_definitions (-D_WEBSOCKETPP_CPP11_SYSTEM_ERROR_)
|
||||
add_definitions (-D_WEBSOCKETPP_CPP11_RANDOM_DEVICE_)
|
||||
add_definitions (-D_WEBSOCKETPP_CPP11_MEMORY_)
|
||||
else()
|
||||
add_definitions (-D_WEBSOCKETPP_CPP11_STL_)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
# Visual studio
|
||||
if (MSVC)
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread regex)
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread)
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL /Gy /GF /Ox /Ob2 /Ot /Oi /MP /arch:SSE2 /fp:fast")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG /INCREMENTAL:NO /OPT:REF /OPT:ICF")
|
||||
add_definitions (/W3 /wd4996 /wd4995 /wd4355)
|
||||
@@ -104,9 +111,9 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
|
||||
# g++
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (WEBSOCKETPP_PLATFORM_LIBS pthread rt)
|
||||
set (WEBSOCKETPP_PLATFORM_TSL_LIBS ssl crypto)
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread regex)
|
||||
set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++0x")
|
||||
set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
if (NOT APPLE)
|
||||
add_definitions (-DNDEBUG -Wall -Wcast-align) # todo: should we use CMAKE_C_FLAGS for these?
|
||||
endif ()
|
||||
@@ -115,8 +122,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
|
||||
execute_process (COMMAND ${CMAKE_CXX_COMPILER} "-dumpversion" OUTPUT_VARIABLE GCC_VERSION)
|
||||
if ("${GCC_VERSION}" STRGREATER "4.4.0")
|
||||
message("* C++11 support partially enabled due to GCC version ${GCC_VERSION}")
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread regex)
|
||||
add_definitions (-D_WEBSOCKETPP_NO_CPP11_REGEX_)
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
@@ -127,8 +133,8 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
|
||||
else()
|
||||
set (WEBSOCKETPP_PLATFORM_LIBS pthread)
|
||||
endif()
|
||||
set (WEBSOCKETPP_PLATFORM_TSL_LIBS ssl crypto)
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread regex)
|
||||
set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
|
||||
set (WEBSOCKETPP_BOOST_LIBS system thread)
|
||||
set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++0x -stdlib=libc++") # todo: is libc++ really needed here?
|
||||
if (NOT APPLE)
|
||||
add_definitions (-DNDEBUG -Wall -Wno-padded) # todo: should we use CMAKE_C_FLAGS for these?
|
||||
@@ -205,6 +211,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
|
||||
message (FATAL_ERROR "Failed to find required dependency: boost")
|
||||
endif ()
|
||||
|
||||
find_package(OpenSSL)
|
||||
endif()
|
||||
|
||||
############ Add projects
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
Main Library:
|
||||
|
||||
Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,13 +13,133 @@ modification, are permitted provided that the following conditions are met:
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Bundled Libraries:
|
||||
|
||||
****** Base 64 Library (base64/base64.hpp) ******
|
||||
base64.hpp is a repackaging of the base64.cpp and base64.h files into a
|
||||
single header suitable for use as a header only library. This conversion was
|
||||
done by Peter Thorson (webmaster@zaphoyd.com) in 2012. All modifications to
|
||||
the code are redistributed under the same license as the original, which is
|
||||
listed below.
|
||||
|
||||
base64.cpp and base64.h
|
||||
|
||||
Copyright (C) 2004-2008 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
****** SHA1 Library (sha1/sha1.hpp) ******
|
||||
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the shallsha1
|
||||
library (http://code.google.com/p/smallsha1/) into a single header suitable for
|
||||
use as a header only library. This conversion was done by Peter Thorson
|
||||
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
|
||||
under the same license as the original, which is listed below.
|
||||
|
||||
Copyright (c) 2011, Micael Hildenborg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Micael Hildenborg nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
****** MD5 Library (common/md5.hpp) ******
|
||||
md5.hpp is a reformulation of the md5.h and md5.c code from
|
||||
http://www.opensource.apple.com/source/cups/cups-59/cups/md5.c to allow it to
|
||||
function as a component of a header only library. This conversion was done by
|
||||
Peter Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The
|
||||
changes are released under the same license as the original (listed below)
|
||||
|
||||
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
||||
|
||||
****** UTF8 Validation logic (utf8_validation.hpp) ******
|
||||
utf8_validation.hpp is adapted from code originally written by Bjoern Hoehrmann
|
||||
<bjoern@hoehrmann.de>. See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for
|
||||
details.
|
||||
|
||||
The original license:
|
||||
|
||||
Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -32,9 +32,7 @@ PROJECT_NAME = "websocketpp"
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
|
||||
PROJECT_NUMBER = "0.3.0-dev"
|
||||
|
||||
PROJECT_NUMBER = "0.6.0"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer
|
||||
@@ -670,7 +668,10 @@ WARN_LOGFILE =
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = websocketpp
|
||||
INPUT = websocketpp \
|
||||
readme.md \
|
||||
changelog.md \
|
||||
roadmap.md
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||
@@ -971,7 +972,7 @@ HTML_COLORSTYLE_GAMMA = 148
|
||||
# page will contain the date and time when the page was generated. Setting
|
||||
# this to NO can help when comparing the output of multiple runs.
|
||||
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_TIMESTAMP = NO
|
||||
|
||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||
# documentation will contain sections that can be hidden and shown after the
|
||||
|
||||
+44
-50
@@ -79,6 +79,8 @@ elif env['PLATFORM'] == 'posix':
|
||||
env.Append(CCFLAGS = ['-Wall'])
|
||||
#env['LINKFLAGS'] = ''
|
||||
elif env['PLATFORM'] == 'darwin':
|
||||
if not os.environ.has_key('CXX'):
|
||||
env['CXX'] = "clang++"
|
||||
if env.has_key('DEBUG'):
|
||||
env.Append(CCFLAGS = ['-g', '-O0'])
|
||||
else:
|
||||
@@ -98,11 +100,28 @@ else:
|
||||
if env['CXX'].startswith('g++'):
|
||||
#env.Append(CCFLAGS = ['-Wconversion'])
|
||||
env.Append(CCFLAGS = ['-Wcast-align'])
|
||||
env.Append(CCFLAGS = ['-Wshadow'])
|
||||
env.Append(CCFLAGS = ['-Wunused-parameter'])
|
||||
elif env['CXX'].startswith('clang++'):
|
||||
#env.Append(CCFLAGS = ['-Wcast-align'])
|
||||
#env.Append(CCFLAGS = ['-Wglobal-constructors'])
|
||||
#env.Append(CCFLAGS = ['-Wconversion'])
|
||||
env.Append(CCFLAGS = ['-Wno-padded'])
|
||||
env.Append(CCFLAGS = ['-Wshadow'])
|
||||
env.Append(CCFLAGS = ['-Wunused-parameter'])
|
||||
|
||||
env.Append(CCFLAGS = ['-Wsometimes-uninitialized'])
|
||||
env.Append(CCFLAGS = ['-Wuninitialized'])
|
||||
|
||||
#env.Append(CCFLAGS = ['-Weverything'])
|
||||
#env.Append(CCFLAGS = ['-Wno-documentation'])
|
||||
#env.Append(CCFLAGS = ['-Wno-weak-vtables'])
|
||||
#env.Append(CCFLAGS = ['-Wno-global-constructors'])
|
||||
#env.Append(CCFLAGS = ['-Wno-sign-conversion'])
|
||||
#env.Append(CCFLAGS = ['-Wno-exit-time-destructors'])
|
||||
|
||||
|
||||
|
||||
|
||||
# Wpadded
|
||||
# Wsign-conversion
|
||||
@@ -128,26 +147,21 @@ env.Append(CPPPATH = ['#'])
|
||||
|
||||
##### Set up C++11 environment
|
||||
polyfill_libs = [] # boost libraries used as drop in replacements for incomplete
|
||||
# C++11 STL implementations
|
||||
# C++11 STL implementations
|
||||
env_cpp11 = env.Clone ()
|
||||
|
||||
if env_cpp11['CXX'].startswith('g++'):
|
||||
# TODO: check g++ version
|
||||
|
||||
# g++ STL lacks support for <regex>
|
||||
|
||||
GCC_VERSION = commands.getoutput(env_cpp11['CXX'] + ' -dumpversion')
|
||||
|
||||
if GCC_VERSION > "4.4.0":
|
||||
print "C++11 build environment partially enabled"
|
||||
env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x'],TOOLSET = ['g++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_','_WEBSOCKETPP_NO_CPP11_REGEX_'])
|
||||
# libstdc++ does not yet support <regex>
|
||||
# boost regex is a drop in replacement
|
||||
polyfill_libs += boostlibs(['regex'],env_cpp11)
|
||||
env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x'],TOOLSET = ['g++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
|
||||
else:
|
||||
print "C++11 build environment is not supported on this version of G++"
|
||||
elif env_cpp11['CXX'].startswith('clang++'):
|
||||
print "C++11 build environment enabled"
|
||||
env.Append(CXXFLANGS = ['-stdlib=libc++'],LINKFLAGS=['-stdlib=libc++'])
|
||||
env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x','-stdlib=libc++'],LINKFLAGS = ['-stdlib=libc++'],TOOLSET = ['clang++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
|
||||
|
||||
# look for optional second boostroot compiled with clang's libc++ STL library
|
||||
@@ -163,21 +177,21 @@ else:
|
||||
print "C++11 build environment disabled"
|
||||
|
||||
# if the build system is known to allow the isystem modifier for library include
|
||||
# values then use it for the boost libraries. Otherwise just add them to the
|
||||
# values then use it for the boost libraries. Otherwise just add them to the
|
||||
# regular CPPPATH values.
|
||||
if env['CXX'].startswith('g++') or env['CXX'].startswith('clang'):
|
||||
env.Append(CPPFLAGS = '-isystem ' + env['BOOST_INCLUDES'])
|
||||
env.Append(CPPFLAGS = '-isystem ' + env['BOOST_INCLUDES'])
|
||||
else:
|
||||
env.Append(CPPPATH = [env['BOOST_INCLUDES']])
|
||||
env.Append(CPPPATH = [env['BOOST_INCLUDES']])
|
||||
env.Append(LIBPATH = [env['BOOST_LIBS']])
|
||||
|
||||
# if the build system is known to allow the isystem modifier for library include
|
||||
# values then use it for the boost libraries. Otherwise just add them to the
|
||||
# values then use it for the boost libraries. Otherwise just add them to the
|
||||
# regular CPPPATH values.
|
||||
if env_cpp11['CXX'].startswith('g++') or env_cpp11['CXX'].startswith('clang'):
|
||||
env_cpp11.Append(CPPFLAGS = '-isystem ' + env_cpp11['BOOST_INCLUDES'])
|
||||
env_cpp11.Append(CPPFLAGS = '-isystem ' + env_cpp11['BOOST_INCLUDES'])
|
||||
else:
|
||||
env_cpp11.Append(CPPPATH = [env_cpp11['BOOST_INCLUDES']])
|
||||
env_cpp11.Append(CPPPATH = [env_cpp11['BOOST_INCLUDES']])
|
||||
env_cpp11.Append(LIBPATH = [env_cpp11['BOOST_LIBS']])
|
||||
|
||||
releasedir = 'build/release/'
|
||||
@@ -209,28 +223,38 @@ if not env['PLATFORM'].startswith('win'):
|
||||
# Main test application
|
||||
#main = SConscript('#/examples/dev/SConscript',variant_dir = builddir + 'dev',duplicate = 0)
|
||||
|
||||
# testee_server
|
||||
testee_server = SConscript('#/examples/testee_server/SConscript',variant_dir = builddir + 'testee_server',duplicate = 0)
|
||||
|
||||
# echo_server
|
||||
echo_server = SConscript('#/examples/echo_server/SConscript',variant_dir = builddir + 'echo_server',duplicate = 0)
|
||||
|
||||
# echo_server_tls
|
||||
if not env['PLATFORM'].startswith('win'):
|
||||
if tls_build:
|
||||
echo_server_tls = SConscript('#/examples/echo_server_tls/SConscript',variant_dir = builddir + 'echo_server_tls',duplicate = 0)
|
||||
echo_server_both = SConscript('#/examples/echo_server_both/SConscript',variant_dir = builddir + 'echo_server_both',duplicate = 0)
|
||||
|
||||
# broadcast_server
|
||||
broadcast_server = SConscript('#/examples/broadcast_server/SConscript',variant_dir = builddir + 'broadcast_server',duplicate = 0)
|
||||
|
||||
# echo_client
|
||||
echo_client = SConscript('#/examples/echo_client/SConscript',variant_dir = builddir + 'echo_client',duplicate = 0)
|
||||
# testee_server
|
||||
testee_server = SConscript('#/examples/testee_server/SConscript',variant_dir = builddir + 'testee_server',duplicate = 0)
|
||||
|
||||
# testee_client
|
||||
testee_client = SConscript('#/examples/testee_client/SConscript',variant_dir = builddir + 'testee_client',duplicate = 0)
|
||||
|
||||
# utility_client
|
||||
utility_client = SConscript('#/examples/utility_client/SConscript',variant_dir = builddir + 'utility_client',duplicate = 0)
|
||||
|
||||
# debug_client
|
||||
debug_client = SConscript('#/examples/debug_client/SConscript',variant_dir = builddir + 'debug_client',duplicate = 0)
|
||||
|
||||
# debug_server
|
||||
debug_server = SConscript('#/examples/debug_server/SConscript',variant_dir = builddir + 'debug_server',duplicate = 0)
|
||||
|
||||
# subprotocol_server
|
||||
subprotocol_server = SConscript('#/examples/subprotocol_server/SConscript',variant_dir = builddir + 'subprotocol_server',duplicate = 0)
|
||||
|
||||
# telemetry_server
|
||||
telemetry_server = SConscript('#/examples/telemetry_server/SConscript',variant_dir = builddir + 'telemetry_server',duplicate = 0)
|
||||
|
||||
if not env['PLATFORM'].startswith('win'):
|
||||
# iostream_server
|
||||
iostream_server = SConscript('#/examples/iostream_server/SConscript',variant_dir = builddir + 'iostream_server',duplicate = 0)
|
||||
@@ -240,33 +264,3 @@ if not env['PLATFORM'].startswith('win'):
|
||||
|
||||
# print_server
|
||||
print_server = SConscript('#/examples/print_server/SConscript',variant_dir = builddir + 'print_server',duplicate = 0)
|
||||
|
||||
#
|
||||
#wsperf = SConscript('#/examples/wsperf/SConscript',
|
||||
# variant_dir = builddir + 'wsperf',
|
||||
# duplicate = 0)
|
||||
|
||||
#echo_server = SConscript('#/examples/echo_server/SConscript',
|
||||
# variant_dir = builddir + 'echo_server',
|
||||
# duplicate = 0)
|
||||
|
||||
#if tls_build:
|
||||
# echo_server_tls = SConscript('#/examples/echo_server_tls/SConscript',
|
||||
# variant_dir = builddir + 'echo_server_tls',
|
||||
# duplicate = 0)
|
||||
|
||||
#echo_client = SConscript('#/examples/echo_client/SConscript',
|
||||
# variant_dir = builddir + 'echo_client',
|
||||
# duplicate = 0)
|
||||
|
||||
#chat_client = SConscript('#/examples/chat_client/SConscript',
|
||||
# variant_dir = builddir + 'chat_client',
|
||||
# duplicate = 0)
|
||||
|
||||
#chat_server = SConscript('#/examples/chat_server/SConscript',
|
||||
# variant_dir = builddir + 'chat_server',
|
||||
# duplicate = 0)
|
||||
|
||||
#concurrent_server = SConscript('#/examples/concurrent_server/SConscript',
|
||||
# variant_dir = builddir + 'concurrent_server',
|
||||
# duplicate = 0)
|
||||
+279
-2
@@ -1,2 +1,279 @@
|
||||
0.3.0b1 - 2013-05-??
|
||||
- Initial Release
|
||||
HEAD
|
||||
|
||||
0.6.0
|
||||
- MINOR BREAKING TRANSPORT POLICY CHANGE: Custom transport policies will now be
|
||||
required to include a new method `void set_uri(uri_ptr u)`. An implementation
|
||||
is not required. The stub transport policy includes an example stub method
|
||||
that can be added to any existing custom transport policy to fulfill this
|
||||
requirement. This does not affect anyone using the bundled transports or
|
||||
configs.
|
||||
- MINOR BREAKING SOCKET POLICY CHANGE: Custom asio transport socket policies
|
||||
will now be required to include a new method `void set_uri(uri_ptr u)`. Like
|
||||
with the transport layer, an implementation is not required. This does not
|
||||
affect anyone using the bundled socket policies.
|
||||
- MINOR BREAKING DEPENDENCY CHANGE: When using Boost versions greater than or
|
||||
equal to 1.49 in C++03 mode, `libboost-chrono` is needed now instead of
|
||||
`libboost-date_time`. Users with C++11 compilers or using Boost versions 1.48
|
||||
and earlier are not affected. Note: This change affects the bundled unit test
|
||||
suite.
|
||||
- Feature: WebSocket++ Asio transport policy can now be used with the standalone
|
||||
version of Asio (1.8.0+) when a C++11 compiler and standard library are
|
||||
present. This means that it is possible now to use WebSocket++'s Asio
|
||||
transport entirely without Boost. Thank you Robert Seiler for proof of concept
|
||||
code that was used as a guide for this implementation. Fixes #324
|
||||
- Feature: Adds a vectored/scatter-gather write handler to the iostream
|
||||
transport.
|
||||
- Feature: Adds the ability to defer sending an HTTP response until sometime
|
||||
after the `http_handler` is run. This allows processing of long running http
|
||||
handlers to defer their response until it is ready without blocking the
|
||||
network thread. references #425
|
||||
- Improvement: `echo_server_tls` has been update to demonstrate how to configure
|
||||
it for Mozilla's recommended intermediate and modern TLS security profiles.
|
||||
- Improvement: `endpoint::set_timer` now uses a steady clock provided by
|
||||
`boost::chrono` or `std::chrono` where available instead of the non-monotonic
|
||||
system clock. Thank you breyed for reporting. fixes #241
|
||||
- Improvement: Outgoing TLS connections to servers using the SNI extension to
|
||||
choose a certificate will now work. Thank you moozzyk for reporting.
|
||||
Fixes #400
|
||||
- Improvement: Removes an unnecessary mutex lock in `get_con_from_hdl`.
|
||||
- Cleanup: Asio transport policy has been refactored to remove many Boost
|
||||
dependencies. On C++03 compilers the `boost::noncopyable` dependency has been
|
||||
removed and the `boost::date_time` dependency has been replaced with the newer
|
||||
`boost::chrono` when possible. On C++11 compilers the `boost::aligned_storage`
|
||||
and `boost::date_time` dependencies are gone, replaced with equivalent C++11
|
||||
standard library features.
|
||||
- Bug: Fixes a potential dangling pointer and inconsistent error message
|
||||
handling in `websocketpp::exception`. #432 Thank you Tom Swirly for the fix.
|
||||
|
||||
0.5.1 - 2015-02-27
|
||||
- Bug: Fixes an issue where some frame data was counted against the max header
|
||||
size limit, resulting in connections that included a lot of frame data
|
||||
immediately after the opening handshake to fail.
|
||||
- Bug: Fix a typo in the name of the set method for `max_http_body_size`. #406
|
||||
Thank you jplatte for reporting.
|
||||
|
||||
0.5.0 - 2015-01-22
|
||||
- BREAKING UTILITY CHANGE: Deprecated methods `http::parser::parse_headers`,
|
||||
`http::response::parse_complete`, and `http::request::parse_complete` have
|
||||
been removed.
|
||||
- Security: Disabled SSLv3 in example servers.
|
||||
- Feature: Adds basic support for accessing HTTP request bodies in the http
|
||||
handler. #181
|
||||
- Feature: Adds the ability to register a shutdown handler when using the
|
||||
iostream transport. This provides a clean interface for triggering the shut
|
||||
down of external sockets and other cleanup without hooking in to higher level
|
||||
WebSocket handlers.
|
||||
- Feature: Adds the ability to register a write handler when using the iostream
|
||||
transport. This handler can be used to handle transport output in place of
|
||||
registering an ostream to write to.
|
||||
- Feature: Adds a new logging policy that outputs to syslog. #386 Thank you Tom
|
||||
Hughes for submitting the initial version of this policy.
|
||||
- Improvement: Message payload logging now prints text for text messages rather
|
||||
than binary.
|
||||
- Improvement: Overhaul of handshake state machine. Should make it impossible
|
||||
for exceptions to bubble out of transport methods like `io_service::run`.
|
||||
- Improvement: Overhaul of handshake error reporting. Fail handler error codes
|
||||
will be more detailed and precise. Adds new [fail] and [http] logging channels
|
||||
that log failed websocket connections and successful HTTP connections
|
||||
respectively. A new aggregate channel package, `alevel::access_core`, allows
|
||||
enabling connect, disconnect, fail, and http together. Successful HTTP
|
||||
connections will no longer trigger a fail handler.
|
||||
- Improvement: Ability to terminate connection during an http handler to cleanly
|
||||
suppress the default outgoing HTTP response.
|
||||
- Documentation: Add Sending & Receiving Messages step to chapter one of the
|
||||
`utility_client` tutorial. Update `utility_client` example to match.
|
||||
- Cleanup: Removes unused files & STL includes. Adds required STL includes.
|
||||
Normalizes include order.
|
||||
- Bug: Fixes a fatal state error when a handshake response is completed
|
||||
immediately after that handshake times out. #389
|
||||
- Bug: MinGW fixes; C++11 feature detection, localtime use. #393 Thank you
|
||||
Schebb for reporting, code, and testing.
|
||||
- Bug: Fixes an issue where `websocketpp::exception::what()` could return an out
|
||||
of scope pointer. #397 Thank you fabioang for reporting.
|
||||
- Bug: Fixes an issue where endpoints were not reset properly after a call to
|
||||
`endpoint::listen` failed. #390 Thank you wyyqyl for reporting.
|
||||
|
||||
0.4.0 - 2014-11-04
|
||||
- BREAKING API CHANGE: All WebSocket++ methods now throw an exception of type
|
||||
`websocketpp::exception` which derives from `std::exception`. This normalizes
|
||||
all exception types under the standard exception hierarchy and allows
|
||||
WebSocket++ exceptions to be caught in the same statement as others. The error
|
||||
code that was previously thrown is wrapped in the exception object and can be
|
||||
accessed via the `websocketpp::exception::code()` method.
|
||||
- BREAKING API CHANGE: Custom logging policies have some new required
|
||||
constructors that take generic config settings rather than pointers to
|
||||
std::ostreams. This allows writing logging policies that do not involve the
|
||||
use of std::ostream. This does not affect anyone using the built in logging
|
||||
policies.
|
||||
- BREAKING UTILITY CHANGE: `websocketpp::lib::net::htonll` and
|
||||
`websocketpp::lib::net::ntohll` have been prefixed with an underscore to avoid
|
||||
conflicts with similarly named macros in some operating systems. If you are
|
||||
using the WebSocket++ provided 64 bit host/network byte order functions you
|
||||
will need to switch to the prefixed versions.
|
||||
- BREAKING UTILITY CHANGE: The signature of `base64_encode` has changed from
|
||||
`websocketpp::base64_encode(unsigned char const *, unsigned int)` to
|
||||
`websocketpp::base64_encode(unsigned char const *, size_t)`.
|
||||
- BREAKING UTILITY CHANGE: The signature of `sha1::calc` has changed from
|
||||
`websocketpp::sha1::calc(void const *, int, unsigned char *)` to
|
||||
`websocketpp::sha1::calc(void const *, size_t, unsigned char *)`
|
||||
- Feature: Adds incomplete `minimal_server` and `minimal_client` configs that
|
||||
can be used to build custom configs without pulling in the dependencies of
|
||||
`core` or `core_client`. These configs will offer a stable base config to
|
||||
future-proof custom configs.
|
||||
- Improvement: Core library no longer has std::iostream as a dependency.
|
||||
std::iostream is still required for the optional iostream logging policy and
|
||||
iostream transport.
|
||||
- Bug: C++11 Chrono support was being incorrectly detected by the `boost_config`
|
||||
header. Thank you Max Dmitrichenko for reporting and a patch.
|
||||
- Bug: use of `std::put_time` is now guarded by a unique flag rather than a
|
||||
chrono library flag. Thank you Max Dmitrichenko for reporting.
|
||||
- Bug: Fixes non-thread safe use of std::localtime. #347 #383
|
||||
- Compatibility: Adjust usage of std::min to be more compatible with systems
|
||||
that define a min(...) macro.
|
||||
- Compatibility: Removes unused parameters from all library, test, and example
|
||||
code. This assists with those developing with -Werror and -Wunused-parameter
|
||||
#376
|
||||
- Compatibility: Renames ntohll and htonll methods to avoid conflicts with
|
||||
platform specific macros. #358 #381, #382 Thank you logotype, unphased,
|
||||
svendjo
|
||||
- Cleanup: Removes unused functions, fixes variable shadow warnings, normalizes
|
||||
all whitespace in library, examples, and tests to 4 spaces. #376
|
||||
|
||||
0.3.0 - 2014-08-10
|
||||
- Feature: Adds `start_perpetual` and `stop_perpetual` methods to asio transport
|
||||
These may be used to replace manually managed `asio::io_service::work` objects
|
||||
- Feature: Allow setting pong and handshake timeouts at runtime.
|
||||
- Feature: Allows changing the listen backlog queue length.
|
||||
- Feature: Split tcp init into pre and post init.
|
||||
- Feature: Adds URI method to extract query string from URI. Thank you Banaan
|
||||
for code. #298
|
||||
- Feature: Adds a compile time switch to asio transport config to disable
|
||||
certain multithreading features (some locks, asio strands)
|
||||
- Feature: Adds the ability to pause reading on a connection. Paused connections
|
||||
will not read more data from their socket, allowing TCP flow control to work
|
||||
without blocking the main thread.
|
||||
- Feature: Adds the ability to specify whether or not to use the `SO_REUSEADDR`
|
||||
TCP socket option. The default for this value has been changed from `true` to
|
||||
`false`.
|
||||
- Feature: Adds the ability to specify a maximum message size.
|
||||
- Feature: Adds `close::status::get_string(...)` method to look up a human
|
||||
readable string given a close code value.
|
||||
- Feature: Adds `connection::read_all(...)` method to iostream transport as a
|
||||
convenience method for reading all data into the connection buffer without the
|
||||
end user needing to manually loop on `read_some`.
|
||||
- Improvement: Open, close, and pong timeouts can be disabled entirely by
|
||||
setting their duration to 0.
|
||||
- Improvement: Numerous performance improvements. Including: tuned default
|
||||
buffer sizes based on profiling, caching of handler binding for async
|
||||
reads/writes, non-malloc allocators for read/write handlers, disabling of a
|
||||
number of questionably useful range sanity checks in tight inner loops.
|
||||
- Improvement: Cleaned up the handling of TLS related errors. TLS errors will
|
||||
now be reported with more detail on the info channel rather than all being
|
||||
`tls_short_read` or `pass_through`. In addition, many cases where a TLS short
|
||||
read was in fact expected are no longer classified as errors. Expected TLS
|
||||
short reads and quasi-expected socket shutdown related errors will no longer
|
||||
be reported as unclean WebSocket shutdowns to the application. Information
|
||||
about them will remain in the info error channel for debugging purposes.
|
||||
- Improvement: `start_accept` and `listen` errors are now reported to the caller
|
||||
either via an exception or an ec parameter.
|
||||
- Improvement: Outgoing writes are now batched for improved message throughput
|
||||
and reduced system call and TCP frame overhead.
|
||||
- Bug: Fix some cases of calls to empty lib::function objects.
|
||||
- Bug: Fix memory leak of connection objects due to cached handlers holding on to
|
||||
reference counted pointers. #310 Thank you otaras for reporting.
|
||||
- Bug: Fix issue with const endpoint accessors (such as `get_user_agent`) not
|
||||
compiling due to non-const mutex use. #292 Thank you logofive for reporting.
|
||||
- Bug: Fix handler allocation crash with multithreaded `io_service`.
|
||||
- Bug: Fixes incorrect whitespace handling in header parsing. #301 Thank you
|
||||
Wolfram Schroers for reporting
|
||||
- Bug: Fix a crash when parsing empty HTTP headers. Thank you Thingol for
|
||||
reporting.
|
||||
- Bug: Fix a crash following use of the `stop_listening` function. Thank you
|
||||
Thingol for reporting.
|
||||
- Bug: Fix use of variable names that shadow function parameters. The library
|
||||
should compile cleanly with -Wshadow now. Thank you giszo for reporting. #318
|
||||
- Bug: Fix an issue where `set_open_handshake_timeout` was ignored by server
|
||||
code. Thank you Robin Rowe for reporting.
|
||||
- Bug: Fix an issue where custom timeout values weren't being propagated from
|
||||
endpoints to new connections.
|
||||
- Bug: Fix a number of memory leaks related to server connection failures. #323
|
||||
#333 #334 #335 Thank you droppy and aydany for reporting and patches.
|
||||
reporting.
|
||||
- Compatibility: Fix compile time conflict with Visual Studio's MIN/MAX macros.
|
||||
Thank you Robin Rowe for reporting.
|
||||
- Documentation: Examples and test suite build system now defaults to clang on
|
||||
OS X
|
||||
|
||||
0.3.0-alpha4 - 2013-10-11
|
||||
- HTTP requests ending normally are no longer logged as errors. Thank you Banaan
|
||||
for reporting. #294
|
||||
- Eliminates spurious expired timers in certain error conditions. Thank you
|
||||
Banaan for reporting. #295
|
||||
- Consolidates all bundled library licenses into the COPYING file. #294
|
||||
- Updates bundled sha1 library to one with a cleaner interface and more
|
||||
straight-forward license. Thank you lotodore for reporting and Evgeni Golov
|
||||
for reviewing. #294
|
||||
- Re-introduces strands to asio transport, allowing `io_service` thread pools to
|
||||
be used (with some limitations).
|
||||
- Removes endpoint code that kept track of a connection list that was never used
|
||||
anywhere. Removes a lock and reduces connection creation/deletion complexity
|
||||
from O(log n) to O(1) in the number of connections.
|
||||
- A number of internal changes to transport APIs
|
||||
- Deprecates iostream transport `readsome` in favor of `read_some` which is more
|
||||
consistent with the naming of the rest of the library.
|
||||
- Adds preliminary signaling to iostream transport of eof and fatal transport
|
||||
errors
|
||||
- Updates transport code to use shared pointers rather than raw pointers to
|
||||
prevent asio from retaining pointers to connection methods after the
|
||||
connection goes out of scope. #293 Thank you otaras for reporting.
|
||||
- Fixes an issue where custom headers couldn't be set for client connections
|
||||
Thank you Jerry Win and Wolfram Schroers for reporting.
|
||||
- Fixes a compile error on visual studio when using interrupts. Thank you Javier
|
||||
Rey Neira for reporting this.
|
||||
- Adds new 1012 and 1013 close codes per IANA registry
|
||||
- Add `set_remote_endpoint` method to iostream transport.
|
||||
- Add `set_secure` method to iostream transport.
|
||||
- Fix typo in .gitattributes file. Thank you jstarasov for reporting this. #280
|
||||
- Add missing locale include. Thank you Toninoso for reporting this. #281
|
||||
- Refactors `asio_transport` endpoint and adds full documentation and exception
|
||||
free varients of all methods.
|
||||
- Removes `asio_transport` endpoint method cancel(). Use `stop_listen()` instead
|
||||
- Wrap internal `io_service` `run_one()` method
|
||||
- Suppress error when trying to shut down a connection that was already closed
|
||||
|
||||
0.3.0-alpha3 - 2013-07-16
|
||||
- Minor refactor to bundled sha1 library
|
||||
- HTTP header comparisons are now case insensitive. #220, #275
|
||||
- Refactors URI to be exception free and not use regular expressions. This
|
||||
eliminates the dependency on boost or C++11 regex libraries allowing native
|
||||
C++11 usage on GCC 4.4 and higher and significantly reduces staticly built
|
||||
binary sizes.
|
||||
- Updates handling of Server and User-Agent headers to better handle custom
|
||||
settings and allow suppression of these headers for security purposes.
|
||||
- Fix issue where pong timeout handler always fired. Thank you Steven Klassen
|
||||
for reporting this bug.
|
||||
- Add ping and pong endpoint wrapper methods
|
||||
- Add `get_request()` pass through method to connection to allow calling methods
|
||||
specific to the HTTP policy in use.
|
||||
- Fix issue compile error with `WEBSOCKETPP_STRICT_MASKING` enabled and another
|
||||
issue where `WEBSOCKETPP_STRICT_MASKING` was not applied to incoming messages.
|
||||
Thank you Petter Norby for reporting and testing these bugs. #264
|
||||
- Add additional macro guards for use with boost_config. Thank you breyed
|
||||
for testing and code. #261
|
||||
|
||||
0.3.0-alpha2 - 2013-06-09
|
||||
- Fix a regression that caused servers being sent two close frames in a row
|
||||
to end a connection uncleanly. #259
|
||||
- Fix a regression that caused spurious frames following a legitimate close
|
||||
frames to erroneously trigger handlers. #258
|
||||
- Change default HTTP response error code when no http_handler is defined from
|
||||
500/Internal Server Error to 426/Upgrade Required
|
||||
- Remove timezone from logger timestamp to work around issues with the Windows
|
||||
implementation of strftime. Thank you breyed for testing and code. #257
|
||||
- Switch integer literals to char literals to improve VCPP compatibility.
|
||||
Thank you breyed for testing and code. #257
|
||||
- Add MSVCPP warning suppression for the bundled SHA1 library. Thank you breyed
|
||||
for testing and code. #257
|
||||
|
||||
0.3.0-alpha1 - 2013-06-09
|
||||
- Initial Release
|
||||
@@ -72,3 +72,7 @@ endmacro ()
|
||||
macro (link_boost)
|
||||
target_link_libraries (${TARGET_NAME} ${Boost_LIBRARIES})
|
||||
endmacro ()
|
||||
|
||||
macro (link_openssl)
|
||||
target_link_libraries (${TARGET_NAME} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
|
||||
endmacro ()
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
|
||||
void run(uint16_t port) {
|
||||
m_server.listen(port);
|
||||
m_server.start_accept();
|
||||
m_server.start_accept();
|
||||
m_server.run();
|
||||
}
|
||||
private:
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
void run(uint16_t port) {
|
||||
m_server.listen(port);
|
||||
m_server.start_accept();
|
||||
m_server.start_accept();
|
||||
m_server.run();
|
||||
}
|
||||
private:
|
||||
|
||||
@@ -20,55 +20,55 @@ class print_server {
|
||||
public:
|
||||
print_server() : m_next_sessionid(1) {
|
||||
m_server.init_asio();
|
||||
|
||||
|
||||
m_server.set_open_handler(bind(&print_server::on_open,this,::_1));
|
||||
m_server.set_close_handler(bind(&print_server::on_close,this,::_1));
|
||||
m_server.set_message_handler(bind(&print_server::on_message,this,::_1,::_2));
|
||||
}
|
||||
|
||||
|
||||
void on_open(connection_hdl hdl) {
|
||||
connection_data data;
|
||||
|
||||
|
||||
data.sessionid = m_next_sessionid++;
|
||||
data.name = "";
|
||||
|
||||
|
||||
m_connections[hdl] = data;
|
||||
}
|
||||
|
||||
|
||||
void on_close(connection_hdl hdl) {
|
||||
connection_data& data = get_data_from_hdl(hdl);
|
||||
|
||||
std::cout << "Closing connection " << data.name
|
||||
|
||||
std::cout << "Closing connection " << data.name
|
||||
<< " with sessionid " << data.sessionid << std::endl;
|
||||
|
||||
|
||||
m_connections.erase(hdl);
|
||||
}
|
||||
|
||||
|
||||
void on_message(connection_hdl hdl, server::message_ptr msg) {
|
||||
connection_data& data = get_data_from_hdl(hdl);
|
||||
|
||||
|
||||
if (data.name == "") {
|
||||
data.name = msg->get_payload();
|
||||
std::cout << "Setting name of connection with sessionid "
|
||||
std::cout << "Setting name of connection with sessionid "
|
||||
<< data.sessionid << " to " << data.name << std::endl;
|
||||
} else {
|
||||
std::cout << "Got a message from connection " << data.name
|
||||
std::cout << "Got a message from connection " << data.name
|
||||
<< " with sessionid " << data.sessionid << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
connection_data& get_data_from_hdl(connection_hdl hdl) {
|
||||
auto it = m_connections.find(hdl);
|
||||
|
||||
|
||||
if (it == m_connections.end()) {
|
||||
// this connection is not in the list. This really shouldn't happen
|
||||
// and probably means something else is wrong.
|
||||
throw std::invalid_argument("No data available for session");
|
||||
}
|
||||
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
void run(uint16_t port) {
|
||||
m_server.listen(port);
|
||||
m_server.start_accept();
|
||||
@@ -85,4 +85,4 @@ private:
|
||||
int main() {
|
||||
print_server server;
|
||||
server.run(9002);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('broadcast_server', ["broadcast_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','thread','regex'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system','thread'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('broadcast_server', ["broadcast_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <websocketpp/server.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
/*#include <boost/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
@@ -34,44 +35,41 @@ enum action_type {
|
||||
|
||||
struct action {
|
||||
action(action_type t, connection_hdl h) : type(t), hdl(h) {}
|
||||
action(action_type t, server::message_ptr m) : type(t), msg(m) {}
|
||||
|
||||
action(action_type t, connection_hdl h, server::message_ptr m)
|
||||
: type(t), hdl(h), msg(m) {}
|
||||
|
||||
action_type type;
|
||||
websocketpp::connection_hdl hdl;
|
||||
server::message_ptr msg;
|
||||
};
|
||||
|
||||
|
||||
class broadcast_server {
|
||||
public:
|
||||
broadcast_server() {
|
||||
// Initialize Asio Transport
|
||||
m_server.init_asio();
|
||||
|
||||
|
||||
// Register handler callbacks
|
||||
m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1));
|
||||
m_server.set_close_handler(bind(&broadcast_server::on_close,this,::_1));
|
||||
m_server.set_message_handler(bind(&broadcast_server::on_message,this,::_1,::_2));
|
||||
}
|
||||
|
||||
|
||||
void run(uint16_t port) {
|
||||
// listen on specified port
|
||||
m_server.listen(port);
|
||||
|
||||
|
||||
// Start the server accept loop
|
||||
m_server.start_accept();
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
m_server.start_accept();
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
try {
|
||||
m_server.run();
|
||||
} catch (const std::exception & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void on_open(connection_hdl hdl) {
|
||||
unique_lock<mutex> lock(m_action_lock);
|
||||
//std::cout << "on_open" << std::endl;
|
||||
@@ -79,7 +77,7 @@ public:
|
||||
lock.unlock();
|
||||
m_action_cond.notify_one();
|
||||
}
|
||||
|
||||
|
||||
void on_close(connection_hdl hdl) {
|
||||
unique_lock<mutex> lock(m_action_lock);
|
||||
//std::cout << "on_close" << std::endl;
|
||||
@@ -87,38 +85,38 @@ public:
|
||||
lock.unlock();
|
||||
m_action_cond.notify_one();
|
||||
}
|
||||
|
||||
|
||||
void on_message(connection_hdl hdl, server::message_ptr msg) {
|
||||
// queue message up for sending by processing thread
|
||||
unique_lock<mutex> lock(m_action_lock);
|
||||
//std::cout << "on_message" << std::endl;
|
||||
m_actions.push(action(MESSAGE,msg));
|
||||
m_actions.push(action(MESSAGE,hdl,msg));
|
||||
lock.unlock();
|
||||
m_action_cond.notify_one();
|
||||
}
|
||||
|
||||
|
||||
void process_messages() {
|
||||
while(1) {
|
||||
unique_lock<mutex> lock(m_action_lock);
|
||||
|
||||
|
||||
while(m_actions.empty()) {
|
||||
m_action_cond.wait(lock);
|
||||
}
|
||||
|
||||
|
||||
action a = m_actions.front();
|
||||
m_actions.pop();
|
||||
|
||||
|
||||
lock.unlock();
|
||||
|
||||
|
||||
if (a.type == SUBSCRIBE) {
|
||||
unique_lock<mutex> lock(m_connection_lock);
|
||||
unique_lock<mutex> con_lock(m_connection_lock);
|
||||
m_connections.insert(a.hdl);
|
||||
} else if (a.type == UNSUBSCRIBE) {
|
||||
unique_lock<mutex> lock(m_connection_lock);
|
||||
unique_lock<mutex> con_lock(m_connection_lock);
|
||||
m_connections.erase(a.hdl);
|
||||
} else if (a.type == MESSAGE) {
|
||||
unique_lock<mutex> lock(m_connection_lock);
|
||||
|
||||
unique_lock<mutex> con_lock(m_connection_lock);
|
||||
|
||||
con_list::iterator it;
|
||||
for (it = m_connections.begin(); it != m_connections.end(); ++it) {
|
||||
m_server.send(*it,a.msg);
|
||||
@@ -129,30 +127,30 @@ public:
|
||||
}
|
||||
}
|
||||
private:
|
||||
typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
|
||||
|
||||
typedef std::set<connection_hdl,std::owner_less<connection_hdl> > con_list;
|
||||
|
||||
server m_server;
|
||||
con_list m_connections;
|
||||
std::queue<action> m_actions;
|
||||
|
||||
|
||||
mutex m_action_lock;
|
||||
mutex m_connection_lock;
|
||||
condition_variable m_action_cond;
|
||||
};
|
||||
|
||||
int main() {
|
||||
try {
|
||||
broadcast_server server;
|
||||
|
||||
// Start a thread to run the processing loop
|
||||
thread t(bind(&broadcast_server::process_messages,&server));
|
||||
|
||||
// Run the asio loop with the main thread
|
||||
server.run(9002);
|
||||
|
||||
t.join();
|
||||
|
||||
} catch (std::exception & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
try {
|
||||
broadcast_server server_instance;
|
||||
|
||||
// Start a thread to run the processing loop
|
||||
thread t(bind(&broadcast_server::process_messages,&server_instance));
|
||||
|
||||
// Run the asio loop with the main thread
|
||||
server_instance.run(9002);
|
||||
|
||||
t.join();
|
||||
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
## Debug client example
|
||||
##
|
||||
|
||||
Import('env')
|
||||
Import('env_cpp11')
|
||||
Import('boostlibs')
|
||||
Import('platform_libs')
|
||||
Import('polyfill_libs')
|
||||
Import('tls_libs')
|
||||
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
prgs = []
|
||||
|
||||
# if a C++11 environment is available build using that, otherwise use boost
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
prgs += env_cpp11.Program('debug_client', ["debug_client.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
prgs += env.Program('debug_client', ["debug_client.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** ====== WARNING ========
|
||||
* This example is presently used as a scratch space. It may or may not be broken
|
||||
* at any given time.
|
||||
*/
|
||||
|
||||
#include <websocketpp/config/asio_client.hpp>
|
||||
|
||||
#include <websocketpp/client.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
|
||||
// pull out the type of messages sent by our config
|
||||
typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
typedef client::connection_ptr connection_ptr;
|
||||
|
||||
|
||||
|
||||
class perftest {
|
||||
public:
|
||||
typedef perftest type;
|
||||
typedef std::chrono::duration<int,std::micro> dur_type;
|
||||
|
||||
perftest () {
|
||||
m_endpoint.set_access_channels(websocketpp::log::alevel::all);
|
||||
m_endpoint.set_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
// Initialize ASIO
|
||||
m_endpoint.init_asio();
|
||||
|
||||
// Register our handlers
|
||||
m_endpoint.set_socket_init_handler(bind(&type::on_socket_init,this,::_1));
|
||||
//m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1));
|
||||
m_endpoint.set_message_handler(bind(&type::on_message,this,::_1,::_2));
|
||||
m_endpoint.set_open_handler(bind(&type::on_open,this,::_1));
|
||||
m_endpoint.set_close_handler(bind(&type::on_close,this,::_1));
|
||||
m_endpoint.set_fail_handler(bind(&type::on_fail,this,::_1));
|
||||
}
|
||||
|
||||
void start(std::string uri) {
|
||||
websocketpp::lib::error_code ec;
|
||||
client::connection_ptr con = m_endpoint.get_connection(uri, ec);
|
||||
|
||||
if (ec) {
|
||||
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ec.message());
|
||||
}
|
||||
|
||||
//con->set_proxy("http://humupdates.uchicago.edu:8443");
|
||||
|
||||
m_endpoint.connect(con);
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
m_start = std::chrono::high_resolution_clock::now();
|
||||
m_endpoint.run();
|
||||
}
|
||||
|
||||
void on_socket_init(websocketpp::connection_hdl) {
|
||||
m_socket_init = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
context_ptr on_tls_init(websocketpp::connection_hdl) {
|
||||
m_tls_init = std::chrono::high_resolution_clock::now();
|
||||
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
|
||||
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void on_fail(websocketpp::connection_hdl hdl) {
|
||||
client::connection_ptr con = m_endpoint.get_con_from_hdl(hdl);
|
||||
|
||||
std::cout << "Fail handler" << std::endl;
|
||||
std::cout << con->get_state() << std::endl;
|
||||
std::cout << con->get_local_close_code() << std::endl;
|
||||
std::cout << con->get_local_close_reason() << std::endl;
|
||||
std::cout << con->get_remote_close_code() << std::endl;
|
||||
std::cout << con->get_remote_close_reason() << std::endl;
|
||||
std::cout << con->get_ec() << " - " << con->get_ec().message() << std::endl;
|
||||
}
|
||||
|
||||
void on_open(websocketpp::connection_hdl hdl) {
|
||||
m_open = std::chrono::high_resolution_clock::now();
|
||||
m_endpoint.send(hdl, "", websocketpp::frame::opcode::text);
|
||||
}
|
||||
void on_message(websocketpp::connection_hdl hdl, message_ptr) {
|
||||
m_message = std::chrono::high_resolution_clock::now();
|
||||
m_endpoint.close(hdl,websocketpp::close::status::going_away,"");
|
||||
}
|
||||
void on_close(websocketpp::connection_hdl) {
|
||||
m_close = std::chrono::high_resolution_clock::now();
|
||||
|
||||
std::cout << "Socket Init: " << std::chrono::duration_cast<dur_type>(m_socket_init-m_start).count() << std::endl;
|
||||
std::cout << "TLS Init: " << std::chrono::duration_cast<dur_type>(m_tls_init-m_start).count() << std::endl;
|
||||
std::cout << "Open: " << std::chrono::duration_cast<dur_type>(m_open-m_start).count() << std::endl;
|
||||
std::cout << "Message: " << std::chrono::duration_cast<dur_type>(m_message-m_start).count() << std::endl;
|
||||
std::cout << "Close: " << std::chrono::duration_cast<dur_type>(m_close-m_start).count() << std::endl;
|
||||
}
|
||||
private:
|
||||
client m_endpoint;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point m_start;
|
||||
std::chrono::high_resolution_clock::time_point m_socket_init;
|
||||
std::chrono::high_resolution_clock::time_point m_tls_init;
|
||||
std::chrono::high_resolution_clock::time_point m_open;
|
||||
std::chrono::high_resolution_clock::time_point m_message;
|
||||
std::chrono::high_resolution_clock::time_point m_close;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::string uri = "wss://echo.websocket.org";
|
||||
|
||||
if (argc == 2) {
|
||||
uri = argv[1];
|
||||
}
|
||||
|
||||
try {
|
||||
perftest endpoint;
|
||||
endpoint.start(uri);
|
||||
} catch (const std::exception & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
init_target (echo_client)
|
||||
init_target (debug_server)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
final_target ()
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
## Debug server example
|
||||
##
|
||||
|
||||
Import('env')
|
||||
Import('env_cpp11')
|
||||
Import('boostlibs')
|
||||
Import('platform_libs')
|
||||
Import('polyfill_libs')
|
||||
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
prgs = []
|
||||
|
||||
# if a C++11 environment is available build using that, otherwise use boost
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('debug_server', ["debug_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('debug_server', ["debug_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** ====== WARNING ========
|
||||
* This example is presently used as a scratch space. It may or may not be broken
|
||||
* at any given time.
|
||||
*/
|
||||
|
||||
#include <websocketpp/config/debug_asio_no_tls.hpp>
|
||||
|
||||
// Custom logger
|
||||
#include <websocketpp/logger/syslog.hpp>
|
||||
|
||||
#include <websocketpp/server.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////// Custom Config for debugging custom policies //////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct debug_custom : public websocketpp::config::debug_asio {
|
||||
typedef debug_custom type;
|
||||
typedef debug_asio base;
|
||||
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
typedef base::response_type response_type;
|
||||
|
||||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
/// Custom Logging policies
|
||||
/*typedef websocketpp::log::syslog<concurrency_type,
|
||||
websocketpp::log::elevel> elog_type;
|
||||
typedef websocketpp::log::syslog<concurrency_type,
|
||||
websocketpp::log::alevel> alog_type;
|
||||
*/
|
||||
typedef base::alog_type alog_type;
|
||||
typedef base::elog_type elog_type;
|
||||
|
||||
typedef base::rng_type rng_type;
|
||||
|
||||
struct transport_config : public base::transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
typedef websocketpp::transport::asio::basic_socket::endpoint
|
||||
socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
static const long timeout_open_handshake = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef websocketpp::server<debug_custom> server;
|
||||
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
|
||||
// pull out the type of messages sent by our config
|
||||
typedef server::message_ptr message_ptr;
|
||||
|
||||
bool validate(server *, websocketpp::connection_hdl) {
|
||||
//sleep(6);
|
||||
return true;
|
||||
}
|
||||
|
||||
void on_http(server* s, websocketpp::connection_hdl hdl) {
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
std::string res = con->get_request_body();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "got HTTP request with " << res.size() << " bytes of body data.";
|
||||
|
||||
con->set_body(ss.str());
|
||||
con->set_status(websocketpp::http::status_code::ok);
|
||||
}
|
||||
|
||||
void on_fail(server* s, websocketpp::connection_hdl hdl) {
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
std::cout << "Fail handler: " << con->get_ec() << " " << con->get_ec().message() << std::endl;
|
||||
}
|
||||
|
||||
void on_close(websocketpp::connection_hdl) {
|
||||
std::cout << "Close handler" << std::endl;
|
||||
}
|
||||
|
||||
// Define a callback to handle incoming messages
|
||||
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||
<< " and message: " << msg->get_payload()
|
||||
<< std::endl;
|
||||
|
||||
try {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
} catch (const websocketpp::lib::error_code& e) {
|
||||
std::cout << "Echo failed because: " << e
|
||||
<< "(" << e.message() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a server endpoint
|
||||
server echo_server;
|
||||
|
||||
try {
|
||||
// Set logging settings
|
||||
echo_server.set_access_channels(websocketpp::log::alevel::all);
|
||||
echo_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||
|
||||
// Initialize ASIO
|
||||
echo_server.init_asio();
|
||||
echo_server.set_reuse_addr(true);
|
||||
|
||||
// Register our message handler
|
||||
echo_server.set_message_handler(bind(&on_message,&echo_server,::_1,::_2));
|
||||
|
||||
echo_server.set_http_handler(bind(&on_http,&echo_server,::_1));
|
||||
echo_server.set_fail_handler(bind(&on_fail,&echo_server,::_1));
|
||||
echo_server.set_close_handler(&on_close);
|
||||
|
||||
echo_server.set_validate_handler(bind(&validate,&echo_server,::_1));
|
||||
|
||||
// Listen on port 9012
|
||||
echo_server.listen(9012);
|
||||
|
||||
// Start the server accept loop
|
||||
echo_server.start_accept();
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
echo_server.run();
|
||||
} catch (const std::exception & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
}
|
||||
+170
-170
@@ -1,5 +1,5 @@
|
||||
//#ifndef _WEBSOCKETPP_CPP11_STL_
|
||||
// #define _WEBSOCKETPP_CPP11_STL_
|
||||
// #define _WEBSOCKETPP_CPP11_STL_
|
||||
//#endif
|
||||
|
||||
#include <random>
|
||||
@@ -24,177 +24,177 @@
|
||||
typedef websocketpp::server<websocketpp::config::core> server;
|
||||
|
||||
/*class handler : public server::handler {
|
||||
bool validate(connection_ptr con) {
|
||||
std::cout << "handler validate" << std::endl;
|
||||
if (con->get_origin() != "http://www.example.com") {
|
||||
con->set_status(websocketpp::http::status_code::FORBIDDEN);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void http(connection_ptr con) {
|
||||
std::cout << "handler http" << std::endl;
|
||||
}
|
||||
|
||||
void on_load(connection_ptr con, ptr old_handler) {
|
||||
std::cout << "handler on_load" << std::endl;
|
||||
}
|
||||
void on_unload(connection_ptr con, ptr new_handler) {
|
||||
std::cout << "handler on_unload" << std::endl;
|
||||
}
|
||||
|
||||
void on_open(connection_ptr con) {
|
||||
std::cout << "handler on_open" << std::endl;
|
||||
}
|
||||
void on_fail(connection_ptr con) {
|
||||
std::cout << "handler on_fail" << std::endl;
|
||||
}
|
||||
|
||||
void on_message(connection_ptr con, message_ptr msg) {
|
||||
std::cout << "handler on_message" << std::endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void on_close(connection_ptr con) {
|
||||
std::cout << "handler on_close" << std::endl;
|
||||
}
|
||||
bool validate(connection_ptr con) {
|
||||
std::cout << "handler validate" << std::endl;
|
||||
if (con->get_origin() != "http://www.example.com") {
|
||||
con->set_status(websocketpp::http::status_code::FORBIDDEN);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void http(connection_ptr con) {
|
||||
std::cout << "handler http" << std::endl;
|
||||
}
|
||||
|
||||
void on_load(connection_ptr con, ptr old_handler) {
|
||||
std::cout << "handler on_load" << std::endl;
|
||||
}
|
||||
void on_unload(connection_ptr con, ptr new_handler) {
|
||||
std::cout << "handler on_unload" << std::endl;
|
||||
}
|
||||
|
||||
void on_open(connection_ptr con) {
|
||||
std::cout << "handler on_open" << std::endl;
|
||||
}
|
||||
void on_fail(connection_ptr con) {
|
||||
std::cout << "handler on_fail" << std::endl;
|
||||
}
|
||||
|
||||
void on_message(connection_ptr con, message_ptr msg) {
|
||||
std::cout << "handler on_message" << std::endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void on_close(connection_ptr con) {
|
||||
std::cout << "handler on_close" << std::endl;
|
||||
}
|
||||
};*/
|
||||
|
||||
int main() {
|
||||
typedef websocketpp::message_buffer::message<websocketpp::message_buffer::alloc::con_msg_manager>
|
||||
message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_man_type;
|
||||
typedef websocketpp::message_buffer::message<websocketpp::message_buffer::alloc::con_msg_manager>
|
||||
message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_man_type;
|
||||
|
||||
con_msg_man_type::ptr manager(new con_msg_man_type());
|
||||
|
||||
size_t foo = 1024;
|
||||
|
||||
message_type::ptr input = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
|
||||
message_type::ptr output = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
|
||||
websocketpp::frame::masking_key_type key;
|
||||
|
||||
std::random_device dev;
|
||||
|
||||
|
||||
|
||||
key.i = 0x12345678;
|
||||
|
||||
double m = 18094238402394.0824923;
|
||||
|
||||
/*std::cout << "Some Math" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
for (int i = 0; i < foo; i++) {
|
||||
m /= 1.001;
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
std::cout << m << std::endl;
|
||||
|
||||
std::cout << "Random Gen" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
}
|
||||
|
||||
std::cout << "Out of place accelerated" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(output->get_raw_payload().data())), foo, key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
|
||||
std::cout << "In place accelerated" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), foo, key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
std::cout << "Out of place byte by byte" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin(), key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
std::cout << "In place byte by byte" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), input->get_raw_payload().begin(), key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'a');
|
||||
output->get_raw_payload().replace(0,foo,foo,'b');
|
||||
std::cout << "Copy" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
std::copy(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin());
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
/*server::handler::ptr h(new handler());
|
||||
|
||||
server test_server(h);
|
||||
server::connection_ptr con;
|
||||
|
||||
std::stringstream output;
|
||||
|
||||
test_server.register_ostream(&output);
|
||||
|
||||
con = test_server.get_connection();
|
||||
|
||||
con->start();
|
||||
|
||||
//foo.handle_accept(con,true);
|
||||
|
||||
std::stringstream input;
|
||||
input << "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
//input << "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
|
||||
input >> *con;
|
||||
|
||||
std::stringstream input2;
|
||||
input2 << "messageabc2";
|
||||
input2 >> *con;
|
||||
|
||||
std::stringstream input3;
|
||||
input3 << "messageabc3";
|
||||
input3 >> *con;
|
||||
|
||||
std::stringstream input4;
|
||||
input4 << "close";
|
||||
input4 >> *con;
|
||||
|
||||
std::cout << "connection output:" << std::endl;
|
||||
std::cout << output.str() << std::endl;*/
|
||||
con_msg_man_type::ptr manager = websocketpp::lib::make_shared<con_msg_man_type>();
|
||||
|
||||
size_t foo = 1024;
|
||||
|
||||
message_type::ptr input = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
|
||||
message_type::ptr output = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
|
||||
websocketpp::frame::masking_key_type key;
|
||||
|
||||
std::random_device dev;
|
||||
|
||||
|
||||
|
||||
key.i = 0x12345678;
|
||||
|
||||
double m = 18094238402394.0824923;
|
||||
|
||||
/*std::cout << "Some Math" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
for (int i = 0; i < foo; i++) {
|
||||
m /= 1.001;
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
std::cout << m << std::endl;
|
||||
|
||||
std::cout << "Random Gen" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
}
|
||||
|
||||
std::cout << "Out of place accelerated" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(output->get_raw_payload().data())), foo, key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
|
||||
std::cout << "In place accelerated" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), foo, key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
std::cout << "Out of place byte by byte" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin(), key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
output->get_raw_payload().replace(0,foo,foo,'\0');
|
||||
std::cout << "In place byte by byte" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), input->get_raw_payload().begin(), key);
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
input->get_raw_payload().replace(0,foo,foo,'a');
|
||||
output->get_raw_payload().replace(0,foo,foo,'b');
|
||||
std::cout << "Copy" << std::endl;
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
|
||||
std::copy(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin());
|
||||
}
|
||||
|
||||
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
|
||||
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
|
||||
|
||||
/*server::handler::ptr h(new handler());
|
||||
|
||||
server test_server(h);
|
||||
server::connection_ptr con;
|
||||
|
||||
std::stringstream output;
|
||||
|
||||
test_server.register_ostream(&output);
|
||||
|
||||
con = test_server.get_connection();
|
||||
|
||||
con->start();
|
||||
|
||||
//foo.handle_accept(con,true);
|
||||
|
||||
std::stringstream input;
|
||||
input << "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
//input << "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
|
||||
input >> *con;
|
||||
|
||||
std::stringstream input2;
|
||||
input2 << "messageabc2";
|
||||
input2 >> *con;
|
||||
|
||||
std::stringstream input3;
|
||||
input3 << "messageabc3";
|
||||
input3 >> *con;
|
||||
|
||||
std::stringstream input4;
|
||||
input4 << "close";
|
||||
input4 >> *con;
|
||||
|
||||
std::cout << "connection output:" << std::endl;
|
||||
std::cout << output.str() << std::endl;*/
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('echo_server', ["echo_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('echo_server', ["echo_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,16 +22,16 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_ECHO_SERVER_HANDLER_HPP
|
||||
#define WEBSOCKETPP_ECHO_SERVER_HANDLER_HPP
|
||||
|
||||
class echo_handler : public server::handler {
|
||||
void on_message(connection_ptr con, std::string msg) {
|
||||
con->write(msg);
|
||||
}
|
||||
void on_message(connection_ptr con, std::string msg) {
|
||||
con->write(msg);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // WEBSOCKETPP_ECHO_SERVER_HANDLER_HPP
|
||||
@@ -15,45 +15,50 @@ typedef server::message_ptr message_ptr;
|
||||
|
||||
// Define a callback to handle incoming messages
|
||||
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||
<< " and message: " << msg->get_payload()
|
||||
<< std::endl;
|
||||
|
||||
// check for a special command to instruct the server to stop listening so
|
||||
// it can be cleanly exited.
|
||||
if (msg->get_payload() == "stop-listening") {
|
||||
s->stop_listening();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
} catch (const websocketpp::lib::error_code& e) {
|
||||
std::cout << "Echo failed because: " << e
|
||||
std::cout << "Echo failed because: " << e
|
||||
<< "(" << e.message() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a server endpoint
|
||||
// Create a server endpoint
|
||||
server echo_server;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
// Set logging settings
|
||||
echo_server.set_access_channels(websocketpp::log::alevel::all);
|
||||
echo_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||
|
||||
|
||||
// Initialize ASIO
|
||||
echo_server.init_asio();
|
||||
|
||||
|
||||
// Register our message handler
|
||||
echo_server.set_message_handler(bind(&on_message,&echo_server,::_1,::_2));
|
||||
|
||||
|
||||
// Listen on port 9002
|
||||
echo_server.listen(9002);
|
||||
|
||||
|
||||
// Start the server accept loop
|
||||
echo_server.start_accept();
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
echo_server.run();
|
||||
} catch (const std::exception & e) {
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
|
||||
init_target (echo_server_both)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
link_openssl()
|
||||
final_target ()
|
||||
endif()
|
||||
@@ -0,0 +1,24 @@
|
||||
## Combo plain+tls echo server
|
||||
##
|
||||
|
||||
Import('env')
|
||||
Import('env_cpp11')
|
||||
Import('boostlibs')
|
||||
Import('platform_libs')
|
||||
Import('polyfill_libs')
|
||||
Import('tls_libs')
|
||||
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
prgs = []
|
||||
|
||||
# if a C++11 environment is available build using that, otherwise use boost
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
prgs += env_cpp11.Program('echo_server_both', ["echo_server_both.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
prgs += env.Program('echo_server_both', ["echo_server_both.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -0,0 +1,87 @@
|
||||
#include <websocketpp/config/asio.hpp>
|
||||
#include <websocketpp/server.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// define types for two different server endpoints, one for each config we are
|
||||
// using
|
||||
typedef websocketpp::server<websocketpp::config::asio> server_plain;
|
||||
typedef websocketpp::server<websocketpp::config::asio_tls> server_tls;
|
||||
|
||||
// alias some of the bind related functions as they are a bit long
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
|
||||
// type of the ssl context pointer is long so alias it
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
|
||||
// The shared on_message handler takes a template parameter so the function can
|
||||
// resolve any endpoint dependent types like message_ptr or connection_ptr
|
||||
template <typename EndpointType>
|
||||
void on_message(EndpointType* s, websocketpp::connection_hdl hdl,
|
||||
typename EndpointType::message_ptr msg)
|
||||
{
|
||||
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||
<< " and message: " << msg->get_payload()
|
||||
<< std::endl;
|
||||
|
||||
try {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
} catch (const websocketpp::lib::error_code& e) {
|
||||
std::cout << "Echo failed because: " << e
|
||||
<< "(" << e.message() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// No change to TLS init methods from echo_server_tls
|
||||
std::string get_password() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
|
||||
std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl;
|
||||
context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
|
||||
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
ctx->set_password_callback(bind(&get_password));
|
||||
ctx->use_certificate_chain_file("server.pem");
|
||||
ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem);
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// set up an external io_service to run both endpoints on. This is not
|
||||
// strictly necessary, but simplifies thread management a bit.
|
||||
boost::asio::io_service ios;
|
||||
|
||||
// set up plain endpoint
|
||||
server_plain endpoint_plain;
|
||||
// initialize asio with our external io_service rather than an internal one
|
||||
endpoint_plain.init_asio(&ios);
|
||||
endpoint_plain.set_message_handler(
|
||||
bind(&on_message<server_plain>,&endpoint_plain,::_1,::_2));
|
||||
endpoint_plain.listen(80);
|
||||
endpoint_plain.start_accept();
|
||||
|
||||
// set up tls endpoint
|
||||
server_tls endpoint_tls;
|
||||
endpoint_tls.init_asio(&ios);
|
||||
endpoint_tls.set_message_handler(
|
||||
bind(&on_message<server_tls>,&endpoint_tls,::_1,::_2));
|
||||
// TLS endpoint has an extra handler for the tls init
|
||||
endpoint_tls.set_tls_init_handler(bind(&on_tls_init,::_1));
|
||||
// tls endpoint listens on a different port
|
||||
endpoint_tls.listen(443);
|
||||
endpoint_tls.start_accept();
|
||||
|
||||
// Start the ASIO io_service run loop running both endpoints
|
||||
ios.run();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,A0ED66EF872A48A9
|
||||
|
||||
gXuvKojXzApVhhPVNdRliiajbC4PtwQG5c8TA7JADLgwOR7o9t6KtXEr37bDRpvB
|
||||
9aO9P+SJaK5OOp3XKPGthOdqv+tvCRTlmzmC8GjPLBX389DWT2xoGu7JkGwDtdSm
|
||||
rnF49Rlp5bfjpACk5xKNiKeDo1CWfeEJzw9Kto0g+5eMaEdors64oPzjXs3geA2g
|
||||
TxCJSHv9qSX6++pCLKKCUTbyzidAxV/Zb0AAubt5V40QKqX4HhSwwstFnTaX3tlb
|
||||
3QOdY+y04VIkM6d7qN5W8M7NzRkMpZ1qBpQcUMpkhQcRzWP2wub5AAff9D2GntRd
|
||||
4Dz1vn3u41U3Okdr0CNj+iH7byCzuokoAhk6ZQEN6WB+GTpGgfBXdtUZrfpb0MKm
|
||||
UNYP5AF2AmUqJRXhViTDVtu/V2tHF3LGuNT+W2Dz+spFZEq0byEO0N858eR0dikc
|
||||
6jOASvNQbSwD0+mkgBC1gXKKU3ngj2gpJUwljeACdWFd8N2egrZfyI05CmX7vPNC
|
||||
NXbs7k2buWNdjP4/D8IM+HDVidWzQa/kG/qokXKqllem9Egg37lUucwnP3cX2/Hw
|
||||
U2mfaBWzeZtqc+GqRp08rYIql+Reai3sUYlQMnNk01prVY47UQb+dxuqjaxGV5Xx
|
||||
Xkx0s2mfQnNRjL4S7Hjhqelufi6GpkCQ2EGsPpA+6K1ztZ0ame9Q2BE1SXeM/6vU
|
||||
rxT5nRrCxueyXAyQSGcqMX9//gSeK8WWBqG/c1IAMVDa0NWrJeOJhSziE+ta3B0m
|
||||
bHAPBY6vh0iB3lLdRlbUOPbC6R1TpxMOs+6Vbs2+OTifFpvOVymEoZq/nroyg68P
|
||||
vn5uCKogwWA7o8EArf/UTlIwWJmH9bgILdZKld4wMel2HQg16RDzm+mEXAJi52a/
|
||||
FC+fgfphdxltmUJ+rqOyR4AHULjaTWUQqTIB6sdlzgmES1nXAiE71zX//KFqomar
|
||||
O60SPPk3C1bs0x5DsvmGJa8SIfDhyd+D7NPyqwEKqrZsaotYGklNkfqxa6pa8mrc
|
||||
ejxquW1PK4FvBk26+osu5a90Jih0PcQM7DUMMr2WHdTiMSXWAiK2ToYF8Itt25Qv
|
||||
Cd0CsSYw9CJkXNr1u1+mObheaY9QYOmztnSJLy4ZO2JsMhqNwuAueIcwmhXOREq7
|
||||
kzlnGMgJcuSeAS/OBNj8Zgx0c7QQ0kzc+YmnOCsqoMtPsu/CsXJ4iJiM3Tki/2jT
|
||||
bywrTiQwE6R3a/87GREOREX+WLicZBWX3k9/4tBL5XSe1p5wPpuIRQUDvAGNfNHP
|
||||
JN7kujDF4SehilF1qtvCygAwvxHFDj+EwhXKNDKJzoZZIM15rAk3k92n2j6nz1qH
|
||||
a3xOU05yydOlO6F6w51I1QoDddmkzCRNB0TeO3D6rekHsCK1aDWmC+qRcm2ZFtVz
|
||||
sY6fdZN2NEmMQokIh9Opi1f8CSYSizPESMzdu2SF0xVO9n/IGIkn1ksK04O2BZo0
|
||||
X3LBPHLfCRsQNY1eF17bj07fYU2oPZKs/XzJiwxkqK6LFvpeAVaYrtg9fqRO/UVe
|
||||
QhUIj3BL550ocEpa15xLehLrmwzYiW5zwGjSHQ4EgZluGLCwyKGTh4QswEJRA9Rt
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIE0DCCA7igAwIBAgIJAM5MuKJezXq0MA0GCSqGSIb3DQEBBQUAMIGgMQswCQYD
|
||||
VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xGDAW
|
||||
BgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0KysxFjAU
|
||||
BgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3RlckB6
|
||||
YXBob3lkLmNvbTAeFw0xMTExMTUyMTIwMDZaFw0xMjExMTQyMTIwMDZaMIGgMQsw
|
||||
CQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28x
|
||||
GDAWBgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0Kysx
|
||||
FjAUBgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3Rl
|
||||
ckB6YXBob3lkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANR0
|
||||
tdwAnIB8I9qRZ7QbzEWY95RpM7GIn0u/9oH90PzdHiE0rXSkKT+yw3XUzH0iw5t0
|
||||
5dEwSC+srSP5Vm4cA6kXc94agVVaPW89tGcdP4fHptCruSrzQsDXELCPl5UUvMpA
|
||||
YUcGisdXYPN/EeOoqb9wKWxoW5mREsyyeWWS89fYN5qU/d0QpbSvEWghqLbL/ZS2
|
||||
hOlXT9LufOeA+vHiV1/T/h5xC7ecIH02YDQw1EnqxbPmkLPcWThztLS9FiufNDRM
|
||||
Rhcoaj2b9VDHvDwdbeA0T5v5qNdG34LaapYOelxzQMOtM0f9Dgqehodyxl2qm9mR
|
||||
lq432dlOEzDnVCPNHwECAwEAAaOCAQkwggEFMB0GA1UdDgQWBBTTPKfNMnKOykhv
|
||||
+vKS7vql5JsMyzCB1QYDVR0jBIHNMIHKgBTTPKfNMnKOykhv+vKS7vql5JsMy6GB
|
||||
pqSBozCBoDELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQH
|
||||
EwdDaGljYWdvMRgwFgYDVQQKEw9aYXBob3lkIFN0dWRpb3MxFDASBgNVBAsTC1dl
|
||||
YlNvY2tldCsrMRYwFAYDVQQDEw1QZXRlciBUaG9yc29uMSQwIgYJKoZIhvcNAQkB
|
||||
FhV3ZWJtYXN0ZXJAemFwaG95ZC5jb22CCQDOTLiiXs16tDAMBgNVHRMEBTADAQH/
|
||||
MA0GCSqGSIb3DQEBBQUAA4IBAQB+SH0s/hrv5VYqgX6SNLzxdSLvCVsUkCdTpxwY
|
||||
wOJ84XmYcXDMhKDtZqLtOtN6pfEwVusFlC9mkieuunztCnWNmsSG83RuljJPjFSi
|
||||
1d4Id4bKEQkQ4cfnjoHKivRrViWLnxuNnLzC6tpyGH/35kKWhhr6T58AXerFgVw3
|
||||
mHvLPTr1DuhdAZA0ZuvuseVAFFAjI3RetSySwHJE3ak8KswDVfLi6E3XxMVsIWTS
|
||||
/iFsC2WwoZQlljya2V/kRYIhu+uCdqJ01wunn2BvmURPSgr4GTBF0FQ9JGpNbXxM
|
||||
TAU7oQJgyFc5sCcuEgPTO0dWVQTvdZVgay4tkmduKDRkmJBF
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
|
||||
init_target (echo_server_tls)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
link_openssl()
|
||||
final_target ()
|
||||
endif()
|
||||
@@ -18,7 +18,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
prgs += env_cpp11.Program('echo_server_tls', ["echo_server_tls.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
prgs += env.Program('echo_server_tls', ["echo_server_tls.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -0,0 +1,8 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEAqxMGKZB8YNV8WQnbJWwwwmifc+PfVRtd1FN5v5aQSsf6dpjX3Zlh
|
||||
N1NmgecsQyg4u2EWe4Umta10QzCgYaxf6QdTCg7iprLzFNw7IvWYbQ6du12NMGDr
|
||||
hmwA6KQKwbTgPL6mSlSlcK2wTP2FzxDTNffFu10cB/6Fj4kdQjPG0c1Koz/z7OOq
|
||||
BuDElJLClS8rjp3z1xvrc7gX95dFa2KaKgOAYDkpe8tfHRhHfJeIVS/whH9hzx6r
|
||||
OBg+E5K9JyvayrUoKgPeptRKCqo8A4YevtMLpRxMup0nMUgAIv6+BGTwPAFpwgl/
|
||||
8UIVcvjh1v95PwGDM/Q8yvIBJznBYk/e2wIBAg==
|
||||
-----END DH PARAMETERS-----
|
||||
@@ -15,58 +15,101 @@ typedef websocketpp::config::asio::message_type::ptr message_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
|
||||
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||
<< " and message: " << msg->get_payload()
|
||||
<< std::endl;
|
||||
|
||||
try {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
} catch (const websocketpp::lib::error_code& e) {
|
||||
std::cout << "Echo failed because: " << e
|
||||
std::cout << "Echo failed because: " << e
|
||||
<< "(" << e.message() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void on_http(server* s, websocketpp::connection_hdl hdl) {
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
con->set_body("Hello World!");
|
||||
con->set_status(websocketpp::http::status_code::ok);
|
||||
}
|
||||
|
||||
std::string get_password() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
|
||||
// See https://wiki.mozilla.org/Security/Server_Side_TLS for more details about
|
||||
// the TLS modes. The code below demonstrates how to implement both the modern
|
||||
enum tls_mode {
|
||||
MOZILLA_INTERMEDIATE = 1,
|
||||
MOZILLA_MODERN = 2
|
||||
};
|
||||
|
||||
context_ptr on_tls_init(tls_mode mode, websocketpp::connection_hdl hdl) {
|
||||
std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl;
|
||||
context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
|
||||
std::cout << "using TLS mode: " << (mode == MOZILLA_MODERN ? "Mozilla Modern" : "Mozilla Intermediate") << std::endl;
|
||||
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);
|
||||
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
if (mode == MOZILLA_MODERN) {
|
||||
// Modern disables TLSv1
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::no_tlsv1 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
} else {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
}
|
||||
ctx->set_password_callback(bind(&get_password));
|
||||
ctx->use_certificate_chain_file("server.pem");
|
||||
ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem);
|
||||
|
||||
// Example method of generating this file:
|
||||
// `openssl dhparam -out dh.pem 2048`
|
||||
// Mozilla Intermediate suggests 1024 as the minimum size to use
|
||||
// Mozilla Modern suggests 2048 as the minimum size to use.
|
||||
ctx->use_tmp_dh_file("dh.pem");
|
||||
|
||||
std::string ciphers;
|
||||
|
||||
if (mode == MOZILLA_MODERN) {
|
||||
ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK";
|
||||
} else {
|
||||
ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
|
||||
}
|
||||
|
||||
if (SSL_CTX_set_cipher_list(ctx->native_handle() , ciphers.c_str()) != 1) {
|
||||
std::cout << "Error setting cipher list" << std::endl;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a server endpoint
|
||||
server echo_server;
|
||||
|
||||
server echo_server;
|
||||
|
||||
// Initialize ASIO
|
||||
echo_server.init_asio();
|
||||
echo_server.init_asio();
|
||||
|
||||
// Register our message handler
|
||||
echo_server.set_message_handler(bind(&on_message,&echo_server,::_1,::_2));
|
||||
echo_server.set_tls_init_handler(bind(&on_tls_init,::_1));
|
||||
echo_server.set_http_handler(bind(&on_http,&echo_server,::_1));
|
||||
echo_server.set_tls_init_handler(bind(&on_tls_init,MOZILLA_INTERMEDIATE,::_1));
|
||||
|
||||
|
||||
// Listen on port 9002
|
||||
echo_server.listen(9002);
|
||||
|
||||
// Start the server accept loop
|
||||
echo_server.start_accept();
|
||||
// Listen on port 9002
|
||||
echo_server.listen(9002);
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
echo_server.run();
|
||||
// Start the server accept loop
|
||||
echo_server.start_accept();
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
echo_server.run();
|
||||
|
||||
}
|
||||
@@ -1,58 +1,55 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,A0ED66EF872A48A9
|
||||
|
||||
gXuvKojXzApVhhPVNdRliiajbC4PtwQG5c8TA7JADLgwOR7o9t6KtXEr37bDRpvB
|
||||
9aO9P+SJaK5OOp3XKPGthOdqv+tvCRTlmzmC8GjPLBX389DWT2xoGu7JkGwDtdSm
|
||||
rnF49Rlp5bfjpACk5xKNiKeDo1CWfeEJzw9Kto0g+5eMaEdors64oPzjXs3geA2g
|
||||
TxCJSHv9qSX6++pCLKKCUTbyzidAxV/Zb0AAubt5V40QKqX4HhSwwstFnTaX3tlb
|
||||
3QOdY+y04VIkM6d7qN5W8M7NzRkMpZ1qBpQcUMpkhQcRzWP2wub5AAff9D2GntRd
|
||||
4Dz1vn3u41U3Okdr0CNj+iH7byCzuokoAhk6ZQEN6WB+GTpGgfBXdtUZrfpb0MKm
|
||||
UNYP5AF2AmUqJRXhViTDVtu/V2tHF3LGuNT+W2Dz+spFZEq0byEO0N858eR0dikc
|
||||
6jOASvNQbSwD0+mkgBC1gXKKU3ngj2gpJUwljeACdWFd8N2egrZfyI05CmX7vPNC
|
||||
NXbs7k2buWNdjP4/D8IM+HDVidWzQa/kG/qokXKqllem9Egg37lUucwnP3cX2/Hw
|
||||
U2mfaBWzeZtqc+GqRp08rYIql+Reai3sUYlQMnNk01prVY47UQb+dxuqjaxGV5Xx
|
||||
Xkx0s2mfQnNRjL4S7Hjhqelufi6GpkCQ2EGsPpA+6K1ztZ0ame9Q2BE1SXeM/6vU
|
||||
rxT5nRrCxueyXAyQSGcqMX9//gSeK8WWBqG/c1IAMVDa0NWrJeOJhSziE+ta3B0m
|
||||
bHAPBY6vh0iB3lLdRlbUOPbC6R1TpxMOs+6Vbs2+OTifFpvOVymEoZq/nroyg68P
|
||||
vn5uCKogwWA7o8EArf/UTlIwWJmH9bgILdZKld4wMel2HQg16RDzm+mEXAJi52a/
|
||||
FC+fgfphdxltmUJ+rqOyR4AHULjaTWUQqTIB6sdlzgmES1nXAiE71zX//KFqomar
|
||||
O60SPPk3C1bs0x5DsvmGJa8SIfDhyd+D7NPyqwEKqrZsaotYGklNkfqxa6pa8mrc
|
||||
ejxquW1PK4FvBk26+osu5a90Jih0PcQM7DUMMr2WHdTiMSXWAiK2ToYF8Itt25Qv
|
||||
Cd0CsSYw9CJkXNr1u1+mObheaY9QYOmztnSJLy4ZO2JsMhqNwuAueIcwmhXOREq7
|
||||
kzlnGMgJcuSeAS/OBNj8Zgx0c7QQ0kzc+YmnOCsqoMtPsu/CsXJ4iJiM3Tki/2jT
|
||||
bywrTiQwE6R3a/87GREOREX+WLicZBWX3k9/4tBL5XSe1p5wPpuIRQUDvAGNfNHP
|
||||
JN7kujDF4SehilF1qtvCygAwvxHFDj+EwhXKNDKJzoZZIM15rAk3k92n2j6nz1qH
|
||||
a3xOU05yydOlO6F6w51I1QoDddmkzCRNB0TeO3D6rekHsCK1aDWmC+qRcm2ZFtVz
|
||||
sY6fdZN2NEmMQokIh9Opi1f8CSYSizPESMzdu2SF0xVO9n/IGIkn1ksK04O2BZo0
|
||||
X3LBPHLfCRsQNY1eF17bj07fYU2oPZKs/XzJiwxkqK6LFvpeAVaYrtg9fqRO/UVe
|
||||
QhUIj3BL550ocEpa15xLehLrmwzYiW5zwGjSHQ4EgZluGLCwyKGTh4QswEJRA9Rt
|
||||
MIIEowIBAAKCAQEA77v5VbFaq+geVd/RCLXoKTWj/LgXGjiOXBpJZca3o5edi7N1
|
||||
Ej41/13jfZ4OxgFIRFAALd+fU4NsObXzskth3rJLmJjUtGajRIPqF2IUVjFMmybQ
|
||||
9dUDSqPzd/bG+ul0DP7DNuiBcLC8XNC3/kchPUzVq9gNDk56jXn87kMoIkVXBWQS
|
||||
Rwk0yCtELSfwxxRCrGKgQDfXnRdwmkPe42DmKtdGksXJlUhP1UVTAXaSw1Nz64LV
|
||||
9bJje/eoDsSe4OxifVVToE6ZxIW+r1jVgrcupeYXQrSHIztl2U/rx2JkGMN0eS+P
|
||||
qrsJmkmRBN1cpgmvSV7WoM3hj6Eq71z4Dfv6EwIDAQABAoIBAEXAL19bZsI1mv3p
|
||||
TOx34MB8tuXEuhQK+ICbtVdDZhLW/iOzZxCTwSo3qwTVg/7gSKJ3lFXEhprJ1idE
|
||||
ZU8u157vyUbw0JJceoxoxSdghgI9/cf2lz2vaHHDGgeBaYt/eSB+z1WeeGrNQUDQ
|
||||
CXiWQXmQbWq+Ra4v70BSieDY8UhmzCTRhvfZV80vaY/4SnHxJ9C8Nu8/An7U3pwq
|
||||
ccfTaWMp3Q5ztmEnExF6/b1SUsnI8rzFovw/4C50AU09N/Z6zZVFsXgJAT2Kd1Tx
|
||||
HfP1vUkWZ/TJ6kcmVIV9U3uMcedBD8Rb/3M0Qdp+eymQ+1oYQ3K3/a2RlUQIeXzf
|
||||
hRbE4wECgYEA/WyULrwBsvSMPqK0K9pZpv921Yl6d4bGnpxKze7ltc9o5/LsU35q
|
||||
8u29Es7cPyhyUDOsPW8v2CNjw54t+eFGsu59bBvXZNz5gB7hTUEyLntB24cO5PmN
|
||||
kVExcMDFC6NgPaauBtUhODievKJ2C8P7sRJDAVKE9KkavDddU7nSEjMCgYEA8ivG
|
||||
AqwNXYsiIFjAo4uj3kuBFt8LU/q4m6GXI+9qyxfiJjuF1dROx5qaQGiE85VaBFUu
|
||||
gpbnjZH7s+BBgoaQhrB4i6mztljdN1KKuAlnjhB+Fywg8m8N9lAi3wIaxnIEqDkU
|
||||
vFiIFPTBCk0U7IZ/OyCrKPQTE9ApWHfBwA/vWKECgYBQixrJg61SkBCms5Vpvprx
|
||||
zY2aLniC1o33yRqpOr09PG9OENH1c19QWCjYenBbjmJOhS2/1L+zBQRnHrXkDion
|
||||
Ik8wdeTORMDzbF0U7ZyiU0BKIjGkqn/I6LI68LlvinxC+9+hgkltkek5cLTt5lrv
|
||||
Gyu6ltx02e4KVdpOiuduKwKBgQC3U0PWigCkK8ttyUIrjG5Evcu/UKH2tPpDdpQ/
|
||||
8+JYVIAyiSTLtqjcmcDjuTvMWeeHGCTZXvtzRGvSw5VUBiIqlDTtJU6SX7s3QhkZ
|
||||
MKVf+kQ5roJShJeBOzDquWEjkPTNlEiKPErn8lCgR7HrS/XNAPIRUpOOkCp8ekwF
|
||||
5Qo/gQKBgAue3TeCeIzxh4PxSAk39Uaj+AaLvlYg8C+ucEodCNQZnJ7jOO0hHkfT
|
||||
NvZBes0VukCGlBLOGRQtC3kgtyrerscnDiZOhdnJrhPIdNPC0k/p/uAfh7+C5Sxm
|
||||
rCEL0S7kORdEjlIGd5j6ZEN/HZe8FyOYSjbFAoJSlAId9WMSxycQ
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIE0DCCA7igAwIBAgIJAM5MuKJezXq0MA0GCSqGSIb3DQEBBQUAMIGgMQswCQYD
|
||||
VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xGDAW
|
||||
BgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0KysxFjAU
|
||||
BgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3RlckB6
|
||||
YXBob3lkLmNvbTAeFw0xMTExMTUyMTIwMDZaFw0xMjExMTQyMTIwMDZaMIGgMQsw
|
||||
CQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28x
|
||||
GDAWBgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0Kysx
|
||||
FjAUBgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3Rl
|
||||
ckB6YXBob3lkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANR0
|
||||
tdwAnIB8I9qRZ7QbzEWY95RpM7GIn0u/9oH90PzdHiE0rXSkKT+yw3XUzH0iw5t0
|
||||
5dEwSC+srSP5Vm4cA6kXc94agVVaPW89tGcdP4fHptCruSrzQsDXELCPl5UUvMpA
|
||||
YUcGisdXYPN/EeOoqb9wKWxoW5mREsyyeWWS89fYN5qU/d0QpbSvEWghqLbL/ZS2
|
||||
hOlXT9LufOeA+vHiV1/T/h5xC7ecIH02YDQw1EnqxbPmkLPcWThztLS9FiufNDRM
|
||||
Rhcoaj2b9VDHvDwdbeA0T5v5qNdG34LaapYOelxzQMOtM0f9Dgqehodyxl2qm9mR
|
||||
lq432dlOEzDnVCPNHwECAwEAAaOCAQkwggEFMB0GA1UdDgQWBBTTPKfNMnKOykhv
|
||||
+vKS7vql5JsMyzCB1QYDVR0jBIHNMIHKgBTTPKfNMnKOykhv+vKS7vql5JsMy6GB
|
||||
pqSBozCBoDELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQH
|
||||
EwdDaGljYWdvMRgwFgYDVQQKEw9aYXBob3lkIFN0dWRpb3MxFDASBgNVBAsTC1dl
|
||||
YlNvY2tldCsrMRYwFAYDVQQDEw1QZXRlciBUaG9yc29uMSQwIgYJKoZIhvcNAQkB
|
||||
FhV3ZWJtYXN0ZXJAemFwaG95ZC5jb22CCQDOTLiiXs16tDAMBgNVHRMEBTADAQH/
|
||||
MA0GCSqGSIb3DQEBBQUAA4IBAQB+SH0s/hrv5VYqgX6SNLzxdSLvCVsUkCdTpxwY
|
||||
wOJ84XmYcXDMhKDtZqLtOtN6pfEwVusFlC9mkieuunztCnWNmsSG83RuljJPjFSi
|
||||
1d4Id4bKEQkQ4cfnjoHKivRrViWLnxuNnLzC6tpyGH/35kKWhhr6T58AXerFgVw3
|
||||
mHvLPTr1DuhdAZA0ZuvuseVAFFAjI3RetSySwHJE3ak8KswDVfLi6E3XxMVsIWTS
|
||||
/iFsC2WwoZQlljya2V/kRYIhu+uCdqJ01wunn2BvmURPSgr4GTBF0FQ9JGpNbXxM
|
||||
TAU7oQJgyFc5sCcuEgPTO0dWVQTvdZVgay4tkmduKDRkmJBF
|
||||
MIIEpzCCA4+gAwIBAgIJAMlCHvwnJ+F/MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
|
||||
VQQGEwJVUzELMAkGA1UECBMCSUwxEDAOBgNVBAcTB0NoaWNhZ28xGTAXBgNVBAoT
|
||||
EFdlYlNvY2tldCsrIERlbW8xIjAgBgNVBAMTGXV0aWxpdGllcy53ZWJzb2NrZXRw
|
||||
cC5vcmcxJjAkBgkqhkiG9w0BCQEWF3dlYnNvY2tldHBwQHphcGhveWQuY29tMB4X
|
||||
DTE1MDQyNTE1NTk1M1oXDTE4MDMyODE1NTk1M1owgZMxCzAJBgNVBAYTAlVTMQsw
|
||||
CQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEZMBcGA1UEChMQV2ViU29ja2V0
|
||||
KysgRGVtbzEiMCAGA1UEAxMZdXRpbGl0aWVzLndlYnNvY2tldHBwLm9yZzEmMCQG
|
||||
CSqGSIb3DQEJARYXd2Vic29ja2V0cHBAemFwaG95ZC5jb20wggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQDvu/lVsVqr6B5V39EItegpNaP8uBcaOI5cGkll
|
||||
xrejl52Ls3USPjX/XeN9ng7GAUhEUAAt359Tg2w5tfOyS2HeskuYmNS0ZqNEg+oX
|
||||
YhRWMUybJtD11QNKo/N39sb66XQM/sM26IFwsLxc0Lf+RyE9TNWr2A0OTnqNefzu
|
||||
QygiRVcFZBJHCTTIK0QtJ/DHFEKsYqBAN9edF3CaQ97jYOYq10aSxcmVSE/VRVMB
|
||||
dpLDU3PrgtX1smN796gOxJ7g7GJ9VVOgTpnEhb6vWNWCty6l5hdCtIcjO2XZT+vH
|
||||
YmQYw3R5L4+quwmaSZEE3VymCa9JXtagzeGPoSrvXPgN+/oTAgMBAAGjgfswgfgw
|
||||
HQYDVR0OBBYEFAWNBET93ZzSukXGkuGb93CfmUkDMIHIBgNVHSMEgcAwgb2AFAWN
|
||||
BET93ZzSukXGkuGb93CfmUkDoYGZpIGWMIGTMQswCQYDVQQGEwJVUzELMAkGA1UE
|
||||
CBMCSUwxEDAOBgNVBAcTB0NoaWNhZ28xGTAXBgNVBAoTEFdlYlNvY2tldCsrIERl
|
||||
bW8xIjAgBgNVBAMTGXV0aWxpdGllcy53ZWJzb2NrZXRwcC5vcmcxJjAkBgkqhkiG
|
||||
9w0BCQEWF3dlYnNvY2tldHBwQHphcGhveWQuY29tggkAyUIe/Ccn4X8wDAYDVR0T
|
||||
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA2DRQSDmo2Q5t8MEjp6jddRIFts5t
|
||||
BDBWPSwJ0qvmheFt53MuLds2hhvMn42WGrKtVJiLiDyOWuUZ41REJZb1uaissUuY
|
||||
r9pLuP5QLdibx7+/30iDEY0OGTgtSTfgwNx8bIApBSHoZEN3/HaikqplBng2+6u/
|
||||
kTe6UnRrBJ+8JOGl+duhCXNPeSyLa2NcrxE9XpWC/k1kC9MTUF+2NuqCtK3zO8ci
|
||||
p0mqARWDSrEBYISh3dAOgDFrcX6zj+0MK+iswu3ijEdItGAjxjlQ2t4XT1T/CDbc
|
||||
ysHg04TJw7v682+v124GrnrAPYUK34OK8kFVJ60SNYRUi7euOCdTM4Lwkw==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -17,12 +17,12 @@ void custom_on_msg(server & s, connection_hdl hdl, server::message_ptr msg) {
|
||||
|
||||
void default_on_msg(server & s, connection_hdl hdl, server::message_ptr msg) {
|
||||
std::cout << "Message sent to default handler" << std::endl;
|
||||
|
||||
|
||||
if (msg->get_payload() == "upgrade") {
|
||||
// Upgrade our connection_hdl to a full connection_ptr
|
||||
server::connection_ptr con = s.get_con_from_hdl(hdl);
|
||||
|
||||
// Change the on message handler for this connection only to
|
||||
|
||||
// Change the on message handler for this connection only to
|
||||
// custom_on_mesage
|
||||
con->set_message_handler(bind(&custom_on_msg,ref(s),::_1,::_2));
|
||||
std::cout << "Upgrading connection to custom handler" << std::endl;
|
||||
@@ -39,4 +39,4 @@ int main() {
|
||||
s.start_accept();
|
||||
|
||||
s.run();
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('iostream_server', ["iostream_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('iostream_server', ["iostream_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -17,75 +17,73 @@ typedef server::message_ptr message_ptr;
|
||||
// Define a callback to handle incoming messages
|
||||
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
if (msg->get_opcode() == websocketpp::frame::opcode::text) {
|
||||
s->get_alog().write(websocketpp::log::alevel::app,
|
||||
"Text Message Received: "+msg->get_payload());
|
||||
s->get_alog().write(websocketpp::log::alevel::app,
|
||||
"Text Message Received: "+msg->get_payload());
|
||||
} else {
|
||||
s->get_alog().write(websocketpp::log::alevel::app,
|
||||
"Binary Message Received: "+websocketpp::utility::to_hex(msg->get_payload()));
|
||||
}
|
||||
|
||||
s->get_alog().write(websocketpp::log::alevel::app,
|
||||
"Binary Message Received: "+websocketpp::utility::to_hex(msg->get_payload()));
|
||||
}
|
||||
|
||||
try {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
} catch (const websocketpp::lib::error_code& e) {
|
||||
s->get_alog().write(websocketpp::log::alevel::app,
|
||||
"Echo Failed: "+e.message());
|
||||
s->get_alog().write(websocketpp::log::alevel::app,
|
||||
"Echo Failed: "+e.message());
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
server s;
|
||||
std::ofstream log;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
// set up access channels to only log interesting things
|
||||
s.clear_access_channels(websocketpp::log::alevel::all);
|
||||
s.set_access_channels(websocketpp::log::alevel::connect);
|
||||
s.set_access_channels(websocketpp::log::alevel::disconnect);
|
||||
s.set_access_channels(websocketpp::log::alevel::app);
|
||||
|
||||
// Log to a file rather than stdout, as we are using stdout for real
|
||||
|
||||
// Log to a file rather than stdout, as we are using stdout for real
|
||||
// output
|
||||
log.open("output.log");
|
||||
s.get_alog().set_ostream(&log);
|
||||
s.get_elog().set_ostream(&log);
|
||||
|
||||
|
||||
// print all output to stdout
|
||||
s.register_ostream(&std::cout);
|
||||
|
||||
|
||||
// Register our message handler
|
||||
s.set_message_handler(bind(&on_message,&s,::_1,::_2));
|
||||
|
||||
|
||||
server::connection_ptr con = s.get_connection();
|
||||
|
||||
|
||||
con->start();
|
||||
|
||||
// C++ iostream's don't support the idea of asynchronous i/o. As such
|
||||
// there are two input strategies demonstrated here. Buffered I/O will
|
||||
// read from stdin in chunks until EOF. This works very well for
|
||||
|
||||
// C++ iostream's don't support the idea of asynchronous i/o. As such
|
||||
// there are two input strategies demonstrated here. Buffered I/O will
|
||||
// read from stdin in chunks until EOF. This works very well for
|
||||
// replaying canned connections as would be done in automated testing.
|
||||
//
|
||||
// If the server is being used live however, assuming input is being
|
||||
// piped from elsewhere in realtime, this strategy will result in small
|
||||
// messages being buffered forever. The non-buffered strategy below
|
||||
// reads characters from stdin one at a time. This is inefficient and
|
||||
// for more serious uses should be replaced with a platform specific
|
||||
// If the server is being used live however, assuming input is being
|
||||
// piped from elsewhere in realtime, this strategy will result in small
|
||||
// messages being buffered forever. The non-buffered strategy below
|
||||
// reads characters from stdin one at a time. This is inefficient and
|
||||
// for more serious uses should be replaced with a platform specific
|
||||
// asyncronous i/o technique like select, poll, IOCP, etc
|
||||
bool buffered_io = false;
|
||||
|
||||
|
||||
if (buffered_io) {
|
||||
std::cin >> *con;
|
||||
con->eof();
|
||||
} else {
|
||||
char a;
|
||||
while(std::cin.get(a)) {
|
||||
con->readsome(&a,1);
|
||||
con->read_some(&a,1);
|
||||
}
|
||||
con->eof();
|
||||
}
|
||||
} catch (const std::exception & e) {
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
log.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
init_target (print_server)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
final_target ()
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('print_server', ["print_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('print_server', ["print_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
typedef websocketpp::server<websocketpp::config::asio> server;
|
||||
|
||||
void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg) {
|
||||
void on_message(websocketpp::connection_hdl, server::message_ptr msg) {
|
||||
std::cout << msg->get_payload() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,20 +13,20 @@ class broadcast_server {
|
||||
public:
|
||||
broadcast_server() {
|
||||
m_server.init_asio();
|
||||
|
||||
|
||||
m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1));
|
||||
m_server.set_close_handler(bind(&broadcast_server::on_close,this,::_1));
|
||||
m_server.set_message_handler(bind(&broadcast_server::on_message,this,::_1,::_2));
|
||||
}
|
||||
|
||||
|
||||
void on_open(connection_hdl hdl) {
|
||||
m_connections.insert(hdl);
|
||||
}
|
||||
|
||||
|
||||
void on_close(connection_hdl hdl) {
|
||||
m_connections.erase(hdl);
|
||||
}
|
||||
|
||||
|
||||
void on_message(connection_hdl hdl, server::message_ptr msg) {
|
||||
for (auto it : m_connections) {
|
||||
m_server.send(it,msg);
|
||||
@@ -48,4 +48,4 @@ private:
|
||||
int main() {
|
||||
broadcast_server server;
|
||||
server.run(9002);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Main development example
|
||||
## SIP client example
|
||||
##
|
||||
|
||||
Import('env')
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('sip_client', ["sip_client.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('sip_client', ["sip_client.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||
|
||||
@@ -21,12 +21,12 @@ typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
|
||||
client sip_client;
|
||||
|
||||
|
||||
bool received;
|
||||
bool received;
|
||||
|
||||
void on_open(client* c, websocketpp::connection_hdl hdl) {
|
||||
// now it is safe to use the connection
|
||||
std::cout << "connection ready" << std::endl;
|
||||
|
||||
|
||||
received=false;
|
||||
// Send a SIP OPTIONS message to the server:
|
||||
std::string SIP_msg="OPTIONS sip:carol@chicago.com SIP/2.0\r\nVia: SIP/2.0/WS df7jal23ls0d.invalid;rport;branch=z9hG4bKhjhs8ass877\r\nMax-Forwards: 70\r\nTo: <sip:carol@chicago.com>\r\nFrom: Alice <sip:alice@atlanta.com>;tag=1928301774\r\nCall-ID: a84b4c76e66710\r\nCSeq: 63104 OPTIONS\r\nContact: <sip:alice@pc33.atlanta.com>\r\nAccept: application/sdp\r\nContent-Length: 0\r\n\r\n";
|
||||
@@ -35,32 +35,32 @@ void on_open(client* c, websocketpp::connection_hdl hdl) {
|
||||
|
||||
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
client::connection_ptr con = sip_client.get_con_from_hdl(hdl);
|
||||
|
||||
|
||||
std::cout << "Received a reply:" << std::endl;
|
||||
fwrite(msg->get_payload().c_str(), msg->get_payload().size(), 1, stdout);
|
||||
received=true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
std::string uri = "ws://localhost:9001";
|
||||
|
||||
if (argc == 2) {
|
||||
uri = argv[1];
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
std::string uri = "ws://localhost:9001";
|
||||
|
||||
if (argc == 2) {
|
||||
uri = argv[1];
|
||||
}
|
||||
|
||||
try {
|
||||
// We expect there to be a lot of errors, so suppress them
|
||||
sip_client.clear_access_channels(websocketpp::log::alevel::all);
|
||||
sip_client.clear_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
|
||||
// Initialize ASIO
|
||||
sip_client.init_asio();
|
||||
|
||||
|
||||
// Register our handlers
|
||||
sip_client.set_open_handler(bind(&on_open,&sip_client,::_1));
|
||||
sip_client.set_message_handler(bind(&on_message,&sip_client,::_1,::_2));
|
||||
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
client::connection_ptr con = sip_client.get_connection(uri, ec);
|
||||
|
||||
@@ -68,21 +68,17 @@ int main(int argc, char* argv[]) {
|
||||
con->add_subprotocol("sip");
|
||||
|
||||
sip_client.connect(con);
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
sip_client.run();
|
||||
|
||||
|
||||
while(!received) {
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
||||
}
|
||||
|
||||
|
||||
std::cout << "done" << std::endl;
|
||||
|
||||
} catch (const std::exception & e) {
|
||||
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('subprotocol_server', ["subprotocol_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('subprotocol_server', ["subprotocol_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -14,20 +14,20 @@ using websocketpp::lib::ref;
|
||||
|
||||
bool validate(server & s, connection_hdl hdl) {
|
||||
server::connection_ptr con = s.get_con_from_hdl(hdl);
|
||||
|
||||
|
||||
std::cout << "Cache-Control: " << con->get_request_header("Cache-Control") << std::endl;
|
||||
|
||||
|
||||
const std::vector<std::string> & subp_requests = con->get_requested_subprotocols();
|
||||
std::vector<std::string>::const_iterator it;
|
||||
|
||||
|
||||
for (it = subp_requests.begin(); it != subp_requests.end(); ++it) {
|
||||
std::cout << "Requested: " << *it << std::endl;
|
||||
}
|
||||
|
||||
|
||||
if (subp_requests.size() > 0) {
|
||||
con->select_subprotocol(subp_requests[0]);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,11 +42,7 @@ int main() {
|
||||
s.start_accept();
|
||||
|
||||
s.run();
|
||||
} catch (const std::exception & e) {
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
init_target (telemetry_client)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
final_target ()
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('telemetry_client', ["telemetry_client.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('telemetry_client', ["telemetry_client.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -9,123 +9,129 @@
|
||||
/**
|
||||
* The telemetry client connects to a WebSocket server and sends a message every
|
||||
* second containing an integer count. This example can be used as the basis for
|
||||
* programs where a client connects and pushes data for logging, stress/load
|
||||
* programs where a client connects and pushes data for logging, stress/load
|
||||
* testing, etc.
|
||||
*/
|
||||
class telemetry_client {
|
||||
public:
|
||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||
typedef websocketpp::lib::lock_guard<websocketpp::lib::mutex> scoped_lock;
|
||||
|
||||
|
||||
telemetry_client() : m_open(false),m_done(false) {
|
||||
// set up access channels to only log interesting things
|
||||
m_client.clear_access_channels(websocketpp::log::alevel::all);
|
||||
m_client.set_access_channels(websocketpp::log::alevel::connect);
|
||||
m_client.set_access_channels(websocketpp::log::alevel::disconnect);
|
||||
m_client.set_access_channels(websocketpp::log::alevel::app);
|
||||
|
||||
|
||||
// Initialize the Asio transport policy
|
||||
m_client.init_asio();
|
||||
|
||||
|
||||
// Bind the handlers we are using
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::bind;
|
||||
m_client.set_open_handler(bind(&telemetry_client::on_open,this,::_1));
|
||||
m_client.set_close_handler(bind(&telemetry_client::on_close,this,::_1));
|
||||
m_client.set_fail_handler(bind(&telemetry_client::on_fail,this,::_1));
|
||||
m_client.set_open_handler(bind(&telemetry_client::on_open,this,_1));
|
||||
m_client.set_close_handler(bind(&telemetry_client::on_close,this,_1));
|
||||
m_client.set_fail_handler(bind(&telemetry_client::on_fail,this,_1));
|
||||
}
|
||||
|
||||
|
||||
// This method will block until the connection is complete
|
||||
void run(const std::string & uri) {
|
||||
// Create a new connection to the given URI
|
||||
// Create a new connection to the given URI
|
||||
websocketpp::lib::error_code ec;
|
||||
client::connection_ptr con = m_client.get_connection(uri, ec);
|
||||
if (ec) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Get Connection Error: "+ec.message());
|
||||
return;
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Get Connection Error: "+ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab a handle for this connection so we can talk to it in a thread
|
||||
|
||||
// Grab a handle for this connection so we can talk to it in a thread
|
||||
// safe manor after the event loop starts.
|
||||
m_hdl = con->get_handle();
|
||||
|
||||
|
||||
// Queue the connection. No DNS queries or network connections will be
|
||||
// made until the io_service event loop is run.
|
||||
m_client.connect(con);
|
||||
|
||||
|
||||
// Create a thread to run the ASIO io_service event loop
|
||||
websocketpp::lib::thread asio_thread(&client::run, &m_client);
|
||||
|
||||
|
||||
// Create a thread to run the telemetry loop
|
||||
websocketpp::lib::thread telemetry_thread(&telemetry_client::telemetry_loop,this);
|
||||
|
||||
|
||||
asio_thread.join();
|
||||
telemetry_thread.join();
|
||||
}
|
||||
|
||||
|
||||
// The open handler will signal that we are ready to start sending telemetry
|
||||
void on_open(websocketpp::connection_hdl hdl) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
void on_open(websocketpp::connection_hdl) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Connection opened, starting telemetry!");
|
||||
|
||||
|
||||
scoped_lock guard(m_lock);
|
||||
m_open = true;
|
||||
}
|
||||
|
||||
|
||||
// The close handler will signal that we should stop sending telemetry
|
||||
void on_close(websocketpp::connection_hdl hdl) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
void on_close(websocketpp::connection_hdl) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Connection closed, stopping telemetry!");
|
||||
|
||||
|
||||
scoped_lock guard(m_lock);
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
|
||||
// The fail handler will signal that we should stop sending telemetry
|
||||
void on_fail(websocketpp::connection_hdl hdl) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
void on_fail(websocketpp::connection_hdl) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Connection failed, stopping telemetry!");
|
||||
|
||||
|
||||
scoped_lock guard(m_lock);
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
|
||||
void telemetry_loop() {
|
||||
uint64_t count = 0;
|
||||
std::stringstream val;
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
while(1) {
|
||||
bool wait = false;
|
||||
|
||||
{
|
||||
scoped_lock guard(m_lock);
|
||||
// If the connection has been closed, stop generating telemetry
|
||||
if (m_done) {break;}
|
||||
|
||||
|
||||
// If the connection hasn't been opened yet wait a bit and retry
|
||||
if (!m_open) {
|
||||
sleep(1);
|
||||
continue;
|
||||
wait = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (wait) {
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
val.str("");
|
||||
val << "count is " << count++;
|
||||
|
||||
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app, val.str());
|
||||
m_client.send(m_hdl,val.str(),websocketpp::frame::opcode::text,ec);
|
||||
|
||||
|
||||
// The most likely error that we will get is that the connection is
|
||||
// not in the right state. Usually this means we tried to send a
|
||||
// message to a connection that was closed or in the process of
|
||||
// closing. While many errors here can be easily recovered from,
|
||||
// not in the right state. Usually this means we tried to send a
|
||||
// message to a connection that was closed or in the process of
|
||||
// closing. While many errors here can be easily recovered from,
|
||||
// in this simple example, we'll stop the telemetry loop.
|
||||
if (ec) {
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Send Error: "+ec.message());
|
||||
m_client.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Send Error: "+ec.message());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
@@ -139,12 +145,12 @@ private:
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
telemetry_client c;
|
||||
|
||||
|
||||
std::string uri = "ws://localhost:9002";
|
||||
|
||||
|
||||
if (argc == 2) {
|
||||
uri = argv[1];
|
||||
}
|
||||
|
||||
|
||||
c.run(uri);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
init_target (telemetry_server)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
final_target ()
|
||||
@@ -15,9 +15,9 @@ prgs = []
|
||||
# if a C++11 environment is available build using that, otherwise use boost
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
|
||||
prgs += env_cpp11.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -0,0 +1,85 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WebSocket++ Telemetry Client</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
var ws;
|
||||
var url;
|
||||
|
||||
function connect() {
|
||||
url = document.getElementById("server_url").value;
|
||||
|
||||
if ("WebSocket" in window) {
|
||||
ws = new WebSocket(url);
|
||||
} else if ("MozWebSocket" in window) {
|
||||
ws = new MozWebSocket(url);
|
||||
} else {
|
||||
document.getElementById("messages").innerHTML += "This Browser does not support WebSockets<br />";
|
||||
return;
|
||||
}
|
||||
ws.onopen = function(e) {
|
||||
document.getElementById("messages").innerHTML += "Client: A connection to "+ws.url+" has been opened.<br />";
|
||||
|
||||
document.getElementById("server_url").disabled = true;
|
||||
document.getElementById("toggle_connect").innerHTML = "Disconnect";
|
||||
};
|
||||
|
||||
ws.onerror = function(e) {
|
||||
document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.<br />";
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
ws.onclose = function(e) {
|
||||
document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed. ["+e.code+(e.reason != "" ? ","+e.reason : "")+"]<br />";
|
||||
cleanup_disconnect();
|
||||
};
|
||||
|
||||
ws.onmessage = function(e) {
|
||||
document.getElementById("messages").innerHTML += "Server: "+e.data+"<br />";
|
||||
};
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
ws.close();
|
||||
cleanup_disconnect();
|
||||
}
|
||||
|
||||
function cleanup_disconnect() {
|
||||
document.getElementById("server_url").disabled = false;
|
||||
document.getElementById("toggle_connect").innerHTML = "Connect";
|
||||
}
|
||||
|
||||
function toggle_connect() {
|
||||
if (document.getElementById("server_url").disabled === false) {
|
||||
connect();
|
||||
} else {
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body,html {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
#controls {
|
||||
float:right;
|
||||
background-color: #999;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="controls">
|
||||
<div id="server">
|
||||
<input type="text" name="server_url" id="server_url" value="ws://localhost:9002" /><br />
|
||||
<button id="toggle_connect" onclick="toggle_connect();">Connect</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="messages"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,204 @@
|
||||
#include <websocketpp/config/asio_no_tls.hpp>
|
||||
|
||||
#include <websocketpp/server.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* The telemetry server accepts connections and sends a message every second to
|
||||
* each client containing an integer count. This example can be used as the
|
||||
* basis for programs that expose a stream of telemetry data for logging,
|
||||
* dashboards, etc.
|
||||
*
|
||||
* This example uses the timer based concurrency method and is self contained
|
||||
* and singled threaded. Refer to telemetry client for an example of a similar
|
||||
* telemetry setup using threads rather than timers.
|
||||
*
|
||||
* This example also includes an example simple HTTP server that serves a web
|
||||
* dashboard displaying the count. This simple design is suitable for use
|
||||
* delivering a small number of files to a small number of clients. It is ideal
|
||||
* for cases like embedded dashboards that don't want the complexity of an extra
|
||||
* HTTP server to serve static files.
|
||||
*
|
||||
* This design *will* fall over under high traffic or DoS conditions. In such
|
||||
* cases you are much better off proxying to a real HTTP server for the http
|
||||
* requests.
|
||||
*/
|
||||
class telemetry_server {
|
||||
public:
|
||||
typedef websocketpp::connection_hdl connection_hdl;
|
||||
typedef websocketpp::server<websocketpp::config::asio> server;
|
||||
typedef websocketpp::lib::lock_guard<websocketpp::lib::mutex> scoped_lock;
|
||||
|
||||
telemetry_server() : m_count(0) {
|
||||
// set up access channels to only log interesting things
|
||||
m_endpoint.clear_access_channels(websocketpp::log::alevel::all);
|
||||
m_endpoint.set_access_channels(websocketpp::log::alevel::access_core);
|
||||
m_endpoint.set_access_channels(websocketpp::log::alevel::app);
|
||||
|
||||
// Initialize the Asio transport policy
|
||||
m_endpoint.init_asio();
|
||||
|
||||
// Bind the handlers we are using
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::bind;
|
||||
m_endpoint.set_open_handler(bind(&telemetry_server::on_open,this,_1));
|
||||
m_endpoint.set_close_handler(bind(&telemetry_server::on_close,this,_1));
|
||||
m_endpoint.set_http_handler(bind(&telemetry_server::on_http,this,_1));
|
||||
}
|
||||
|
||||
void run(std::string docroot, uint16_t port) {
|
||||
std::stringstream ss;
|
||||
ss << "Running telemetry server on port "<< port <<" using docroot=" << docroot;
|
||||
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ss.str());
|
||||
|
||||
m_docroot = docroot;
|
||||
|
||||
// listen on specified port
|
||||
m_endpoint.listen(port);
|
||||
|
||||
// Start the server accept loop
|
||||
m_endpoint.start_accept();
|
||||
|
||||
// Set the initial timer to start telemetry
|
||||
set_timer();
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
try {
|
||||
m_endpoint.run();
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void set_timer() {
|
||||
m_timer = m_endpoint.set_timer(
|
||||
1000,
|
||||
websocketpp::lib::bind(
|
||||
&telemetry_server::on_timer,
|
||||
this,
|
||||
websocketpp::lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void on_timer(websocketpp::lib::error_code const & ec) {
|
||||
if (ec) {
|
||||
// there was an error, stop telemetry
|
||||
m_endpoint.get_alog().write(websocketpp::log::alevel::app,
|
||||
"Timer Error: "+ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream val;
|
||||
val << "count is " << m_count++;
|
||||
|
||||
// Broadcast count to all connections
|
||||
con_list::iterator it;
|
||||
for (it = m_connections.begin(); it != m_connections.end(); ++it) {
|
||||
m_endpoint.send(*it,val.str(),websocketpp::frame::opcode::text);
|
||||
}
|
||||
|
||||
// set timer for next telemetry check
|
||||
set_timer();
|
||||
}
|
||||
|
||||
void on_http(connection_hdl hdl) {
|
||||
// Upgrade our connection handle to a full connection_ptr
|
||||
server::connection_ptr con = m_endpoint.get_con_from_hdl(hdl);
|
||||
|
||||
std::ifstream file;
|
||||
std::string filename = con->get_uri()->get_resource();
|
||||
std::string response;
|
||||
|
||||
m_endpoint.get_alog().write(websocketpp::log::alevel::app,
|
||||
"http request1: "+filename);
|
||||
|
||||
if (filename == "/") {
|
||||
filename = m_docroot+"index.html";
|
||||
} else {
|
||||
filename = m_docroot+filename.substr(1);
|
||||
}
|
||||
|
||||
m_endpoint.get_alog().write(websocketpp::log::alevel::app,
|
||||
"http request2: "+filename);
|
||||
|
||||
file.open(filename.c_str(), std::ios::in);
|
||||
if (!file) {
|
||||
// 404 error
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "<!doctype html><html><head>"
|
||||
<< "<title>Error 404 (Resource not found)</title><body>"
|
||||
<< "<h1>Error 404</h1>"
|
||||
<< "<p>The requested URL " << filename << " was not found on this server.</p>"
|
||||
<< "</body></head></html>";
|
||||
|
||||
con->set_body(ss.str());
|
||||
con->set_status(websocketpp::http::status_code::not_found);
|
||||
return;
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
response.reserve(file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
response.assign((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
con->set_body(response);
|
||||
con->set_status(websocketpp::http::status_code::ok);
|
||||
}
|
||||
|
||||
void on_open(connection_hdl hdl) {
|
||||
m_connections.insert(hdl);
|
||||
}
|
||||
|
||||
void on_close(connection_hdl hdl) {
|
||||
m_connections.erase(hdl);
|
||||
}
|
||||
private:
|
||||
typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
|
||||
|
||||
server m_endpoint;
|
||||
con_list m_connections;
|
||||
server::timer_ptr m_timer;
|
||||
|
||||
std::string m_docroot;
|
||||
|
||||
// Telemetry data
|
||||
uint64_t m_count;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
telemetry_server s;
|
||||
|
||||
std::string docroot;
|
||||
uint16_t port = 9002;
|
||||
|
||||
if (argc == 1) {
|
||||
std::cout << "Usage: telemetry_server [documentroot] [port]" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc >= 2) {
|
||||
docroot = std::string(argv[1]);
|
||||
}
|
||||
|
||||
if (argc >= 3) {
|
||||
int i = atoi(argv[2]);
|
||||
if (i <= 0 || i > 65535) {
|
||||
std::cout << "invalid port" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
port = uint16_t(i);
|
||||
}
|
||||
|
||||
s.run(docroot, port);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
init_target (testee_client)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
final_target ()
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
## Autobahn test client example
|
||||
##
|
||||
|
||||
Import('env')
|
||||
Import('env_cpp11')
|
||||
Import('boostlibs')
|
||||
Import('platform_libs')
|
||||
Import('polyfill_libs')
|
||||
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
prgs = []
|
||||
|
||||
# if a C++11 environment is available build using that, otherwise use boost
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -17,9 +17,10 @@ int case_count = 0;
|
||||
|
||||
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
client::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||
|
||||
|
||||
if (con->get_resource() == "/getCaseCount") {
|
||||
std::cout << "Detected " << msg->get_payload() << " test cases." << std::endl;
|
||||
std::cout << "Detected " << msg->get_payload() << " test cases."
|
||||
<< std::endl;
|
||||
case_count = atoi(msg->get_payload().c_str());
|
||||
} else {
|
||||
c->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
@@ -27,56 +28,53 @@ void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Create a server endpoint
|
||||
client echo_client;
|
||||
|
||||
std::string uri = "ws://localhost:9001";
|
||||
|
||||
if (argc == 2) {
|
||||
uri = argv[1];
|
||||
}
|
||||
|
||||
try {
|
||||
// Create a server endpoint
|
||||
client c;
|
||||
|
||||
std::string uri = "ws://localhost:9001";
|
||||
|
||||
if (argc == 2) {
|
||||
uri = argv[1];
|
||||
}
|
||||
|
||||
try {
|
||||
// We expect there to be a lot of errors, so suppress them
|
||||
echo_client.clear_access_channels(websocketpp::log::alevel::all);
|
||||
echo_client.clear_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
c.clear_access_channels(websocketpp::log::alevel::all);
|
||||
c.clear_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
// Initialize ASIO
|
||||
echo_client.init_asio();
|
||||
|
||||
c.init_asio();
|
||||
|
||||
// Register our handlers
|
||||
echo_client.set_message_handler(bind(&on_message,&echo_client,::_1,::_2));
|
||||
|
||||
c.set_message_handler(bind(&on_message,&c,::_1,::_2));
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
client::connection_ptr con = echo_client.get_connection(uri+"/getCaseCount", ec);
|
||||
echo_client.connect(con);
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
echo_client.run();
|
||||
|
||||
client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec);
|
||||
c.connect(con);
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
c.run();
|
||||
|
||||
std::cout << "case count: " << case_count << std::endl;
|
||||
|
||||
|
||||
for (int i = 1; i <= case_count; i++) {
|
||||
echo_client.reset();
|
||||
|
||||
c.reset();
|
||||
|
||||
std::stringstream url;
|
||||
|
||||
url << uri << "/runCase?case=" << i << "&agent=WebSocket++/0.3.0-dev";
|
||||
|
||||
con = echo_client.get_connection(url.str(), ec);
|
||||
|
||||
echo_client.connect(con);
|
||||
|
||||
echo_client.run();
|
||||
|
||||
url << uri << "/runCase?case=" << i << "&agent="
|
||||
<< websocketpp::user_agent;
|
||||
|
||||
con = c.get_connection(url.str(), ec);
|
||||
|
||||
c.connect(con);
|
||||
|
||||
c.run();
|
||||
}
|
||||
|
||||
|
||||
std::cout << "done" << std::endl;
|
||||
|
||||
} catch (const std::exception & e) {
|
||||
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
|
||||
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -29,7 +29,44 @@
|
||||
#include <websocketpp/server.hpp>
|
||||
#include <iostream>
|
||||
|
||||
typedef websocketpp::server<websocketpp::config::asio> server;
|
||||
struct testee_config : public websocketpp::config::asio {
|
||||
// pull default settings from our core config
|
||||
typedef websocketpp::config::asio core;
|
||||
|
||||
typedef core::concurrency_type concurrency_type;
|
||||
typedef core::request_type request_type;
|
||||
typedef core::response_type response_type;
|
||||
typedef core::message_type message_type;
|
||||
typedef core::con_msg_manager_type con_msg_manager_type;
|
||||
typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
typedef core::alog_type alog_type;
|
||||
typedef core::elog_type elog_type;
|
||||
typedef core::rng_type rng_type;
|
||||
typedef core::endpoint_base endpoint_base;
|
||||
|
||||
static bool const enable_multithreading = true;
|
||||
|
||||
struct transport_config : public core::transport_config {
|
||||
typedef core::concurrency_type concurrency_type;
|
||||
typedef core::elog_type elog_type;
|
||||
typedef core::alog_type alog_type;
|
||||
typedef core::request_type request_type;
|
||||
typedef core::response_type response_type;
|
||||
|
||||
static bool const enable_multithreading = true;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
static const websocketpp::log::level elog_level =
|
||||
websocketpp::log::elevel::none;
|
||||
static const websocketpp::log::level alog_level =
|
||||
websocketpp::log::alevel::none;
|
||||
};
|
||||
|
||||
typedef websocketpp::server<testee_config> server;
|
||||
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
@@ -43,34 +80,59 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a server endpoint
|
||||
void on_socket_init(websocketpp::connection_hdl, boost::asio::ip::tcp::socket & s) {
|
||||
boost::asio::ip::tcp::no_delay option(true);
|
||||
s.set_option(option);
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
// Create a server endpoint
|
||||
server testee_server;
|
||||
|
||||
try {
|
||||
short port = 9002;
|
||||
size_t num_threads = 1;
|
||||
|
||||
if (argc == 3) {
|
||||
port = atoi(argv[1]);
|
||||
num_threads = atoi(argv[2]);
|
||||
}
|
||||
|
||||
try {
|
||||
// Total silence
|
||||
testee_server.clear_access_channels(websocketpp::log::alevel::all);
|
||||
testee_server.clear_error_channels(websocketpp::log::alevel::all);
|
||||
|
||||
// Initialize ASIO
|
||||
testee_server.init_asio();
|
||||
testee_server.set_reuse_addr(true);
|
||||
|
||||
// Register our message handler
|
||||
testee_server.set_message_handler(bind(&on_message,&testee_server,::_1,::_2));
|
||||
testee_server.set_socket_init_handler(bind(&on_socket_init,::_1,::_2));
|
||||
|
||||
// Listen on port 9002
|
||||
testee_server.listen(9002);
|
||||
// Listen on specified port with extended listen backlog
|
||||
testee_server.set_listen_backlog(8192);
|
||||
testee_server.listen(port);
|
||||
|
||||
// Start the server accept loop
|
||||
testee_server.start_accept();
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
testee_server.run();
|
||||
} catch (const std::exception & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
// Start the ASIO io_service run loop
|
||||
if (num_threads == 1) {
|
||||
testee_server.run();
|
||||
} else {
|
||||
typedef websocketpp::lib::shared_ptr<websocketpp::lib::thread> thread_ptr;
|
||||
std::vector<thread_ptr> ts;
|
||||
for (size_t i = 0; i < num_threads; i++) {
|
||||
ts.push_back(websocketpp::lib::make_shared<websocketpp::lib::thread>(&server::run, &testee_server));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_threads; i++) {
|
||||
ts[i]->join();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (websocketpp::exception const & e) {
|
||||
std::cout << "exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
file (GLOB SOURCE_FILES *.cpp)
|
||||
file (GLOB HEADER_FILES *.hpp)
|
||||
|
||||
init_target (utility_client)
|
||||
|
||||
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
link_boost ()
|
||||
final_target ()
|
||||
|
||||
@@ -6,7 +6,6 @@ Import('env_cpp11')
|
||||
Import('boostlibs')
|
||||
Import('platform_libs')
|
||||
Import('polyfill_libs')
|
||||
Import('tls_libs')
|
||||
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
@@ -15,10 +14,10 @@ prgs = []
|
||||
|
||||
# if a C++11 environment is available build using that, otherwise use boost
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env_cpp11.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
|
||||
else:
|
||||
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
|
||||
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
|
||||
prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
|
||||
|
||||
Return('prgs')
|
||||
@@ -1,126 +1,325 @@
|
||||
/**
|
||||
* This example is presently used as a scratch space. It may or may not be broken
|
||||
* at any given time.
|
||||
/*
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <websocketpp/config/asio_client.hpp>
|
||||
// **NOTE:** This file is a snapshot of the WebSocket++ utility client tutorial.
|
||||
// Additional related material can be found in the tutorials/utility_client
|
||||
// directory of the WebSocket++ repository.
|
||||
|
||||
#include <websocketpp/config/asio_no_tls_client.hpp>
|
||||
#include <websocketpp/client.hpp>
|
||||
|
||||
#include <websocketpp/common/thread.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
|
||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
|
||||
// pull out the type of messages sent by our config
|
||||
typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
typedef client::connection_ptr connection_ptr;
|
||||
|
||||
|
||||
|
||||
class perftest {
|
||||
class connection_metadata {
|
||||
public:
|
||||
typedef perftest type;
|
||||
typedef std::chrono::duration<int,std::micro> dur_type;
|
||||
|
||||
perftest () {
|
||||
m_endpoint.set_access_channels(websocketpp::log::alevel::all);
|
||||
m_endpoint.set_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
// Initialize ASIO
|
||||
m_endpoint.init_asio();
|
||||
|
||||
// Register our handlers
|
||||
m_endpoint.set_socket_init_handler(bind(&type::on_socket_init,this,::_1));
|
||||
m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1));
|
||||
m_endpoint.set_message_handler(bind(&type::on_message,this,::_1,::_2));
|
||||
m_endpoint.set_open_handler(bind(&type::on_open,this,::_1));
|
||||
m_endpoint.set_close_handler(bind(&type::on_close,this,::_1));
|
||||
}
|
||||
|
||||
void start(std::string uri) {
|
||||
websocketpp::lib::error_code ec;
|
||||
client::connection_ptr con = m_endpoint.get_connection(uri, ec);
|
||||
|
||||
if (ec) {
|
||||
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ec.message());
|
||||
}
|
||||
|
||||
//con->set_proxy("http://humupdates.uchicago.edu:8443");
|
||||
|
||||
m_endpoint.connect(con);
|
||||
|
||||
// Start the ASIO io_service run loop
|
||||
m_start = std::chrono::high_resolution_clock::now();
|
||||
m_endpoint.run();
|
||||
}
|
||||
|
||||
void on_socket_init(websocketpp::connection_hdl hdl) {
|
||||
m_socket_init = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
|
||||
m_tls_init = std::chrono::high_resolution_clock::now();
|
||||
context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
|
||||
typedef websocketpp::lib::shared_ptr<connection_metadata> ptr;
|
||||
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
connection_metadata(int id, websocketpp::connection_hdl hdl, std::string uri)
|
||||
: m_id(id)
|
||||
, m_hdl(hdl)
|
||||
, m_status("Connecting")
|
||||
, m_uri(uri)
|
||||
, m_server("N/A")
|
||||
{}
|
||||
|
||||
void on_open(client * c, websocketpp::connection_hdl hdl) {
|
||||
m_status = "Open";
|
||||
|
||||
client::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||
m_server = con->get_response_header("Server");
|
||||
}
|
||||
|
||||
void on_fail(client * c, websocketpp::connection_hdl hdl) {
|
||||
m_status = "Failed";
|
||||
|
||||
client::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||
m_server = con->get_response_header("Server");
|
||||
m_error_reason = con->get_ec().message();
|
||||
}
|
||||
|
||||
void on_close(client * c, websocketpp::connection_hdl hdl) {
|
||||
m_status = "Closed";
|
||||
client::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||
std::stringstream s;
|
||||
s << "close code: " << con->get_remote_close_code() << " ("
|
||||
<< websocketpp::close::status::get_string(con->get_remote_close_code())
|
||||
<< "), close reason: " << con->get_remote_close_reason();
|
||||
m_error_reason = s.str();
|
||||
}
|
||||
|
||||
void on_message(websocketpp::connection_hdl, client::message_ptr msg) {
|
||||
if (msg->get_opcode() == websocketpp::frame::opcode::text) {
|
||||
m_messages.push_back("<< " + msg->get_payload());
|
||||
} else {
|
||||
m_messages.push_back("<< " + websocketpp::utility::to_hex(msg->get_payload()));
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
websocketpp::connection_hdl get_hdl() const {
|
||||
return m_hdl;
|
||||
}
|
||||
|
||||
void on_open(websocketpp::connection_hdl hdl) {
|
||||
m_open = std::chrono::high_resolution_clock::now();
|
||||
m_endpoint.send(hdl, "", websocketpp::frame::opcode::text);
|
||||
int get_id() const {
|
||||
return m_id;
|
||||
}
|
||||
void on_message(websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
m_message = std::chrono::high_resolution_clock::now();
|
||||
m_endpoint.close(hdl,websocketpp::close::status::going_away,"");
|
||||
|
||||
std::string get_status() const {
|
||||
return m_status;
|
||||
}
|
||||
void on_close(websocketpp::connection_hdl hdl) {
|
||||
m_close = std::chrono::high_resolution_clock::now();
|
||||
|
||||
std::cout << "Socket Init: " << std::chrono::duration_cast<dur_type>(m_socket_init-m_start).count() << std::endl;
|
||||
std::cout << "TLS Init: " << std::chrono::duration_cast<dur_type>(m_tls_init-m_start).count() << std::endl;
|
||||
std::cout << "Open: " << std::chrono::duration_cast<dur_type>(m_open-m_start).count() << std::endl;
|
||||
std::cout << "Message: " << std::chrono::duration_cast<dur_type>(m_message-m_start).count() << std::endl;
|
||||
std::cout << "Close: " << std::chrono::duration_cast<dur_type>(m_close-m_start).count() << std::endl;
|
||||
|
||||
void record_sent_message(std::string message) {
|
||||
m_messages.push_back(">> " + message);
|
||||
}
|
||||
|
||||
friend std::ostream & operator<< (std::ostream & out, connection_metadata const & data);
|
||||
private:
|
||||
client m_endpoint;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point m_start;
|
||||
std::chrono::high_resolution_clock::time_point m_socket_init;
|
||||
std::chrono::high_resolution_clock::time_point m_tls_init;
|
||||
std::chrono::high_resolution_clock::time_point m_open;
|
||||
std::chrono::high_resolution_clock::time_point m_message;
|
||||
std::chrono::high_resolution_clock::time_point m_close;
|
||||
int m_id;
|
||||
websocketpp::connection_hdl m_hdl;
|
||||
std::string m_status;
|
||||
std::string m_uri;
|
||||
std::string m_server;
|
||||
std::string m_error_reason;
|
||||
std::vector<std::string> m_messages;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::string uri = "wss://echo.websocket.org";
|
||||
|
||||
if (argc == 2) {
|
||||
uri = argv[1];
|
||||
}
|
||||
|
||||
try {
|
||||
perftest endpoint;
|
||||
endpoint.start(uri);
|
||||
} catch (const std::exception & e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (websocketpp::lib::error_code e) {
|
||||
std::cout << e.message() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "other exception" << std::endl;
|
||||
std::ostream & operator<< (std::ostream & out, connection_metadata const & data) {
|
||||
out << "> URI: " << data.m_uri << "\n"
|
||||
<< "> Status: " << data.m_status << "\n"
|
||||
<< "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << "\n"
|
||||
<< "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason) << "\n";
|
||||
out << "> Messages Processed: (" << data.m_messages.size() << ") \n";
|
||||
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = data.m_messages.begin(); it != data.m_messages.end(); ++it) {
|
||||
out << *it << "\n";
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
class websocket_endpoint {
|
||||
public:
|
||||
websocket_endpoint () : m_next_id(0) {
|
||||
m_endpoint.clear_access_channels(websocketpp::log::alevel::all);
|
||||
m_endpoint.clear_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
m_endpoint.init_asio();
|
||||
m_endpoint.start_perpetual();
|
||||
|
||||
m_thread = websocketpp::lib::make_shared<websocketpp::lib::thread>(&client::run, &m_endpoint);
|
||||
}
|
||||
|
||||
~websocket_endpoint() {
|
||||
m_endpoint.stop_perpetual();
|
||||
|
||||
for (con_list::const_iterator it = m_connection_list.begin(); it != m_connection_list.end(); ++it) {
|
||||
if (it->second->get_status() != "Open") {
|
||||
// Only close open connections
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "> Closing connection " << it->second->get_id() << std::endl;
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
m_endpoint.close(it->second->get_hdl(), websocketpp::close::status::going_away, "", ec);
|
||||
if (ec) {
|
||||
std::cout << "> Error closing connection " << it->second->get_id() << ": "
|
||||
<< ec.message() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
m_thread->join();
|
||||
}
|
||||
|
||||
int connect(std::string const & uri) {
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
client::connection_ptr con = m_endpoint.get_connection(uri, ec);
|
||||
|
||||
if (ec) {
|
||||
std::cout << "> Connect initialization error: " << ec.message() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int new_id = m_next_id++;
|
||||
connection_metadata::ptr metadata_ptr = websocketpp::lib::make_shared<connection_metadata>(new_id, con->get_handle(), uri);
|
||||
m_connection_list[new_id] = metadata_ptr;
|
||||
|
||||
con->set_open_handler(websocketpp::lib::bind(
|
||||
&connection_metadata::on_open,
|
||||
metadata_ptr,
|
||||
&m_endpoint,
|
||||
websocketpp::lib::placeholders::_1
|
||||
));
|
||||
con->set_fail_handler(websocketpp::lib::bind(
|
||||
&connection_metadata::on_fail,
|
||||
metadata_ptr,
|
||||
&m_endpoint,
|
||||
websocketpp::lib::placeholders::_1
|
||||
));
|
||||
con->set_close_handler(websocketpp::lib::bind(
|
||||
&connection_metadata::on_close,
|
||||
metadata_ptr,
|
||||
&m_endpoint,
|
||||
websocketpp::lib::placeholders::_1
|
||||
));
|
||||
con->set_message_handler(websocketpp::lib::bind(
|
||||
&connection_metadata::on_message,
|
||||
metadata_ptr,
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2
|
||||
));
|
||||
|
||||
m_endpoint.connect(con);
|
||||
|
||||
return new_id;
|
||||
}
|
||||
|
||||
void close(int id, websocketpp::close::status::value code, std::string reason) {
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
con_list::iterator metadata_it = m_connection_list.find(id);
|
||||
if (metadata_it == m_connection_list.end()) {
|
||||
std::cout << "> No connection found with id " << id << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
m_endpoint.close(metadata_it->second->get_hdl(), code, reason, ec);
|
||||
if (ec) {
|
||||
std::cout << "> Error initiating close: " << ec.message() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void send(int id, std::string message) {
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
con_list::iterator metadata_it = m_connection_list.find(id);
|
||||
if (metadata_it == m_connection_list.end()) {
|
||||
std::cout << "> No connection found with id " << id << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
m_endpoint.send(metadata_it->second->get_hdl(), message, websocketpp::frame::opcode::text, ec);
|
||||
if (ec) {
|
||||
std::cout << "> Error sending message: " << ec.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
metadata_it->second->record_sent_message(message);
|
||||
}
|
||||
|
||||
connection_metadata::ptr get_metadata(int id) const {
|
||||
con_list::const_iterator metadata_it = m_connection_list.find(id);
|
||||
if (metadata_it == m_connection_list.end()) {
|
||||
return connection_metadata::ptr();
|
||||
} else {
|
||||
return metadata_it->second;
|
||||
}
|
||||
}
|
||||
private:
|
||||
typedef std::map<int,connection_metadata::ptr> con_list;
|
||||
|
||||
client m_endpoint;
|
||||
websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread;
|
||||
|
||||
con_list m_connection_list;
|
||||
int m_next_id;
|
||||
};
|
||||
|
||||
int main() {
|
||||
bool done = false;
|
||||
std::string input;
|
||||
websocket_endpoint endpoint;
|
||||
|
||||
while (!done) {
|
||||
std::cout << "Enter Command: ";
|
||||
std::getline(std::cin, input);
|
||||
|
||||
if (input == "quit") {
|
||||
done = true;
|
||||
} else if (input == "help") {
|
||||
std::cout
|
||||
<< "\nCommand List:\n"
|
||||
<< "connect <ws uri>\n"
|
||||
<< "send <connection id> <message>\n"
|
||||
<< "close <connection id> [<close code:default=1000>] [<close reason>]\n"
|
||||
<< "show <connection id>\n"
|
||||
<< "help: Display this help text\n"
|
||||
<< "quit: Exit the program\n"
|
||||
<< std::endl;
|
||||
} else if (input.substr(0,7) == "connect") {
|
||||
int id = endpoint.connect(input.substr(8));
|
||||
if (id != -1) {
|
||||
std::cout << "> Created connection with id " << id << std::endl;
|
||||
}
|
||||
} else if (input.substr(0,4) == "send") {
|
||||
std::stringstream ss(input);
|
||||
|
||||
std::string cmd;
|
||||
int id;
|
||||
std::string message = "";
|
||||
|
||||
ss >> cmd >> id;
|
||||
std::getline(ss,message);
|
||||
|
||||
endpoint.send(id, message);
|
||||
} else if (input.substr(0,5) == "close") {
|
||||
std::stringstream ss(input);
|
||||
|
||||
std::string cmd;
|
||||
int id;
|
||||
int close_code = websocketpp::close::status::normal;
|
||||
std::string reason = "";
|
||||
|
||||
ss >> cmd >> id >> close_code;
|
||||
std::getline(ss,reason);
|
||||
|
||||
endpoint.close(id, close_code, reason);
|
||||
} else if (input.substr(0,4) == "show") {
|
||||
int id = atoi(input.substr(5).c_str());
|
||||
|
||||
connection_metadata::ptr metadata = endpoint.get_metadata(id);
|
||||
if (metadata) {
|
||||
std::cout << *metadata << std::endl;
|
||||
} else {
|
||||
std::cout << "> Unknown connection id " << id << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "> Unrecognized Command" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,22 +1,12 @@
|
||||
WebSocket++ (0.3.x branch)
|
||||
WebSocket++ (0.6.0)
|
||||
==========================
|
||||
|
||||
WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket
|
||||
Protocol. It allows integrating WebSocket client and server functionality into
|
||||
C++ programs. It uses interchangeable network transport modules including one
|
||||
based on C++ iostreams and one based on Boost Asio.
|
||||
|
||||
*This branch is no longer "experimental". It represents the current edge release
|
||||
of the WebSocket++ library. The API of 0.3.x has some significant changes from
|
||||
0.2.x, so care should be taken when upgrading.*
|
||||
|
||||
*This branch's API is relatively stable now. Features implemented so far are
|
||||
unlikely to change (except where explicitly noted). New features will be added
|
||||
regularly until parity with the 0.2 branch is reached.*
|
||||
|
||||
*This is the preferred branch for new projects, especially those that involve
|
||||
multithreaded servers. It is better tested and documented. The 0.3.x API will
|
||||
be the basis for the 1.0 release.*
|
||||
based on raw char buffers, one based on C++ iostreams, and one based on Asio
|
||||
(either via Boost or standalone). End users can write additional transport
|
||||
policies to support other networking or event libraries as needed.
|
||||
|
||||
Major Features
|
||||
==============
|
||||
@@ -25,30 +15,33 @@ Major Features
|
||||
* Message/event based interface
|
||||
* Supports secure WebSockets (TLS), IPv6, and explicit proxies.
|
||||
* Flexible dependency management (C++11 Standard Library or Boost)
|
||||
* Interchangeable network transport modules (iostream and Boost Asio)
|
||||
* Portable, cross platform and architecture design
|
||||
* Interchangeable network transport modules (raw, iostream, Asio, or custom)
|
||||
* Portable/cross platform (Posix/Windows, 32/64bit, Intel/ARM/PPC)
|
||||
* Thread-safe
|
||||
|
||||
Get Involved
|
||||
============
|
||||
|
||||
[](https://travis-ci.org/zaphoyd/websocketpp)
|
||||
|
||||
**Project Website**
|
||||
**Project Website**
|
||||
http://www.zaphoyd.com/websocketpp/
|
||||
|
||||
**User Manual**
|
||||
**User Manual**
|
||||
http://www.zaphoyd.com/websocketpp/manual/
|
||||
|
||||
**GitHub Repository**
|
||||
**GitHub Repository**
|
||||
https://github.com/zaphoyd/websocketpp/
|
||||
|
||||
**Announcements Mailing List**
|
||||
GitHub pull requests should be submitted to the `develop` branch.
|
||||
|
||||
**Announcements Mailing List**
|
||||
http://groups.google.com/group/websocketpp-announcements/
|
||||
|
||||
**IRC Channel**
|
||||
#websocketpp (freenode)
|
||||
**IRC Channel**
|
||||
#websocketpp (freenode)
|
||||
|
||||
**Discussion / Development / Support Mailing List / Forum**
|
||||
**Discussion / Development / Support Mailing List / Forum**
|
||||
http://groups.google.com/group/websocketpp/
|
||||
|
||||
Author
|
||||
|
||||
+22
-24
@@ -8,38 +8,36 @@ Complete & Tested:
|
||||
- GCC support
|
||||
- 64 bit support
|
||||
- 32 bit support
|
||||
|
||||
Implimented, needs more testing
|
||||
- TLS support
|
||||
- echo_server & echo_server_tls
|
||||
- External io_service support
|
||||
- socket_init_handler
|
||||
- tls_init_handler
|
||||
- Logging
|
||||
- Client role
|
||||
- message_handler
|
||||
- ping_handler
|
||||
- pong_handler
|
||||
- tcp_init_handler
|
||||
- exception/error handling
|
||||
- Logging
|
||||
- Client role
|
||||
- Subprotocol negotiation
|
||||
- Hybi 00/Hixie 76 legacy protocol support
|
||||
- Performance tuning
|
||||
- Outgoing Proxy Support
|
||||
- PowerPC support
|
||||
- Visual Studio / Windows support
|
||||
|
||||
Implimented, API not finalized
|
||||
- open_handler
|
||||
- close_handler
|
||||
- echo_server & echo_server_tls
|
||||
- External io_service support
|
||||
- TLS support
|
||||
- exception/error handling
|
||||
- Timeouts
|
||||
- Subprotocol negotiation
|
||||
- validate_handler
|
||||
- Hybi 00/Hixie 76 legacy protocol support
|
||||
- Outgoing Proxy Support
|
||||
- socket_init_handler
|
||||
- tls_init_handler
|
||||
- tcp_init_handler
|
||||
|
||||
Ongoing work
|
||||
- Performance tuning
|
||||
- PowerPC support
|
||||
- Visual Studio / Windows support
|
||||
- CMake build/install support
|
||||
- http_handler
|
||||
|
||||
Needs work:
|
||||
- Timeouts
|
||||
|
||||
Non-release blocking feature roadmap
|
||||
Future feature roadmap
|
||||
- Extension support
|
||||
- permessage_compress extension
|
||||
- Message buffer pool
|
||||
- CMake build/install support
|
||||
- flow control
|
||||
- tutorials & documentation
|
||||
@@ -10,7 +10,7 @@ Import('polyfill_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs]
|
||||
|
||||
objs = env.Object('connection_boost.o', ["connection.cpp"], LIBS = BOOST_LIBS)
|
||||
objs = env.Object('connection_tu2_boost.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS)
|
||||
|
||||
+405
-42
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE connection
|
||||
@@ -30,31 +30,35 @@
|
||||
|
||||
#include "connection_tu2.hpp"
|
||||
|
||||
// NOTE: these tests currently test against hardcoded output values. I am not
|
||||
// sure how problematic this will be. If issues arise like order of headers the
|
||||
// Include special debugging transport
|
||||
//#include <websocketpp/config/minimal_client.hpp>
|
||||
#include <websocketpp/transport/debug/endpoint.hpp>
|
||||
|
||||
// NOTE: these tests currently test against hardcoded output values. I am not
|
||||
// sure how problematic this will be. If issues arise like order of headers the
|
||||
// output should be parsed by http::response and have values checked directly
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_http_request ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 500 Internal Server Error\r\nServer: " +
|
||||
std::string(websocketpp::user_agent)+"\r\n\r\n";
|
||||
|
||||
std::string o2 = run_server_test(input);
|
||||
std::string output = "HTTP/1.1 426 Upgrade Required\r\nServer: " +
|
||||
std::string(websocketpp::user_agent)+"\r\n\r\n";
|
||||
|
||||
std::string o2 = run_server_test(input);
|
||||
|
||||
BOOST_CHECK(o2 == output);
|
||||
}
|
||||
|
||||
struct connection_extension {
|
||||
connection_extension() : extension_value(5) {}
|
||||
|
||||
|
||||
int extension_method() {
|
||||
return extension_value;
|
||||
}
|
||||
|
||||
|
||||
bool is_server() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int extension_value;
|
||||
};
|
||||
|
||||
@@ -72,24 +76,74 @@ struct stub_config : public websocketpp::config::core {
|
||||
typedef core::elog_type elog_type;
|
||||
|
||||
typedef core::rng_type rng_type;
|
||||
|
||||
|
||||
typedef core::transport_type transport_type;
|
||||
|
||||
|
||||
typedef core::endpoint_base endpoint_base;
|
||||
typedef connection_extension connection_base;
|
||||
};
|
||||
|
||||
struct connection_setup {
|
||||
connection_setup(bool server)
|
||||
: c(server,"",alog,elog,rng) {}
|
||||
struct debug_config_client : public websocketpp::config::core {
|
||||
typedef debug_config_client type;
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
stub_config::alog_type alog;
|
||||
stub_config::elog_type elog;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::connection<stub_config> c;
|
||||
typedef core::concurrency_type concurrency_type;
|
||||
|
||||
typedef core::request_type request_type;
|
||||
typedef core::response_type response_type;
|
||||
|
||||
typedef core::message_type message_type;
|
||||
typedef core::con_msg_manager_type con_msg_manager_type;
|
||||
typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
typedef core::alog_type alog_type;
|
||||
typedef core::elog_type elog_type;
|
||||
|
||||
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
|
||||
|
||||
struct transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
|
||||
/// Controls compile time enabling/disabling of thread syncronization
|
||||
/// code Disabling can provide a minor performance improvement to single
|
||||
/// threaded applications
|
||||
static bool const enable_multithreading = true;
|
||||
|
||||
/// Default timer values (in ms)
|
||||
static const long timeout_socket_pre_init = 5000;
|
||||
static const long timeout_proxy = 5000;
|
||||
static const long timeout_socket_post_init = 5000;
|
||||
static const long timeout_connect = 5000;
|
||||
static const long timeout_socket_shutdown = 5000;
|
||||
};
|
||||
|
||||
/// Transport Endpoint Component
|
||||
typedef websocketpp::transport::debug::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
typedef core::endpoint_base endpoint_base;
|
||||
typedef connection_extension connection_base;
|
||||
|
||||
static const websocketpp::log::level elog_level = websocketpp::log::elevel::none;
|
||||
static const websocketpp::log::level alog_level = websocketpp::log::alevel::none;
|
||||
};
|
||||
|
||||
struct connection_setup {
|
||||
connection_setup(bool p_is_server) : c(p_is_server, "", alog, elog, rng) {}
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
stub_config::alog_type alog;
|
||||
stub_config::elog_type elog;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::connection<stub_config> c;
|
||||
};
|
||||
|
||||
typedef websocketpp::client<debug_config_client> debug_client;
|
||||
typedef websocketpp::server<debug_config_client> debug_server;
|
||||
|
||||
/*void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
}*/
|
||||
@@ -98,21 +152,59 @@ void validate_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg)
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
}
|
||||
|
||||
bool validate_set_ua(server* s, websocketpp::connection_hdl hdl) {
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
con->replace_header("Server","foo");
|
||||
return true;
|
||||
}
|
||||
|
||||
void http_func(server* s, websocketpp::connection_hdl hdl) {
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
|
||||
std::string res = con->get_resource();
|
||||
|
||||
|
||||
con->set_body(res);
|
||||
con->set_status(websocketpp::http::status_code::ok);
|
||||
}
|
||||
|
||||
void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) {
|
||||
*deferred = true;
|
||||
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
websocketpp::lib::error_code ec = con->defer_http_response();
|
||||
BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
|
||||
}
|
||||
|
||||
void check_on_fail(server* s, websocketpp::lib::error_code ec, bool & called,
|
||||
websocketpp::connection_hdl hdl)
|
||||
{
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
BOOST_CHECK_EQUAL(ec, con->get_ec());
|
||||
called = true;
|
||||
}
|
||||
|
||||
void on_open_print(server* s, websocketpp::connection_hdl hdl)
|
||||
{
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
std::cout << con->get_uri() << std::endl;
|
||||
}
|
||||
|
||||
void fail_on_open(websocketpp::connection_hdl) {
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
void fail_on_http(websocketpp::connection_hdl) {
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( connection_extensions ) {
|
||||
connection_setup env(true);
|
||||
|
||||
|
||||
BOOST_CHECK( env.c.extension_value == 5 );
|
||||
BOOST_CHECK( env.c.extension_method() == 5 );
|
||||
|
||||
|
||||
BOOST_CHECK( env.c.is_server() == true );
|
||||
}
|
||||
|
||||
@@ -121,10 +213,10 @@ BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: ";
|
||||
output+=websocketpp::user_agent;
|
||||
output+="\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
server s;
|
||||
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
|
||||
|
||||
|
||||
server s;
|
||||
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
|
||||
|
||||
BOOST_CHECK(run_server_test(s,input) == output);
|
||||
}
|
||||
|
||||
@@ -133,30 +225,301 @@ BOOST_AUTO_TEST_CASE( http_request ) {
|
||||
std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
|
||||
output+=websocketpp::user_agent;
|
||||
output+="\r\n\r\n/foo/bar";
|
||||
|
||||
server s;
|
||||
s.set_http_handler(bind(&http_func,&s,::_1));
|
||||
|
||||
|
||||
server s;
|
||||
s.set_http_handler(bind(&http_func,&s,::_1));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( deferred_http_request ) {
|
||||
std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
|
||||
output+=websocketpp::user_agent;
|
||||
output+="\r\n\r\n/foo/bar";
|
||||
|
||||
server s;
|
||||
server::connection_ptr con;
|
||||
bool deferred = false;
|
||||
s.set_http_handler(bind(&defer_http_func,&s, &deferred,::_1));
|
||||
|
||||
s.clear_access_channels(websocketpp::log::alevel::all);
|
||||
s.clear_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
std::stringstream ostream;
|
||||
s.register_ostream(&ostream);
|
||||
|
||||
con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
BOOST_CHECK(!deferred);
|
||||
BOOST_CHECK_EQUAL(ostream.str(), "");
|
||||
con->read_some(input.data(),input.size());
|
||||
BOOST_CHECK(deferred);
|
||||
BOOST_CHECK_EQUAL(ostream.str(), "");
|
||||
|
||||
con->set_body(con->get_resource());
|
||||
con->set_status(websocketpp::http::status_code::ok);
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
s.send_http_response(con->get_handle(),ec);
|
||||
BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
|
||||
BOOST_CHECK_EQUAL(ostream.str(), output);
|
||||
con->send_http_response(ec);
|
||||
BOOST_CHECK_EQUAL(ec, make_error_code(websocketpp::error::invalid_state));
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( request_no_server_header ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
server s;
|
||||
s.set_user_agent("");
|
||||
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( request_no_server_header_override ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
server s;
|
||||
s.set_user_agent("");
|
||||
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
|
||||
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
|
||||
std::string uri = "ws://localhost";
|
||||
|
||||
//std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string ref = "GET / HTTP/1.1\r\nConnection: Upgrade\r\nFoo: Bar\r\nHost: localhost\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\nSec-WebSocket-Version: 13\r\nUpgrade: websocket\r\nUser-Agent: foo\r\n\r\n";
|
||||
|
||||
std::stringstream output;
|
||||
|
||||
client e;
|
||||
e.set_access_channels(websocketpp::log::alevel::none);
|
||||
e.set_error_channels(websocketpp::log::elevel::none);
|
||||
e.set_user_agent("foo");
|
||||
e.register_ostream(&output);
|
||||
|
||||
client::connection_ptr con;
|
||||
websocketpp::lib::error_code ec;
|
||||
con = e.get_connection(uri, ec);
|
||||
con->append_header("Foo","Bar");
|
||||
e.connect(con);
|
||||
|
||||
BOOST_CHECK_EQUAL(ref, output.str());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( set_max_message_size ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
|
||||
|
||||
// After the handshake, add a single frame with a message that is too long.
|
||||
char frame0[10] = {char(0x82), char(0x83), 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
|
||||
input.append(frame0, 10);
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
// After the handshake, add a single frame with a close message with message too big
|
||||
// error code.
|
||||
char frame1[4] = {char(0x88), 0x19, 0x03, char(0xf1)};
|
||||
output.append(frame1, 4);
|
||||
output.append("A message was too large");
|
||||
|
||||
server s;
|
||||
s.set_user_agent("");
|
||||
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
|
||||
s.set_max_message_size(2);
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( websocket_fail_parse_error ) {
|
||||
std::string input = "asdf\r\n\r\n";
|
||||
|
||||
server s;
|
||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::http_parse_error);
|
||||
bool called = false;
|
||||
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
|
||||
|
||||
run_server_test(s,input,false);
|
||||
BOOST_CHECK(called);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( websocket_fail_invalid_version ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: foo\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
|
||||
server s;
|
||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::invalid_version);
|
||||
bool called = false;
|
||||
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
|
||||
|
||||
run_server_test(s,input,false);
|
||||
BOOST_CHECK(called);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( websocket_fail_unsupported_version ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 12\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
|
||||
server s;
|
||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
|
||||
bool called = false;
|
||||
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
|
||||
|
||||
run_server_test(s,input,false);
|
||||
BOOST_CHECK(called);
|
||||
}
|
||||
|
||||
/*BOOST_AUTO_TEST_CASE( websocket_fail_invalid_uri ) {
|
||||
std::string input = "GET http://345.123.123.123/foo HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
|
||||
server s;
|
||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
|
||||
bool called = false;
|
||||
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
|
||||
s.set_open_handler(bind(&on_open_print,&s,::_1));
|
||||
|
||||
std::cout << run_server_test(s,input,true) << std::endl;
|
||||
BOOST_CHECK(called);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( websocket_fail_invalid_uri_http ) {
|
||||
std::string input = "GET http://345.123.123.123/foo HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
|
||||
server s;
|
||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
|
||||
bool called = false;
|
||||
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
|
||||
s.set_open_handler(bind(&on_open_print,&s,::_1));
|
||||
|
||||
std::cout << run_server_test(s,input,true) << std::endl;
|
||||
BOOST_CHECK(called);
|
||||
}*/
|
||||
|
||||
BOOST_AUTO_TEST_CASE( websocket_fail_upgrade_required ) {
|
||||
std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
|
||||
server s;
|
||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::upgrade_required);
|
||||
bool called = false;
|
||||
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
|
||||
|
||||
run_server_test(s,input,false);
|
||||
BOOST_CHECK(called);
|
||||
}
|
||||
|
||||
// TODO: set max message size in client endpoint test case
|
||||
// TODO: set max message size mid connection test case
|
||||
// TODO: [maybe] set max message size in open handler
|
||||
|
||||
/*
|
||||
|
||||
BOOST_AUTO_TEST_CASE( user_reject_origin ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example2.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 403 Forbidden\r\nServer: "+websocketpp::USER_AGENT+"\r\n\r\n";
|
||||
|
||||
|
||||
BOOST_CHECK(run_server_test(input) == output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_text_message ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
|
||||
unsigned char frames[8] = {0x82,0x82,0xFF,0xFF,0xFF,0xFF,0xD5,0xD5};
|
||||
input.append(reinterpret_cast<char*>(frames),8);
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: "+websocketpp::USER_AGENT+"\r\nUpgrade: websocket\r\n\r\n**";
|
||||
|
||||
unsigned char frames[8] = {0x82,0x82,0xFF,0xFF,0xFF,0xFF,0xD5,0xD5};
|
||||
input.append(reinterpret_cast<char*>(frames),8);
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: "+websocketpp::USER_AGENT+"\r\nUpgrade: websocket\r\n\r\n**";
|
||||
|
||||
BOOST_CHECK( run_server_test(input) == output);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_timeout_race1 ) {
|
||||
debug_client c;
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
debug_client::connection_ptr con = c.get_connection("ws://localhost:9002", ec);
|
||||
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
// This test the case where a handshake times out immediately before the
|
||||
// handler that would have completed it gets invoked. This situation happens
|
||||
// when clients are connecting to overloaded servers and on servers that are
|
||||
// overloaded.
|
||||
c.connect(con);
|
||||
|
||||
con->expire_timer(websocketpp::lib::error_code());
|
||||
// Fullfil the write to simulate the write completing immediately after
|
||||
// timer expires
|
||||
con->fullfil_write();
|
||||
|
||||
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_timeout_race2 ) {
|
||||
debug_client c;
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
debug_client::connection_ptr con = c.get_connection("ws://localhost:9002", ec);
|
||||
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: ICX+Yqv66kxgM0FcWaLWlFLwTAI=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
// This test the case where a handshake times out immediately before the
|
||||
// handler that would have completed it gets invoked. This situation happens
|
||||
// when clients are connecting to overloaded servers and on servers that are
|
||||
// overloaded.
|
||||
c.connect(con);
|
||||
con->fullfil_write();
|
||||
|
||||
con->expire_timer(websocketpp::lib::error_code());
|
||||
// Read valid handshake to simulate receiving the handshake response
|
||||
// immediately after the timer expires
|
||||
con->read_all(output.data(),output.size());
|
||||
|
||||
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( server_handshake_timeout_race1 ) {
|
||||
debug_server s;
|
||||
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\n\r\n";
|
||||
|
||||
debug_server::connection_ptr con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
con->expire_timer(websocketpp::lib::error_code());
|
||||
// Read handshake immediately after timer expire
|
||||
con->read_all(input.data(), input.size());
|
||||
|
||||
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( server_handshake_timeout_race2 ) {
|
||||
debug_server s;
|
||||
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\n\r\n";
|
||||
|
||||
debug_server::connection_ptr con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
con->read_all(input.data(), input.size());
|
||||
|
||||
con->expire_timer(websocketpp::lib::error_code());
|
||||
// Complete write immediately after timer expire
|
||||
con->fullfil_write();
|
||||
|
||||
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "connection_tu2.hpp"
|
||||
@@ -31,27 +31,32 @@ void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
|
||||
s->send(hdl, msg->get_payload(), msg->get_opcode());
|
||||
}
|
||||
|
||||
std::string run_server_test(std::string input) {
|
||||
std::string run_server_test(std::string input, bool log) {
|
||||
server test_server;
|
||||
return run_server_test(test_server,input);
|
||||
return run_server_test(test_server,input,log);
|
||||
}
|
||||
|
||||
std::string run_server_test(server& s, std::string input) {
|
||||
std::string run_server_test(server & s, std::string input, bool log) {
|
||||
server::connection_ptr con;
|
||||
std::stringstream output;
|
||||
|
||||
s.clear_access_channels(websocketpp::log::alevel::all);
|
||||
s.clear_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
s.register_ostream(&output);
|
||||
|
||||
con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
std::stringstream channel;
|
||||
|
||||
channel << input;
|
||||
channel >> *con;
|
||||
|
||||
return output.str();
|
||||
}
|
||||
|
||||
if (log) {
|
||||
s.set_access_channels(websocketpp::log::alevel::all);
|
||||
s.set_error_channels(websocketpp::log::elevel::all);
|
||||
} else {
|
||||
s.clear_access_channels(websocketpp::log::alevel::all);
|
||||
s.clear_error_channels(websocketpp::log::elevel::all);
|
||||
}
|
||||
|
||||
s.register_ostream(&output);
|
||||
|
||||
con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
std::stringstream channel;
|
||||
|
||||
channel << input;
|
||||
channel >> *con;
|
||||
|
||||
return output.str();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
@@ -30,27 +30,22 @@
|
||||
|
||||
// Test Environment:
|
||||
// server, no TLS, no locks, iostream based transport
|
||||
#include <websocketpp/config/debug.hpp>
|
||||
#include <websocketpp/config/core.hpp>
|
||||
#include <websocketpp/server.hpp>
|
||||
#include <websocketpp/client.hpp>
|
||||
|
||||
typedef websocketpp::server<websocketpp::config::core> server;
|
||||
/// NOTE: the "server" config is being used for the client here because we don't
|
||||
/// want to pull in the real RNG. A better way to do this might be a custom
|
||||
/// client config with the RNG explicitly stubbed out.
|
||||
typedef websocketpp::client<websocketpp::config::core> client;
|
||||
typedef websocketpp::config::core::message_type::ptr message_ptr;
|
||||
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
|
||||
/*class echo_handler : public server::handler {
|
||||
bool validate(connection_ptr con) {
|
||||
std::cout << "handler validate" << std::endl;
|
||||
if (con->get_origin() != "http://www.example.com") {
|
||||
con->set_status(websocketpp::http::status_code::FORBIDDEN);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};*/
|
||||
|
||||
void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg);
|
||||
std::string run_server_test(std::string input);
|
||||
std::string run_server_test(server & s,std::string input);
|
||||
std::string run_server_test(std::string input, bool log = false);
|
||||
std::string run_server_test(server & s, std::string input, bool log = false);
|
||||
@@ -11,7 +11,7 @@ Import('tls_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs] + [tls_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs] + [tls_libs]
|
||||
|
||||
objs = env.Object('endpoint_boost.o', ["endpoint.cpp"], LIBS = BOOST_LIBS)
|
||||
prgs = env.Program('test_endpoint_boost', ["endpoint_boost.o"], LIBS = BOOST_LIBS)
|
||||
|
||||
+70
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2015, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE endpoint
|
||||
@@ -57,17 +57,46 @@ BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) {
|
||||
s.init_asio(&ios);
|
||||
}
|
||||
|
||||
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
BOOST_AUTO_TEST_CASE( move_construct_server_core ) {
|
||||
websocketpp::server<websocketpp::config::core> s1;
|
||||
|
||||
websocketpp::server<websocketpp::config::core> s2(std::move(s1));
|
||||
}
|
||||
|
||||
/*
|
||||
// temporary disable because library doesn't pass
|
||||
BOOST_AUTO_TEST_CASE( emplace ) {
|
||||
std::stringstream out1;
|
||||
std::stringstream out2;
|
||||
|
||||
std::vector<websocketpp::server<websocketpp::config::asio_tls>> v;
|
||||
|
||||
v.emplace_back();
|
||||
v.emplace_back();
|
||||
|
||||
v[0].get_alog().set_ostream(&out1);
|
||||
v[0].get_alog().set_ostream(&out2);
|
||||
|
||||
v[0].get_alog().write(websocketpp::log::alevel::app,"devel0");
|
||||
v[1].get_alog().write(websocketpp::log::alevel::app,"devel1");
|
||||
BOOST_CHECK( out1.str().size() > 0 );
|
||||
BOOST_CHECK( out2.str().size() > 0 );
|
||||
}*/
|
||||
|
||||
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
|
||||
struct endpoint_extension {
|
||||
endpoint_extension() : extension_value(5) {}
|
||||
|
||||
|
||||
int extension_method() {
|
||||
return extension_value;
|
||||
}
|
||||
|
||||
|
||||
bool is_server() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int extension_value;
|
||||
};
|
||||
|
||||
@@ -85,17 +114,42 @@ struct stub_config : public websocketpp::config::core {
|
||||
typedef core::elog_type elog_type;
|
||||
|
||||
typedef core::rng_type rng_type;
|
||||
|
||||
|
||||
typedef core::transport_type transport_type;
|
||||
|
||||
|
||||
typedef endpoint_extension endpoint_base;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( endpoint_extensions ) {
|
||||
websocketpp::server<stub_config> s;
|
||||
|
||||
BOOST_CHECK( s.extension_value == 5 );
|
||||
BOOST_CHECK( s.extension_method() == 5 );
|
||||
|
||||
BOOST_CHECK( s.is_server() == true );
|
||||
|
||||
BOOST_CHECK_EQUAL( s.extension_value, 5 );
|
||||
BOOST_CHECK_EQUAL( s.extension_method(), 5 );
|
||||
|
||||
BOOST_CHECK( s.is_server() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) {
|
||||
using websocketpp::transport::asio::error::make_error_code;
|
||||
using websocketpp::transport::asio::error::pass_through;
|
||||
|
||||
websocketpp::server<websocketpp::config::asio> server1;
|
||||
websocketpp::server<websocketpp::config::asio> server2;
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
server1.init_asio();
|
||||
server2.init_asio();
|
||||
|
||||
boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::address::from_string("127.0.0.1"), 12345);
|
||||
boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::address::from_string("127.0.0.1"), 23456);
|
||||
|
||||
server1.listen(ep1, ec);
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
server2.listen(ep1, ec);
|
||||
BOOST_REQUIRE_EQUAL(ec, make_error_code(pass_through));
|
||||
|
||||
server2.listen(ep2, ec);
|
||||
BOOST_CHECK(!ec);
|
||||
}
|
||||
@@ -10,14 +10,18 @@ Import('polyfill_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system','regex'],env) + [platform_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs] + ['z']
|
||||
|
||||
objs = env.Object('extension_boost.o', ["extension.cpp"], LIBS = BOOST_LIBS)
|
||||
objs += env.Object('permessage_deflate_boost.o', ["permessage_deflate.cpp"], LIBS = BOOST_LIBS)
|
||||
prgs = env.Program('test_extension_boost', ["extension_boost.o"], LIBS = BOOST_LIBS)
|
||||
prgs += env.Program('test_permessage_deflate_boost', ["permessage_deflate_boost.o"], LIBS = BOOST_LIBS)
|
||||
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
|
||||
objs += env_cpp11.Object('extension_stl.o', ["extension.cpp"], LIBS = BOOST_LIBS_CPP11)
|
||||
objs += env_cpp11.Object('permessage_deflate_stl.o', ["permessage_deflate.cpp"], LIBS = BOOST_LIBS_CPP11)
|
||||
prgs += env_cpp11.Program('test_extension_stl', ["extension_stl.o"], LIBS = BOOST_LIBS_CPP11)
|
||||
prgs += env_cpp11.Program('test_permessage_deflate_stl', ["permessage_deflate_stl.o"], LIBS = BOOST_LIBS_CPP11)
|
||||
|
||||
Return('prgs')
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE extension
|
||||
|
||||
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE permessage_deflate
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <websocketpp/error.hpp>
|
||||
|
||||
#include <websocketpp/extensions/extension.hpp>
|
||||
#include <websocketpp/extensions/permessage_deflate/disabled.hpp>
|
||||
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/utilities.hpp>
|
||||
#include <iostream>
|
||||
|
||||
class config {};
|
||||
|
||||
typedef websocketpp::extensions::permessage_deflate::enabled<config> enabled_type;
|
||||
typedef websocketpp::extensions::permessage_deflate::disabled<config> disabled_type;
|
||||
|
||||
struct ext_vars {
|
||||
enabled_type exts;
|
||||
enabled_type extc;
|
||||
websocketpp::lib::error_code ec;
|
||||
websocketpp::err_str_pair esp;
|
||||
websocketpp::http::attribute_list attr;
|
||||
};
|
||||
namespace pmde = websocketpp::extensions::permessage_deflate::error;
|
||||
namespace pmd_mode = websocketpp::extensions::permessage_deflate::mode;
|
||||
|
||||
// Ensure the disabled extension behaves appropriately disabled
|
||||
|
||||
BOOST_AUTO_TEST_CASE( disabled_is_disabled ) {
|
||||
disabled_type exts;
|
||||
BOOST_CHECK( !exts.is_implemented() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( disabled_is_off ) {
|
||||
disabled_type exts;
|
||||
BOOST_CHECK( !exts.is_enabled() );
|
||||
}
|
||||
|
||||
// Ensure the enabled version actually works
|
||||
|
||||
BOOST_AUTO_TEST_CASE( enabled_is_enabled ) {
|
||||
ext_vars v;
|
||||
BOOST_CHECK( v.exts.is_implemented() );
|
||||
BOOST_CHECK( v.extc.is_implemented() );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( enabled_starts_disabled ) {
|
||||
ext_vars v;
|
||||
BOOST_CHECK( !v.exts.is_enabled() );
|
||||
BOOST_CHECK( !v.extc.is_enabled() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiation_empty_attr ) {
|
||||
ext_vars v;
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiation_invalid_attr ) {
|
||||
ext_vars v;
|
||||
v.attr["foo"] = "bar";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( !v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attributes) );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "");
|
||||
}
|
||||
|
||||
// Negotiate s2c_no_context_takeover
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover_invalid ) {
|
||||
ext_vars v;
|
||||
v.attr["s2c_no_context_takeover"] = "foo";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( !v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover ) {
|
||||
ext_vars v;
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover_server_initiated ) {
|
||||
ext_vars v;
|
||||
|
||||
v.exts.enable_s2c_no_context_takeover();
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover");
|
||||
}
|
||||
|
||||
// Negotiate c2s_no_context_takeover
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover_invalid ) {
|
||||
ext_vars v;
|
||||
v.attr["c2s_no_context_takeover"] = "foo";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( !v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover ) {
|
||||
ext_vars v;
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover_server_initiated ) {
|
||||
ext_vars v;
|
||||
|
||||
v.exts.enable_c2s_no_context_takeover();
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover");
|
||||
}
|
||||
|
||||
|
||||
// Negotiate s2c_max_window_bits
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_invalid ) {
|
||||
ext_vars v;
|
||||
|
||||
std::vector<std::string> values;
|
||||
values.push_back("");
|
||||
values.push_back("foo");
|
||||
values.push_back("7");
|
||||
values.push_back("16");
|
||||
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
v.attr["s2c_max_window_bits"] = *it;
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( !v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_valid ) {
|
||||
ext_vars v;
|
||||
v.attr["s2c_max_window_bits"] = "8";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
|
||||
|
||||
v.attr["s2c_max_window_bits"] = "15";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( invalid_set_s2c_max_window_bits ) {
|
||||
ext_vars v;
|
||||
|
||||
v.ec = v.exts.set_s2c_max_window_bits(7,pmd_mode::decline);
|
||||
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
|
||||
|
||||
v.ec = v.exts.set_s2c_max_window_bits(16,pmd_mode::decline);
|
||||
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_decline ) {
|
||||
ext_vars v;
|
||||
v.attr["s2c_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::decline);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_accept ) {
|
||||
ext_vars v;
|
||||
v.attr["s2c_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::accept);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_largest ) {
|
||||
ext_vars v;
|
||||
v.attr["s2c_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::largest);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_smallest ) {
|
||||
ext_vars v;
|
||||
v.attr["s2c_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::smallest);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
|
||||
}
|
||||
|
||||
// Negotiate s2c_max_window_bits
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_invalid ) {
|
||||
ext_vars v;
|
||||
|
||||
std::vector<std::string> values;
|
||||
values.push_back("foo");
|
||||
values.push_back("7");
|
||||
values.push_back("16");
|
||||
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
v.attr["c2s_max_window_bits"] = *it;
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( !v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_valid ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["c2s_max_window_bits"] = "";
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
|
||||
|
||||
v.attr["c2s_max_window_bits"] = "8";
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
|
||||
|
||||
v.attr["c2s_max_window_bits"] = "15";
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( invalid_set_c2s_max_window_bits ) {
|
||||
ext_vars v;
|
||||
|
||||
v.ec = v.exts.set_c2s_max_window_bits(7,pmd_mode::decline);
|
||||
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
|
||||
|
||||
v.ec = v.exts.set_c2s_max_window_bits(16,pmd_mode::decline);
|
||||
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_decline ) {
|
||||
ext_vars v;
|
||||
v.attr["c2s_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_c2s_max_window_bits(8,pmd_mode::decline);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_accept ) {
|
||||
ext_vars v;
|
||||
v.attr["c2s_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_c2s_max_window_bits(15,pmd_mode::accept);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_largest ) {
|
||||
ext_vars v;
|
||||
v.attr["c2s_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_c2s_max_window_bits(15,pmd_mode::largest);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_smallest ) {
|
||||
ext_vars v;
|
||||
v.attr["c2s_max_window_bits"] = "8";
|
||||
|
||||
v.ec = v.exts.set_c2s_max_window_bits(15,pmd_mode::smallest);
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
|
||||
}
|
||||
|
||||
|
||||
// Combinations with 2
|
||||
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated1 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated2 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
v.attr["s2c_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; s2c_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated3 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
v.attr["c2s_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated4 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
v.attr["s2c_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover; s2c_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated5 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
v.attr["c2s_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover; c2s_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated6 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_max_window_bits"] = "10";
|
||||
v.attr["c2s_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=10; c2s_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated1 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
v.attr["s2c_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover; s2c_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated2 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
v.attr["c2s_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover; c2s_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated3 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
v.attr["s2c_max_window_bits"] = "10";
|
||||
v.attr["c2s_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; s2c_max_window_bits=10; c2s_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated4 ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
v.attr["s2c_max_window_bits"] = "10";
|
||||
v.attr["c2s_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover; s2c_max_window_bits=10; c2s_max_window_bits=10");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( negotiate_four_client_initiated ) {
|
||||
ext_vars v;
|
||||
|
||||
v.attr["s2c_no_context_takeover"] = "";
|
||||
v.attr["c2s_no_context_takeover"] = "";
|
||||
v.attr["s2c_max_window_bits"] = "10";
|
||||
v.attr["c2s_max_window_bits"] = "10";
|
||||
|
||||
v.esp = v.exts.negotiate(v.attr);
|
||||
BOOST_CHECK( v.exts.is_enabled() );
|
||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
||||
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover; s2c_max_window_bits=10; c2s_max_window_bits=10");
|
||||
}
|
||||
|
||||
// Compression
|
||||
/*
|
||||
BOOST_AUTO_TEST_CASE( compress_data ) {
|
||||
ext_vars v;
|
||||
|
||||
std::string in = "Hello";
|
||||
std::string out;
|
||||
std::string in2;
|
||||
std::string out2;
|
||||
|
||||
v.exts.init();
|
||||
|
||||
v.ec = v.exts.compress(in,out);
|
||||
|
||||
std::cout << "in : " << websocketpp::utility::to_hex(in) << std::endl;
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
std::cout << "out: " << websocketpp::utility::to_hex(out) << std::endl;
|
||||
|
||||
in2 = out;
|
||||
|
||||
v.ec = v.exts.decompress(reinterpret_cast<const uint8_t *>(in2.data()),in2.size(),out2);
|
||||
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
std::cout << "out: " << websocketpp::utility::to_hex(out2) << std::endl;
|
||||
BOOST_CHECK_EQUAL( out, out2 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( decompress_data ) {
|
||||
ext_vars v;
|
||||
|
||||
uint8_t in[12] = {0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00, 0x00, 0x00, 0xff, 0xff};
|
||||
std::string out;
|
||||
|
||||
v.exts.init();
|
||||
|
||||
v.ec = v.exts.decompress(in,12,out);
|
||||
|
||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||
std::cout << "out: " << websocketpp::utility::to_hex(out) << std::endl;
|
||||
BOOST_CHECK( false );
|
||||
}
|
||||
*/
|
||||
@@ -10,7 +10,7 @@ Import('polyfill_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','regex'],env) + [platform_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework'],env) + [platform_libs]
|
||||
|
||||
objs = env.Object('parser_boost.o', ["parser.cpp"], LIBS = BOOST_LIBS)
|
||||
prgs = env.Program('test_http_boost', ["parser_boost.o"], LIBS = BOOST_LIBS)
|
||||
|
||||
+486
-252
File diff suppressed because it is too large.
Load diff
+108
-108
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
@@ -31,111 +31,111 @@
|
||||
|
||||
class scoped_timer {
|
||||
public:
|
||||
scoped_timer(std::string i) : m_id(i),m_start(std::chrono::steady_clock::now()) {
|
||||
std::cout << "Clock " << i << ": ";
|
||||
}
|
||||
~scoped_timer() {
|
||||
std::chrono::nanoseconds time_taken = std::chrono::steady_clock::now()-m_start;
|
||||
|
||||
//nanoseconds_per_test
|
||||
|
||||
//tests_per_second
|
||||
|
||||
//1000000000.0/(double(time_taken.count())/1000.0)
|
||||
|
||||
std::cout << 1000000000.0/(double(time_taken.count())/1000.0) << std::endl;
|
||||
|
||||
//std::cout << (1.0/double(time_taken.count())) * double(1000000000*1000) << std::endl;
|
||||
}
|
||||
|
||||
scoped_timer(std::string i) : m_id(i),m_start(std::chrono::steady_clock::now()) {
|
||||
std::cout << "Clock " << i << ": ";
|
||||
}
|
||||
~scoped_timer() {
|
||||
std::chrono::nanoseconds time_taken = std::chrono::steady_clock::now()-m_start;
|
||||
|
||||
//nanoseconds_per_test
|
||||
|
||||
//tests_per_second
|
||||
|
||||
//1000000000.0/(double(time_taken.count())/1000.0)
|
||||
|
||||
std::cout << 1000000000.0/(double(time_taken.count())/1000.0) << std::endl;
|
||||
|
||||
//std::cout << (1.0/double(time_taken.count())) * double(1000000000*1000) << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_id;
|
||||
std::chrono::steady_clock::time_point m_start;
|
||||
std::string m_id;
|
||||
std::chrono::steady_clock::time_point m_start;
|
||||
};
|
||||
|
||||
int main() {
|
||||
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
|
||||
|
||||
std::string firefox = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string firefox1 = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\n";
|
||||
|
||||
std::string firefox2 = "Accept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
{
|
||||
scoped_timer timer("Simplest 1 chop");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume(raw.c_str(),raw.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
scoped_timer timer("FireFox, 1 chop, consume old");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume2(firefox.c_str(),firefox.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
scoped_timer timer("FireFox, 1 chop");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume(firefox.c_str(),firefox.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
scoped_timer timer("FireFox, 2 chop");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume(firefox1.c_str(),firefox1.size());
|
||||
r.consume(firefox2.c_str(),firefox2.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
|
||||
|
||||
std::string firefox = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string firefox1 = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\n";
|
||||
|
||||
std::string firefox2 = "Accept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
{
|
||||
scoped_timer timer("Simplest 1 chop");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume(raw.c_str(),raw.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
scoped_timer timer("FireFox, 1 chop, consume old");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume2(firefox.c_str(),firefox.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
scoped_timer timer("FireFox, 1 chop");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume(firefox.c_str(),firefox.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
scoped_timer timer("FireFox, 2 chop");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
try {
|
||||
r.consume(firefox1.c_str(),firefox1.size());
|
||||
r.consume(firefox2.c_str(),firefox2.size());
|
||||
} catch (...) {
|
||||
std::cout << "exception" << std::endl;
|
||||
}
|
||||
|
||||
if (!r.ready()) {
|
||||
std::cout << "error" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ Import('polyfill_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs]
|
||||
|
||||
objs = env.Object('logger_basic_boost.o', ["basic.cpp"], LIBS = BOOST_LIBS)
|
||||
prgs = env.Program('logger_basic_boost', ["logger_basic_boost.o"], LIBS = BOOST_LIBS)
|
||||
|
||||
+81
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE basic_log
|
||||
@@ -34,18 +34,20 @@
|
||||
#include <websocketpp/concurrency/none.hpp>
|
||||
#include <websocketpp/concurrency/basic.hpp>
|
||||
|
||||
typedef websocketpp::log::basic<websocketpp::concurrency::basic,websocketpp::log::alevel> basic_access_log_type;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( is_token_char ) {
|
||||
typedef websocketpp::log::basic<websocketpp::concurrency::none,websocketpp::log::elevel> error_log;
|
||||
|
||||
|
||||
error_log elog;
|
||||
|
||||
|
||||
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::info ) == true );
|
||||
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::warn ) == true );
|
||||
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::rerror ) == true );
|
||||
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::fatal ) == true );
|
||||
|
||||
|
||||
elog.set_channels(websocketpp::log::elevel::info);
|
||||
|
||||
|
||||
elog.write(websocketpp::log::elevel::info,"Information");
|
||||
elog.write(websocketpp::log::elevel::warn,"A warning");
|
||||
elog.write(websocketpp::log::elevel::rerror,"A error");
|
||||
@@ -54,13 +56,13 @@ BOOST_AUTO_TEST_CASE( is_token_char ) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE( access_clear ) {
|
||||
typedef websocketpp::log::basic<websocketpp::concurrency::none,websocketpp::log::alevel> access_log;
|
||||
|
||||
|
||||
std::stringstream out;
|
||||
access_log logger(0xffffffff,&out);
|
||||
|
||||
|
||||
// clear all channels
|
||||
logger.clear_channels(0xffffffff);
|
||||
|
||||
|
||||
// writes shouldn't happen
|
||||
logger.write(websocketpp::log::alevel::devel,"devel");
|
||||
//std::cout << "|" << out.str() << "|" << std::endl;
|
||||
@@ -69,13 +71,75 @@ BOOST_AUTO_TEST_CASE( access_clear ) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_concurrency ) {
|
||||
typedef websocketpp::log::basic<websocketpp::concurrency::basic,websocketpp::log::alevel> access_log;
|
||||
|
||||
|
||||
std::stringstream out;
|
||||
access_log logger(0xffffffff,&out);
|
||||
|
||||
|
||||
logger.set_channels(0xffffffff);
|
||||
|
||||
|
||||
logger.write(websocketpp::log::alevel::devel,"devel");
|
||||
//std::cout << "|" << out.str() << "|" << std::endl;
|
||||
BOOST_CHECK( out.str().size() > 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( copy_constructor ) {
|
||||
std::stringstream out;
|
||||
|
||||
basic_access_log_type logger1(0xffffffff,&out);
|
||||
basic_access_log_type logger2(logger1);
|
||||
|
||||
logger2.set_channels(0xffffffff);
|
||||
logger2.write(websocketpp::log::alevel::devel,"devel");
|
||||
BOOST_CHECK( out.str().size() > 0 );
|
||||
}
|
||||
|
||||
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
BOOST_AUTO_TEST_CASE( move_constructor ) {
|
||||
std::stringstream out;
|
||||
|
||||
basic_access_log_type logger1(0xffffffff,&out);
|
||||
basic_access_log_type logger2(std::move(logger1));
|
||||
|
||||
logger2.set_channels(0xffffffff);
|
||||
logger2.write(websocketpp::log::alevel::devel,"devel");
|
||||
BOOST_CHECK( out.str().size() > 0 );
|
||||
}
|
||||
|
||||
// Emplace requires move assignment, which logger doesn't support right now
|
||||
// due to const members. This is pretty irritating and will probably result in
|
||||
// the const members being removed. For now though this test will fail to
|
||||
// compile
|
||||
/*BOOST_AUTO_TEST_CASE( emplace ) {
|
||||
std::stringstream out1;
|
||||
std::stringstream out2;
|
||||
|
||||
std::vector<basic_access_log_type> v;
|
||||
|
||||
v.emplace_back(websocketpp::log::level(0xffffffff),&out1);
|
||||
v.emplace_back(websocketpp::log::level(0xffffffff),&out2);
|
||||
|
||||
v[0].set_channels(0xffffffff);
|
||||
v[1].set_channels(0xffffffff);
|
||||
v[0].write(websocketpp::log::alevel::devel,"devel");
|
||||
v[1].write(websocketpp::log::alevel::devel,"devel");
|
||||
BOOST_CHECK( out1.str().size() > 0 );
|
||||
BOOST_CHECK( out2.str().size() > 0 );
|
||||
}*/
|
||||
#endif // #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
|
||||
// As long as there are const member variables these can't exist
|
||||
// These remain commented as they are useful for testing the deleted operators
|
||||
/*BOOST_AUTO_TEST_CASE( copy_assign ) {
|
||||
basic_access_log_type logger1;
|
||||
basic_access_log_type logger2;
|
||||
|
||||
logger2 = logger1;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( move_assign ) {
|
||||
basic_access_log_type logger1;
|
||||
basic_access_log_type logger2;
|
||||
|
||||
logger2 = std::move(logger1);
|
||||
}*/
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE message_buffer_alloc
|
||||
@@ -35,62 +35,62 @@
|
||||
|
||||
template <template <class> class con_msg_manager>
|
||||
struct stub {
|
||||
typedef websocketpp::lib::shared_ptr<stub> ptr;
|
||||
|
||||
typedef con_msg_manager<stub> con_msg_man_type;
|
||||
typedef typename con_msg_man_type::ptr con_msg_man_ptr;
|
||||
typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<stub> ptr;
|
||||
|
||||
stub(con_msg_man_ptr manager, websocketpp::frame::opcode::value op, size_t size = 128)
|
||||
: m_opcode(op)
|
||||
, m_manager(manager)
|
||||
, m_size(size) {}
|
||||
typedef con_msg_manager<stub> con_msg_man_type;
|
||||
typedef typename con_msg_man_type::ptr con_msg_man_ptr;
|
||||
typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr;
|
||||
|
||||
bool recycle() {
|
||||
con_msg_man_ptr shared = m_manager.lock();
|
||||
stub(con_msg_man_ptr manager, websocketpp::frame::opcode::value op, size_t size = 128)
|
||||
: m_opcode(op)
|
||||
, m_manager(manager)
|
||||
, m_size(size) {}
|
||||
|
||||
if (shared) {
|
||||
return shared->recycle(this);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
websocketpp::frame::opcode::value m_opcode;
|
||||
con_msg_man_weak_ptr m_manager;
|
||||
size_t m_size;
|
||||
bool recycle() {
|
||||
con_msg_man_ptr shared = m_manager.lock();
|
||||
|
||||
if (shared) {
|
||||
return shared->recycle(this);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
websocketpp::frame::opcode::value m_opcode;
|
||||
con_msg_man_weak_ptr m_manager;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_get_message ) {
|
||||
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
|
||||
message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_man_type;
|
||||
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
|
||||
message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_man_type;
|
||||
|
||||
con_msg_man_type::ptr manager(new con_msg_man_type());
|
||||
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
|
||||
con_msg_man_type::ptr manager(new con_msg_man_type());
|
||||
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
|
||||
|
||||
BOOST_CHECK(msg);
|
||||
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
|
||||
BOOST_CHECK(msg->m_manager.lock() == manager);
|
||||
BOOST_CHECK(msg->m_size == 512);
|
||||
BOOST_CHECK(msg);
|
||||
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
|
||||
BOOST_CHECK(msg->m_manager.lock() == manager);
|
||||
BOOST_CHECK(msg->m_size == 512);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_get_manager ) {
|
||||
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
|
||||
message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_man_type;
|
||||
typedef websocketpp::message_buffer::alloc::endpoint_msg_manager
|
||||
<con_msg_man_type> endpoint_manager_type;
|
||||
|
||||
endpoint_manager_type em;
|
||||
con_msg_man_type::ptr manager = em.get_manager();
|
||||
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
|
||||
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
|
||||
message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_man_type;
|
||||
typedef websocketpp::message_buffer::alloc::endpoint_msg_manager
|
||||
<con_msg_man_type> endpoint_manager_type;
|
||||
|
||||
BOOST_CHECK(msg);
|
||||
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
|
||||
BOOST_CHECK(msg->m_manager.lock() == manager);
|
||||
BOOST_CHECK(msg->m_size == 512);
|
||||
endpoint_manager_type em;
|
||||
con_msg_man_type::ptr manager = em.get_manager();
|
||||
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
|
||||
|
||||
BOOST_CHECK(msg);
|
||||
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
|
||||
BOOST_CHECK(msg->m_manager.lock() == manager);
|
||||
BOOST_CHECK(msg->m_size == 512);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE message
|
||||
@@ -35,38 +35,38 @@
|
||||
|
||||
template <typename message>
|
||||
struct stub {
|
||||
typedef websocketpp::lib::weak_ptr<stub> weak_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<stub> ptr;
|
||||
|
||||
stub() : recycled(false) {}
|
||||
typedef websocketpp::lib::weak_ptr<stub> weak_ptr;
|
||||
typedef websocketpp::lib::shared_ptr<stub> ptr;
|
||||
|
||||
bool recycle(message * msg) {
|
||||
this->recycled = true;
|
||||
return false;
|
||||
}
|
||||
stub() : recycled(false) {}
|
||||
|
||||
bool recycled;
|
||||
bool recycle(message *) {
|
||||
this->recycled = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool recycled;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( basic_size_check ) {
|
||||
typedef websocketpp::message_buffer::message<stub> message_type;
|
||||
typedef stub<message_type> stub_type;
|
||||
typedef websocketpp::message_buffer::message<stub> message_type;
|
||||
typedef stub<message_type> stub_type;
|
||||
|
||||
stub_type::ptr s(new stub_type());
|
||||
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
|
||||
|
||||
BOOST_CHECK(msg->get_payload().capacity() >= 500);
|
||||
stub_type::ptr s(new stub_type());
|
||||
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
|
||||
|
||||
BOOST_CHECK(msg->get_payload().capacity() >= 500);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( recycle ) {
|
||||
typedef websocketpp::message_buffer::message<stub> message_type;
|
||||
typedef stub<message_type> stub_type;
|
||||
typedef websocketpp::message_buffer::message<stub> message_type;
|
||||
typedef stub<message_type> stub_type;
|
||||
|
||||
stub_type::ptr s(new stub_type());
|
||||
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
|
||||
stub_type::ptr s(new stub_type());
|
||||
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
|
||||
|
||||
BOOST_CHECK(s->recycled == false);
|
||||
BOOST_CHECK(msg->recycle() == false);
|
||||
BOOST_CHECK(s->recycled == true);
|
||||
BOOST_CHECK(s->recycled == false);
|
||||
BOOST_CHECK(msg->recycle() == false);
|
||||
BOOST_CHECK(s->recycled == true);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE hybi_00_processor
|
||||
@@ -40,37 +40,37 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||
websocketpp::http::parser::request r;
|
||||
websocketpp::http::parser::response response;
|
||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
r.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
BOOST_CHECK(p.validate_handshake(r));
|
||||
|
||||
|
||||
websocketpp::uri_ptr u;
|
||||
bool exception;
|
||||
|
||||
|
||||
try {
|
||||
u = p.get_uri(r);
|
||||
u = p.get_uri(r);
|
||||
} catch (const websocketpp::uri_exception& e) {
|
||||
exception = true;
|
||||
exception = true;
|
||||
}
|
||||
|
||||
|
||||
BOOST_CHECK(exception == false);
|
||||
BOOST_CHECK(u->get_secure() == false);
|
||||
BOOST_CHECK(u->get_host() == "www.example.com");
|
||||
BOOST_CHECK(u->get_resource() == "/");
|
||||
BOOST_CHECK(u->get_port() == websocketpp::URI_DEFAULT_PORT);
|
||||
|
||||
|
||||
p.process_handshake(r,response);
|
||||
|
||||
|
||||
BOOST_CHECK(response.get_header("Connection") == "Upgrade");
|
||||
BOOST_CHECK(response.get_header("Upgrade") == "websocket");
|
||||
BOOST_CHECK(response.get_header("Sec-WebSocket-Origin") == "http://example.com");
|
||||
|
||||
|
||||
BOOST_CHECK(response.get_header("Sec-WebSocket-Location") == "ws://www.example.com/");
|
||||
BOOST_CHECK(response.get_header("Sec-WebSocket-Key3") == "n`9eBk9z$R8pOtVb");
|
||||
}
|
||||
@@ -78,12 +78,12 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||
BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
websocketpp::http::parser::request r;
|
||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
||||
|
||||
|
||||
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
BOOST_CHECK(!p.validate_handshake(r));
|
||||
@@ -92,12 +92,12 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
websocketpp::http::parser::request r;
|
||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
BOOST_CHECK(!p.validate_handshake(r));
|
||||
@@ -106,12 +106,12 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
websocketpp::http::parser::request r;
|
||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
BOOST_CHECK(!p.validate_handshake(r));
|
||||
@@ -120,12 +120,12 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||
websocketpp::http::parser::request r;
|
||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
BOOST_CHECK(!p.validate_handshake(r));
|
||||
@@ -136,21 +136,21 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
|
||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
||||
websocketpp::uri_ptr u;
|
||||
bool exception = false;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
BOOST_CHECK(!p.validate_handshake(r));
|
||||
|
||||
|
||||
try {
|
||||
u = p.get_uri(r);
|
||||
u = p.get_uri(r);
|
||||
} catch (const websocketpp::uri_exception& e) {
|
||||
exception = true;
|
||||
exception = true;
|
||||
}
|
||||
|
||||
|
||||
BOOST_CHECK(exception == true);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ Import('polyfill_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs] + ['z']
|
||||
|
||||
objs = env.Object('test_processor_boost.o', ["processor.cpp"], LIBS = BOOST_LIBS)
|
||||
objs += env.Object('test_hybi13_boost.o', ["hybi13.cpp"], LIBS = BOOST_LIBS)
|
||||
@@ -27,8 +27,8 @@ prgs += env.Program('test_hybi00_boost', ["test_hybi00_boost.o"], LIBS = BOOST_L
|
||||
prgs += env.Program('test_extension_permessage_compress_boost', ["test_extension_permessage_compress_boost.o"], LIBS = BOOST_LIBS + ['z'])
|
||||
|
||||
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
|
||||
# no C++11 features are used in processor so there are no C++11 versions of
|
||||
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
|
||||
# no C++11 features are used in processor so there are no C++11 versions of
|
||||
# these tests.
|
||||
objs += env_cpp11.Object('test_processor_stl.o', ["processor.cpp"], LIBS = BOOST_LIBS_CPP11)
|
||||
objs += env_cpp11.Object('test_hybi13_stl.o', ["hybi13.cpp"], LIBS = BOOST_LIBS_CPP11)
|
||||
@@ -36,7 +36,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
|
||||
objs += env_cpp11.Object('test_hybi07_stl.o', ["hybi07.cpp"], LIBS = BOOST_LIBS_CPP11)
|
||||
objs += env_cpp11.Object('test_hybi00_stl.o', ["hybi00.cpp"], LIBS = BOOST_LIBS_CPP11)
|
||||
objs += env_cpp11.Object('test_extension_permessage_compress_stl.o', ["extension_permessage_compress.cpp"], LIBS = BOOST_LIBS_CPP11 + ['z'])
|
||||
|
||||
|
||||
prgs += env_cpp11.Program('test_processor_stl', ["test_processor_stl.o"], LIBS = BOOST_LIBS_CPP11)
|
||||
prgs += env_cpp11.Program('test_hybi13_stl', ["test_hybi13_stl.o"], LIBS = BOOST_LIBS_CPP11)
|
||||
prgs += env_cpp11.Program('test_hybi08_stl', ["test_hybi08_stl.o"], LIBS = BOOST_LIBS_CPP11)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE extension_permessage_deflate
|
||||
@@ -38,7 +38,7 @@
|
||||
struct config {
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
};
|
||||
typedef websocketpp::extensions::permessage_deflate::enabled<config>
|
||||
typedef websocketpp::extensions::permessage_deflate::enabled<config>
|
||||
compressor_type;
|
||||
|
||||
using namespace websocketpp;
|
||||
@@ -50,23 +50,23 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
|
||||
|
||||
neg_ret = compressor.negotiate(attributes);
|
||||
|
||||
BOOST_CHECK_EQUAL( neg_ret.first,
|
||||
BOOST_CHECK_EQUAL( neg_ret.first,
|
||||
extensions::permessage_deflate::error::invalid_parameters );*/
|
||||
|
||||
|
||||
/**
|
||||
* Window size is primarily controlled by the writer. A stream can only be
|
||||
* read by a window size equal to or greater than the one use to compress
|
||||
* it initially. The default windows size is also the maximum window size.
|
||||
* it initially. The default windows size is also the maximum window size.
|
||||
* Thus:
|
||||
*
|
||||
* Outbound window size can be limited unilaterally under the assumption
|
||||
* that the opposite end will be using the default (maximum size which can
|
||||
* read anything)
|
||||
*
|
||||
* Inbound window size must be limited by asking the remote endpoint to
|
||||
* Inbound window size must be limited by asking the remote endpoint to
|
||||
* do so and it agreeing.
|
||||
*
|
||||
* Context takeover is also primarily controlled by the writer. If the
|
||||
*
|
||||
* Context takeover is also primarily controlled by the writer. If the
|
||||
* compressor does not clear its context between messages then the reader
|
||||
* can't either.
|
||||
*
|
||||
@@ -81,17 +81,17 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
|
||||
* - whether or not to request that the server disallow context takeover
|
||||
*
|
||||
* Server must answer in the following ways
|
||||
* - If client requested a window size limit, is the window size limit
|
||||
* - If client requested a window size limit, is the window size limit
|
||||
* acceptable?
|
||||
* - If client allows window limit requests, should we send one?
|
||||
* - If client requested no context takeover, should we accept?
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* All Defaults
|
||||
* Req: permessage-compress; method=deflate
|
||||
* Ans: permessage-compress; method=deflate
|
||||
*
|
||||
*
|
||||
* # Client wants to limit the size of inbound windows from server
|
||||
* permessage-compress; method="deflate; s2c_max_window_bits=8, deflate"
|
||||
* Ans: permessage-compress; method="deflate; s2c_max_window_bits=8"
|
||||
@@ -99,13 +99,13 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
|
||||
* Ans: permessage-compress; method=deflate
|
||||
*
|
||||
* # Server wants to limit the size of inbound windows from client
|
||||
* Client:
|
||||
* Client:
|
||||
* permessage-compress; method="deflate; c2s_max_window_bits, deflate"
|
||||
*
|
||||
*
|
||||
* Server:
|
||||
* permessage-compress; method="deflate; c2s_max_window_bits=8"
|
||||
*
|
||||
* # Client wants to
|
||||
*
|
||||
* # Client wants to
|
||||
*
|
||||
*
|
||||
*
|
||||
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -144,30 +144,30 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
|
||||
attributes.push_back(http::parser::attribute("s2c_max_window_bits","9"));
|
||||
ec = d.init(attributes);
|
||||
BOOST_CHECK( !ec);
|
||||
|
||||
|
||||
attributes.clear();
|
||||
ec = d.init(attributes);
|
||||
BOOST_CHECK( !ec);
|
||||
|
||||
|
||||
processor::extensions::deflate_engine de;
|
||||
|
||||
|
||||
unsigned char test_in[] = "HelloHelloHelloHello";
|
||||
unsigned char test_out[30];
|
||||
|
||||
|
||||
uLongf test_out_size = 30;
|
||||
|
||||
|
||||
int ret;
|
||||
|
||||
ret = compress(test_out, &test_out_size, test_in, 20);
|
||||
|
||||
ret = compress(test_out, &test_out_size, test_in, 20);
|
||||
|
||||
std::cout << ret << std::endl
|
||||
<< websocketpp::utility::to_hex(test_in,20) << std::endl
|
||||
<< websocketpp::utility::to_hex(test_out,test_out_size) << std::endl;
|
||||
|
||||
|
||||
std::string input = "Hello";
|
||||
std::string output = "";
|
||||
ec = de.compress(input,output);
|
||||
|
||||
|
||||
BOOST_CHECK( ec == processor::extensions::error::uninitialized );
|
||||
|
||||
//std::cout << ec.message() << websocketpp::utility::to_hex(output) << std::endl;
|
||||
@@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
|
||||
std::cout << ec.message() << std::endl
|
||||
<< websocketpp::utility::to_hex(input) << std::endl
|
||||
<< websocketpp::utility::to_hex(output) << std::endl;
|
||||
|
||||
|
||||
output = "";
|
||||
|
||||
ec = de.compress(input,output);
|
||||
|
||||
+62
-60
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE hybi_00_processor
|
||||
@@ -38,167 +38,169 @@
|
||||
#include <websocketpp/message_buffer/alloc.hpp>
|
||||
|
||||
struct stub_config {
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
static const size_t max_message_size = 16000000;
|
||||
};
|
||||
|
||||
struct processor_setup {
|
||||
processor_setup(bool server)
|
||||
processor_setup(bool server)
|
||||
: msg_manager(new stub_config::con_msg_manager_type())
|
||||
, p(false,server,msg_manager) {}
|
||||
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::request_type req;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::request_type req;
|
||||
stub_config::response_type res;
|
||||
websocketpp::processor::hybi00<stub_config> p;
|
||||
websocketpp::processor::hybi00<stub_config> p;
|
||||
};
|
||||
|
||||
typedef stub_config::message_type::ptr message_ptr;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
env.req.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
env.ec = env.p.validate_handshake(env.req);
|
||||
BOOST_CHECK(!env.ec);
|
||||
|
||||
|
||||
websocketpp::uri_ptr u;
|
||||
|
||||
BOOST_CHECK_NO_THROW( u = env.p.get_uri(env.req) );
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(u->get_secure(), false);
|
||||
BOOST_CHECK_EQUAL(u->get_host(), "www.example.com");
|
||||
BOOST_CHECK_EQUAL(u->get_resource(), "/");
|
||||
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::URI_DEFAULT_PORT);
|
||||
|
||||
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::uri_default_port);
|
||||
|
||||
env.p.process_handshake(env.req,"",env.res);
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Connection"), "Upgrade");
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Upgrade"), "WebSocket");
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Origin"), "http://example.com");
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Location"), "ws://www.example.com/");
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Key3"), "n`9eBk9z$R8pOtVb");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::invalid_http_method );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::invalid_http_version );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( bad_host ) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
websocketpp::uri_ptr u;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK( !env.p.validate_handshake(env.req) );
|
||||
|
||||
BOOST_CHECK_THROW( u = env.p.get_uri(env.req), websocketpp::uri_exception );
|
||||
BOOST_CHECK( !env.p.get_uri(env.req)->get_valid() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( extract_subprotocols ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::vector<std::string> subps;
|
||||
|
||||
|
||||
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
|
||||
BOOST_CHECK_EQUAL( subps.size(), 0 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( prepare_data_frame_null ) {
|
||||
processor_setup env(true);
|
||||
|
||||
|
||||
message_ptr in = env.msg_manager->get_message();
|
||||
message_ptr out = env.msg_manager->get_message();
|
||||
message_ptr invalid;
|
||||
|
||||
|
||||
// empty pointers arguements should return sane error
|
||||
// empty pointers arguements should return sane error
|
||||
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(invalid,invalid), websocketpp::processor::error::invalid_arguments );
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(in,invalid), websocketpp::processor::error::invalid_arguments );
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(invalid,out), websocketpp::processor::error::invalid_arguments );
|
||||
|
||||
|
||||
// test valid opcodes
|
||||
// text (1) should be the only valid opcode
|
||||
for (int i = 0; i < 0xF; i++) {
|
||||
in->set_opcode(websocketpp::frame::opcode::value(i));
|
||||
|
||||
|
||||
env.ec = env.p.prepare_data_frame(in,out);
|
||||
|
||||
|
||||
if (i != 1) {
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
|
||||
} else {
|
||||
BOOST_CHECK_NE( env.ec, websocketpp::processor::error::invalid_opcode );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* TODO: tests for invalid UTF8
|
||||
char buf[2] = {0x00, 0x00};
|
||||
@@ -213,15 +215,15 @@ BOOST_AUTO_TEST_CASE( prepare_data_frame_null ) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
|
||||
processor_setup env(true);
|
||||
|
||||
|
||||
message_ptr in = env.msg_manager->get_message();
|
||||
message_ptr out = env.msg_manager->get_message();
|
||||
|
||||
|
||||
in->set_opcode(websocketpp::frame::opcode::text);
|
||||
in->set_payload("foo");
|
||||
|
||||
env.ec = env.p.prepare_data_frame(in,out);
|
||||
|
||||
|
||||
unsigned char raw_header[1] = {0x00};
|
||||
unsigned char raw_payload[4] = {0x66,0x6f,0x6f,0xff};
|
||||
|
||||
|
||||
+69
-80
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE hybi_07_processor
|
||||
@@ -40,21 +40,23 @@
|
||||
#include <websocketpp/random/none.hpp>
|
||||
|
||||
struct stub_config {
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
|
||||
|
||||
|
||||
static const size_t max_message_size = 16000000;
|
||||
|
||||
/// Extension related config
|
||||
static const bool enable_extensions = false;
|
||||
|
||||
|
||||
/// Extension specific config
|
||||
|
||||
|
||||
/// permessage_compress_config
|
||||
struct permessage_deflate_config {
|
||||
typedef stub_config::request_type request_type;
|
||||
@@ -65,56 +67,51 @@ struct stub_config {
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
|
||||
websocketpp::uri_ptr u;
|
||||
bool exception = false;
|
||||
|
||||
try {
|
||||
u = p.get_uri(r);
|
||||
} catch (const websocketpp::uri_exception& e) {
|
||||
exception = true;
|
||||
}
|
||||
|
||||
BOOST_CHECK(exception == false);
|
||||
BOOST_CHECK(u->get_secure() == false);
|
||||
BOOST_CHECK(u->get_host() == "www.example.com");
|
||||
BOOST_CHECK(u->get_resource() == "/");
|
||||
BOOST_CHECK(u->get_port() == websocketpp::uri_default_port);
|
||||
|
||||
|
||||
u = p.get_uri(r);
|
||||
|
||||
BOOST_CHECK(u->get_valid());
|
||||
BOOST_CHECK(!u->get_secure());
|
||||
BOOST_CHECK_EQUAL(u->get_host(), "www.example.com");
|
||||
BOOST_CHECK_EQUAL(u->get_resource(), "/");
|
||||
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::uri_default_port);
|
||||
|
||||
p.process_handshake(r,"",response);
|
||||
|
||||
BOOST_CHECK(response.get_header("Connection") == "upgrade");
|
||||
BOOST_CHECK(response.get_header("Upgrade") == "websocket");
|
||||
BOOST_CHECK(response.get_header("Sec-WebSocket-Accept") == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
|
||||
|
||||
BOOST_CHECK_EQUAL(response.get_header("Connection"), "upgrade");
|
||||
BOOST_CHECK_EQUAL(response.get_header("Upgrade"), "websocket");
|
||||
BOOST_CHECK_EQUAL(response.get_header("Sec-WebSocket-Accept"), "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -122,17 +119,17 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -140,17 +137,17 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -158,17 +155,17 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -176,29 +173,21 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( bad_host ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::uri_ptr u;
|
||||
bool exception = false;
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
BOOST_CHECK( !ec );
|
||||
|
||||
try {
|
||||
u = p.get_uri(r);
|
||||
} catch (const websocketpp::uri_exception& e) {
|
||||
exception = true;
|
||||
}
|
||||
|
||||
BOOST_CHECK(exception == true);
|
||||
|
||||
BOOST_CHECK( !p.get_uri(r)->get_valid() );
|
||||
}
|
||||
+61
-69
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE hybi_08_processor
|
||||
@@ -40,21 +40,23 @@
|
||||
#include <websocketpp/random/none.hpp>
|
||||
|
||||
struct stub_config {
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
|
||||
|
||||
static const size_t max_message_size = 16000000;
|
||||
|
||||
/// Extension related config
|
||||
static const bool enable_extensions = false;
|
||||
|
||||
|
||||
/// Extension specific config
|
||||
|
||||
|
||||
/// permessage_deflate_config
|
||||
struct permessage_deflate_config {
|
||||
typedef stub_config::request_type request_type;
|
||||
@@ -65,56 +67,51 @@ struct stub_config {
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
|
||||
websocketpp::uri_ptr u;
|
||||
bool exception = false;
|
||||
|
||||
try {
|
||||
u = p.get_uri(r);
|
||||
} catch (const websocketpp::uri_exception& e) {
|
||||
exception = true;
|
||||
}
|
||||
|
||||
BOOST_CHECK(exception == false);
|
||||
|
||||
u = p.get_uri(r);
|
||||
|
||||
BOOST_CHECK(u->get_valid() == true);
|
||||
BOOST_CHECK(u->get_secure() == false);
|
||||
BOOST_CHECK(u->get_host() == "www.example.com");
|
||||
BOOST_CHECK(u->get_resource() == "/");
|
||||
BOOST_CHECK(u->get_port() == websocketpp::uri_default_port);
|
||||
|
||||
|
||||
p.process_handshake(r,"",response);
|
||||
|
||||
|
||||
BOOST_CHECK(response.get_header("Connection") == "upgrade");
|
||||
BOOST_CHECK(response.get_header("Upgrade") == "websocket");
|
||||
BOOST_CHECK(response.get_header("Sec-WebSocket-Accept") == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -122,17 +119,17 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -140,17 +137,17 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -158,17 +155,17 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
@@ -176,30 +173,25 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( bad_host ) {
|
||||
stub_config::request_type r;
|
||||
stub_config::request_type r;
|
||||
stub_config::response_type response;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||
websocketpp::uri_ptr u;
|
||||
bool exception = false;
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
|
||||
ec = p.validate_handshake(r);
|
||||
BOOST_CHECK( !ec );
|
||||
|
||||
try {
|
||||
u = p.get_uri(r);
|
||||
} catch (const websocketpp::uri_exception& e) {
|
||||
exception = true;
|
||||
}
|
||||
|
||||
BOOST_CHECK(exception == true);
|
||||
|
||||
u = p.get_uri(r);
|
||||
|
||||
BOOST_CHECK( !u->get_valid() );
|
||||
}
|
||||
|
||||
+291
-260
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE hybi_13_processor
|
||||
@@ -43,16 +43,16 @@
|
||||
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
|
||||
|
||||
struct stub_config {
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
|
||||
|
||||
|
||||
struct permessage_deflate_config {
|
||||
typedef stub_config::request_type request_type;
|
||||
};
|
||||
@@ -60,27 +60,29 @@ struct stub_config {
|
||||
typedef websocketpp::extensions::permessage_deflate::disabled
|
||||
<permessage_deflate_config> permessage_deflate_type;
|
||||
|
||||
static const size_t max_message_size = 16000000;
|
||||
static const bool enable_extensions = false;
|
||||
};
|
||||
|
||||
struct stub_config_ext {
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
typedef websocketpp::message_buffer::message
|
||||
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
|
||||
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
|
||||
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
|
||||
|
||||
|
||||
struct permessage_deflate_config {
|
||||
typedef stub_config_ext::request_type request_type;
|
||||
};
|
||||
|
||||
|
||||
typedef websocketpp::extensions::permessage_deflate::enabled
|
||||
<permessage_deflate_config> permessage_deflate_type;
|
||||
|
||||
static const size_t max_message_size = 16000000;
|
||||
static const bool enable_extensions = true;
|
||||
};
|
||||
|
||||
@@ -90,89 +92,89 @@ typedef stub_config::message_type::ptr message_ptr;
|
||||
// Set up a structure that constructs new copies of all of the support structure
|
||||
// for using connection processors
|
||||
struct processor_setup {
|
||||
processor_setup(bool server)
|
||||
processor_setup(bool server)
|
||||
: msg_manager(new con_msg_manager_type())
|
||||
, p(false,server,msg_manager,rng) {}
|
||||
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::request_type req;
|
||||
con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::request_type req;
|
||||
stub_config::response_type res;
|
||||
websocketpp::processor::hybi13<stub_config> p;
|
||||
websocketpp::processor::hybi13<stub_config> p;
|
||||
};
|
||||
|
||||
struct processor_setup_ext {
|
||||
processor_setup_ext(bool server)
|
||||
processor_setup_ext(bool server)
|
||||
: msg_manager(new con_msg_manager_type())
|
||||
, p(false,server,msg_manager,rng) {}
|
||||
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::request_type req;
|
||||
con_msg_manager_type::ptr msg_manager;
|
||||
stub_config::rng_type rng;
|
||||
stub_config::request_type req;
|
||||
stub_config::response_type res;
|
||||
websocketpp::processor::hybi13<stub_config_ext> p;
|
||||
websocketpp::processor::hybi13<stub_config_ext> p;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK(!env.p.validate_handshake(env.req));
|
||||
|
||||
|
||||
websocketpp::uri_ptr u;
|
||||
|
||||
|
||||
BOOST_CHECK_NO_THROW( u = env.p.get_uri(env.req) );
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(u->get_secure(), false);
|
||||
BOOST_CHECK_EQUAL(u->get_host(), "www.example.com");
|
||||
BOOST_CHECK_EQUAL(u->get_resource(), "/");
|
||||
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::uri_default_port);
|
||||
|
||||
|
||||
env.p.process_handshake(env.req,"",env.res);
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Connection"), "upgrade");
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Upgrade"), "websocket");
|
||||
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Accept"), "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK( env.p.validate_handshake(env.req) == websocketpp::processor::error::invalid_http_method );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
|
||||
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
|
||||
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::invalid_http_version );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
|
||||
BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
|
||||
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
|
||||
@@ -180,27 +182,27 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||
processor_setup env(true);
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
|
||||
BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
|
||||
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( bad_host ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
||||
|
||||
|
||||
env.req.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
|
||||
BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
|
||||
BOOST_CHECK( !env.p.validate_handshake(env.req) );
|
||||
BOOST_CHECK_THROW( env.p.get_uri(env.req), websocketpp::uri_exception );
|
||||
BOOST_CHECK( !env.p.validate_handshake(env.req) );
|
||||
BOOST_CHECK( !env.p.get_uri(env.req)->get_valid() );
|
||||
}
|
||||
|
||||
// FRAME TESTS TO DO
|
||||
@@ -218,249 +220,249 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
|
||||
// 0x81 0x80
|
||||
|
||||
BOOST_AUTO_TEST_CASE( frame_empty_binary_unmasked ) {
|
||||
uint8_t frame[2] = {0x82, 0x00};
|
||||
uint8_t frame[2] = {0x82, 0x00};
|
||||
|
||||
// all in one chunk
|
||||
processor_setup env1(false);
|
||||
// all in one chunk
|
||||
processor_setup env1(false);
|
||||
|
||||
size_t ret1 = env1.p.consume(frame,2,env1.ec);
|
||||
|
||||
BOOST_CHECK_EQUAL( ret1, 2 );
|
||||
BOOST_CHECK( !env1.ec );
|
||||
BOOST_CHECK_EQUAL( env1.p.ready(), true );
|
||||
|
||||
// two separate chunks
|
||||
processor_setup env2(false);
|
||||
size_t ret1 = env1.p.consume(frame,2,env1.ec);
|
||||
|
||||
BOOST_CHECK_EQUAL( env2.p.consume(frame,1,env2.ec), 1 );
|
||||
BOOST_CHECK( !env2.ec );
|
||||
BOOST_CHECK_EQUAL( env2.p.ready(), false );
|
||||
BOOST_CHECK_EQUAL( ret1, 2 );
|
||||
BOOST_CHECK( !env1.ec );
|
||||
BOOST_CHECK_EQUAL( env1.p.ready(), true );
|
||||
|
||||
BOOST_CHECK_EQUAL( env2.p.consume(frame+1,1,env2.ec), 1 );
|
||||
BOOST_CHECK( !env2.ec );
|
||||
BOOST_CHECK_EQUAL( env2.p.ready(), true );
|
||||
// two separate chunks
|
||||
processor_setup env2(false);
|
||||
|
||||
BOOST_CHECK_EQUAL( env2.p.consume(frame,1,env2.ec), 1 );
|
||||
BOOST_CHECK( !env2.ec );
|
||||
BOOST_CHECK_EQUAL( env2.p.ready(), false );
|
||||
|
||||
BOOST_CHECK_EQUAL( env2.p.consume(frame+1,1,env2.ec), 1 );
|
||||
BOOST_CHECK( !env2.ec );
|
||||
BOOST_CHECK_EQUAL( env2.p.ready(), true );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( frame_small_binary_unmasked ) {
|
||||
processor_setup env(false);
|
||||
processor_setup env(false);
|
||||
|
||||
uint8_t frame[4] = {0x82, 0x02, 0x2A, 0x2A};
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,4,env.ec), 4 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
|
||||
message_ptr foo = env.p.get_message();
|
||||
uint8_t frame[4] = {0x82, 0x02, 0x2A, 0x2A};
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( foo->get_payload(), "**" );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,4,env.ec), 4 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
|
||||
message_ptr foo = env.p.get_message();
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( foo->get_payload(), "**" );
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( frame_extended_binary_unmasked ) {
|
||||
processor_setup env(false);
|
||||
processor_setup env(false);
|
||||
|
||||
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
|
||||
frame[0] = 0x82;
|
||||
frame[1] = 0x7E;
|
||||
frame[2] = 0x00;
|
||||
frame[3] = 0x7E;
|
||||
std::fill_n(frame+4,126,0x2A);
|
||||
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
|
||||
frame[0] = 0x82;
|
||||
frame[1] = 0x7E;
|
||||
frame[2] = 0x00;
|
||||
frame[3] = 0x7E;
|
||||
std::fill_n(frame+4,126,0x2A);
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
|
||||
message_ptr foo = env.p.get_message();
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
|
||||
message_ptr foo = env.p.get_message();
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( frame_jumbo_binary_unmasked ) {
|
||||
processor_setup env(false);
|
||||
processor_setup env(false);
|
||||
|
||||
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
|
||||
std::fill_n(frame+4,126,0x2A);
|
||||
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
|
||||
std::fill_n(frame+4,126,0x2A);
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
|
||||
message_ptr foo = env.p.get_message();
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
|
||||
message_ptr foo = env.p.get_message();
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( control_frame_too_large ) {
|
||||
processor_setup env(false);
|
||||
processor_setup env(false);
|
||||
|
||||
uint8_t frame[130] = {0x88, 0x7E, 0x00, 0x7E};
|
||||
std::fill_n(frame+4,126,0x2A);
|
||||
uint8_t frame[130] = {0x88, 0x7E, 0x00, 0x7E};
|
||||
std::fill_n(frame+4,126,0x2A);
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,130,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::control_too_big );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,130,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::control_too_big );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( rsv_bits_used ) {
|
||||
uint8_t frame[3][2] = {{0x90, 0x00},
|
||||
{0xA0, 0x00},
|
||||
{0xC0, 0x00}};
|
||||
uint8_t frame[3][2] = {{0x90, 0x00},
|
||||
{0xA0, 0x00},
|
||||
{0xC0, 0x00}};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
processor_setup env(false);
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_rsv_bit );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
processor_setup env(false);
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_rsv_bit );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( reserved_opcode_used ) {
|
||||
uint8_t frame[10][2] = {{0x83, 0x00},
|
||||
{0x84, 0x00},
|
||||
{0x85, 0x00},
|
||||
{0x86, 0x00},
|
||||
{0x87, 0x00},
|
||||
{0x8B, 0x00},
|
||||
{0x8C, 0x00},
|
||||
{0x8D, 0x00},
|
||||
{0x8E, 0x00},
|
||||
{0x8F, 0x00}};
|
||||
uint8_t frame[10][2] = {{0x83, 0x00},
|
||||
{0x84, 0x00},
|
||||
{0x85, 0x00},
|
||||
{0x86, 0x00},
|
||||
{0x87, 0x00},
|
||||
{0x8B, 0x00},
|
||||
{0x8C, 0x00},
|
||||
{0x8D, 0x00},
|
||||
{0x8E, 0x00},
|
||||
{0x8F, 0x00}};
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
processor_setup env(false);
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
processor_setup env(false);
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( fragmented_control_message ) {
|
||||
processor_setup env(false);
|
||||
processor_setup env(false);
|
||||
|
||||
uint8_t frame[2] = {0x08, 0x00};
|
||||
uint8_t frame[2] = {0x08, 0x00};
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::fragmented_control );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::fragmented_control );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( fragmented_binary_message ) {
|
||||
processor_setup env0(false);
|
||||
processor_setup env1(false);
|
||||
processor_setup env0(false);
|
||||
processor_setup env1(false);
|
||||
|
||||
uint8_t frame0[6] = {0x02, 0x01, 0x2A, 0x80, 0x01, 0x2A};
|
||||
uint8_t frame1[8] = {0x02, 0x01, 0x2A, 0x89, 0x00, 0x80, 0x01, 0x2A};
|
||||
uint8_t frame0[6] = {0x02, 0x01, 0x2A, 0x80, 0x01, 0x2A};
|
||||
uint8_t frame1[8] = {0x02, 0x01, 0x2A, 0x89, 0x00, 0x80, 0x01, 0x2A};
|
||||
|
||||
// read fragmented message in one chunk
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame0,6,env0.ec), 6 );
|
||||
// read fragmented message in one chunk
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame0,6,env0.ec), 6 );
|
||||
BOOST_CHECK( !env0.ec );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
|
||||
|
||||
// read fragmented message in two chunks
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame0,3,env0.ec), 3 );
|
||||
BOOST_CHECK( !env0.ec );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), false );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame0+3,3,env0.ec), 3 );
|
||||
BOOST_CHECK( !env0.ec );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
|
||||
|
||||
// read fragmented message with control message in between
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame1,8,env0.ec), 5 );
|
||||
// read fragmented message in two chunks
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame0,3,env0.ec), 3 );
|
||||
BOOST_CHECK( !env0.ec );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_opcode(), websocketpp::frame::opcode::PING);
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame1+5,3,env0.ec), 3 );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), false );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame0+3,3,env0.ec), 3 );
|
||||
BOOST_CHECK( !env0.ec );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
|
||||
|
||||
// read fragmented message with control message in between
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame1,8,env0.ec), 5 );
|
||||
BOOST_CHECK( !env0.ec );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_opcode(), websocketpp::frame::opcode::PING);
|
||||
BOOST_CHECK_EQUAL( env0.p.consume(frame1+5,3,env0.ec), 3 );
|
||||
BOOST_CHECK( !env0.ec );
|
||||
BOOST_CHECK_EQUAL( env0.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
|
||||
|
||||
// read lone continuation frame
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env0.p.consume(frame0+3,3,env0.ec), 0);
|
||||
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env0.p.consume(frame0+3,3,env0.ec), 0);
|
||||
BOOST_CHECK_EQUAL( env0.ec, websocketpp::processor::error::invalid_continuation );
|
||||
|
||||
// read two start frames in a row
|
||||
BOOST_CHECK_EQUAL( env1.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env1.p.consume(frame0,3,env1.ec), 3);
|
||||
BOOST_CHECK_EQUAL( env1.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env1.p.consume(frame0,3,env1.ec), 3);
|
||||
BOOST_CHECK( !env1.ec );
|
||||
BOOST_CHECK_GT( env1.p.consume(frame0,3,env1.ec), 0);
|
||||
BOOST_CHECK_GT( env1.p.consume(frame0,3,env1.ec), 0);
|
||||
BOOST_CHECK_EQUAL( env1.ec, websocketpp::processor::error::invalid_continuation );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( unmasked_client_frame ) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
|
||||
uint8_t frame[2] = {0x82, 0x00};
|
||||
uint8_t frame[2] = {0x82, 0x00};
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_required );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_required );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( masked_server_frame ) {
|
||||
processor_setup env(false);
|
||||
processor_setup env(false);
|
||||
|
||||
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
|
||||
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,8,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_forbidden );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_GT( env.p.consume(frame,8,env.ec), 0 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_forbidden );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), false );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( frame_small_binary_masked ) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
|
||||
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
|
||||
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,8,env.ec), 8 );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame,8,env.ec), 8 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( masked_fragmented_binary_message ) {
|
||||
processor_setup env(true);
|
||||
|
||||
uint8_t frame0[14] = {0x02, 0x81, 0xAB, 0x23, 0x98, 0x45, 0x81,
|
||||
0x80, 0x81, 0xB8, 0x34, 0x12, 0xFF, 0x92};
|
||||
uint8_t frame0[14] = {0x02, 0x81, 0xAB, 0x23, 0x98, 0x45, 0x81,
|
||||
0x80, 0x81, 0xB8, 0x34, 0x12, 0xFF, 0x92};
|
||||
|
||||
// read fragmented message in one chunk
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame0,14,env.ec), 14 );
|
||||
// read fragmented message in one chunk
|
||||
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame0,14,env.ec), 14 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
|
||||
BOOST_CHECK_EQUAL( env.p.ready(), true );
|
||||
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
|
||||
processor_setup env(true);
|
||||
|
||||
processor_setup env(true);
|
||||
|
||||
message_ptr in = env.msg_manager->get_message();
|
||||
message_ptr out = env.msg_manager->get_message();
|
||||
message_ptr invalid;
|
||||
|
||||
// empty pointers arguements should return sane error
|
||||
// empty pointers arguements should return sane error
|
||||
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(invalid,invalid), websocketpp::processor::error::invalid_arguments );
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(in,invalid), websocketpp::processor::error::invalid_arguments );
|
||||
@@ -471,43 +473,73 @@ BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
|
||||
// control opcodes should return an error, data ones shouldn't
|
||||
for (int i = 0; i < 0xF; i++) {
|
||||
in->set_opcode(websocketpp::frame::opcode::value(i));
|
||||
|
||||
|
||||
env.ec = env.p.prepare_data_frame(in,out);
|
||||
|
||||
|
||||
if (websocketpp::frame::opcode::is_control(in->get_opcode())) {
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
|
||||
} else {
|
||||
BOOST_CHECK_NE( env.ec, websocketpp::processor::error::invalid_opcode );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//in.set_payload("foo");
|
||||
|
||||
|
||||
//e = prepare_data_frame(in,out);
|
||||
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( single_frame_message_too_large ) {
|
||||
processor_setup env(true);
|
||||
|
||||
env.p.set_max_message_size(3);
|
||||
|
||||
uint8_t frame0[10] = {0x82, 0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01};
|
||||
|
||||
// read message that is one byte too large
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame0,10,env.ec), 6 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( multiple_frame_message_too_large ) {
|
||||
processor_setup env(true);
|
||||
|
||||
env.p.set_max_message_size(4);
|
||||
|
||||
uint8_t frame0[8] = {0x02, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
|
||||
uint8_t frame1[9] = {0x80, 0x83, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
|
||||
|
||||
// read first message frame with size under the limit
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame0,8,env.ec), 8 );
|
||||
BOOST_CHECK( !env.ec );
|
||||
|
||||
// read second message frame that puts the size over the limit
|
||||
BOOST_CHECK_EQUAL( env.p.consume(frame1,9,env.ec), 6 );
|
||||
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_request ) {
|
||||
processor_setup env(false);
|
||||
|
||||
|
||||
websocketpp::uri_ptr u(new websocketpp::uri("ws://localhost/"));
|
||||
|
||||
|
||||
env.p.client_handshake_request(env.req,u, std::vector<std::string>());
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( env.req.get_method(), "GET" );
|
||||
BOOST_CHECK_EQUAL( env.req.get_version(), "HTTP/1.1");
|
||||
BOOST_CHECK_EQUAL( env.req.get_uri(), "/");
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( env.req.get_header("Host"), "localhost");
|
||||
BOOST_CHECK_EQUAL( env.req.get_header("Sec-WebSocket-Version"), "13");
|
||||
BOOST_CHECK_EQUAL( env.req.get_header("Connection"), "Upgrade");
|
||||
BOOST_CHECK_EQUAL( env.req.get_header("Upgrade"), "websocket");
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// TODO:
|
||||
// test cases
|
||||
// - adding headers
|
||||
// - adding Upgrade header
|
||||
@@ -524,48 +556,48 @@ BOOST_AUTO_TEST_CASE( client_handshake_request ) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_response_404 ) {
|
||||
processor_setup env(false);
|
||||
|
||||
|
||||
std::string res = "HTTP/1.1 404 Not Found\r\n\r\n";
|
||||
env.res.consume(res.data(),res.size());
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::invalid_http_status );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_response_no_upgrade ) {
|
||||
processor_setup env(false);
|
||||
|
||||
|
||||
std::string res = "HTTP/1.1 101 Switching Protocols\r\n\r\n";
|
||||
env.res.consume(res.data(),res.size());
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_response_no_connection ) {
|
||||
processor_setup env(false);
|
||||
|
||||
|
||||
std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\n\r\n";
|
||||
env.res.consume(res.data(),res.size());
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_response_no_accept ) {
|
||||
processor_setup env(false);
|
||||
|
||||
|
||||
std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\n\r\n";
|
||||
env.res.consume(res.data(),res.size());
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_handshake_response ) {
|
||||
processor_setup env(false);
|
||||
|
||||
|
||||
env.req.append_header("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
|
||||
|
||||
|
||||
std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
|
||||
env.res.consume(res.data(),res.size());
|
||||
|
||||
|
||||
BOOST_CHECK( !env.p.validate_server_handshake_response(env.req,env.res) );
|
||||
}
|
||||
|
||||
@@ -576,7 +608,7 @@ BOOST_AUTO_TEST_CASE( extensions_disabled ) {
|
||||
|
||||
std::pair<websocketpp::lib::error_code,std::string> neg_results;
|
||||
neg_results = env.p.negotiate_extensions(env.req);
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( neg_results.first, websocketpp::processor::error::extensions_disabled );
|
||||
BOOST_CHECK_EQUAL( neg_results.second, "" );
|
||||
}
|
||||
@@ -588,7 +620,7 @@ BOOST_AUTO_TEST_CASE( extension_negotiation_blank ) {
|
||||
|
||||
std::pair<websocketpp::lib::error_code,std::string> neg_results;
|
||||
neg_results = env.p.negotiate_extensions(env.req);
|
||||
|
||||
|
||||
BOOST_CHECK( !neg_results.first );
|
||||
BOOST_CHECK_EQUAL( neg_results.second, "" );
|
||||
}
|
||||
@@ -600,36 +632,36 @@ BOOST_AUTO_TEST_CASE( extension_negotiation_unknown ) {
|
||||
|
||||
std::pair<websocketpp::lib::error_code,std::string> neg_results;
|
||||
neg_results = env.p.negotiate_extensions(env.req);
|
||||
|
||||
|
||||
BOOST_CHECK( !neg_results.first );
|
||||
BOOST_CHECK_EQUAL( neg_results.second, "" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( extract_subprotocols_empty ) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
std::vector<std::string> subps;
|
||||
|
||||
|
||||
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
|
||||
BOOST_CHECK_EQUAL( subps.size(), 0 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( extract_subprotocols_one ) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
std::vector<std::string> subps;
|
||||
|
||||
|
||||
env.req.replace_header("Sec-WebSocket-Protocol","foo");
|
||||
|
||||
|
||||
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
|
||||
BOOST_REQUIRE_EQUAL( subps.size(), 1 );
|
||||
BOOST_CHECK_EQUAL( subps[0], "foo" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( extract_subprotocols_multiple ) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
std::vector<std::string> subps;
|
||||
|
||||
|
||||
env.req.replace_header("Sec-WebSocket-Protocol","foo,bar");
|
||||
|
||||
|
||||
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
|
||||
BOOST_REQUIRE_EQUAL( subps.size(), 2 );
|
||||
BOOST_CHECK_EQUAL( subps[0], "foo" );
|
||||
@@ -637,26 +669,25 @@ BOOST_AUTO_TEST_CASE( extract_subprotocols_multiple ) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( extract_subprotocols_invalid) {
|
||||
processor_setup env(true);
|
||||
processor_setup env(true);
|
||||
std::vector<std::string> subps;
|
||||
|
||||
|
||||
env.req.replace_header("Sec-WebSocket-Protocol","foo,bar,,,,");
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( env.p.extract_subprotocols(env.req,subps), websocketpp::processor::error::make_error_code(websocketpp::processor::error::subprotocol_parse_error) );
|
||||
BOOST_CHECK_EQUAL( subps.size(), 0 );
|
||||
}
|
||||
|
||||
/*BOOST_AUTO_TEST_CASE( extension_negotiation_permessage_deflate ) {
|
||||
BOOST_AUTO_TEST_CASE( extension_negotiation_permessage_deflate ) {
|
||||
processor_setup_ext env(true);
|
||||
|
||||
env.req.replace_header("Sec-WebSocket-Extensions","permessage-deflate; foo; bar=\"x x\"");
|
||||
env.req.replace_header("Sec-WebSocket-Extensions",
|
||||
"permessage-deflate; c2s_max_window_bits");
|
||||
|
||||
std::pair<websocketpp::lib::error_code,std::string> neg_results;
|
||||
neg_results = env.p.negotiate_extensions(env.req);
|
||||
|
||||
std::cout << neg_results.first.message() << neg_results.second << std::endl;
|
||||
|
||||
BOOST_CHECK( !neg_results.first );
|
||||
BOOST_CHECK_EQUAL( neg_results.second, "permessage-deflate" );
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE processors
|
||||
@@ -36,100 +36,100 @@
|
||||
|
||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( non_match ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(!websocketpp::processor::is_websocket_handshake(r));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ci_exact_match ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: UpGrAde\r\nUpgrade: WebSocket\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( non_exact_match1 ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade,foo\r\nUpgrade: websocket,foo\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( non_exact_match2 ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: keep-alive,Upgrade,foo\r\nUpgrade: foo,websocket,bar\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( version_blank ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( version_7 ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 7);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( version_8 ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 8);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( version_13 ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 13);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( version_non_numeric ) {
|
||||
websocketpp::http::parser::request r;
|
||||
|
||||
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: abc\r\n\r\n";
|
||||
|
||||
|
||||
r.consume(handshake.c_str(),handshake.size());
|
||||
|
||||
|
||||
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == -1);
|
||||
}
|
||||
@@ -10,7 +10,7 @@ Import('polyfill_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','random'],env) + [platform_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','random','system'],env) + [platform_libs]
|
||||
|
||||
objs = env.Object('random_none_boost.o', ["none.cpp"], LIBS = BOOST_LIBS)
|
||||
objs += env.Object('random_device_boost.o', ["random_device.cpp"], LIBS = BOOST_LIBS)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE random_none
|
||||
@@ -33,8 +33,8 @@
|
||||
|
||||
BOOST_AUTO_TEST_CASE( does_it_compile ) {
|
||||
websocketpp::random::none::int_generator<int32_t> rng;
|
||||
|
||||
|
||||
int32_t foo = rng();
|
||||
|
||||
|
||||
BOOST_CHECK( foo == 0 );
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE random_device
|
||||
@@ -36,15 +36,15 @@
|
||||
|
||||
BOOST_AUTO_TEST_CASE( compiles ) {
|
||||
websocketpp::random::random_device::int_generator<int32_t,websocketpp::concurrency::none> rng;
|
||||
|
||||
|
||||
bool e = false;
|
||||
|
||||
|
||||
try {
|
||||
int32_t foo = rng();
|
||||
std::cout << foo << std::endl;
|
||||
} catch (...) {
|
||||
e = true;
|
||||
}
|
||||
|
||||
|
||||
BOOST_CHECK( e == false );
|
||||
}
|
||||
@@ -10,7 +10,7 @@ Import('polyfill_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system','regex','random'],env) + [platform_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system','random'],env) + [platform_libs]
|
||||
|
||||
objs = env.Object('client_boost.o', ["client.cpp"], LIBS = BOOST_LIBS)
|
||||
objs += env.Object('server_boost.o', ["server.cpp"], LIBS = BOOST_LIBS)
|
||||
|
||||
+41
-41
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE client
|
||||
@@ -52,11 +52,11 @@ struct stub_config : public websocketpp::config::core {
|
||||
|
||||
//typedef core::rng_type rng_type;
|
||||
typedef websocketpp::random::random_device::int_generator<uint32_t,concurrency_type> rng_type;
|
||||
|
||||
|
||||
typedef core::transport_type transport_type;
|
||||
|
||||
|
||||
typedef core::endpoint_base endpoint_base;
|
||||
|
||||
|
||||
static const websocketpp::log::level elog_level = websocketpp::log::elevel::none;
|
||||
static const websocketpp::log::level alog_level = websocketpp::log::alevel::none;
|
||||
};
|
||||
@@ -67,27 +67,27 @@ typedef client::connection_ptr connection_ptr;
|
||||
BOOST_AUTO_TEST_CASE( invalid_uri ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
connection_ptr con = c.get_connection("foo", ec);
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( ec , websocketpp::error::make_error_code(websocketpp::error::invalid_uri) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( unsecure_endpoint ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
connection_ptr con = c.get_connection("wss://localhost/", ec);
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( ec , websocketpp::error::make_error_code(websocketpp::error::endpoint_not_secure) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( get_connection ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
|
||||
|
||||
BOOST_CHECK( con );
|
||||
BOOST_CHECK_EQUAL( con->get_host() , "localhost" );
|
||||
BOOST_CHECK_EQUAL( con->get_port() , 80 );
|
||||
@@ -100,69 +100,69 @@ BOOST_AUTO_TEST_CASE( connect_con ) {
|
||||
websocketpp::lib::error_code ec;
|
||||
std::stringstream out;
|
||||
std::string o;
|
||||
|
||||
|
||||
c.register_ostream(&out);
|
||||
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
c.connect(con);
|
||||
|
||||
|
||||
o = out.str();
|
||||
websocketpp::http::parser::request r;
|
||||
r.consume(o.data(),o.size());
|
||||
|
||||
|
||||
BOOST_CHECK( r.ready() );
|
||||
BOOST_CHECK_EQUAL( r.get_method(), "GET");
|
||||
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1");
|
||||
BOOST_CHECK_EQUAL( r.get_uri(), "/");
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( r.get_header("Host"), "localhost");
|
||||
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Version"), "13");
|
||||
BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade");
|
||||
BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket");
|
||||
|
||||
|
||||
// Key is randomly generated & User-Agent will change so just check that
|
||||
// they are not empty.
|
||||
BOOST_CHECK_NE( r.get_header("Sec-WebSocket-Key"), "");
|
||||
BOOST_CHECK_NE( r.get_header("User-Agent"), "" );
|
||||
|
||||
|
||||
// connection should have written out an opening handshake request and be in
|
||||
// the read response internal state
|
||||
|
||||
|
||||
// TODO: more tests related to reading the HTTP response
|
||||
std::stringstream channel2;
|
||||
channel2 << "e\r\n\r\n";
|
||||
channel2 >> *con;
|
||||
channel2 << "e\r\n\r\n";
|
||||
channel2 >> *con;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( select_subprotocol ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
using websocketpp::error::make_error_code;
|
||||
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
|
||||
|
||||
BOOST_CHECK( con );
|
||||
|
||||
|
||||
con->select_subprotocol("foo",ec);
|
||||
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::server_only) );
|
||||
BOOST_CHECK_THROW( con->select_subprotocol("foo") , websocketpp::lib::error_code );
|
||||
BOOST_CHECK_THROW( con->select_subprotocol("foo") , websocketpp::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( add_subprotocols_invalid ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
using websocketpp::error::make_error_code;
|
||||
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
BOOST_CHECK( con );
|
||||
|
||||
|
||||
con->add_subprotocol("",ec);
|
||||
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::invalid_subprotocol) );
|
||||
BOOST_CHECK_THROW( con->add_subprotocol("") , websocketpp::lib::error_code );
|
||||
|
||||
BOOST_CHECK_THROW( con->add_subprotocol("") , websocketpp::exception );
|
||||
|
||||
con->add_subprotocol("foo,bar",ec);
|
||||
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::invalid_subprotocol) );
|
||||
BOOST_CHECK_THROW( con->add_subprotocol("foo,bar") , websocketpp::lib::error_code );
|
||||
BOOST_CHECK_THROW( con->add_subprotocol("foo,bar") , websocketpp::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( add_subprotocols ) {
|
||||
@@ -170,23 +170,23 @@ BOOST_AUTO_TEST_CASE( add_subprotocols ) {
|
||||
websocketpp::lib::error_code ec;
|
||||
std::stringstream out;
|
||||
std::string o;
|
||||
|
||||
|
||||
c.register_ostream(&out);
|
||||
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
BOOST_CHECK( con );
|
||||
|
||||
|
||||
con->add_subprotocol("foo",ec);
|
||||
BOOST_CHECK( !ec );
|
||||
|
||||
|
||||
BOOST_CHECK_NO_THROW( con->add_subprotocol("bar") );
|
||||
|
||||
|
||||
c.connect(con);
|
||||
|
||||
|
||||
o = out.str();
|
||||
websocketpp::http::parser::request r;
|
||||
r.consume(o.data(),o.size());
|
||||
|
||||
|
||||
BOOST_CHECK( r.ready() );
|
||||
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "foo, bar");
|
||||
}
|
||||
|
||||
+80
-80
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE server
|
||||
@@ -56,9 +56,9 @@ using websocketpp::lib::bind;
|
||||
typedef core::elog_type elog_type;
|
||||
|
||||
typedef core::rng_type rng_type;
|
||||
|
||||
|
||||
typedef core::transport_type transport_type;
|
||||
|
||||
|
||||
typedef core::endpoint_base endpoint_base;
|
||||
};*/
|
||||
|
||||
@@ -66,20 +66,20 @@ using websocketpp::lib::bind;
|
||||
std::string run_server_test(server& s, std::string input) {
|
||||
server::connection_ptr con;
|
||||
std::stringstream output;
|
||||
|
||||
s.register_ostream(&output);
|
||||
s.clear_access_channels(websocketpp::log::alevel::all);
|
||||
|
||||
s.register_ostream(&output);
|
||||
s.clear_access_channels(websocketpp::log::alevel::all);
|
||||
s.clear_error_channels(websocketpp::log::elevel::all);
|
||||
|
||||
con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
std::stringstream channel;
|
||||
|
||||
channel << input;
|
||||
channel >> *con;
|
||||
|
||||
return output.str();
|
||||
|
||||
con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
std::stringstream channel;
|
||||
|
||||
channel << input;
|
||||
channel >> *con;
|
||||
|
||||
return output.str();
|
||||
}
|
||||
|
||||
/* handler library*/
|
||||
@@ -91,28 +91,28 @@ bool validate_func_subprotocol(server* s, std::string* out, std::string accept,
|
||||
websocketpp::connection_hdl hdl)
|
||||
{
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
|
||||
std::stringstream o;
|
||||
|
||||
|
||||
const std::vector<std::string> & protocols = con->get_requested_subprotocols();
|
||||
std::vector<std::string>::const_iterator it;
|
||||
|
||||
|
||||
for (it = protocols.begin(); it != protocols.end(); ++it) {
|
||||
o << *it << ",";
|
||||
}
|
||||
|
||||
*out = o.str();
|
||||
|
||||
|
||||
if (accept != "") {
|
||||
con->select_subprotocol(accept);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void open_func_subprotocol(server* s, std::string* out, websocketpp::connection_hdl hdl) {
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
|
||||
*out = con->get_subprotocol();
|
||||
}
|
||||
|
||||
@@ -120,21 +120,21 @@ void open_func_subprotocol(server* s, std::string* out, websocketpp::connection_
|
||||
BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( invalid_websocket_version ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: a\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 400 Bad Request\r\nServer: test\r\n\r\n";
|
||||
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
//s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
|
||||
|
||||
//s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
@@ -142,10 +142,10 @@ BOOST_AUTO_TEST_CASE( unimplemented_websocket_version ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 14\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
|
||||
std::string output = "HTTP/1.1 400 Bad Request\r\nSec-WebSocket-Version: 0,7,8,13\r\nServer: test\r\n\r\n";
|
||||
|
||||
server s;
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
@@ -153,13 +153,13 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_empty ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string subprotocol;
|
||||
|
||||
server s;
|
||||
|
||||
std::string subprotocol;
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&subprotocol,::_1));
|
||||
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&subprotocol,::_1));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
BOOST_CHECK_EQUAL(subprotocol, "");
|
||||
}
|
||||
@@ -168,15 +168,15 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_one ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
BOOST_CHECK_EQUAL(validate, "foo,");
|
||||
BOOST_CHECK_EQUAL(open, "");
|
||||
@@ -186,15 +186,15 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_one ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: foo\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
BOOST_CHECK_EQUAL(validate, "foo,");
|
||||
BOOST_CHECK_EQUAL(open, "foo");
|
||||
@@ -204,33 +204,33 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_invalid ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: foo\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo2",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
std::string o;
|
||||
|
||||
BOOST_CHECK_THROW(o = run_server_test(s,input), websocketpp::lib::error_code);
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo2",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
std::string o;
|
||||
|
||||
BOOST_CHECK_THROW(o = run_server_test(s,input), websocketpp::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( accept_subprotocol_two ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo, bar\r\n\r\n";
|
||||
|
||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: bar\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
|
||||
std::string validate;
|
||||
std::string open;
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"bar",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"bar",::_1));
|
||||
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
BOOST_CHECK_EQUAL(validate, "foo,bar,");
|
||||
BOOST_CHECK_EQUAL(open, "bar");
|
||||
@@ -239,9 +239,9 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_two ) {
|
||||
/*BOOST_AUTO_TEST_CASE( user_reject_origin ) {
|
||||
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example2.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 403 Forbidden\r\nServer: test\r\n\r\n";
|
||||
|
||||
|
||||
server s;
|
||||
s.set_user_agent("test");
|
||||
|
||||
|
||||
BOOST_CHECK(run_server_test(s,input) == output);
|
||||
}*/
|
||||
@@ -11,7 +11,7 @@ Import('tls_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','regex','random'],env) + [platform_libs] + [tls_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','random','chrono'],env) + [platform_libs] + [tls_libs]
|
||||
|
||||
objs = env.Object('boost_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS)
|
||||
prgs = env.Program('test_boost_integration', ["boost_integration.o"], LIBS = BOOST_LIBS)
|
||||
|
||||
@@ -11,7 +11,7 @@ Import('tls_libs')
|
||||
env = env.Clone ()
|
||||
env_cpp11 = env_cpp11.Clone ()
|
||||
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','regex'],env) + [platform_libs] + [tls_libs]
|
||||
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','chrono'],env) + [platform_libs] + [tls_libs]
|
||||
|
||||
objs = env.Object('base_boost.o', ["base.cpp"], LIBS = BOOST_LIBS)
|
||||
objs += env.Object('timers_boost.o', ["timers.cpp"], LIBS = BOOST_LIBS)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE transport_asio_base
|
||||
@@ -34,16 +34,16 @@
|
||||
|
||||
BOOST_AUTO_TEST_CASE( blank_error ) {
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
||||
BOOST_CHECK( !ec );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( asio_error ) {
|
||||
using websocketpp::transport::asio::error::make_error_code;
|
||||
using websocketpp::transport::asio::error::general;
|
||||
|
||||
|
||||
websocketpp::lib::error_code ec = make_error_code(general);
|
||||
|
||||
|
||||
BOOST_CHECK( ec == general );
|
||||
BOOST_CHECK( ec.value() == 1 );
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE transport_asio_timers
|
||||
@@ -52,12 +52,12 @@
|
||||
// Accept a connection, read data, and discard until EOF
|
||||
void run_dummy_server(int port) {
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
boost::asio::io_service io_service;
|
||||
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port));
|
||||
tcp::socket socket(io_service);
|
||||
|
||||
|
||||
acceptor.accept(socket);
|
||||
for (;;) {
|
||||
char data[512];
|
||||
@@ -94,7 +94,9 @@ struct config {
|
||||
typedef websocketpp::http::parser::request request_type;
|
||||
typedef websocketpp::http::parser::response response_type;
|
||||
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
|
||||
|
||||
|
||||
static const bool enable_multithreading = true;
|
||||
|
||||
static const long timeout_socket_pre_init = 1000;
|
||||
static const long timeout_proxy = 1000;
|
||||
static const long timeout_socket_post_init = 1000;
|
||||
@@ -105,27 +107,27 @@ struct config {
|
||||
|
||||
// Mock context that does no validation
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
|
||||
context_ptr on_tls_init(websocketpp::connection_hdl) {
|
||||
return context_ptr(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
|
||||
}
|
||||
|
||||
// Mock connection
|
||||
struct mock_con: public websocketpp::transport::asio::connection<config> {
|
||||
typedef websocketpp::transport::asio::connection<config> base;
|
||||
|
||||
|
||||
mock_con(bool a, config::alog_type& b, config::elog_type& c) : base(a,b,c) {}
|
||||
|
||||
|
||||
void start() {
|
||||
base::init(websocketpp::lib::bind(&mock_con::handle_start,this,
|
||||
websocketpp::lib::placeholders::_1));
|
||||
}
|
||||
|
||||
|
||||
void handle_start(const websocketpp::lib::error_code& ec) {
|
||||
using websocketpp::transport::asio::socket::make_error_code;
|
||||
using websocketpp::transport::asio::socket::error::tls_handshake_timeout;
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( ec, make_error_code(tls_handshake_timeout) );
|
||||
|
||||
|
||||
base::cancel_socket();
|
||||
}
|
||||
};
|
||||
@@ -135,19 +137,20 @@ typedef websocketpp::lib::shared_ptr<mock_con> connection_ptr;
|
||||
|
||||
struct mock_endpoint : public websocketpp::transport::asio::endpoint<config> {
|
||||
typedef websocketpp::transport::asio::endpoint<config> base;
|
||||
|
||||
|
||||
mock_endpoint() {
|
||||
alog.set_channels(websocketpp::log::alevel::all);
|
||||
base::init_logging(&alog,&elog);
|
||||
init_asio();
|
||||
}
|
||||
|
||||
|
||||
void connect(std::string u) {
|
||||
m_con.reset(new mock_con(false,alog,elog));
|
||||
websocketpp::uri_ptr uri(new websocketpp::uri(u));
|
||||
|
||||
|
||||
BOOST_CHECK( uri->get_valid() );
|
||||
BOOST_CHECK_EQUAL( base::init(m_con), websocketpp::lib::error_code() );
|
||||
|
||||
|
||||
base::async_connect(
|
||||
m_con,
|
||||
uri,
|
||||
@@ -155,19 +158,17 @@ struct mock_endpoint : public websocketpp::transport::asio::endpoint<config> {
|
||||
&mock_endpoint::handle_connect,
|
||||
this,
|
||||
m_con,
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2
|
||||
websocketpp::lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_connect(connection_ptr con, websocketpp::connection_hdl,
|
||||
const websocketpp::lib::error_code & ec)
|
||||
|
||||
void handle_connect(connection_ptr con, websocketpp::lib::error_code const & ec)
|
||||
{
|
||||
BOOST_CHECK( !ec );
|
||||
con->start();
|
||||
}
|
||||
|
||||
|
||||
connection_ptr m_con;
|
||||
config::alog_type alog;
|
||||
config::elog_type elog;
|
||||
@@ -178,9 +179,9 @@ BOOST_AUTO_TEST_CASE( tls_handshake_timeout ) {
|
||||
websocketpp::lib::thread timer(websocketpp::lib::bind(&run_test_timer,5000));
|
||||
dummy_server.detach();
|
||||
timer.detach();
|
||||
|
||||
|
||||
mock_endpoint endpoint;
|
||||
endpoint.set_tls_init_handler(&on_tls_init);
|
||||
endpoint.connect("wss://localhost:9005");
|
||||
endpoint.run();
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE hybi_util
|
||||
@@ -36,15 +36,15 @@
|
||||
BOOST_AUTO_TEST_CASE( circshift_0 ) {
|
||||
if (sizeof(size_t) == 8) {
|
||||
size_t test = 0x0123456789abcdef;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,0);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0x0123456789abcdef);
|
||||
} else {
|
||||
size_t test = 0x01234567;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,0);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0x01234567);
|
||||
}
|
||||
}
|
||||
@@ -52,15 +52,15 @@ BOOST_AUTO_TEST_CASE( circshift_0 ) {
|
||||
BOOST_AUTO_TEST_CASE( circshift_1 ) {
|
||||
if (sizeof(size_t) == 8) {
|
||||
size_t test = 0x0123456789abcdef;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,1);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0xef0123456789abcd);
|
||||
} else {
|
||||
size_t test = 0x01234567;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,1);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0x67012345);
|
||||
}
|
||||
}
|
||||
@@ -68,15 +68,15 @@ BOOST_AUTO_TEST_CASE( circshift_1 ) {
|
||||
BOOST_AUTO_TEST_CASE( circshift_2 ) {
|
||||
if (sizeof(size_t) == 8) {
|
||||
size_t test = 0x0123456789abcdef;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,2);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0xcdef0123456789ab);
|
||||
} else {
|
||||
size_t test = 0x01234567;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,2);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0x45670123);
|
||||
}
|
||||
}
|
||||
@@ -84,15 +84,15 @@ BOOST_AUTO_TEST_CASE( circshift_2 ) {
|
||||
BOOST_AUTO_TEST_CASE( circshift_3 ) {
|
||||
if (sizeof(size_t) == 8) {
|
||||
size_t test = 0x0123456789abcdef;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,3);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0xabcdef0123456789);
|
||||
} else {
|
||||
size_t test = 0x01234567;
|
||||
|
||||
|
||||
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,3);
|
||||
|
||||
|
||||
BOOST_CHECK( test == 0x23456701);
|
||||
}
|
||||
}
|
||||
+311
-55
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE transport_integration
|
||||
@@ -30,45 +30,90 @@
|
||||
|
||||
#include <websocketpp/common/thread.hpp>
|
||||
|
||||
#include <websocketpp/config/asio_no_tls.hpp>
|
||||
#include <websocketpp/config/asio_no_tls_client.hpp>
|
||||
#include <websocketpp/config/core.hpp>
|
||||
#include <websocketpp/config/core_client.hpp>
|
||||
#include <websocketpp/config/asio.hpp>
|
||||
#include <websocketpp/config/asio_client.hpp>
|
||||
#include <websocketpp/config/debug_asio.hpp>
|
||||
#include <websocketpp/server.hpp>
|
||||
#include <websocketpp/client.hpp>
|
||||
|
||||
struct config : public websocketpp::config::asio_client {
|
||||
typedef config type;
|
||||
typedef websocketpp::config::asio base;
|
||||
|
||||
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
|
||||
typedef base::request_type request_type;
|
||||
typedef base::response_type response_type;
|
||||
|
||||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
|
||||
typedef base::alog_type alog_type;
|
||||
typedef base::elog_type elog_type;
|
||||
|
||||
|
||||
typedef base::rng_type rng_type;
|
||||
|
||||
|
||||
struct transport_config : public base::transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
typedef websocketpp::transport::asio::basic_socket::endpoint
|
||||
typedef websocketpp::transport::asio::basic_socket::endpoint
|
||||
socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
|
||||
//static const websocketpp::log::level elog_level = websocketpp::log::elevel::all;
|
||||
//static const websocketpp::log::level alog_level = websocketpp::log::alevel::all;
|
||||
|
||||
|
||||
/// Length of time before an opening handshake is aborted
|
||||
static const long timeout_open_handshake = 500;
|
||||
/// Length of time before a closing handshake is aborted
|
||||
static const long timeout_close_handshake = 500;
|
||||
/// Length of time to wait for a pong after a ping
|
||||
static const long timeout_pong = 500;
|
||||
};
|
||||
|
||||
struct config_tls : public websocketpp::config::asio_tls_client {
|
||||
typedef config type;
|
||||
typedef websocketpp::config::asio base;
|
||||
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
typedef base::response_type response_type;
|
||||
|
||||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
typedef base::alog_type alog_type;
|
||||
typedef base::elog_type elog_type;
|
||||
|
||||
typedef base::rng_type rng_type;
|
||||
|
||||
struct transport_config : public base::transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
typedef websocketpp::transport::asio::basic_socket::endpoint
|
||||
socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
//static const websocketpp::log::level elog_level = websocketpp::log::elevel::all;
|
||||
//static const websocketpp::log::level alog_level = websocketpp::log::alevel::all;
|
||||
|
||||
/// Length of time before an opening handshake is aborted
|
||||
static const long timeout_open_handshake = 500;
|
||||
/// Length of time before a closing handshake is aborted
|
||||
@@ -80,10 +125,25 @@ struct config : public websocketpp::config::asio_client {
|
||||
typedef websocketpp::server<config> server;
|
||||
typedef websocketpp::client<config> client;
|
||||
|
||||
typedef websocketpp::server<config_tls> server_tls;
|
||||
typedef websocketpp::client<config_tls> client_tls;
|
||||
|
||||
typedef websocketpp::server<websocketpp::config::core> iostream_server;
|
||||
typedef websocketpp::client<websocketpp::config::core_client> iostream_client;
|
||||
|
||||
using websocketpp::lib::placeholders::_1;
|
||||
using websocketpp::lib::placeholders::_2;
|
||||
using websocketpp::lib::bind;
|
||||
|
||||
template <typename T>
|
||||
void close_after_timeout(T & e, websocketpp::connection_hdl hdl, long timeout) {
|
||||
sleep(timeout);
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
e.close(hdl,websocketpp::close::status::normal,"",ec);
|
||||
BOOST_CHECK(!ec);
|
||||
}
|
||||
|
||||
void run_server(server * s, int port, bool log = false) {
|
||||
if (log) {
|
||||
s->set_access_channels(websocketpp::log::alevel::all);
|
||||
@@ -94,6 +154,7 @@ void run_server(server * s, int port, bool log = false) {
|
||||
}
|
||||
|
||||
s->init_asio();
|
||||
s->set_reuse_addr(true);
|
||||
|
||||
s->listen(port);
|
||||
s->start_accept();
|
||||
@@ -108,9 +169,11 @@ void run_client(client & c, std::string uri, bool log = false) {
|
||||
c.clear_access_channels(websocketpp::log::alevel::all);
|
||||
c.clear_error_channels(websocketpp::log::elevel::all);
|
||||
}
|
||||
c.init_asio();
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
c.init_asio(ec);
|
||||
c.set_reuse_addr(true);
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
client::connection_ptr con = c.get_connection(uri,ec);
|
||||
BOOST_CHECK( !ec );
|
||||
c.connect(con);
|
||||
@@ -118,14 +181,50 @@ void run_client(client & c, std::string uri, bool log = false) {
|
||||
c.run();
|
||||
}
|
||||
|
||||
void run_client_and_mark(client * c, bool * flag, websocketpp::lib::mutex * mutex) {
|
||||
c->run();
|
||||
BOOST_CHECK( true );
|
||||
websocketpp::lib::lock_guard<websocketpp::lib::mutex> lock(*mutex);
|
||||
*flag = true;
|
||||
BOOST_CHECK( true );
|
||||
}
|
||||
|
||||
void run_time_limited_client(client & c, std::string uri, long timeout,
|
||||
bool log)
|
||||
{
|
||||
if (log) {
|
||||
c.set_access_channels(websocketpp::log::alevel::all);
|
||||
c.set_error_channels(websocketpp::log::elevel::all);
|
||||
} else {
|
||||
c.clear_access_channels(websocketpp::log::alevel::all);
|
||||
c.clear_error_channels(websocketpp::log::elevel::all);
|
||||
}
|
||||
c.init_asio();
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
client::connection_ptr con = c.get_connection(uri,ec);
|
||||
BOOST_CHECK( !ec );
|
||||
c.connect(con);
|
||||
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(
|
||||
&close_after_timeout<client>,
|
||||
websocketpp::lib::ref(c),
|
||||
con->get_handle(),
|
||||
timeout
|
||||
));
|
||||
tthread.detach();
|
||||
|
||||
c.run();
|
||||
}
|
||||
|
||||
void run_dummy_server(int port) {
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
boost::asio::io_service io_service;
|
||||
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port));
|
||||
tcp::socket socket(io_service);
|
||||
|
||||
|
||||
acceptor.accept(socket);
|
||||
for (;;) {
|
||||
char data[512];
|
||||
@@ -147,14 +246,14 @@ void run_dummy_server(int port) {
|
||||
|
||||
void run_dummy_client(std::string port) {
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
boost::asio::io_service io_service;
|
||||
tcp::resolver resolver(io_service);
|
||||
tcp::resolver::query query("localhost", port);
|
||||
tcp::resolver::iterator iterator = resolver.resolve(query);
|
||||
tcp::socket socket(io_service);
|
||||
|
||||
|
||||
boost::asio::connect(socket, iterator);
|
||||
for (;;) {
|
||||
char data[512];
|
||||
@@ -174,12 +273,13 @@ void run_dummy_client(std::string port) {
|
||||
}
|
||||
}
|
||||
|
||||
bool on_ping(websocketpp::connection_hdl, std::string payload) {
|
||||
bool on_ping(server * s, websocketpp::connection_hdl, std::string) {
|
||||
s->get_alog().write(websocketpp::log::alevel::app,"got ping");
|
||||
return false;
|
||||
}
|
||||
|
||||
void cancel_on_open(server * s, websocketpp::connection_hdl hdl) {
|
||||
s->cancel();
|
||||
void cancel_on_open(server * s, websocketpp::connection_hdl) {
|
||||
s->stop_listening();
|
||||
}
|
||||
|
||||
void stop_on_close(server * s, websocketpp::connection_hdl hdl) {
|
||||
@@ -192,23 +292,35 @@ void stop_on_close(server * s, websocketpp::connection_hdl hdl) {
|
||||
template <typename T>
|
||||
void ping_on_open(T * c, std::string payload, websocketpp::connection_hdl hdl) {
|
||||
typename T::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||
con->ping(payload);
|
||||
websocketpp::lib::error_code ec;
|
||||
con->ping(payload,ec);
|
||||
BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
|
||||
}
|
||||
|
||||
void fail_on_pong(websocketpp::connection_hdl hdl, std::string payload) {
|
||||
void fail_on_pong(websocketpp::connection_hdl, std::string) {
|
||||
BOOST_FAIL( "expected no pong handler" );
|
||||
}
|
||||
|
||||
void fail_on_open(websocketpp::connection_hdl hdl) {
|
||||
void fail_on_pong_timeout(websocketpp::connection_hdl, std::string) {
|
||||
BOOST_FAIL( "expected no pong timeout" );
|
||||
}
|
||||
|
||||
void req_pong(std::string expected_payload, websocketpp::connection_hdl,
|
||||
std::string payload)
|
||||
{
|
||||
BOOST_CHECK_EQUAL( expected_payload, payload );
|
||||
}
|
||||
|
||||
void fail_on_open(websocketpp::connection_hdl) {
|
||||
BOOST_FAIL( "expected no open handler" );
|
||||
}
|
||||
|
||||
void delay(websocketpp::connection_hdl hdl, long duration) {
|
||||
void delay(websocketpp::connection_hdl, long duration) {
|
||||
sleep(duration);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void check_ec(T * c, websocketpp::lib::error_code ec,
|
||||
void check_ec(T * c, websocketpp::lib::error_code ec,
|
||||
websocketpp::connection_hdl hdl)
|
||||
{
|
||||
typename T::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||
@@ -218,7 +330,7 @@ void check_ec(T * c, websocketpp::lib::error_code ec,
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void check_ec_and_stop(T * e, websocketpp::lib::error_code ec,
|
||||
void check_ec_and_stop(T * e, websocketpp::lib::error_code ec,
|
||||
websocketpp::connection_hdl hdl)
|
||||
{
|
||||
typename T::connection_ptr con = e->get_con_from_hdl(hdl);
|
||||
@@ -229,7 +341,7 @@ void check_ec_and_stop(T * e, websocketpp::lib::error_code ec,
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void req_pong_timeout(T * c, std::string expected_payload,
|
||||
void req_pong_timeout(T * c, std::string expected_payload,
|
||||
websocketpp::connection_hdl hdl, std::string payload)
|
||||
{
|
||||
typename T::connection_ptr con = c->get_con_from_hdl(hdl);
|
||||
@@ -248,31 +360,55 @@ void run_test_timer(long value) {
|
||||
BOOST_FAIL( "Test timed out" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( pong_no_timeout ) {
|
||||
server s;
|
||||
client c;
|
||||
|
||||
s.set_close_handler(bind(&stop_on_close,&s,::_1));
|
||||
|
||||
// send a ping when the connection is open
|
||||
c.set_open_handler(bind(&ping_on_open<client>,&c,"foo",::_1));
|
||||
// require that a pong with matching payload is received
|
||||
c.set_pong_handler(bind(&req_pong,"foo",::_1,::_2));
|
||||
// require that a pong timeout is NOT received
|
||||
c.set_pong_timeout_handler(bind(&fail_on_pong_timeout,::_1,::_2));
|
||||
|
||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||
|
||||
// Run a client that closes the connection after 1 seconds
|
||||
run_time_limited_client(c, "http://localhost:9005", 1, false);
|
||||
|
||||
sthread.join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( pong_timeout ) {
|
||||
server s;
|
||||
client c;
|
||||
|
||||
s.set_ping_handler(on_ping);
|
||||
s.set_ping_handler(bind(&on_ping, &s,::_1,::_2));
|
||||
s.set_close_handler(bind(&stop_on_close,&s,::_1));
|
||||
|
||||
c.set_fail_handler(bind(&check_ec<client>,&c,
|
||||
websocketpp::lib::error_code(),::_1));
|
||||
|
||||
c.set_pong_handler(bind(&fail_on_pong,::_1,::_2));
|
||||
c.set_open_handler(bind(&ping_on_open<client>,&c,"foo",::_1));
|
||||
c.set_pong_timeout_handler(bind(&req_pong_timeout<client>,&c,"foo",::_1,::_2));
|
||||
c.set_close_handler(bind(&check_ec<client>,&c,
|
||||
websocketpp::lib::error_code(),::_1));
|
||||
|
||||
|
||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
||||
tthread.detach();
|
||||
|
||||
|
||||
run_client(c, "http://localhost:9005",false);
|
||||
|
||||
|
||||
sthread.join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_open_handshake_timeout ) {
|
||||
client c;
|
||||
|
||||
|
||||
// set open handler to fail test
|
||||
c.set_open_handler(bind(&fail_on_open,::_1));
|
||||
// set fail hander to test for the right fail error code
|
||||
@@ -280,16 +416,16 @@ BOOST_AUTO_TEST_CASE( client_open_handshake_timeout ) {
|
||||
websocketpp::error::open_handshake_timeout,::_1));
|
||||
|
||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_dummy_server,9005));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
||||
sthread.detach();
|
||||
tthread.detach();
|
||||
|
||||
|
||||
run_client(c, "http://localhost:9005");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( server_open_handshake_timeout ) {
|
||||
server s;
|
||||
|
||||
|
||||
// set open handler to fail test
|
||||
s.set_open_handler(bind(&fail_on_open,::_1));
|
||||
// set fail hander to test for the right fail error code
|
||||
@@ -297,11 +433,11 @@ BOOST_AUTO_TEST_CASE( server_open_handshake_timeout ) {
|
||||
websocketpp::error::open_handshake_timeout,::_1));
|
||||
|
||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
||||
tthread.detach();
|
||||
|
||||
|
||||
run_dummy_client("9005");
|
||||
|
||||
|
||||
sthread.join();
|
||||
}
|
||||
|
||||
@@ -318,13 +454,13 @@ BOOST_AUTO_TEST_CASE( client_self_initiated_close_handshake_timeout ) {
|
||||
c.set_open_handler(bind(&close<client>,&c,::_1));
|
||||
c.set_close_handler(bind(&check_ec<client>,&c,
|
||||
websocketpp::error::close_handshake_timeout,::_1));
|
||||
|
||||
|
||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
||||
tthread.detach();
|
||||
|
||||
run_client(c, "http://localhost:9005",false);
|
||||
|
||||
|
||||
run_client(c, "http://localhost:9005", false);
|
||||
|
||||
sthread.join();
|
||||
}
|
||||
|
||||
@@ -333,7 +469,7 @@ BOOST_AUTO_TEST_CASE( client_peer_initiated_close_handshake_timeout ) {
|
||||
// client should ack normally and then wait
|
||||
// server leaves TCP connection open
|
||||
// client handshake timer should be triggered
|
||||
|
||||
|
||||
// TODO: how to make a mock server that leaves the TCP connection open?
|
||||
}
|
||||
|
||||
@@ -350,12 +486,132 @@ BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) {
|
||||
websocketpp::error::close_handshake_timeout,::_1));
|
||||
|
||||
c.set_open_handler(bind(&delay,::_1,1));
|
||||
|
||||
|
||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
||||
tthread.detach();
|
||||
|
||||
run_client(c, "http://localhost:9005",false);
|
||||
|
||||
sthread.join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) {
|
||||
client c;
|
||||
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,3));
|
||||
tthread.detach();
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
c.init_asio(ec);
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
c.run();
|
||||
|
||||
// This test checks that an io_service with no work ends immediately.
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_is_perpetual ) {
|
||||
client c;
|
||||
bool flag = false;
|
||||
websocketpp::lib::mutex mutex;
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
c.init_asio(ec);
|
||||
BOOST_CHECK(!ec);
|
||||
|
||||
c.start_perpetual();
|
||||
|
||||
websocketpp::lib::thread cthread(websocketpp::lib::bind(&run_client_and_mark,&c,&flag,&mutex));
|
||||
|
||||
sleep(1);
|
||||
|
||||
{
|
||||
// Checks that the thread hasn't exited yet
|
||||
websocketpp::lib::lock_guard<websocketpp::lib::mutex> lock(mutex);
|
||||
BOOST_CHECK( !flag );
|
||||
}
|
||||
|
||||
c.stop_perpetual();
|
||||
|
||||
sleep(1);
|
||||
|
||||
{
|
||||
// Checks that the thread has exited
|
||||
websocketpp::lib::lock_guard<websocketpp::lib::mutex> lock(mutex);
|
||||
BOOST_CHECK( flag );
|
||||
}
|
||||
|
||||
cthread.join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( client_failed_connection ) {
|
||||
client c;
|
||||
|
||||
run_time_limited_client(c,"http://localhost:9005", 5, false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( stop_listening ) {
|
||||
server s;
|
||||
client c;
|
||||
|
||||
// the first connection stops the server from listening
|
||||
s.set_open_handler(bind(&cancel_on_open,&s,::_1));
|
||||
|
||||
// client immediately closes after opening a connection
|
||||
c.set_open_handler(bind(&close<client>,&c,::_1));
|
||||
|
||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,5));
|
||||
tthread.detach();
|
||||
|
||||
run_client(c, "http://localhost:9005",false);
|
||||
|
||||
sthread.join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( pause_reading ) {
|
||||
iostream_server s;
|
||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
|
||||
char buffer[2] = { char(0x81), char(0x80) };
|
||||
|
||||
// suppress output (it needs a place to go to avoid error but we don't care what it is)
|
||||
std::stringstream null_output;
|
||||
s.register_ostream(&null_output);
|
||||
|
||||
iostream_server::connection_ptr con = s.get_connection();
|
||||
con->start();
|
||||
|
||||
// read handshake, should work
|
||||
BOOST_CHECK_EQUAL( con->read_some(handshake.data(), handshake.length()), handshake.length());
|
||||
|
||||
// pause reading and try again. The first read should work, the second should return 0
|
||||
// the first read was queued already after the handshake so it will go through because
|
||||
// reading wasn't paused when it was queued. The byte it reads wont be enough to
|
||||
// complete the frame so another read will be requested. This one wont actually happen
|
||||
// because the connection is paused now.
|
||||
con->pause_reading();
|
||||
BOOST_CHECK_EQUAL( con->read_some(buffer, 1), 1);
|
||||
BOOST_CHECK_EQUAL( con->read_some(buffer+1, 1), 0);
|
||||
// resume reading and try again. Should work this time because the resume should have
|
||||
// re-queued a read.
|
||||
con->resume_reading();
|
||||
BOOST_CHECK_EQUAL( con->read_some(buffer+1, 1), 1);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( server_connection_cleanup ) {
|
||||
server_tls s;
|
||||
}
|
||||
|
||||
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
BOOST_AUTO_TEST_CASE( move_construct_transport ) {
|
||||
server s1;
|
||||
|
||||
server s2(std::move(s1));
|
||||
}
|
||||
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE transport_iostream_base
|
||||
@@ -30,4 +30,4 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( placeholder ) {}
|
||||
BOOST_AUTO_TEST_CASE( placeholder ) {}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,10 +11,10 @@
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
@@ -22,7 +22,7 @@
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//#define BOOST_TEST_DYN_LINK
|
||||
#define BOOST_TEST_MODULE transport_iostream_connection
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
|
||||
#include <websocketpp/error.hpp>
|
||||
#include <websocketpp/transport/iostream/connection.hpp>
|
||||
|
||||
@@ -52,231 +54,556 @@ typedef websocketpp::transport::iostream::connection<config> iostream_con;
|
||||
using websocketpp::transport::iostream::error::make_error_code;
|
||||
|
||||
struct stub_con : public iostream_con {
|
||||
typedef stub_con type;
|
||||
typedef websocketpp::lib::shared_ptr<type> ptr;
|
||||
typedef iostream_con::timer_ptr timer_ptr;
|
||||
|
||||
stub_con(bool is_server, config::alog_type &a, config::elog_type & e)
|
||||
stub_con(bool is_server, config::alog_type & a, config::elog_type & e)
|
||||
: iostream_con(is_server,a,e)
|
||||
// Set the error to a known code that is unused by the library
|
||||
// This way we can easily confirm that the handler was run at all.
|
||||
, ec(websocketpp::error::make_error_code(websocketpp::error::test))
|
||||
, indef_read_total(0)
|
||||
{}
|
||||
|
||||
|
||||
/// Get a shared pointer to this component
|
||||
ptr get_shared() {
|
||||
return websocketpp::lib::static_pointer_cast<type>(iostream_con::get_shared());
|
||||
}
|
||||
|
||||
void write(std::string msg) {
|
||||
iostream_con::async_write(
|
||||
msg.data(),
|
||||
msg.size(),
|
||||
websocketpp::lib::bind(
|
||||
&stub_con::handle_op,
|
||||
this,
|
||||
type::get_shared(),
|
||||
websocketpp::lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void write(std::vector<websocketpp::transport::buffer> & bufs) {
|
||||
iostream_con::async_write(
|
||||
bufs,
|
||||
websocketpp::lib::bind(
|
||||
&stub_con::handle_op,
|
||||
this,
|
||||
type::get_shared(),
|
||||
websocketpp::lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void async_read_at_least(size_t num_bytes, char *buf, size_t len)
|
||||
{
|
||||
{
|
||||
iostream_con::async_read_at_least(
|
||||
num_bytes,
|
||||
buf,
|
||||
len,
|
||||
websocketpp::lib::bind(
|
||||
&stub_con::handle_op,
|
||||
this,
|
||||
type::get_shared(),
|
||||
websocketpp::lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_op(const websocketpp::lib::error_code& e) {
|
||||
|
||||
void handle_op(websocketpp::lib::error_code const & e) {
|
||||
ec = e;
|
||||
}
|
||||
|
||||
|
||||
void async_read_indef(size_t num_bytes, char *buf, size_t len)
|
||||
{
|
||||
indef_read_size = num_bytes;
|
||||
indef_read_buf = buf;
|
||||
indef_read_len = len;
|
||||
|
||||
indef_read();
|
||||
}
|
||||
|
||||
void indef_read() {
|
||||
iostream_con::async_read_at_least(
|
||||
indef_read_size,
|
||||
indef_read_buf,
|
||||
indef_read_len,
|
||||
websocketpp::lib::bind(
|
||||
&stub_con::handle_indef,
|
||||
type::get_shared(),
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_indef(websocketpp::lib::error_code const & e, size_t amt_read) {
|
||||
ec = e;
|
||||
indef_read_total += amt_read;
|
||||
|
||||
indef_read();
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
iostream_con::async_shutdown(
|
||||
websocketpp::lib::bind(
|
||||
&stub_con::handle_async_shutdown,
|
||||
type::get_shared(),
|
||||
websocketpp::lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_async_shutdown(websocketpp::lib::error_code const & e) {
|
||||
ec = e;
|
||||
}
|
||||
|
||||
websocketpp::lib::error_code ec;
|
||||
size_t indef_read_size;
|
||||
char * indef_read_buf;
|
||||
size_t indef_read_len;
|
||||
size_t indef_read_total;
|
||||
};
|
||||
|
||||
// Stubs
|
||||
config::alog_type a;
|
||||
config::elog_type e;
|
||||
config::alog_type alogger;
|
||||
config::elog_type elogger;
|
||||
|
||||
BOOST_AUTO_TEST_CASE( const_methods ) {
|
||||
iostream_con con(true,a,e);
|
||||
|
||||
BOOST_CHECK( con.is_secure() == false );
|
||||
BOOST_CHECK( con.get_remote_endpoint() == "iostream transport" );
|
||||
iostream_con::ptr con(new iostream_con(true,alogger,elogger));
|
||||
|
||||
BOOST_CHECK( !con->is_secure() );
|
||||
BOOST_CHECK_EQUAL( con->get_remote_endpoint(), "iostream transport" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( write_before_ostream_set ) {
|
||||
stub_con con(true,a,e);
|
||||
|
||||
con.write("foo");
|
||||
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
|
||||
|
||||
BOOST_AUTO_TEST_CASE( write_before_output_method_set ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
con->write("foo");
|
||||
BOOST_CHECK( con->ec == make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
con.write(bufs);
|
||||
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
|
||||
con->write(bufs);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write ) {
|
||||
stub_con con(true,a,e);
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_ostream ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
std::stringstream output;
|
||||
|
||||
con.register_ostream(&output);
|
||||
|
||||
con.write("foo");
|
||||
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( output.str() == "foo" );
|
||||
|
||||
con->register_ostream(&output);
|
||||
|
||||
con->write("foo");
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output.str(), "foo" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_0 ) {
|
||||
websocketpp::lib::error_code write_handler(std::string & o, websocketpp::connection_hdl, char const * buf, size_t len) {
|
||||
o += std::string(buf,len);
|
||||
return websocketpp::lib::error_code();
|
||||
}
|
||||
|
||||
websocketpp::lib::error_code vector_write_handler(std::string & o, websocketpp::connection_hdl, std::vector<websocketpp::transport::buffer> const & bufs) {
|
||||
std::vector<websocketpp::transport::buffer>::const_iterator it;
|
||||
for (it = bufs.begin(); it != bufs.end(); it++) {
|
||||
o += std::string((*it).buf, (*it).len);
|
||||
}
|
||||
|
||||
return websocketpp::lib::error_code();
|
||||
}
|
||||
|
||||
websocketpp::lib::error_code write_handler_error(websocketpp::connection_hdl, char const *, size_t) {
|
||||
return make_error_code(websocketpp::transport::error::general);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_handler ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
std::string output;
|
||||
|
||||
con->set_write_handler(websocketpp::lib::bind(
|
||||
&write_handler,
|
||||
websocketpp::lib::ref(output),
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2,
|
||||
websocketpp::lib::placeholders::_3
|
||||
));
|
||||
con->write("foo");
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL(output, "foo");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_handler_error ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
con->set_write_handler(&write_handler_error);
|
||||
con->write("foo");
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::general) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_0_ostream ) {
|
||||
std::stringstream output;
|
||||
|
||||
stub_con con(true,a,e);
|
||||
con.register_ostream(&output);
|
||||
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
con->register_ostream(&output);
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
|
||||
con.write(bufs);
|
||||
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( output.str() == "" );
|
||||
|
||||
con->write(bufs);
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output.str(), "" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_1 ) {
|
||||
std::stringstream output;
|
||||
|
||||
stub_con con(true,a,e);
|
||||
con.register_ostream(&output);
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_0_write_handler ) {
|
||||
std::string output;
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
con->set_write_handler(websocketpp::lib::bind(
|
||||
&write_handler,
|
||||
websocketpp::lib::ref(output),
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2,
|
||||
websocketpp::lib::placeholders::_3
|
||||
));
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
|
||||
|
||||
con->write(bufs);
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output, "" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_1_ostream ) {
|
||||
std::stringstream output;
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
con->register_ostream(&output);
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
|
||||
std::string foo = "foo";
|
||||
|
||||
|
||||
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
|
||||
|
||||
con.write(bufs);
|
||||
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( output.str() == "foo" );
|
||||
|
||||
con->write(bufs);
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output.str(), "foo" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_2 ) {
|
||||
std::stringstream output;
|
||||
|
||||
stub_con con(true,a,e);
|
||||
con.register_ostream(&output);
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_1_write_handler ) {
|
||||
std::string output;
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
con->set_write_handler(websocketpp::lib::bind(
|
||||
&write_handler,
|
||||
websocketpp::lib::ref(output),
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2,
|
||||
websocketpp::lib::placeholders::_3
|
||||
));
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
|
||||
|
||||
std::string foo = "foo";
|
||||
|
||||
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
|
||||
|
||||
con->write(bufs);
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output, "foo" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_2_ostream ) {
|
||||
std::stringstream output;
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
con->register_ostream(&output);
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
|
||||
std::string foo = "foo";
|
||||
std::string bar = "bar";
|
||||
|
||||
|
||||
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
|
||||
bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
|
||||
|
||||
con.write(bufs);
|
||||
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( output.str() == "foobar" );
|
||||
|
||||
con->write(bufs);
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output.str(), "foobar" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_2_write_handler ) {
|
||||
std::string output;
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
con->set_write_handler(websocketpp::lib::bind(
|
||||
&write_handler,
|
||||
websocketpp::lib::ref(output),
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2,
|
||||
websocketpp::lib::placeholders::_3
|
||||
));
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
|
||||
std::string foo = "foo";
|
||||
std::string bar = "bar";
|
||||
|
||||
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
|
||||
bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
|
||||
|
||||
con->write(bufs);
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output, "foobar" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_write_vector_2_vector_write_handler ) {
|
||||
std::string output;
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
con->set_vector_write_handler(websocketpp::lib::bind(
|
||||
&vector_write_handler,
|
||||
websocketpp::lib::ref(output),
|
||||
websocketpp::lib::placeholders::_1,
|
||||
websocketpp::lib::placeholders::_2
|
||||
));
|
||||
|
||||
std::vector<websocketpp::transport::buffer> bufs;
|
||||
|
||||
std::string foo = "foo";
|
||||
std::string bar = "bar";
|
||||
|
||||
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
|
||||
bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
|
||||
|
||||
con->write(bufs);
|
||||
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( output, "foobar" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_read_at_least_too_much ) {
|
||||
stub_con con(true,a,e);
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
char buf[10];
|
||||
|
||||
con.async_read_at_least(11,buf,10);
|
||||
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::invalid_num_bytes) );
|
||||
|
||||
con->async_read_at_least(11,buf,10);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::invalid_num_bytes) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_read_at_least_double_read ) {
|
||||
stub_con con(true,a,e);
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
char buf[10];
|
||||
|
||||
con.async_read_at_least(5,buf,10);
|
||||
con.async_read_at_least(5,buf,10);
|
||||
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::double_read) );
|
||||
|
||||
con->async_read_at_least(5,buf,10);
|
||||
con->async_read_at_least(5,buf,10);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::double_read) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_read_at_least ) {
|
||||
stub_con con(true,a,e);
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
char buf[10];
|
||||
|
||||
|
||||
memset(buf,'x',10);
|
||||
|
||||
con.async_read_at_least(5,buf,10);
|
||||
BOOST_CHECK( con.ec == make_error_code(websocketpp::error::test) );
|
||||
|
||||
|
||||
con->async_read_at_least(5,buf,10);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
|
||||
std::stringstream channel;
|
||||
channel << "abcd";
|
||||
channel >> con;
|
||||
BOOST_CHECK( channel.tellg() == -1 );
|
||||
BOOST_CHECK( con.ec == make_error_code(websocketpp::error::test) );
|
||||
|
||||
channel << "abcd";
|
||||
channel >> *con;
|
||||
BOOST_CHECK_EQUAL( channel.tellg(), -1 );
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
|
||||
std::stringstream channel2;
|
||||
channel2 << "e";
|
||||
channel2 >> con;
|
||||
BOOST_CHECK( channel2.tellg() == -1 );
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( std::string(buf,10) == "abcdexxxxx" );
|
||||
|
||||
channel2 << "e";
|
||||
channel2 >> *con;
|
||||
BOOST_CHECK_EQUAL( channel2.tellg(), -1 );
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
|
||||
|
||||
std::stringstream channel3;
|
||||
channel3 << "f";
|
||||
channel3 >> con;
|
||||
BOOST_CHECK( channel3.tellg() == 0 );
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( std::string(buf,10) == "abcdexxxxx" );
|
||||
con.async_read_at_least(1,buf+5,5);
|
||||
channel3 >> con;
|
||||
BOOST_CHECK( channel3.tellg() == -1 );
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( std::string(buf,10) == "abcdefxxxx" );
|
||||
channel3 << "f";
|
||||
channel3 >> *con;
|
||||
BOOST_CHECK_EQUAL( channel3.tellg(), 0 );
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
|
||||
con->async_read_at_least(1,buf+5,5);
|
||||
channel3 >> *con;
|
||||
BOOST_CHECK_EQUAL( channel3.tellg(), -1 );
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefxxxx" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_read_at_least2 ) {
|
||||
stub_con con(true,a,e);
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
char buf[10];
|
||||
|
||||
|
||||
memset(buf,'x',10);
|
||||
|
||||
con.async_read_at_least(5,buf,5);
|
||||
BOOST_CHECK( con.ec == make_error_code(websocketpp::error::test) );
|
||||
|
||||
|
||||
con->async_read_at_least(5,buf,5);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
|
||||
std::stringstream channel;
|
||||
channel << "abcdefg";
|
||||
channel >> con;
|
||||
BOOST_CHECK( channel.tellg() == 5 );
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( std::string(buf,10) == "abcdexxxxx" );
|
||||
|
||||
con.async_read_at_least(1,buf+5,5);
|
||||
channel >> con;
|
||||
BOOST_CHECK( channel.tellg() == -1 );
|
||||
BOOST_CHECK( !con.ec );
|
||||
BOOST_CHECK( std::string(buf,10) == "abcdefgxxx" );
|
||||
channel << "abcdefg";
|
||||
channel >> *con;
|
||||
BOOST_CHECK_EQUAL( channel.tellg(), 5 );
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
|
||||
|
||||
con->async_read_at_least(1,buf+5,5);
|
||||
channel >> *con;
|
||||
BOOST_CHECK_EQUAL( channel.tellg(), -1 );
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefgxxx" );
|
||||
}
|
||||
|
||||
void timer_callback_stub(const websocketpp::lib::error_code & ec) {}
|
||||
void timer_callback_stub(websocketpp::lib::error_code const &) {}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( set_timer ) {
|
||||
stub_con con(true,a,e);
|
||||
|
||||
stub_con::timer_ptr tp = con.set_timer(1000,timer_callback_stub);
|
||||
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
stub_con::timer_ptr tp = con->set_timer(1000,timer_callback_stub);
|
||||
|
||||
BOOST_CHECK( !tp );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_read_at_least_read_some ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
char buf[10];
|
||||
memset(buf,'x',10);
|
||||
|
||||
con->async_read_at_least(5,buf,5);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
|
||||
char input[10] = "abcdefg";
|
||||
BOOST_CHECK_EQUAL(con->read_some(input,5), 5);
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
|
||||
|
||||
BOOST_CHECK_EQUAL(con->read_some(input+5,2), 0);
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
|
||||
|
||||
con->async_read_at_least(1,buf+5,5);
|
||||
BOOST_CHECK_EQUAL(con->read_some(input+5,2), 2);
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefgxxx" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_read_at_least_read_some_indef ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
char buf[20];
|
||||
memset(buf,'x',20);
|
||||
|
||||
con->async_read_indef(5,buf,5);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
|
||||
// here we expect to return early from read some because the outstanding
|
||||
// read was for 5 bytes and we were called with 10.
|
||||
char input[11] = "aaaaabbbbb";
|
||||
BOOST_CHECK_EQUAL(con->read_some(input,10), 5);
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "aaaaaxxxxx" );
|
||||
BOOST_CHECK_EQUAL( con->indef_read_total, 5 );
|
||||
|
||||
// A subsequent read should read 5 more because the indef read refreshes
|
||||
// itself. The new read will start again at the beginning of the buffer.
|
||||
BOOST_CHECK_EQUAL(con->read_some(input+5,5), 5);
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "bbbbbxxxxx" );
|
||||
BOOST_CHECK_EQUAL( con->indef_read_total, 10 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( async_read_at_least_read_all ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
char buf[20];
|
||||
memset(buf,'x',20);
|
||||
|
||||
con->async_read_indef(5,buf,5);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
|
||||
char input[11] = "aaaaabbbbb";
|
||||
BOOST_CHECK_EQUAL(con->read_all(input,10), 10);
|
||||
BOOST_CHECK( !con->ec );
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "bbbbbxxxxx" );
|
||||
BOOST_CHECK_EQUAL( con->indef_read_total, 10 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( eof_flag ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
char buf[10];
|
||||
con->async_read_at_least(5,buf,5);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
con->eof();
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::eof) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( fatal_error_flag ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
char buf[10];
|
||||
con->async_read_at_least(5,buf,5);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
con->fatal_error();
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::pass_through) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( shutdown ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
con->shutdown();
|
||||
BOOST_CHECK_EQUAL( con->ec, websocketpp::lib::error_code() );
|
||||
}
|
||||
|
||||
websocketpp::lib::error_code sd_handler(websocketpp::connection_hdl) {
|
||||
return make_error_code(websocketpp::transport::error::general);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( shutdown_handler ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
con->set_shutdown_handler(&sd_handler);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
con->shutdown();
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::general) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( shared_pointer_memory_cleanup ) {
|
||||
stub_con::ptr con(new stub_con(true,alogger,elogger));
|
||||
|
||||
BOOST_CHECK_EQUAL(con.use_count(), 1);
|
||||
|
||||
char buf[10];
|
||||
memset(buf,'x',10);
|
||||
con->async_read_at_least(5,buf,5);
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
|
||||
BOOST_CHECK_EQUAL(con.use_count(), 2);
|
||||
|
||||
char input[10] = "foo";
|
||||
con->read_some(input,3);
|
||||
BOOST_CHECK_EQUAL(con.use_count(), 2);
|
||||
|
||||
con->read_some(input,2);
|
||||
BOOST_CHECK_EQUAL( std::string(buf,10), "foofoxxxxx" );
|
||||
BOOST_CHECK_EQUAL(con.use_count(), 1);
|
||||
|
||||
con->async_read_at_least(5,buf,5);
|
||||
BOOST_CHECK_EQUAL(con.use_count(), 2);
|
||||
|
||||
con->eof();
|
||||
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::eof) );
|
||||
BOOST_CHECK_EQUAL(con.use_count(), 1);
|
||||
}
|
||||
|
||||
Loaded 100 of 221 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user