commit
0b4d0e334c
133 files changed
+6832
-2225
No files matched your search
@@ -11,7 +11,7 @@ Linux:
|
||||
- libgsasl version >= 1.4 --> http://www.gnu.org/software/gsasl/
|
||||
- libboost_thread, libboost_filesystem, libboost_datetime, libboost_program_options,
|
||||
libboost_iostreams, libboost_asio, libboost_regex, libboost_random, libboost_uuid
|
||||
(version >= 1.44, latest always recommended) --> http://www.boost.org/
|
||||
(version >= 1.49, latest always recommended) --> http://www.boost.org/
|
||||
- libSDL_mixer, libSDL --> http://www.libsdl.org/
|
||||
- libSQLite3 --> http://sqlite.org/
|
||||
- libtinyxml > 2.0 --> http://www.sourceforge.net/projects/tinyxml
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@
|
||||
# of binary-size if you leave Qt out.
|
||||
# (see http://trolltech.com/developer/downloads/qt/mac)
|
||||
|
||||
QT_FW_PATH="/Developer/Qt5/5/clang_64/lib"
|
||||
QT_PLUGIN_PATH="/Developer/Qt5/5/clang_64/plugins"
|
||||
QT_FW_PATH="/Users/$USER/Qt/5.9/clang_64/lib"
|
||||
QT_PLUGIN_PATH="/Users/$USER/Qt/5.9/clang_64/plugins"
|
||||
SDL_FW_PATH="/Library/Frameworks"
|
||||
APPLICATION="./pokerth.app"
|
||||
BINARY="$APPLICATION/Contents/MacOs/pokerth"
|
||||
|
||||
Executable → Regular
File mode changed.
@@ -0,0 +1,26 @@
|
||||
# QMake pro-file for PokerTH
|
||||
|
||||
!c++11 {
|
||||
system( $$QMAKE_CXX -dumpversion | grep -e "^6.[0-9]" > /dev/null ) {
|
||||
greaterThan(QT_MAJOR_VERSION, 5) | equals(QT_MAJOR_VERSION, 5) {
|
||||
CONFIG += c++11
|
||||
}
|
||||
else {
|
||||
equals(QT_MAJOR_VERSION, 4) : greaterThan(QT_MINOR_VERSION, 7) {
|
||||
CONFIG += "c++11"
|
||||
QMAKE_CXXFLAGS += "-std=gnu++11"
|
||||
}
|
||||
else {
|
||||
error (QT must be greater and 4.8+)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c++11 {
|
||||
!system( $$QMAKE_CXX -dumpversion | grep -e "^6.[0-9]" > /dev/null ) {
|
||||
equals(QT_MAJOR_VERSION, 4) : greaterThan(QT_MINOR_VERSION, 7) {
|
||||
QMAKE_CXXFLAGS += "-std=gnu++11"
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -17,6 +17,9 @@ DEFINES += ENABLE_IPV6 TIXML_USE_STL
|
||||
QT -= core gui
|
||||
#PRECOMPILED_HEADER = src/pch_lib.h
|
||||
|
||||
# Check for c++11
|
||||
include(pokerth_common.pro)
|
||||
|
||||
INCLUDEPATH += . \
|
||||
src
|
||||
|
||||
@@ -57,7 +60,7 @@ mac{
|
||||
CONFIG += x86_64
|
||||
CONFIG -= x86
|
||||
CONFIG -= ppc
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
|
||||
QMAKE_CXXFLAGS -= -std=gnu++0x
|
||||
|
||||
# for universal-compilation on PPC-Mac uncomment the following line
|
||||
|
||||
@@ -14,6 +14,9 @@ OBJECTS_DIR = obj
|
||||
QT -= core \
|
||||
gui
|
||||
|
||||
# Check for c++11
|
||||
include(pokerth_common.pro)
|
||||
|
||||
# PRECOMPILED_HEADER = dbofficial/pch_lib.h
|
||||
INCLUDEPATH += . \
|
||||
./src
|
||||
|
||||
+46
-14
@@ -26,6 +26,9 @@ DEFINES += ENABLE_IPV6 TIXML_USE_STL BOOST_FILESYSTEM_DEPRECATED
|
||||
DEFINES += PREFIX=\"$${PREFIX}\"
|
||||
TARGET = pokerth
|
||||
|
||||
# Check for c++11
|
||||
include(pokerth_common.pro)
|
||||
|
||||
# PRECOMPILED_HEADER = src/pch_game.h
|
||||
|
||||
android{
|
||||
@@ -427,6 +430,8 @@ unix:!mac {
|
||||
boost_system-mt
|
||||
BOOST_RANDOM = boost_random \
|
||||
boost_random-mt
|
||||
BOOST_CHRONO = boost_chrono \
|
||||
boost_chrono-mt
|
||||
|
||||
# searching in $PREFIX/lib, $PREFIX/lib64 and $$system(qmake -query QT_INSTALL_LIBS)
|
||||
# to override the default '/usr' pass PREFIX
|
||||
@@ -482,15 +487,37 @@ unix:!mac {
|
||||
message("Found $$lib")
|
||||
BOOST_SYS = -l$$lib
|
||||
}
|
||||
!c++11 {
|
||||
for(lib, BOOST_CHRONO):exists($${dir}/lib$${lib}.so*) {
|
||||
message("Found $$lib")
|
||||
BOOST_CHRONO = -l$$lib
|
||||
}
|
||||
for(lib, BOOST_CHRONO):exists($${dir}/lib$${lib}.a) {
|
||||
message("Found $$lib")
|
||||
BOOST_CHRONO = -l$$lib
|
||||
}
|
||||
}
|
||||
}
|
||||
!android{
|
||||
BOOST_LIBS = $$BOOST_THREAD \
|
||||
c++11 {
|
||||
BOOST_LIBS = $$BOOST_THREAD \
|
||||
$$BOOST_FS \
|
||||
$$BOOST_IOSTREAMS \
|
||||
$$BOOST_REGEX \
|
||||
$$BOOST_RANDOM \
|
||||
$$BOOST_SYS
|
||||
!count(BOOST_LIBS, 6):error("Unable to find boost libraries in PREFIX=$${PREFIX}")
|
||||
}
|
||||
!c++11 {
|
||||
BOOST_LIBS = $$BOOST_THREAD \
|
||||
$$BOOST_FS \
|
||||
$$BOOST_IOSTREAMS \
|
||||
$$BOOST_REGEX \
|
||||
$$BOOST_RANDOM \
|
||||
$$$$BOOST_SYS \
|
||||
$$BOOST_CHRONO
|
||||
!count(BOOST_LIBS, 7):error("Unable to find boost libraries in PREFIX=$${PREFIX}")
|
||||
}
|
||||
if($$system(sdl-config --version)):error("sdl-config not found in PATH - libSDL_mixer, libSDL are required!")
|
||||
UNAME = $$system(uname -s)
|
||||
BSD = $$find(UNAME, "BSD")
|
||||
@@ -549,7 +576,7 @@ mac {
|
||||
CONFIG += x86_64
|
||||
CONFIG -= x86
|
||||
CONFIG -= ppc
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
|
||||
QMAKE_CXXFLAGS -= -std=gnu++0x
|
||||
|
||||
# workaround for problems with boost_filesystem exceptions
|
||||
@@ -561,19 +588,18 @@ mac {
|
||||
LIBPATH += lib
|
||||
|
||||
# QT dynamic linked framework (see also mac_post_make.sh)
|
||||
LIBS += -F /Library/Frameworks
|
||||
LIBS += -framework \
|
||||
QtCore
|
||||
LIBS += -framework \
|
||||
QtGui
|
||||
|
||||
# SDL and SDL_mixer come as frameworks
|
||||
LIBS += -framework \
|
||||
SDL
|
||||
LIBS += -framework \
|
||||
SDL_mixer
|
||||
LIBS += -framework \
|
||||
SDL
|
||||
LIBS += -framework \
|
||||
SDL_mixer
|
||||
|
||||
# make sure you have an x86_64 version of boost
|
||||
LIBS += /usr/local/lib/libboost_thread.a
|
||||
LIBS += /usr/local/lib/libboost_thread-mt.a
|
||||
LIBS += /usr/local/lib/libboost_filesystem.a
|
||||
LIBS += /usr/local/lib/libboost_regex.a
|
||||
LIBS += /usr/local/lib/libboost_random.a
|
||||
@@ -589,15 +615,21 @@ mac {
|
||||
-lprotobuf \
|
||||
-lz \
|
||||
-framework \
|
||||
Carbon
|
||||
Cocoa
|
||||
|
||||
# set the application icon
|
||||
RC_FILE = pokerth.icns
|
||||
LIBPATH += /Developer/SDKs/MacOSX10.6.sdk/usr/lib
|
||||
INCLUDEPATH += /Developer/SDKs/MacOSX10.6.sdk/usr/include/
|
||||
INCLUDEPATH += /Library/Frameworks/SDL.framework/Headers
|
||||
INCLUDEPATH += /Library/Frameworks/SDL_mixer.framework/Headers
|
||||
|
||||
LIBPATH += /usr/local/lib
|
||||
LIBPATH += /usr/local/opt/openssl/lib
|
||||
LIBPATH += /usr/local/opt/tinyxml/lib
|
||||
LIBPATH += /usr/local/opt/protobuf/lib
|
||||
INCLUDEPATH += /usr/local/include
|
||||
INCLUDEPATH += /usr/local/opt/openssl/include
|
||||
INCLUDEPATH += /usr/local/opt/tinyxml/include
|
||||
INCLUDEPATH += /usr/local/opt/protobuf/include
|
||||
INCLUDEPATH += /Library/Frameworks/SDL.framework/Headers
|
||||
INCLUDEPATH += /Library/Frameworks/SDL_mixer.framework/Headers
|
||||
}
|
||||
OTHER_FILES += docs/infomessage-id-desc.txt
|
||||
official_server {
|
||||
|
||||
+8
-5
@@ -17,6 +17,9 @@ DEFINES += ENABLE_IPV6 TIXML_USE_STL BOOST_FILESYSTEM_DEPRECATED
|
||||
QT -= core gui
|
||||
#PRECOMPILED_HEADER = src/pch_lib.h
|
||||
|
||||
# Check for c++11
|
||||
include(pokerth_common.pro)
|
||||
|
||||
INCLUDEPATH += . \
|
||||
src \
|
||||
src/engine \
|
||||
@@ -291,17 +294,17 @@ mac{
|
||||
CONFIG += x86_64
|
||||
CONFIG -= x86
|
||||
CONFIG -= ppc
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
|
||||
QMAKE_CXXFLAGS -= -std=gnu++0x
|
||||
|
||||
# for universal-compilation on PPC-Mac uncomment the following line
|
||||
# on Intel-Mac you have to comment this line out or build will fail.
|
||||
# QMAKE_MAC_SDK=/Developer/SDKs/MacOSX10.4u.sdk/
|
||||
|
||||
INCLUDEPATH += /Developer/SDKs/MacOSX10.6.sdk/usr/include/
|
||||
INCLUDEPATH += /Library/Frameworks/SDL.framework/Headers
|
||||
INCLUDEPATH += /Library/Frameworks/SDL_mixer.framework/Headers
|
||||
LIBPATH += /usr/local/opt/openssl/lib
|
||||
INCLUDEPATH += /usr/local/opt/openssl/include
|
||||
INCLUDEPATH += /usr/local/include
|
||||
INCLUDEPATH += /Library/Frameworks/SDL.framework/Headers
|
||||
INCLUDEPATH += /Library/Frameworks/SDL_mixer.framework/Headers
|
||||
}
|
||||
|
||||
android{
|
||||
|
||||
@@ -17,6 +17,9 @@ QT -= core \
|
||||
gui
|
||||
# PRECOMPILED_HEADER = src/pch_lib.h
|
||||
|
||||
# Check for c++11
|
||||
include(pokerth_common.pro)
|
||||
|
||||
INCLUDEPATH += . \
|
||||
src
|
||||
DEPENDPATH += . \
|
||||
@@ -49,7 +52,7 @@ mac {
|
||||
CONFIG += x86_64
|
||||
CONFIG -= x86
|
||||
CONFIG -= ppc
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
|
||||
|
||||
# for universal-compilation on PPC-Mac uncomment the following line
|
||||
# on Intel-Mac you have to comment this line out or build will fail.
|
||||
|
||||
+27
-5
@@ -19,6 +19,9 @@ DEFINES += PREFIX=\"$${PREFIX}\"
|
||||
QT -= core gui
|
||||
#PRECOMPILED_HEADER = src/pch_lib.h
|
||||
|
||||
# Check for c++11
|
||||
include(pokerth_common.pro)
|
||||
|
||||
INCLUDEPATH += . \
|
||||
src \
|
||||
src/engine \
|
||||
@@ -185,6 +188,7 @@ unix : !mac {
|
||||
BOOST_SYS = boost_system boost_system-mt
|
||||
BOOST_REGEX = boost_regex boost_regex-mt
|
||||
BOOST_RANDOM = boost_random boost_random-mt
|
||||
BOOST_CHRONO = boost_chrono boost_chrono-mt
|
||||
|
||||
#
|
||||
# searching in $PREFIX/lib, $PREFIX/lib64 and $$system(qmake -query QT_INSTALL_LIBS)
|
||||
@@ -249,11 +253,29 @@ unix : !mac {
|
||||
message("Found $$lib")
|
||||
BOOST_SYS = -l$$lib
|
||||
}
|
||||
!c++11 {
|
||||
for(lib, BOOST_CHRONO):exists($${dir}/lib$${lib}.so*) {
|
||||
message("Found $$lib")
|
||||
BOOST_CHRONO = -l$$lib
|
||||
}
|
||||
for(lib, BOOST_CHRONO):exists($${dir}/lib$${lib}.a) {
|
||||
message("Found $$lib")
|
||||
BOOST_CHRONO = -l$$lib
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_LIBS = $$BOOST_THREAD $$BOOST_FS $$BOOST_PROGRAM_OPTIONS $$BOOST_IOSTREAMS $$BOOST_REGEX $$BOOST_RANDOM $$BOOST_SYS
|
||||
!count(BOOST_LIBS, 7){
|
||||
error("Unable to find boost libraries in PREFIX=$${PREFIX}")
|
||||
c++11 {
|
||||
BOOST_LIBS = $$BOOST_THREAD $$BOOST_FS $$BOOST_PROGRAM_OPTIONS $$BOOST_IOSTREAMS $$BOOST_REGEX $$BOOST_RANDOM $$BOOST_SYS
|
||||
!count(BOOST_LIBS, 7){
|
||||
error("Unable to find boost libraries in PREFIX=$${PREFIX}")
|
||||
}
|
||||
}
|
||||
!c++11 {
|
||||
BOOST_LIBS = $$BOOST_THREAD $$BOOST_FS $$BOOST_PROGRAM_OPTIONS $$BOOST_IOSTREAMS $$BOOST_REGEX $$BOOST_RANDOM $$BOOST_SYS $$BOOST_CHRONO
|
||||
!count(BOOST_LIBS, 8){
|
||||
error("Unable to find boost libraries in PREFIX=$${PREFIX}")
|
||||
}
|
||||
}
|
||||
|
||||
UNAME = $$system(uname -s)
|
||||
@@ -288,7 +310,7 @@ mac {
|
||||
CONFIG += x86_64
|
||||
CONFIG -= x86
|
||||
CONFIG -= ppc
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
|
||||
QMAKE_CXXFLAGS -= -std=gnu++0x
|
||||
|
||||
# workaround for problems with boost_filesystem exceptions
|
||||
@@ -300,7 +322,7 @@ mac {
|
||||
|
||||
LIBPATH += lib
|
||||
# make sure you have an x86_64 version of boost
|
||||
LIBS += /usr/local/lib/libboost_thread.a
|
||||
LIBS += /usr/local/lib/libboost_thread-mt.a
|
||||
LIBS += /usr/local/lib/libboost_filesystem.a
|
||||
LIBS += /usr/local/lib/libboost_regex.a
|
||||
LIBS += /usr/local/lib/libboost_random.a
|
||||
|
||||
@@ -482,11 +482,11 @@ ServerDBThread::EstablishDBConnection()
|
||||
if (!prepareNick.exec() || !prepareAvatarBlacklist.exec() || !prepareLogin.exec() || !prepareCreateGame.exec()
|
||||
|| !prepareEndGame.exec() || !prepareRelation.exec() || !prepareScore.exec() || !prepareReportAvatar.exec()
|
||||
|| !prepareReportGame.exec() || !prepareAdminPlayer.exec() || !prepareBlockPlayer.exec()) {
|
||||
string tmpError = string(prepareNick.error()) + prepareAvatarBlacklist.error() + prepareLogin.error() + prepareCreateGame.error() +
|
||||
prepareEndGame.error() + prepareRelation.error() + prepareScore.error() + prepareReportAvatar.error() +
|
||||
prepareReportGame.error() + prepareAdminPlayer.error() + prepareBlockPlayer.error();
|
||||
m_connData->conn.disconnect();
|
||||
m_ioService->post(boost::bind(&ServerDBCallback::ConnectFailed, &m_callback,
|
||||
string(prepareNick.error()) + prepareAvatarBlacklist.error() + prepareLogin.error() + prepareCreateGame.error()
|
||||
+ prepareEndGame.error() + prepareRelation.error() + prepareScore.error() + prepareReportAvatar.error()
|
||||
+ prepareReportGame.error() + prepareAdminPlayer.error() + prepareBlockPlayer.error()));
|
||||
m_ioService->post(boost::bind(&ServerDBCallback::ConnectFailed, &m_callback, tmpError));
|
||||
m_permanentError = true;
|
||||
} else {
|
||||
m_ioService->post(boost::bind(&ServerDBCallback::ConnectSuccess, &m_callback));
|
||||
@@ -537,8 +537,9 @@ ServerDBThread::HandleNextQuery()
|
||||
++i;
|
||||
}
|
||||
if (!paramQuery.exec()) {
|
||||
string tmpError = paramQuery.error();
|
||||
m_connData->conn.disconnect();
|
||||
m_ioService->post(boost::bind(&ServerDBCallback::QueryError, &m_callback, paramQuery.error()));
|
||||
m_ioService->post(boost::bind(&ServerDBCallback::QueryError, &m_callback, tmpError));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@
|
||||
#define POKERTH_VERSION ((POKERTH_VERSION_MAJOR << 8) | POKERTH_VERSION_MINOR)
|
||||
|
||||
#define POKERTH_BETA_REVISION 0
|
||||
#define POKERTH_BETA_RELEASE_STRING "1.1.1"
|
||||
#define POKERTH_BETA_RELEASE_STRING "1.1.2"
|
||||
|
||||
#define SQLITE_LOG_VERSION 1
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifndef ANDROID_TEST
|
||||
#include "QtGui/5.2.0/QtGui/qpa/qplatformnativeinterface.h"
|
||||
#include "QtGui/5.7.1/QtGui/qpa/qplatformnativeinterface.h"
|
||||
#include <jni.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -275,6 +275,9 @@ int gameLobbyDialogImpl::exec()
|
||||
registeredUserMode();
|
||||
}
|
||||
|
||||
// Bug #320: https://github.com/pokerth/pokerth/issues/320
|
||||
myChat->refreshIgnoreList();
|
||||
|
||||
#ifdef ANDROID
|
||||
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifndef ANDROID_TEST
|
||||
#include "QtGui/5.2.0/QtGui/qpa/qplatformnativeinterface.h"
|
||||
#include "QtGui/5.7.1/QtGui/qpa/qplatformnativeinterface.h"
|
||||
#include <jni.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -73,3 +73,10 @@ bool MyActionButton::event(QEvent *event)
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void MyActionButton::click()
|
||||
{
|
||||
if (!eatMyEvents) {
|
||||
QPushButton::click();
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,9 @@ public:
|
||||
}
|
||||
bool event(QEvent *e);
|
||||
|
||||
public slots:
|
||||
void click();
|
||||
|
||||
private:
|
||||
|
||||
QString fKeyText;
|
||||
|
||||
@@ -156,9 +156,14 @@ void MyAvatarLabel::setPlayerRating(QString playerInfo)
|
||||
std::list<std::string> result;
|
||||
std::string separator="(!#$%)";
|
||||
std::list<std::string>::iterator iterator;
|
||||
|
||||
// Bug #319: https://github.com/pokerth/pokerth/issues/319
|
||||
QString playerName = playerInfoList.at(0);
|
||||
playerName = QUrl::fromPercentEncoding(playerName.toUtf8());
|
||||
|
||||
for(iterator = tipsList.begin(); iterator != tipsList.end(); ++iterator) {
|
||||
tipInfo=QString::fromUtf8(iterator->c_str()).split("(!#$%)", QString::KeepEmptyParts, Qt::CaseSensitive);
|
||||
if(tipInfo.at(0)==playerInfoList.at(0)) {
|
||||
if(tipInfo.at(0)==playerName) {
|
||||
result.push_back(tipInfo.at(0).toUtf8().constData()+separator+tipInfo.at(1).toUtf8().constData()+separator+playerInfoList.at(1).toUtf8().constData()+separator);
|
||||
found=1;
|
||||
} else {
|
||||
@@ -166,7 +171,7 @@ void MyAvatarLabel::setPlayerRating(QString playerInfo)
|
||||
}
|
||||
}
|
||||
if(found==0) {
|
||||
result.push_back(playerInfoList.at(0).toUtf8().constData()+separator+separator+playerInfoList.at(1).toUtf8().constData()+separator);
|
||||
result.push_back(playerName.toUtf8().constData()+separator+separator+playerInfoList.at(1).toUtf8().constData()+separator);
|
||||
}
|
||||
myW->getMyConfig()->writeConfigStringList("PlayerTooltips", result);
|
||||
myW->getMyConfig()->writeBuffer();
|
||||
@@ -224,7 +229,12 @@ void MyAvatarLabel::refreshStars()
|
||||
for(int i=1; i<=5; i++)myW->playerStarsArray[i][seatPlace]->setText("");
|
||||
if(myW->myStartWindow->getSession()->getGameType() == Session::GAME_TYPE_INTERNET && !myW->getSession()->getClientPlayerInfo((*it_c)->getMyUniqueID()).isGuest && (*it_c)->getMyType() != PLAYER_TYPE_COMPUTER) {
|
||||
if((*it_c)->getMyStayOnTableStatus() == true && (*it_c)->getMyName()!="" && seatPlace!=0) {
|
||||
int playerStars=getPlayerRating(QString::fromUtf8((*it_c)->getMyName().c_str()));
|
||||
|
||||
// Bug #319: https://github.com/pokerth/pokerth/issues/319
|
||||
QString playerName = QString::fromUtf8((*it_c)->getMyName().c_str());
|
||||
int playerStars=getPlayerRating(playerName);
|
||||
playerName = QString(QUrl::toPercentEncoding(playerName));
|
||||
|
||||
for(int i=1; i<=5; i++) {
|
||||
myW->playerStarsArray[i][seatPlace]->setText("<a style='color: #"+myW->getMyGameTableStyle()->getRatingStarsColor()+"; "+fontFamily+" font-size: "+fontSize+"px; text-decoration: none;' href='"+QString::fromUtf8((*it_c)->getMyName().c_str())+"\""+QString::number(i)+"'>☆</a>");
|
||||
}
|
||||
|
||||
@@ -92,11 +92,21 @@ void MyNameLabel::setText ( const QString &t, bool trans, bool guest, bool compu
|
||||
} else {
|
||||
linkString = QString("http://pokerth.net/redirect_user_profile.php?nick="+QUrl::toPercentEncoding(t));
|
||||
}
|
||||
|
||||
// truncate nicknames longer than 10 characters
|
||||
QString t2 = t;
|
||||
if(t2.size() > 10){
|
||||
int chop = t.size() - 10 - 3;
|
||||
t2.chop(chop);
|
||||
t2.append("...");
|
||||
}
|
||||
|
||||
QString tTruncated;
|
||||
|
||||
if(trans) {
|
||||
text = "<a style='color: rgba("+red+", "+green+", "+blue+", 80);' href='"+linkString+"'>"+t+"</a>";
|
||||
text = "<a style='color: rgba("+red+", "+green+", "+blue+", 80);' href='"+linkString+"'>"+t2+"</a>";
|
||||
} else {
|
||||
text = "<a style='color: #"+myW->getMyGameTableStyle()->getPlayerNickTextColor()+";' href='"+linkString+"'>"+t+"</a>";
|
||||
text = "<a style='color: #"+myW->getMyGameTableStyle()->getPlayerNickTextColor()+";' href='"+linkString+"'>"+t2+"</a>";
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifndef ANDROID_TEST
|
||||
#include "QtGui/5.2.0/QtGui/qpa/qplatformnativeinterface.h"
|
||||
#include "QtGui/5.7.1/QtGui/qpa/qplatformnativeinterface.h"
|
||||
#include <jni.h>
|
||||
#endif
|
||||
#endif
|
||||
@@ -774,12 +774,24 @@ void startWindowImpl::networkError(int errorID, int /*osErrorID*/)
|
||||
QMessageBox::Close);
|
||||
}
|
||||
break;
|
||||
case ERR_SOCK_CONNECT_IPV6_FAILED: {
|
||||
MyMessageBox::warning(this, tr("Network Error"),
|
||||
tr("Could not connect to the server.\n\nPlease note: IPv6 is enabled in the settings. The connection fails if your provider does not support IPv6.\nThis may be fixed by unchecking the \"Use IPv6\" checkbox in the settings."),
|
||||
QMessageBox::Close);
|
||||
}
|
||||
break;
|
||||
case ERR_SOCK_CONNECT_TIMEOUT: {
|
||||
MyMessageBox::warning(this, tr("Network Error"),
|
||||
tr("Connection timed out.\nPlease check the server address.\n\nIf the server is behind a NAT-Router, make sure port forwarding has been set up on server side."),
|
||||
QMessageBox::Close);
|
||||
}
|
||||
break;
|
||||
case ERR_SOCK_CONNECT_IPV6_TIMEOUT: {
|
||||
MyMessageBox::warning(this, tr("Network Error"),
|
||||
tr("Connection timed out.\nPlease check the server address.\n\nPlease note: IPv6 is enabled in the settings. The connection fails if your provider does not support IPv6.\nThis may be fixed by unchecking the \"Use IPv6\" checkbox in the settings."),
|
||||
QMessageBox::Close);
|
||||
}
|
||||
break;
|
||||
case ERR_SOCK_SELECT_FAILED: {
|
||||
MyMessageBox::warning(this, tr("Network Error"),
|
||||
tr("Internal network error: \"select\" failed."),
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
@@ -218,7 +219,7 @@ protected:
|
||||
|
||||
ClientState &GetState();
|
||||
void SetState(ClientState &newState);
|
||||
boost::asio::deadline_timer &GetStateTimer();
|
||||
boost::asio::steady_timer &GetStateTimer();
|
||||
|
||||
SenderHelper &GetSender();
|
||||
|
||||
@@ -341,8 +342,8 @@ private:
|
||||
mutable boost::mutex m_pingDataMutex;
|
||||
PingData m_pingData;
|
||||
|
||||
boost::asio::deadline_timer m_stateTimer;
|
||||
boost::asio::deadline_timer m_avatarTimer;
|
||||
boost::asio::steady_timer m_stateTimer;
|
||||
boost::asio::steady_timer m_avatarTimer;
|
||||
|
||||
friend class AbstractClientStateReceiving;
|
||||
friend class ClientStateInit;
|
||||
|
||||
@@ -60,6 +60,12 @@
|
||||
using namespace std;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
#define CLIENT_WAIT_TIMEOUT_MSEC 50
|
||||
#define CLIENT_CONNECT_TIMEOUT_SEC 10
|
||||
|
||||
@@ -238,7 +244,7 @@ void
|
||||
ClientStateDownloadingServerList::Enter(boost::shared_ptr<ClientThread> client)
|
||||
{
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateDownloadingServerList::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
@@ -265,7 +271,7 @@ ClientStateDownloadingServerList::TimerLoop(const boost::system::error_code& ec,
|
||||
client->SetState(ClientStateReadingServerList::Instance());
|
||||
} else {
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateDownloadingServerList::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
@@ -409,7 +415,7 @@ void
|
||||
ClientStateWaitChooseServer::Enter(boost::shared_ptr<ClientThread> client)
|
||||
{
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateWaitChooseServer::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
@@ -432,7 +438,7 @@ ClientStateWaitChooseServer::TimerLoop(const boost::system::error_code& ec, boos
|
||||
client->SetState(ClientStateStartResolve::Instance());
|
||||
} else {
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateWaitChooseServer::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
@@ -461,7 +467,7 @@ void
|
||||
ClientStateStartConnect::Enter(boost::shared_ptr<ClientThread> client)
|
||||
{
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::seconds(CLIENT_CONNECT_TIMEOUT_SEC));
|
||||
seconds(CLIENT_CONNECT_TIMEOUT_SEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateStartConnect::TimerTimeout, this, boost::asio::placeholders::error, client));
|
||||
@@ -511,7 +517,11 @@ ClientStateStartConnect::HandleConnect(const boost::system::error_code& ec, boos
|
||||
client));
|
||||
} else {
|
||||
if (ec != boost::asio::error::operation_aborted) {
|
||||
throw ClientException(__FILE__, __LINE__, ERR_SOCK_CONNECT_FAILED, ec.value());
|
||||
if (client->GetContext().GetAddrFamily() == AF_INET6) {
|
||||
throw ClientException(__FILE__, __LINE__, ERR_SOCK_CONNECT_IPV6_FAILED, ec.value());
|
||||
} else {
|
||||
throw ClientException(__FILE__, __LINE__, ERR_SOCK_CONNECT_FAILED, ec.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,7 +533,12 @@ ClientStateStartConnect::TimerTimeout(const boost::system::error_code& ec, boost
|
||||
if (!ec && &client->GetState() == this) {
|
||||
boost::system::error_code ec;
|
||||
client->GetContext().GetSessionData()->GetAsioSocket()->close(ec);
|
||||
throw ClientException(__FILE__, __LINE__, ERR_SOCK_CONNECT_TIMEOUT, 0);
|
||||
if (client->GetContext().GetAddrFamily() == AF_INET6) {
|
||||
throw ClientException(__FILE__, __LINE__, ERR_SOCK_CONNECT_IPV6_TIMEOUT, 0);
|
||||
}
|
||||
else {
|
||||
throw ClientException(__FILE__, __LINE__, ERR_SOCK_CONNECT_TIMEOUT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -986,7 +1001,7 @@ void
|
||||
ClientStateWaitEnterLogin::Enter(boost::shared_ptr<ClientThread> client)
|
||||
{
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateWaitEnterLogin::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
@@ -1065,7 +1080,7 @@ ClientStateWaitEnterLogin::TimerLoop(const boost::system::error_code& ec, boost:
|
||||
}
|
||||
} else {
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateWaitEnterLogin::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
@@ -1399,7 +1414,7 @@ void
|
||||
ClientStateSynchronizeStart::Enter(boost::shared_ptr<ClientThread> client)
|
||||
{
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateSynchronizeStart::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
@@ -1429,7 +1444,7 @@ ClientStateSynchronizeStart::TimerLoop(const boost::system::error_code& ec, boos
|
||||
client->SetState(ClientStateWaitStart::Instance());
|
||||
} else {
|
||||
client->GetStateTimer().expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
milliseconds(CLIENT_WAIT_TIMEOUT_MSEC));
|
||||
client->GetStateTimer().async_wait(
|
||||
boost::bind(
|
||||
&ClientStateSynchronizeStart::TimerLoop, this, boost::asio::placeholders::error, client));
|
||||
|
||||
@@ -66,6 +66,12 @@ using namespace std;
|
||||
using namespace boost::filesystem;
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
ClientThread::ClientThread(GuiInterface &gui, AvatarManager &avatarManager, Log *myLog)
|
||||
: m_ioService(new boost::asio::io_service), m_clientLog(myLog), m_curState(NULL), m_gui(gui),
|
||||
m_avatarManager(avatarManager), m_isServerSelected(false),
|
||||
@@ -586,7 +592,7 @@ void
|
||||
ClientThread::RegisterTimers()
|
||||
{
|
||||
m_avatarTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_AVATAR_LOOP_MSEC));
|
||||
milliseconds(CLIENT_AVATAR_LOOP_MSEC));
|
||||
m_avatarTimer.async_wait(
|
||||
boost::bind(
|
||||
&ClientThread::TimerCheckAvatarDownloads, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -910,7 +916,7 @@ ClientThread::TimerCheckAvatarDownloads(const boost::system::error_code& ec)
|
||||
PassAvatarFileToManager(playerId, tmpAvatar);
|
||||
}
|
||||
m_avatarTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(CLIENT_AVATAR_LOOP_MSEC));
|
||||
milliseconds(CLIENT_AVATAR_LOOP_MSEC));
|
||||
m_avatarTimer.async_wait(
|
||||
boost::bind(
|
||||
&ClientThread::TimerCheckAvatarDownloads, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -1022,7 +1028,7 @@ ClientThread::SetState(ClientState &newState)
|
||||
m_curState->Enter(shared_from_this());
|
||||
}
|
||||
|
||||
boost::asio::deadline_timer &
|
||||
boost::asio::steady_timer &
|
||||
ClientThread::GetStateTimer()
|
||||
{
|
||||
return m_stateTimer;
|
||||
|
||||
@@ -49,6 +49,12 @@
|
||||
using namespace std;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
ServerAdminBot::ServerAdminBot(boost::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_notifyTimeoutMinutes(0), m_notifyIntervalMinutes(0), m_notifyCounter(0),
|
||||
m_notifyTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::second_timer::manual_start),
|
||||
@@ -272,17 +278,17 @@ ServerAdminBot::Run()
|
||||
if (m_ircAdminThread) {
|
||||
// Initialise the timers.
|
||||
m_reconnectTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
m_reconnectTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerAdminBot::ReconnectHandler, shared_from_this(), boost::asio::placeholders::error));
|
||||
m_notifyLoopTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_NOTIFY_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_NOTIFY_IRC_BOT_INTERVAL_SEC));
|
||||
m_notifyLoopTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerAdminBot::NotifyLoop, shared_from_this(), boost::asio::placeholders::error));
|
||||
m_checkFileTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_CHECK_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_CHECK_IRC_BOT_INTERVAL_SEC));
|
||||
m_checkFileTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerAdminBot::CheckFileHandler, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -298,7 +304,7 @@ ServerAdminBot::ReconnectHandler(const boost::system::error_code& ec)
|
||||
Reconnect();
|
||||
|
||||
m_reconnectTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
m_reconnectTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerAdminBot::ReconnectHandler, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -330,7 +336,7 @@ ServerAdminBot::CheckFileHandler(const boost::system::error_code& ec)
|
||||
Reconnect();
|
||||
}
|
||||
m_checkFileTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_CHECK_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_CHECK_IRC_BOT_INTERVAL_SEC));
|
||||
m_checkFileTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerAdminBot::CheckFileHandler, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -386,7 +392,7 @@ ServerAdminBot::NotifyLoop(const boost::system::error_code& ec)
|
||||
}
|
||||
}
|
||||
m_notifyLoopTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_NOTIFY_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_NOTIFY_IRC_BOT_INTERVAL_SEC));
|
||||
m_notifyLoopTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerAdminBot::NotifyLoop, shared_from_this(), boost::asio::placeholders::error));
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
ServerBanManager::ServerBanManager(boost::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_ioService(ioService), m_curBanId(0)
|
||||
@@ -126,7 +131,7 @@ ServerBanManager::GetBanList(list<string> &list) const
|
||||
banText << (*i_nick).first << ": (nickStr) - " << (*i_nick).second.nameStr;
|
||||
|
||||
if ((*i_nick).second.timer)
|
||||
banText << " duration: " << (*i_nick).second.timer->expires_from_now().hours() << "h";
|
||||
banText << " duration: " << duration_cast<hours>((*i_nick).second.timer->expires_from_now()).count() << "h";
|
||||
list.push_back(banText.str());
|
||||
++i_nick;
|
||||
}
|
||||
@@ -136,7 +141,7 @@ ServerBanManager::GetBanList(list<string> &list) const
|
||||
ostringstream banText;
|
||||
banText << (*i_ip).first << ": (IP) - " << (*i_ip).second.ipAddress;
|
||||
if ((*i_ip).second.timer)
|
||||
banText << " duration: " << (*i_ip).second.timer->expires_from_now().hours() << "h";
|
||||
banText << " duration: " << duration_cast<hours>((*i_ip).second.timer->expires_from_now()).count() << "h";
|
||||
list.push_back(banText.str());
|
||||
++i_ip;
|
||||
}
|
||||
@@ -235,14 +240,14 @@ ServerBanManager::IsBadGameName(const std::string &name) const
|
||||
return retVal;
|
||||
}
|
||||
|
||||
boost::shared_ptr<boost::asio::deadline_timer>
|
||||
boost::shared_ptr<boost::asio::steady_timer>
|
||||
ServerBanManager::InternalRegisterTimedBan(unsigned timerId, unsigned durationHours)
|
||||
{
|
||||
boost::shared_ptr<boost::asio::deadline_timer> tmpTimer;
|
||||
boost::shared_ptr<boost::asio::steady_timer> tmpTimer;
|
||||
if (durationHours) {
|
||||
tmpTimer.reset(new boost::asio::deadline_timer(*m_ioService));
|
||||
tmpTimer.reset(new boost::asio::steady_timer(*m_ioService));
|
||||
tmpTimer->expires_from_now(
|
||||
boost::posix_time::hours(durationHours));
|
||||
hours(durationHours));
|
||||
tmpTimer->async_wait(
|
||||
boost::bind(
|
||||
&ServerBanManager::TimerRemoveBan, shared_from_this(), boost::asio::placeholders::error, timerId, tmpTimer));
|
||||
@@ -251,7 +256,7 @@ ServerBanManager::InternalRegisterTimedBan(unsigned timerId, unsigned durationHo
|
||||
}
|
||||
|
||||
void
|
||||
ServerBanManager::TimerRemoveBan(const boost::system::error_code &ec, unsigned banId, boost::shared_ptr<boost::asio::deadline_timer> timer)
|
||||
ServerBanManager::TimerRemoveBan(const boost::system::error_code &ec, unsigned banId, boost::shared_ptr<boost::asio::steady_timer> timer)
|
||||
{
|
||||
if (!ec && timer)
|
||||
UnBan(banId);
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
static bool LessThanPlayerHandStartMoney(const boost::shared_ptr<PlayerInterface> p1, const boost::shared_ptr<PlayerInterface> p2)
|
||||
{
|
||||
return p1->getMyRoundStartCash() < p2->getMyRoundStartCash();
|
||||
@@ -276,7 +282,7 @@ ServerGame::TimerVoteKick(const boost::system::error_code &ec)
|
||||
m_voteKickData.reset();
|
||||
}
|
||||
m_voteKickTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC));
|
||||
milliseconds(SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC));
|
||||
m_voteKickTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerGame::TimerVoteKick, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -515,7 +521,7 @@ ServerGame::InternalAskVoteKick(boost::shared_ptr<SessionData> byWhom, unsigned
|
||||
SendToAllPlayers(packet, SessionData::Game);
|
||||
|
||||
m_voteKickTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC));
|
||||
milliseconds(SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC));
|
||||
m_voteKickTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerGame::TimerVoteKick, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -1073,13 +1079,13 @@ ServerGame::SetState(ServerGameState &newState)
|
||||
m_curState->Enter(shared_from_this());
|
||||
}
|
||||
|
||||
boost::asio::deadline_timer &
|
||||
boost::asio::steady_timer &
|
||||
ServerGame::GetStateTimer1()
|
||||
{
|
||||
return m_stateTimer1;
|
||||
}
|
||||
|
||||
boost::asio::deadline_timer &
|
||||
boost::asio::steady_timer &
|
||||
ServerGame::GetStateTimer2()
|
||||
{
|
||||
return m_stateTimer2;
|
||||
|
||||
@@ -52,6 +52,12 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
//#define POKERTH_SERVER_TEST
|
||||
|
||||
#ifdef POKERTH_SERVER_TEST
|
||||
@@ -575,7 +581,7 @@ ServerGameStateInit::RegisterAdminTimer(boost::shared_ptr<ServerGame> server)
|
||||
// No admin timeout in LAN or ranking games.
|
||||
if (server->GetLobbyThread().GetServerMode() != SERVER_MODE_LAN && server->GetGameData().gameType != GAME_TYPE_RANKING) {
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_GAME_ADMIN_TIMEOUT_SEC - SERVER_GAME_ADMIN_WARNING_REMAINING_SEC));
|
||||
seconds(SERVER_GAME_ADMIN_TIMEOUT_SEC - SERVER_GAME_ADMIN_WARNING_REMAINING_SEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateInit::TimerAdminWarning, this, boost::asio::placeholders::error, server));
|
||||
@@ -594,7 +600,7 @@ ServerGameStateInit::RegisterAutoStartTimer(boost::shared_ptr<ServerGame> server
|
||||
// No autostart in LAN games.
|
||||
if (server->GetLobbyThread().GetServerMode() != SERVER_MODE_LAN) {
|
||||
server->GetStateTimer2().expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_AUTOSTART_GAME_DELAY_SEC));
|
||||
seconds(SERVER_AUTOSTART_GAME_DELAY_SEC));
|
||||
server->GetStateTimer2().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateInit::TimerAutoStart, this, boost::asio::placeholders::error, server));
|
||||
@@ -632,7 +638,7 @@ ServerGameStateInit::TimerAdminWarning(const boost::system::error_code &ec, boos
|
||||
}
|
||||
// Start timeout timer.
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_GAME_ADMIN_WARNING_REMAINING_SEC));
|
||||
seconds(SERVER_GAME_ADMIN_WARNING_REMAINING_SEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateInit::TimerAdminTimeout, this, boost::asio::placeholders::error, server));
|
||||
@@ -767,7 +773,7 @@ void
|
||||
ServerGameStateStartGame::Enter(boost::shared_ptr<ServerGame> server)
|
||||
{
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_START_GAME_TIMEOUT_SEC));
|
||||
seconds(SERVER_START_GAME_TIMEOUT_SEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateStartGame::TimerTimeout, this, boost::asio::placeholders::error, server));
|
||||
@@ -930,7 +936,7 @@ void
|
||||
ServerGameStateHand::Enter(boost::shared_ptr<ServerGame> server)
|
||||
{
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_LOOP_DELAY_MSEC));
|
||||
milliseconds(SERVER_LOOP_DELAY_MSEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
||||
@@ -1007,7 +1013,7 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr<ServerGame> server)
|
||||
curGame.getCurrentHand()->setCardsShown(true);
|
||||
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_SHOW_CARDS_DELAY_SEC));
|
||||
seconds(SERVER_SHOW_CARDS_DELAY_SEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateHand::TimerShowCards, this, boost::asio::placeholders::error, server));
|
||||
@@ -1015,7 +1021,7 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr<ServerGame> server)
|
||||
SendNewRoundCards(*server, curGame, newRound);
|
||||
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(GetDealCardsDelaySec(*server)));
|
||||
seconds(GetDealCardsDelaySec(*server)));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
||||
@@ -1043,7 +1049,7 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr<ServerGame> server)
|
||||
// If the player is computer controlled, let the engine act.
|
||||
if (curPlayer->getMyType() == PLAYER_TYPE_COMPUTER) {
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_COMPUTER_ACTION_DELAY_SEC));
|
||||
seconds(SERVER_COMPUTER_ACTION_DELAY_SEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateHand::TimerComputerAction, this, boost::asio::placeholders::error, server));
|
||||
@@ -1054,7 +1060,7 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr<ServerGame> server)
|
||||
PerformPlayerAction(*server, curPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_LOOP_DELAY_MSEC));
|
||||
milliseconds(SERVER_LOOP_DELAY_MSEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
||||
@@ -1122,7 +1128,7 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr<ServerGame> server)
|
||||
|
||||
// View a dialog for a new game - delayed.
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_DELAY_NEXT_GAME_SEC));
|
||||
seconds(SERVER_DELAY_NEXT_GAME_SEC));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateHand::TimerNextGame, this, boost::asio::placeholders::error, server, winnerPlayer->getMyUniqueID()));
|
||||
@@ -1141,7 +1147,7 @@ ServerGameStateHand::TimerShowCards(const boost::system::error_code &ec, boost::
|
||||
SendNewRoundCards(*server, curGame, curGame.getCurrentHand()->getCurrentRound());
|
||||
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(GetDealCardsDelaySec(*server)));
|
||||
seconds(GetDealCardsDelaySec(*server)));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
||||
@@ -1512,7 +1518,7 @@ ServerGameStateWaitPlayerAction::Enter(boost::shared_ptr<ServerGame> server)
|
||||
int timeoutSec = server->GetGameData().playerActionTimeoutSec + SERVER_PLAYER_TIMEOUT_ADD_DELAY_SEC;
|
||||
#endif
|
||||
|
||||
server->GetStateTimer1().expires_from_now(boost::posix_time::seconds(timeoutSec));
|
||||
server->GetStateTimer1().expires_from_now(seconds(timeoutSec));
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
&ServerGameStateWaitPlayerAction::TimerTimeout, this, boost::asio::placeholders::error, server));
|
||||
@@ -1646,7 +1652,7 @@ ServerGameStateWaitNextHand::Enter(boost::shared_ptr<ServerGame> server)
|
||||
#endif
|
||||
|
||||
server->GetStateTimer1().expires_from_now(
|
||||
boost::posix_time::seconds(timeoutSec));
|
||||
seconds(timeoutSec));
|
||||
|
||||
server->GetStateTimer1().async_wait(
|
||||
boost::bind(
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
ServerLobbyBot::ServerLobbyBot(boost::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_reconnectTimer(*ioService)
|
||||
{
|
||||
@@ -110,7 +116,7 @@ ServerLobbyBot::Run()
|
||||
if (m_ircLobbyThread) {
|
||||
// Initialise the reconnect timer.
|
||||
m_reconnectTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
m_reconnectTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyBot::Reconnect, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -132,7 +138,7 @@ ServerLobbyBot::Reconnect(const boost::system::error_code& ec)
|
||||
}
|
||||
}
|
||||
m_reconnectTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
seconds(SERVER_RESTART_IRC_BOT_INTERVAL_SEC));
|
||||
m_reconnectTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyBot::Reconnect, shared_from_this(), boost::asio::placeholders::error));
|
||||
|
||||
@@ -95,6 +95,11 @@
|
||||
using namespace std;
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
class InternalServerCallback : public SessionDataCallback, public ChatCleanerCallback, public ServerDBCallback
|
||||
{
|
||||
@@ -860,19 +865,19 @@ ServerLobbyThread::RegisterTimers()
|
||||
{
|
||||
// Remove closed games.
|
||||
m_removeGameTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_REMOVE_GAME_INTERVAL_MSEC));
|
||||
milliseconds(SERVER_REMOVE_GAME_INTERVAL_MSEC));
|
||||
m_removeGameTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyThread::TimerRemoveGame, shared_from_this(), boost::asio::placeholders::error));
|
||||
// Update the statistics file.
|
||||
m_saveStatisticsTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_SAVE_STATISTICS_INTERVAL_SEC));
|
||||
seconds(SERVER_SAVE_STATISTICS_INTERVAL_SEC));
|
||||
m_saveStatisticsTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyThread::TimerSaveStatisticsFile, shared_from_this(), boost::asio::placeholders::error));
|
||||
// Update the avatar upload locks.
|
||||
m_loginLockTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_UPDATE_LOGIN_LOCK_INTERVAL_MSEC));
|
||||
milliseconds(SERVER_UPDATE_LOGIN_LOCK_INTERVAL_MSEC));
|
||||
m_loginLockTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyThread::TimerUpdateClientLoginLock, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -1872,7 +1877,7 @@ ServerLobbyThread::TimerRemoveGame(const boost::system::error_code &ec)
|
||||
}
|
||||
// Restart timer
|
||||
m_removeGameTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_REMOVE_GAME_INTERVAL_MSEC));
|
||||
milliseconds(SERVER_REMOVE_GAME_INTERVAL_MSEC));
|
||||
m_removeGameTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyThread::TimerRemoveGame, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -1897,7 +1902,7 @@ ServerLobbyThread::TimerUpdateClientLoginLock(const boost::system::error_code &e
|
||||
}
|
||||
// Restart timer
|
||||
m_loginLockTimer.expires_from_now(
|
||||
boost::posix_time::milliseconds(SERVER_UPDATE_LOGIN_LOCK_INTERVAL_MSEC));
|
||||
milliseconds(SERVER_UPDATE_LOGIN_LOCK_INTERVAL_MSEC));
|
||||
m_loginLockTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyThread::TimerUpdateClientLoginLock, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -2244,7 +2249,7 @@ ServerLobbyThread::TimerSaveStatisticsFile(const boost::system::error_code &ec)
|
||||
}
|
||||
// Restart timer
|
||||
m_saveStatisticsTimer.expires_from_now(
|
||||
boost::posix_time::seconds(SERVER_SAVE_STATISTICS_INTERVAL_SEC));
|
||||
seconds(SERVER_SAVE_STATISTICS_INTERVAL_SEC));
|
||||
m_saveStatisticsTimer.async_wait(
|
||||
boost::bind(
|
||||
&ServerLobbyThread::TimerSaveStatisticsFile, shared_from_this(), boost::asio::placeholders::error));
|
||||
|
||||
@@ -41,6 +41,12 @@
|
||||
using namespace std;
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace boost::chrono;
|
||||
#endif
|
||||
|
||||
SessionData::SessionData(boost::shared_ptr<boost::asio::ip::tcp::socket> sock, SessionId id, SessionDataCallback &cb, boost::asio::io_service &ioService)
|
||||
: m_socket(sock), m_id(id), m_state(SessionData::Init), m_readyFlag(false), m_wantsLobbyMsg(true),
|
||||
m_activityTimeoutSec(0), m_activityWarningRemainingSec(0), m_initTimeoutTimer(ioService), m_globalTimeoutTimer(ioService),
|
||||
@@ -236,7 +242,7 @@ SessionData::TimerActivityWarning(const boost::system::error_code &ec)
|
||||
m_callback.SessionTimeoutWarning(shared_from_this(), m_activityWarningRemainingSec);
|
||||
|
||||
m_activityTimeoutTimer.expires_from_now(
|
||||
boost::posix_time::seconds(m_activityWarningRemainingSec));
|
||||
seconds(m_activityWarningRemainingSec));
|
||||
m_activityTimeoutTimer.async_wait(
|
||||
boost::bind(
|
||||
&SessionData::TimerSessionTimeout, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -312,8 +318,13 @@ void
|
||||
SessionData::CloseWebSocketHandle()
|
||||
{
|
||||
if (m_webData) {
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) // c++11
|
||||
std::error_code std_ec;
|
||||
m_webData->webSocketServer->close(m_webData->webHandle, websocketpp::close::status::normal, "PokerTH server closed the connection.", std_ec);
|
||||
#else
|
||||
boost::system::error_code ec;
|
||||
m_webData->webSocketServer->close(m_webData->webHandle, websocketpp::close::status::normal, "PokerTH server closed the connection.", ec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +333,7 @@ SessionData::ResetActivityTimer()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_activityTimeoutTimer.expires_from_now(
|
||||
boost::posix_time::seconds(m_activityTimeoutSec - m_activityWarningRemainingSec));
|
||||
seconds(m_activityTimeoutSec - m_activityWarningRemainingSec));
|
||||
m_activityTimeoutTimer.async_wait(
|
||||
boost::bind(
|
||||
&SessionData::TimerActivityWarning, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -333,7 +344,7 @@ SessionData::StartTimerInitTimeout(unsigned timeoutSec)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_initTimeoutTimer.expires_from_now(
|
||||
boost::posix_time::seconds(timeoutSec));
|
||||
seconds(timeoutSec));
|
||||
m_initTimeoutTimer.async_wait(
|
||||
boost::bind(
|
||||
&SessionData::TimerInitTimeout, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -344,7 +355,7 @@ SessionData::StartTimerGlobalTimeout(unsigned timeoutSec)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_globalTimeoutTimer.expires_from_now(
|
||||
boost::posix_time::seconds(timeoutSec));
|
||||
seconds(timeoutSec));
|
||||
m_globalTimeoutTimer.async_wait(
|
||||
boost::bind(
|
||||
&SessionData::TimerSessionTimeout, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -358,7 +369,7 @@ SessionData::StartTimerActivityTimeout(unsigned timeoutSec, unsigned warningRema
|
||||
m_activityWarningRemainingSec = warningRemainingSec;
|
||||
|
||||
m_activityTimeoutTimer.expires_from_now(
|
||||
boost::posix_time::seconds(timeoutSec - warningRemainingSec));
|
||||
seconds(timeoutSec - warningRemainingSec));
|
||||
m_activityTimeoutTimer.async_wait(
|
||||
boost::bind(
|
||||
&SessionData::TimerActivityWarning, shared_from_this(), boost::asio::placeholders::error));
|
||||
|
||||
@@ -57,9 +57,14 @@ void
|
||||
WebSendBuffer::AsyncSendNextPacket(boost::shared_ptr<SessionData> session)
|
||||
{
|
||||
if (closeAfterSend) {
|
||||
boost::system::error_code ec;
|
||||
boost::shared_ptr<WebSocketData> webData = session->GetWebData();
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
|
||||
std::error_code std_ec;
|
||||
webData->webSocketServer->close(webData->webHandle, websocketpp::close::status::normal, "PokerTH server closed the connection.", std_ec);
|
||||
#else
|
||||
boost::system::error_code ec;
|
||||
webData->webSocketServer->close(webData->webHandle, websocketpp::close::status::normal, "PokerTH server closed the connection.", ec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,10 +75,16 @@ WebSendBuffer::InternalStorePacket(boost::shared_ptr<SessionData> session, boost
|
||||
google::protobuf::uint8 *buf = new google::protobuf::uint8[packetSize];
|
||||
packet->GetMsg()->SerializeWithCachedSizesToArray(buf);
|
||||
|
||||
boost::system::error_code ec;
|
||||
boost::shared_ptr<WebSocketData> webData = session->GetWebData();
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
|
||||
std::error_code std_ec;
|
||||
webData->webSocketServer->send(webData->webHandle, string((const char *)buf, packetSize), websocketpp::frame::opcode::BINARY, std_ec);
|
||||
if (std_ec) {
|
||||
#else
|
||||
boost::system::error_code ec;
|
||||
webData->webSocketServer->send(webData->webHandle, string((const char *)buf, packetSize), websocketpp::frame::opcode::BINARY, ec);
|
||||
if (ec) {
|
||||
#endif
|
||||
SetCloseAfterSend();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,9 +49,11 @@ public:
|
||||
virtual void Close();
|
||||
|
||||
protected:
|
||||
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) // c++11
|
||||
typedef std::map<websocketpp::connection_hdl, boost::weak_ptr<SessionData>, std::owner_less<websocketpp::connection_hdl> > SessionMap;
|
||||
#else
|
||||
typedef std::map<websocketpp::connection_hdl, boost::weak_ptr<SessionData> > SessionMap;
|
||||
|
||||
#endif
|
||||
bool validate(websocketpp::connection_hdl hdl);
|
||||
void on_open(websocketpp::connection_hdl hdl);
|
||||
void on_close(websocketpp::connection_hdl hdl);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define _SERVERADMINBOT_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <third_party/boost/timers.hpp>
|
||||
@@ -96,9 +97,9 @@ private:
|
||||
boost::shared_ptr<IrcThread> m_ircAdminThread;
|
||||
boost::timers::portable::second_timer m_notifyTimer;
|
||||
|
||||
boost::asio::deadline_timer m_reconnectTimer;
|
||||
boost::asio::deadline_timer m_notifyLoopTimer;
|
||||
boost::asio::deadline_timer m_checkFileTimer;
|
||||
boost::asio::steady_timer m_reconnectTimer;
|
||||
boost::asio::steady_timer m_notifyLoopTimer;
|
||||
boost::asio::steady_timer m_checkFileTimer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include <db/dbdefs.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
@@ -67,12 +68,12 @@ public:
|
||||
protected:
|
||||
|
||||
struct TimedPlayerBan {
|
||||
boost::shared_ptr<boost::asio::deadline_timer> timer;
|
||||
boost::shared_ptr<boost::asio::steady_timer> timer;
|
||||
std::string nameStr;
|
||||
boost::regex nameRegex;
|
||||
};
|
||||
struct TimedIPBan {
|
||||
boost::shared_ptr<boost::asio::deadline_timer> timer;
|
||||
boost::shared_ptr<boost::asio::steady_timer> timer;
|
||||
std::string ipAddress;
|
||||
};
|
||||
|
||||
@@ -81,8 +82,8 @@ protected:
|
||||
typedef std::list<boost::regex> RegexList;
|
||||
typedef std::vector<DB_id> DBPlayerIdList;
|
||||
|
||||
boost::shared_ptr<boost::asio::deadline_timer> InternalRegisterTimedBan(unsigned timerId, unsigned durationHours);
|
||||
void TimerRemoveBan(const boost::system::error_code &ec, unsigned banId, boost::shared_ptr<boost::asio::deadline_timer> timer);
|
||||
boost::shared_ptr<boost::asio::steady_timer> InternalRegisterTimedBan(unsigned timerId, unsigned durationHours);
|
||||
void TimerRemoveBan(const boost::system::error_code &ec, unsigned banId, boost::shared_ptr<boost::asio::steady_timer> timer);
|
||||
|
||||
boost::shared_ptr<boost::asio::io_service> m_ioService;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define _SERVERGAME_H_
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <third_party/boost/timers.hpp>
|
||||
#include <map>
|
||||
|
||||
@@ -180,8 +181,8 @@ protected:
|
||||
ServerGameState &GetState();
|
||||
void SetState(ServerGameState &newState);
|
||||
|
||||
boost::asio::deadline_timer &GetStateTimer1();
|
||||
boost::asio::deadline_timer &GetStateTimer2();
|
||||
boost::asio::steady_timer &GetStateTimer1();
|
||||
boost::asio::steady_timer &GetStateTimer2();
|
||||
|
||||
const StartData &GetStartData() const;
|
||||
void SetStartData(const StartData &startData);
|
||||
@@ -242,9 +243,9 @@ private:
|
||||
ConfigFile &m_playerConfig;
|
||||
unsigned m_gameNum;
|
||||
unsigned m_curPetitionId;
|
||||
boost::asio::deadline_timer m_voteKickTimer;
|
||||
boost::asio::deadline_timer m_stateTimer1;
|
||||
boost::asio::deadline_timer m_stateTimer2;
|
||||
boost::asio::steady_timer m_voteKickTimer;
|
||||
boost::asio::steady_timer m_stateTimer1;
|
||||
boost::asio::steady_timer m_stateTimer2;
|
||||
bool m_isNameReported;
|
||||
|
||||
friend class ServerLobbyThread;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define _SERVERLOBBYBOT_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <string>
|
||||
#include <list>
|
||||
@@ -86,7 +87,7 @@ private:
|
||||
boost::shared_ptr<ServerLobbyThread> m_lobbyThread;
|
||||
boost::shared_ptr<IrcThread> m_ircLobbyThread;
|
||||
|
||||
boost::asio::deadline_timer m_reconnectTimer;
|
||||
boost::asio::steady_timer m_reconnectTimer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -34,6 +34,7 @@
|
||||
#define _SERVERLOBBYTHREAD_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
|
||||
@@ -268,9 +269,9 @@ private:
|
||||
boost::shared_ptr<ChatCleanerManager> m_chatCleanerManager;
|
||||
boost::shared_ptr<ServerDBInterface> m_database;
|
||||
|
||||
boost::asio::deadline_timer m_removeGameTimer;
|
||||
boost::asio::deadline_timer m_saveStatisticsTimer;
|
||||
boost::asio::deadline_timer m_loginLockTimer;
|
||||
boost::asio::steady_timer m_removeGameTimer;
|
||||
boost::asio::steady_timer m_saveStatisticsTimer;
|
||||
boost::asio::steady_timer m_loginLockTimer;
|
||||
|
||||
boost::uuids::random_generator m_sessionIdGenerator;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
typedef unsigned SessionId;
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <string>
|
||||
@@ -144,9 +145,9 @@ private:
|
||||
bool m_wantsLobbyMsg;
|
||||
unsigned m_activityTimeoutSec;
|
||||
unsigned m_activityWarningRemainingSec;
|
||||
boost::asio::deadline_timer m_initTimeoutTimer;
|
||||
boost::asio::deadline_timer m_globalTimeoutTimer;
|
||||
boost::asio::deadline_timer m_activityTimeoutTimer;
|
||||
boost::asio::steady_timer m_initTimeoutTimer;
|
||||
boost::asio::steady_timer m_globalTimeoutTimer;
|
||||
boost::asio::steady_timer m_activityTimeoutTimer;
|
||||
SessionDataCallback &m_callback;
|
||||
Gsasl_session *m_authSession;
|
||||
int m_curAuthStep;
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#define ERR_SOCK_TRANSFER_INVALID_URL 26
|
||||
#define ERR_SOCK_TRANSFER_SELECT_FAILED 27
|
||||
#define ERR_SOCK_TRANSFER_FAILED 28
|
||||
#define ERR_SOCK_CONNECT_IPV6_FAILED 29
|
||||
#define ERR_SOCK_CONNECT_IPV6_TIMEOUT 30
|
||||
// The following errors are game errors.
|
||||
#define ERR_NET_VERSION_NOT_SUPPORTED 101
|
||||
#define ERR_NET_SERVER_MAINTENANCE 102
|
||||
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
Main Library:
|
||||
|
||||
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:
|
||||
|
||||
+35
-13
@@ -45,6 +45,11 @@ static std::string const base64_chars =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
/// Test whether a character is a valid base64 character
|
||||
/**
|
||||
* @param c The character to test
|
||||
* @return true if c is a valid base64 character
|
||||
*/
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (c == 43 || // +
|
||||
(c >= 47 && c <= 57) || // /-9
|
||||
@@ -52,17 +57,21 @@ static inline bool is_base64(unsigned char c) {
|
||||
(c >= 97 && c <= 122)); // a-z
|
||||
}
|
||||
|
||||
inline std::string base64_encode(unsigned char const * bytes_to_encode, unsigned
|
||||
int in_len)
|
||||
{
|
||||
/// Encode a char buffer into a base64 string
|
||||
/**
|
||||
* @param input The input data
|
||||
* @param len The length of input in bytes
|
||||
* @return A base64 encoded string representing input
|
||||
*/
|
||||
inline std::string base64_encode(unsigned char const * input, size_t len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
while (len--) {
|
||||
char_array_3[i++] = *(input++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
|
||||
@@ -97,25 +106,38 @@ inline std::string base64_encode(unsigned char const * bytes_to_encode, unsigned
|
||||
while((i++ < 3)) {
|
||||
ret += '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline std::string base64_encode(std::string const & data) {
|
||||
return base64_encode(reinterpret_cast<const unsigned char *>(data.data()),data.size());
|
||||
/// Encode a string into a base64 string
|
||||
/**
|
||||
* @param input The input data
|
||||
* @return A base64 encoded string representing input
|
||||
*/
|
||||
inline std::string base64_encode(std::string const & input) {
|
||||
return base64_encode(
|
||||
reinterpret_cast<const unsigned char *>(input.data()),
|
||||
input.size()
|
||||
);
|
||||
}
|
||||
|
||||
inline std::string base64_decode(std::string const & encoded_string) {
|
||||
size_t in_len = encoded_string.size();
|
||||
/// Decode a base64 encoded string into a string of raw bytes
|
||||
/**
|
||||
* @param input The base64 encoded input data
|
||||
* @return A string representing the decoded raw bytes
|
||||
*/
|
||||
inline std::string base64_decode(std::string const & input) {
|
||||
size_t in_len = input.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
while (in_len-- && ( input[in_] != '=') && is_base64(input[in_])) {
|
||||
char_array_4[i++] = input[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++) {
|
||||
char_array_4[i] = static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
|
||||
|
||||
+1
-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:
|
||||
|
||||
+61
-2
@@ -1,6 +1,6 @@
|
||||
|
||||
/*
|
||||
* 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:
|
||||
@@ -150,6 +150,21 @@ namespace status {
|
||||
* illegal on the wire.
|
||||
*/
|
||||
static value const tls_handshake = 1015;
|
||||
|
||||
/// A generic subprotocol error
|
||||
/**
|
||||
* Indicates that a subprotocol error occurred. Typically this involves
|
||||
* receiving a message that is not formatted as a valid message for the
|
||||
* subprotocol in use.
|
||||
*/
|
||||
static value const subprotocol_error = 3000;
|
||||
|
||||
/// A invalid subprotocol data
|
||||
/**
|
||||
* Indicates that data was received that violated the specification of the
|
||||
* subprotocol in use.
|
||||
*/
|
||||
static value const invalid_subprotocol_data = 3001;
|
||||
|
||||
/// First value in range reserved for future protocol use
|
||||
static value const rsv_start = 1016;
|
||||
@@ -199,6 +214,50 @@ namespace status {
|
||||
code == policy_violation || code == message_too_big ||
|
||||
code == internal_endpoint_error);
|
||||
}
|
||||
|
||||
/// Return a human readable interpretation of a WebSocket close code
|
||||
/**
|
||||
* See https://tools.ietf.org/html/rfc6455#section-7.4 for more details.
|
||||
*
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @param [in] code The code to look up.
|
||||
* @return A human readable interpretation of the code.
|
||||
*/
|
||||
inline std::string get_string(value code) {
|
||||
switch (code) {
|
||||
case normal:
|
||||
return "Normal close";
|
||||
case going_away:
|
||||
return "Going away";
|
||||
case protocol_error:
|
||||
return "Protocol error";
|
||||
case unsupported_data:
|
||||
return "Unsupported data";
|
||||
case no_status:
|
||||
return "No status set";
|
||||
case abnormal_close:
|
||||
return "Abnormal close";
|
||||
case invalid_payload:
|
||||
return "Invalid payload";
|
||||
case policy_violation:
|
||||
return "Policy violoation";
|
||||
case message_too_big:
|
||||
return "Message too big";
|
||||
case extension_required:
|
||||
return "Extension required";
|
||||
case internal_endpoint_error:
|
||||
return "Internal endpoint error";
|
||||
case tls_handshake:
|
||||
return "TLS handshake failure";
|
||||
case subprotocol_error:
|
||||
return "Generic subprotocol error";
|
||||
case invalid_subprotocol_data:
|
||||
return "Invalid subprotocol data";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
} // namespace status
|
||||
|
||||
/// Type used to convert close statuses between integer and wire representations
|
||||
@@ -263,7 +322,7 @@ inline status::value extract_code(std::string const & payload, lib::error_code
|
||||
inline std::string extract_reason(std::string const & payload, lib::error_code
|
||||
& ec)
|
||||
{
|
||||
std::string reason = "";
|
||||
std::string reason;
|
||||
ec = lib::error_code();
|
||||
|
||||
if (payload.size() > 2) {
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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:
|
||||
* * 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_COMMON_ASIO_HPP
|
||||
#define WEBSOCKETPP_COMMON_ASIO_HPP
|
||||
|
||||
// This file goes to some length to preserve compatibility with versions of
|
||||
// boost older than 1.49 (where the first modern steady_timer timer based on
|
||||
// boost/std chrono was introduced.
|
||||
//
|
||||
// For the versions older than 1.49, the deadline_timer is used instead. this
|
||||
// brings in dependencies on boost date_time and it has a different interface
|
||||
// that is normalized by the `lib::asio::is_neg` and `lib::asio::milliseconds`
|
||||
// wrappers provided by this file.
|
||||
//
|
||||
// The primary reason for this continued support is that boost 1.48 is the
|
||||
// default and not easily changeable version of boost supplied by the package
|
||||
// manager of popular Linux distributions like Ubuntu 12.04 LTS. Once the need
|
||||
// for this has passed this should be cleaned up and simplified.
|
||||
|
||||
#ifdef ASIO_STANDALONE
|
||||
#include <asio/version.hpp>
|
||||
|
||||
#if (ASIO_VERSION/100000) == 1 && ((ASIO_VERSION/100)%1000) < 8
|
||||
static_assert(false, "The minimum version of standalone Asio is 1.8.0");
|
||||
#endif
|
||||
|
||||
#include <asio.hpp>
|
||||
#include <asio/steady_timer.hpp>
|
||||
#include <websocketpp/common/chrono.hpp>
|
||||
#else
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// See note above about boost <1.49 compatibility. If we are running on
|
||||
// boost > 1.48 pull in the steady timer and chrono library
|
||||
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <websocketpp/common/chrono.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#endif
|
||||
|
||||
namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
#ifdef ASIO_STANDALONE
|
||||
namespace asio {
|
||||
using namespace ::asio;
|
||||
// Here we assume that we will be using std::error_code with standalone
|
||||
// Asio. This is probably a good assumption, but it is possible in rare
|
||||
// cases that local Asio versions would be used.
|
||||
using std::errc;
|
||||
|
||||
// See note above about boost <1.49 compatibility. Because we require
|
||||
// a standalone Asio version of 1.8+ we are guaranteed to have
|
||||
// steady_timer available. By convention we require the chrono library
|
||||
// (either boost or std) for use with standalone Asio.
|
||||
template <typename T>
|
||||
bool is_neg(T duration) {
|
||||
return duration.count() < 0;
|
||||
}
|
||||
inline lib::chrono::milliseconds milliseconds(long duration) {
|
||||
return lib::chrono::milliseconds(duration);
|
||||
}
|
||||
} // namespace asio
|
||||
|
||||
#else
|
||||
namespace asio {
|
||||
using namespace boost::asio;
|
||||
|
||||
// See note above about boost <1.49 compatibility
|
||||
#if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48
|
||||
// Using boost::asio >=1.49 so we use chrono and steady_timer
|
||||
template <typename T>
|
||||
bool is_neg(T duration) {
|
||||
return duration.count() < 0;
|
||||
}
|
||||
inline lib::chrono::milliseconds milliseconds(long duration) {
|
||||
return lib::chrono::milliseconds(duration);
|
||||
}
|
||||
#else
|
||||
// Using boost::asio <1.49 we pretend a deadline timer is a steady
|
||||
// timer and wrap the negative detection and duration conversion
|
||||
// appropriately.
|
||||
typedef boost::asio::deadline_timer steady_timer;
|
||||
|
||||
template <typename T>
|
||||
bool is_neg(T duration) {
|
||||
return duration.is_negative();
|
||||
}
|
||||
inline boost::posix_time::time_duration milliseconds(long duration) {
|
||||
return boost::posix_time::milliseconds(duration);
|
||||
}
|
||||
#endif
|
||||
|
||||
using boost::system::error_code;
|
||||
namespace errc = boost::system::errc;
|
||||
} // namespace asio
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace lib
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_ASIO_HPP
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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:
|
||||
* * 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_COMMON_ASIO_SSL_HPP
|
||||
#define WEBSOCKETPP_COMMON_ASIO_SSL_HPP
|
||||
|
||||
// NOTE: This file must be included before common/asio.hpp
|
||||
|
||||
#ifdef ASIO_STANDALONE
|
||||
#include <asio/ssl.hpp>
|
||||
#else
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#endif
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_ASIO_SSL_HPP
|
||||
+17
-4
@@ -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:
|
||||
@@ -28,7 +28,20 @@
|
||||
#ifndef WEBSOCKETPP_COMMON_CHRONO_HPP
|
||||
#define WEBSOCKETPP_COMMON_CHRONO_HPP
|
||||
|
||||
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
|
||||
// If we've determined that we're in full C++11 mode and the user hasn't
|
||||
// explicitly disabled the use of C++11 functional header, then prefer it to
|
||||
// boost.
|
||||
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_
|
||||
#ifndef _WEBSOCKETPP_CPP11_CHRONO_
|
||||
#define _WEBSOCKETPP_CPP11_CHRONO_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If we're on Visual Studio 2012 or higher and haven't explicitly disabled
|
||||
// the use of C++11 chrono header then prefer it to boost.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_
|
||||
#ifndef _WEBSOCKETPP_CPP11_CHRONO_
|
||||
#define _WEBSOCKETPP_CPP11_CHRONO_
|
||||
#endif
|
||||
@@ -44,9 +57,9 @@ namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
|
||||
using std::chrono::system_clock;
|
||||
namespace chrono = std::chrono;
|
||||
#else
|
||||
using boost::chrono::system_clock;
|
||||
namespace chrono = boost::chrono;
|
||||
#endif
|
||||
|
||||
} // namespace lib
|
||||
|
||||
@@ -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:
|
||||
@@ -34,7 +34,7 @@ namespace websocketpp {
|
||||
|
||||
/// A handle to uniquely identify a connection.
|
||||
/**
|
||||
* This type uniquely identifies a connection. It is implimented as a weak
|
||||
* This type uniquely identifies a connection. It is implemented as a weak
|
||||
* pointer to the connection in question. This provides uniqueness across
|
||||
* multiple endpoints and ensures that IDs never conflict or run out.
|
||||
*
|
||||
|
||||
+71
-4
@@ -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:
|
||||
@@ -40,10 +40,34 @@
|
||||
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
|
||||
#endif
|
||||
|
||||
// The code below attempts to use information provided by the build system or
|
||||
// user supplied defines to selectively enable C++11 language and library
|
||||
// features. In most cases features that are targeted individually may also be
|
||||
// selectively disabled via an associated _WEBSOCKETPP_NOXXX_ define.
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_STL_
|
||||
// This flag indicates that all of the C++11 language features are available
|
||||
// to us.
|
||||
#if defined(_WEBSOCKETPP_CPP11_STL_) || __cplusplus >= 201103L || defined(_WEBSOCKETPP_CPP11_STRICT_)
|
||||
// This check tests for blanket c++11 coverage. It can be activated in one
|
||||
// of three ways. Either the compiler itself reports that it is a full
|
||||
// C++11 compiler via the __cplusplus macro or the user/build system
|
||||
// supplies one of the two preprocessor defines below:
|
||||
|
||||
// This is defined to allow other WebSocket++ common headers to enable
|
||||
// C++11 features when they are detected by this file rather than
|
||||
// duplicating the above logic in every common header.
|
||||
#define _WEBSOCKETPP_CPP11_INTERNAL_
|
||||
|
||||
// _WEBSOCKETPP_CPP11_STRICT_
|
||||
//
|
||||
// This define reports to WebSocket++ that 100% of the language and library
|
||||
// features of C++11 are available. Using this define on a non-C++11
|
||||
// compiler will result in problems.
|
||||
|
||||
// _WEBSOCKETPP_CPP11_STL_
|
||||
//
|
||||
// This define enables *most* C++11 options that were implemented early on
|
||||
// by compilers. It is typically used for compilers that have many, but not
|
||||
// all C++11 features. It should be safe to use on GCC 4.7-4.8 and perhaps
|
||||
// earlier.
|
||||
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
|
||||
#endif
|
||||
@@ -53,7 +77,25 @@
|
||||
#ifndef _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||
#endif
|
||||
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||
#endif
|
||||
#ifndef _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
#define _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
#endif
|
||||
#ifndef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
#define _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
// GCC as of version 4.9 (latest) does not support std::put_time yet.
|
||||
// so ignore it
|
||||
#define _WEBSOCKETPP_PUTTIME_
|
||||
#endif
|
||||
#else
|
||||
// In the absence of a blanket define, try to use compiler versions or
|
||||
// feature testing macros to selectively enable what we can.
|
||||
|
||||
// Test for noexcept
|
||||
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
||||
#ifdef _WEBSOCKETPP_NOEXCEPT_
|
||||
@@ -63,6 +105,9 @@
|
||||
#if __has_feature(cxx_noexcept)
|
||||
// clang feature detect says we have noexcept
|
||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
// Visual Studio 2015+ has noexcept
|
||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
|
||||
#else
|
||||
// assume we don't have noexcept
|
||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
||||
@@ -79,6 +124,9 @@
|
||||
#if __has_feature(cxx_constexpr)
|
||||
// clang feature detect says we have constexpr
|
||||
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
// Visual Studio 2015+ has constexpr
|
||||
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr
|
||||
#else
|
||||
// assume we don't have constexpr
|
||||
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_
|
||||
@@ -90,6 +138,25 @@
|
||||
#if __has_feature(cxx_generalized_initializers) && !defined(_WEBSOCKETPP_INITIALIZER_LISTS_)
|
||||
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||
#endif
|
||||
|
||||
// Test for nullptr
|
||||
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
|
||||
#ifdef _WEBSOCKETPP_NULLPTR_
|
||||
// build system says we have nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||
#else
|
||||
#if __has_feature(cxx_nullptr)
|
||||
// clang feature detect says we have nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||
#elif defined(_MSC_VER) &&_MSC_VER >= 1600
|
||||
// Visual Studio version that has nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||
#else
|
||||
// assume we don't have nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_CPP11_HPP
|
||||
@@ -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:
|
||||
@@ -28,19 +28,37 @@
|
||||
#ifndef WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
|
||||
#define WEBSOCKETPP_COMMON_FUNCTIONAL_HPP
|
||||
|
||||
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
|
||||
// If we've determined that we're in full C++11 mode and the user hasn't
|
||||
// explicitly disabled the use of C++11 functional header, then prefer it to
|
||||
// boost.
|
||||
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
|
||||
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
|
||||
// the use of C++11 functional header then prefer it to boost.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_
|
||||
#ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||
#include <functional>
|
||||
#else
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
@@ -49,6 +67,18 @@ namespace lib {
|
||||
using std::bind;
|
||||
using std::ref;
|
||||
namespace placeholders = std::placeholders;
|
||||
|
||||
// There are some cases where a C++11 compiler balks at using std::ref
|
||||
// but a C++03 compiler using boost function requires boost::ref. As such
|
||||
// lib::ref is not useful in these cases. Instead this macro allows the use
|
||||
// of boost::ref in the case of a boost compile or no reference wrapper at
|
||||
// all in the case of a C++11 compile
|
||||
#define _WEBSOCKETPP_REF(x) x
|
||||
|
||||
template <typename T>
|
||||
void clear_function(T & x) {
|
||||
x = nullptr;
|
||||
}
|
||||
#else
|
||||
using boost::function;
|
||||
using boost::bind;
|
||||
@@ -57,6 +87,15 @@ namespace lib {
|
||||
/// \todo this feels hacky, is there a better way?
|
||||
using ::_1;
|
||||
using ::_2;
|
||||
using ::_3;
|
||||
}
|
||||
|
||||
// See above definition for more details on what this is and why it exists
|
||||
#define _WEBSOCKETPP_REF(x) boost::ref(x)
|
||||
|
||||
template <typename T>
|
||||
void clear_function(T & x) {
|
||||
x.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+70
-70
@@ -34,7 +34,7 @@
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
@@ -45,12 +45,12 @@
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
@@ -80,9 +80,9 @@ typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
@@ -94,7 +94,7 @@ inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes)
|
||||
/* Finish the message and return the digest. */
|
||||
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
|
||||
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
@@ -169,8 +169,8 @@ inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
|
||||
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if ZSW_MD5_BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
@@ -183,51 +183,51 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
|
||||
{
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static int const w = 1;
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static int const w = 1;
|
||||
|
||||
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
||||
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (md5_word_t const *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
std::memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (md5_word_t const *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
std::memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if ZSW_MD5_BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -361,71 +361,71 @@ void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
||||
|
||||
std::memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
std::memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
std::memcpy(pms->buf, p, left);
|
||||
std::memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
||||
static md5_byte_t const pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
||||
|
||||
// some convenience c++ functions
|
||||
inline std::string md5_hash_string(std::string const & s) {
|
||||
char digest[16];
|
||||
char digest[16];
|
||||
|
||||
md5_state_t state;
|
||||
md5_state_t state;
|
||||
|
||||
md5_init(&state);
|
||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||
md5_finish(&state, (md5_byte_t *)digest);
|
||||
md5_init(&state);
|
||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||
md5_finish(&state, (md5_byte_t *)digest);
|
||||
|
||||
std::string ret;
|
||||
ret.resize(16);
|
||||
std::copy(digest,digest+16,ret.begin());
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
+23
-2
@@ -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:
|
||||
@@ -28,16 +28,32 @@
|
||||
#ifndef WEBSOCKETPP_COMMON_MEMORY_HPP
|
||||
#define WEBSOCKETPP_COMMON_MEMORY_HPP
|
||||
|
||||
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
|
||||
// If we've determined that we're in full C++11 mode and the user hasn't
|
||||
// explicitly disabled the use of C++11 memory header, then prefer it to
|
||||
// boost.
|
||||
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
|
||||
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
|
||||
#define _WEBSOCKETPP_CPP11_MEMORY_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
|
||||
// the use of C++11 functional header then prefer it to boost.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
|
||||
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
|
||||
#define _WEBSOCKETPP_CPP11_MEMORY_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
|
||||
#include <memory>
|
||||
#else
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/pointer_cast.hpp>
|
||||
@@ -49,15 +65,20 @@ namespace lib {
|
||||
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
|
||||
using std::shared_ptr;
|
||||
using std::weak_ptr;
|
||||
using std::auto_ptr;
|
||||
using std::enable_shared_from_this;
|
||||
using std::static_pointer_cast;
|
||||
using std::make_shared;
|
||||
using std::unique_ptr;
|
||||
|
||||
typedef std::unique_ptr<unsigned char[]> unique_ptr_uchar_array;
|
||||
#else
|
||||
using boost::shared_ptr;
|
||||
using boost::weak_ptr;
|
||||
using std::auto_ptr;
|
||||
using boost::enable_shared_from_this;
|
||||
using boost::static_pointer_cast;
|
||||
using boost::make_shared;
|
||||
|
||||
typedef boost::scoped_array<unsigned char> unique_ptr_uchar_array;
|
||||
#endif
|
||||
|
||||
+30
-6
@@ -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,20 +29,22 @@
|
||||
#define WEBSOCKETPP_COMMON_NETWORK_HPP
|
||||
|
||||
// For ntohs and htons
|
||||
#if defined(WIN32)
|
||||
#if defined(_WIN32)
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
//#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace lib {
|
||||
namespace net {
|
||||
|
||||
inline bool is_little_endian() {
|
||||
short int val = 0x1;
|
||||
char *ptr = (char*)&val;
|
||||
char *ptr = reinterpret_cast<char *>(&val);
|
||||
return (ptr[0] == 1);
|
||||
}
|
||||
|
||||
@@ -50,7 +52,18 @@ inline bool is_little_endian() {
|
||||
#define TYP_SMLE 1
|
||||
#define TYP_BIGE 2
|
||||
|
||||
inline uint64_t htonll(uint64_t src) {
|
||||
/// Convert 64 bit value to network byte order
|
||||
/**
|
||||
* This method is prefixed to avoid conflicts with operating system level
|
||||
* macros for this functionality.
|
||||
*
|
||||
* TODO: figure out if it would be beneficial to use operating system level
|
||||
* macros for this.
|
||||
*
|
||||
* @param src The integer in host byte order
|
||||
* @return src converted to network byte order
|
||||
*/
|
||||
inline uint64_t _htonll(uint64_t src) {
|
||||
static int typ = TYP_INIT;
|
||||
unsigned char c;
|
||||
union {
|
||||
@@ -71,8 +84,19 @@ inline uint64_t htonll(uint64_t src) {
|
||||
return x.ull;
|
||||
}
|
||||
|
||||
inline uint64_t ntohll(uint64_t src) {
|
||||
return htonll(src);
|
||||
/// Convert 64 bit value to host byte order
|
||||
/**
|
||||
* This method is prefixed to avoid conflicts with operating system level
|
||||
* macros for this functionality.
|
||||
*
|
||||
* TODO: figure out if it would be beneficial to use operating system level
|
||||
* macros for this.
|
||||
*
|
||||
* @param src The integer in network byte order
|
||||
* @return src converted to host byte order
|
||||
*/
|
||||
inline uint64_t _ntohll(uint64_t src) {
|
||||
return _htonll(src);
|
||||
}
|
||||
|
||||
} // net
|
||||
|
||||
@@ -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:
|
||||
@@ -33,9 +33,14 @@
|
||||
* don't fit somewhere else better.
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && !defined(NOMINMAX)
|
||||
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||
// don't define min and max macros that conflict with std::min and std::max
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
// Bump up the variadic parameter max for Visual Studio 2012
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1700
|
||||
#define _VARIADIC_MAX 8
|
||||
#endif
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_PLATFORMS_HPP
|
||||
+18
-2
@@ -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:
|
||||
@@ -28,12 +28,28 @@
|
||||
#ifndef WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP
|
||||
#define WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP
|
||||
|
||||
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_RANDOM_DEVICE_
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
|
||||
// If we've determined that we're in full C++11 mode and the user hasn't
|
||||
// explicitly disabled the use of C++11 random header, then prefer it to
|
||||
// boost.
|
||||
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_RANDOM_DEVICE_
|
||||
#ifndef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
|
||||
#define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
|
||||
// the use of C++11 random header then prefer it to boost.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_
|
||||
#ifndef _WEBSOCKETPP_CPP11_MEMORY_
|
||||
#define _WEBSOCKETPP_CPP11_MEMORY_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_
|
||||
#include <random>
|
||||
#else
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
@@ -32,7 +32,7 @@
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
|
||||
#if WIN32 && (_MSC_VER < 1600)
|
||||
#if defined (_WIN32) && defined (_MSC_VER) && (_MSC_VER < 1600)
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
using boost::int8_t;
|
||||
|
||||
@@ -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:
|
||||
@@ -28,12 +28,28 @@
|
||||
#ifndef WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP
|
||||
#define WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP
|
||||
|
||||
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
|
||||
// If we've determined that we're in full C++11 mode and the user hasn't
|
||||
// explicitly disabled the use of C++11 system_error header, then prefer it to
|
||||
// boost.
|
||||
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_
|
||||
#ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
|
||||
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If we're on Visual Studio 2010 or higher and haven't explicitly disabled
|
||||
// the use of C++11 system_error header then prefer it to boost.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_
|
||||
#ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
|
||||
#define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
|
||||
#include <system_error>
|
||||
#else
|
||||
@@ -45,6 +61,7 @@ namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
|
||||
using std::errc;
|
||||
using std::error_code;
|
||||
using std::error_category;
|
||||
using std::error_condition;
|
||||
@@ -52,6 +69,7 @@ namespace lib {
|
||||
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ namespace std {
|
||||
#define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ }
|
||||
#else
|
||||
namespace errc = boost::system::errc;
|
||||
using boost::system::error_code;
|
||||
using boost::system::error_category;
|
||||
using boost::system::error_condition;
|
||||
|
||||
+19
-2
@@ -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:
|
||||
@@ -28,7 +28,24 @@
|
||||
#ifndef WEBSOCKETPP_COMMON_THREAD_HPP
|
||||
#define WEBSOCKETPP_COMMON_THREAD_HPP
|
||||
|
||||
#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_THREAD_
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
|
||||
// If we autodetect C++11 and haven't been explicitly instructed to not use
|
||||
// C++11 threads, then set the defines that instructs the rest of this header
|
||||
// to use C++11 <thread> and <mutex>
|
||||
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_THREAD_
|
||||
// MinGW by default does not support C++11 thread/mutex so even if the
|
||||
// internal check for C++11 passes, ignore it if we are on MinGW
|
||||
#if (!defined(__MINGW32__) && !defined(__MINGW64__))
|
||||
#ifndef _WEBSOCKETPP_CPP11_THREAD_
|
||||
#define _WEBSOCKETPP_CPP11_THREAD_
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If we're on Visual Studio 2013 or higher and haven't explicitly disabled
|
||||
// the use of C++11 thread header then prefer it to boost.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1800 && !defined _WEBSOCKETPP_NO_CPP11_THREAD_
|
||||
#ifndef _WEBSOCKETPP_CPP11_THREAD_
|
||||
#define _WEBSOCKETPP_CPP11_THREAD_
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_COMMON_TIME_HPP
|
||||
#define WEBSOCKETPP_COMMON_TIME_HPP
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
// Code in this header was inspired by the following article and includes some
|
||||
// code from the related project g2log. The g2log code is public domain licensed
|
||||
// http://kjellkod.wordpress.com/2013/01/22/exploring-c11-part-2-localtime-and-time-again/
|
||||
|
||||
/// Thread safe cross platform localtime
|
||||
inline std::tm localtime(std::time_t const & time) {
|
||||
std::tm tm_snapshot;
|
||||
#if (defined(__MINGW32__) || defined(__MINGW64__))
|
||||
memcpy(&tm_snapshot, ::localtime(&time), sizeof(std::tm));
|
||||
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
localtime_s(&tm_snapshot, &time);
|
||||
#else
|
||||
localtime_r(&time, &tm_snapshot); // POSIX
|
||||
#endif
|
||||
return tm_snapshot;
|
||||
}
|
||||
|
||||
} // lib
|
||||
} // websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_TIME_HPP
|
||||
+33
-39
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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:
|
||||
@@ -25,47 +25,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_ERROR_MESSAGE_HPP
|
||||
#define WEBSOCKETPP_ERROR_MESSAGE_HPP
|
||||
#ifndef WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
|
||||
#define WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
|
||||
// If we've determined that we're in full C++11 mode and the user hasn't
|
||||
// explicitly disabled the use of C++11 functional header, then prefer it to
|
||||
// boost.
|
||||
#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_TYPE_TRAITS_
|
||||
#ifndef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
|
||||
#define _WEBSOCKETPP_CPP11_TYPE_TRAITS_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
|
||||
#include <type_traits>
|
||||
#else
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
/**
|
||||
* The transport::security::* classes are a set of security/socket related
|
||||
* policies and support code for the ASIO transport types.
|
||||
*/
|
||||
class error_msg {
|
||||
public:
|
||||
const std::string& get_msg() const {
|
||||
return m_error_msg;
|
||||
}
|
||||
|
||||
void set_msg(const std::string& msg) {
|
||||
m_error_msg = msg;
|
||||
}
|
||||
|
||||
void append_msg(const std::string& msg) {
|
||||
m_error_msg.append(msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_msg(const T& thing) {
|
||||
std::stringsteam val;
|
||||
val << thing;
|
||||
this->set_msg(val.str());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void append_msg(const T& thing) {
|
||||
std::stringsteam val;
|
||||
val << thing;
|
||||
this->append_msg(val.str());
|
||||
}
|
||||
private:
|
||||
// error resources
|
||||
std::string m_error_msg;
|
||||
};
|
||||
#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_
|
||||
using std::aligned_storage;
|
||||
using std::is_same;
|
||||
#else
|
||||
using boost::aligned_storage;
|
||||
using boost::is_same;
|
||||
#endif
|
||||
|
||||
} // namespace lib
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_ERROR_MESSAGE_HPP
|
||||
#endif // WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP
|
||||
@@ -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:
|
||||
|
||||
@@ -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,26 +29,48 @@
|
||||
#define WEBSOCKETPP_CONCURRENCY_NONE_HPP
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
/// Concurrency handling support
|
||||
namespace concurrency {
|
||||
|
||||
/// Implementation for no-op locking primitives
|
||||
namespace none_impl {
|
||||
/// A fake mutex implementation that does nothing
|
||||
class fake_mutex {
|
||||
public:
|
||||
fake_mutex() {}
|
||||
~fake_mutex() {}
|
||||
};
|
||||
|
||||
/// A fake lock guard implementation that does nothing
|
||||
class fake_lock_guard {
|
||||
public:
|
||||
explicit fake_lock_guard(fake_mutex foo) {}
|
||||
explicit fake_lock_guard(fake_mutex) {}
|
||||
~fake_lock_guard() {}
|
||||
};
|
||||
} // namespace none_impl
|
||||
|
||||
/// Stub Concurrency policy to remove locking in single threaded projects
|
||||
/// Stub concurrency policy that implements the interface using no-ops.
|
||||
/**
|
||||
* This policy documents the concurrency policy interface using no-ops. It can
|
||||
* be used as a reference or base for building a new concurrency policy. It can
|
||||
* also be used as is to disable all locking for endpoints used in purely single
|
||||
* threaded programs.
|
||||
*/
|
||||
class none {
|
||||
public:
|
||||
/// The type of a mutex primitive
|
||||
/**
|
||||
* std::mutex is an example.
|
||||
*/
|
||||
typedef none_impl::fake_mutex mutex_type;
|
||||
|
||||
/// The type of a scoped/RAII lock primitive.
|
||||
/**
|
||||
* The scoped lock constructor should take a mutex_type as a parameter,
|
||||
* acquire that lock, and release it in its destructor. std::lock_guard is
|
||||
* an example.
|
||||
*/
|
||||
typedef none_impl::fake_lock_guard scoped_lock_type;
|
||||
};
|
||||
|
||||
|
||||
+1
-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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
@@ -25,9 +25,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// This header defines WebSocket++ macros for C++11 compatibility based on the Boost.Config library.
|
||||
// This will correctly configure most target platforms simply by including this header before
|
||||
// any other WebSocket++ header.
|
||||
// This header defines WebSocket++ macros for C++11 compatibility based on the
|
||||
// Boost.Config library. This will correctly configure most target platforms
|
||||
// simply by including this header before any other WebSocket++ header.
|
||||
|
||||
#ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||
#define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||
@@ -41,7 +41,7 @@
|
||||
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ASIO_HAS_STD_CHRONO
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
#define _WEBSOCKETPP_CPP11_CHRONO_
|
||||
#endif
|
||||
|
||||
@@ -67,5 +67,6 @@
|
||||
|
||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT
|
||||
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR
|
||||
// TODO: nullptr support
|
||||
|
||||
#endif // WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||
+25
-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:
|
||||
@@ -215,6 +215,30 @@ struct core {
|
||||
*/
|
||||
static const bool silent_close = false;
|
||||
|
||||
/// Default maximum message size
|
||||
/**
|
||||
* Default value for the processor's maximum message size. Maximum message size
|
||||
* determines the point at which the library will fail a connection with the
|
||||
* message_too_big protocol error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
static const size_t max_message_size = 32000000;
|
||||
|
||||
/// Default maximum http body size
|
||||
/**
|
||||
* Default value for the http parser's maximum body size. Maximum body size
|
||||
* determines the point at which the library will abort reading an HTTP
|
||||
* connection with the 413/request entity too large error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.5.0
|
||||
*/
|
||||
static const size_t max_http_body_size = 32000000;
|
||||
|
||||
/// Global flag for enabling/disabling extensions
|
||||
static const bool enable_extensions = true;
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -34,7 +34,11 @@
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
|
||||
// Concurrency
|
||||
#ifndef _WEBSOCKETPP_NO_THREADING_
|
||||
#include <websocketpp/concurrency/basic.hpp>
|
||||
#else
|
||||
#include <websocketpp/concurrency/none.hpp>
|
||||
#endif
|
||||
|
||||
// Transport
|
||||
#include <websocketpp/transport/iostream/endpoint.hpp>
|
||||
@@ -68,7 +72,11 @@ struct core_client {
|
||||
typedef core_client type;
|
||||
|
||||
// Concurrency policy
|
||||
#ifndef _WEBSOCKETPP_NO_THREADING_
|
||||
typedef websocketpp::concurrency::basic concurrency_type;
|
||||
#else
|
||||
typedef websocketpp::concurrency::none concurrency_type;
|
||||
#endif
|
||||
|
||||
// HTTP Parser Policies
|
||||
typedef http::parser::request request_type;
|
||||
@@ -216,6 +224,30 @@ struct core_client {
|
||||
*/
|
||||
static const bool silent_close = false;
|
||||
|
||||
/// Default maximum message size
|
||||
/**
|
||||
* Default value for the processor's maximum message size. Maximum message size
|
||||
* determines the point at which the library will fail a connection with the
|
||||
* message_too_big protocol error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
static const size_t max_message_size = 32000000;
|
||||
|
||||
/// Default maximum http body size
|
||||
/**
|
||||
* Default value for the http parser's maximum body size. Maximum body size
|
||||
* determines the point at which the library will abort reading an HTTP
|
||||
* connection with the 413/request entity too large error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.5.0
|
||||
*/
|
||||
static const size_t max_http_body_size = 32000000;
|
||||
|
||||
/// Global flag for enabling/disabling extensions
|
||||
static const bool enable_extensions = true;
|
||||
|
||||
|
||||
+25
-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:
|
||||
@@ -216,6 +216,30 @@ struct debug_core {
|
||||
*/
|
||||
static const bool silent_close = false;
|
||||
|
||||
/// Default maximum message size
|
||||
/**
|
||||
* Default value for the processor's maximum message size. Maximum message size
|
||||
* determines the point at which the library will fail a connection with the
|
||||
* message_too_big protocol error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
static const size_t max_message_size = 32000000;
|
||||
|
||||
/// Default maximum http body size
|
||||
/**
|
||||
* Default value for the http parser's maximum body size. Maximum body size
|
||||
* determines the point at which the library will abort reading an HTTP
|
||||
* connection with the 413/request entity too large error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.5.0
|
||||
*/
|
||||
static const size_t max_http_body_size = 32000000;
|
||||
|
||||
/// Global flag for enabling/disabling extensions
|
||||
static const bool enable_extensions = true;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP
|
||||
#define WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP
|
||||
|
||||
#include <websocketpp/config/minimal_server.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace config {
|
||||
|
||||
/// Client config with minimal dependencies
|
||||
/**
|
||||
* This config strips out as many dependencies as possible. It is suitable for
|
||||
* use as a base class for custom configs that want to implement or choose their
|
||||
* own policies for components that even the core config includes.
|
||||
*
|
||||
* NOTE: this config stubs out enough that it cannot be used directly. You must
|
||||
* supply at least a transport policy and a cryptographically secure random
|
||||
* number generation policy for a config based on `minimal_client` to do
|
||||
* anything useful.
|
||||
*
|
||||
* Present dependency list for minimal_server config:
|
||||
*
|
||||
* C++98 STL:
|
||||
* <algorithm>
|
||||
* <map>
|
||||
* <sstream>
|
||||
* <string>
|
||||
* <vector>
|
||||
*
|
||||
* C++11 STL or Boost
|
||||
* <memory>
|
||||
* <functional>
|
||||
* <system_error>
|
||||
*
|
||||
* Operating System:
|
||||
* <stdint.h> or <boost/cstdint.hpp>
|
||||
* <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this)
|
||||
*
|
||||
* @since 0.4.0-dev
|
||||
*/
|
||||
typedef minimal_server minimal_client;
|
||||
|
||||
} // namespace config
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP
|
||||
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_CONFIG_MINIMAL_HPP
|
||||
#define WEBSOCKETPP_CONFIG_MINIMAL_HPP
|
||||
|
||||
// Non-Policy common stuff
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
|
||||
// Concurrency
|
||||
#include <websocketpp/concurrency/none.hpp>
|
||||
|
||||
// Transport
|
||||
#include <websocketpp/transport/stub/endpoint.hpp>
|
||||
|
||||
// HTTP
|
||||
#include <websocketpp/http/request.hpp>
|
||||
#include <websocketpp/http/response.hpp>
|
||||
|
||||
// Messages
|
||||
#include <websocketpp/message_buffer/message.hpp>
|
||||
#include <websocketpp/message_buffer/alloc.hpp>
|
||||
|
||||
// Loggers
|
||||
#include <websocketpp/logger/stub.hpp>
|
||||
|
||||
// RNG
|
||||
#include <websocketpp/random/none.hpp>
|
||||
|
||||
// User stub base classes
|
||||
#include <websocketpp/endpoint_base.hpp>
|
||||
#include <websocketpp/connection_base.hpp>
|
||||
|
||||
// Extensions
|
||||
#include <websocketpp/extensions/permessage_deflate/disabled.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace config {
|
||||
|
||||
/// Server config with minimal dependencies
|
||||
/**
|
||||
* This config strips out as many dependencies as possible. It is suitable for
|
||||
* use as a base class for custom configs that want to implement or choose their
|
||||
* own policies for components that even the core config includes.
|
||||
*
|
||||
* NOTE: this config stubs out enough that it cannot be used directly. You must
|
||||
* supply at least a transport policy for a config based on `minimal_server` to
|
||||
* do anything useful.
|
||||
*
|
||||
* Present dependency list for minimal_server config:
|
||||
*
|
||||
* C++98 STL:
|
||||
* <algorithm>
|
||||
* <map>
|
||||
* <sstream>
|
||||
* <string>
|
||||
* <vector>
|
||||
*
|
||||
* C++11 STL or Boost
|
||||
* <memory>
|
||||
* <functional>
|
||||
* <system_error>
|
||||
*
|
||||
* Operating System:
|
||||
* <stdint.h> or <boost/cstdint.hpp>
|
||||
* <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this)
|
||||
*
|
||||
* @since 0.4.0-dev
|
||||
*/
|
||||
struct minimal_server {
|
||||
typedef minimal_server type;
|
||||
|
||||
// Concurrency policy
|
||||
typedef websocketpp::concurrency::none concurrency_type;
|
||||
|
||||
// HTTP Parser Policies
|
||||
typedef http::parser::request request_type;
|
||||
typedef http::parser::response response_type;
|
||||
|
||||
// Message Policies
|
||||
typedef message_buffer::message<message_buffer::alloc::con_msg_manager>
|
||||
message_type;
|
||||
typedef message_buffer::alloc::con_msg_manager<message_type>
|
||||
con_msg_manager_type;
|
||||
typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type>
|
||||
endpoint_msg_manager_type;
|
||||
|
||||
/// Logging policies
|
||||
typedef websocketpp::log::stub elog_type;
|
||||
typedef websocketpp::log::stub alog_type;
|
||||
|
||||
/// RNG policies
|
||||
typedef websocketpp::random::none::int_generator<uint32_t> rng_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;
|
||||
|
||||
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)
|
||||
|
||||
/// Length of time to wait for socket pre-initialization
|
||||
/**
|
||||
* Exactly what this includes depends on the socket policy in use
|
||||
*/
|
||||
static const long timeout_socket_pre_init = 5000;
|
||||
|
||||
/// Length of time to wait before a proxy handshake is aborted
|
||||
static const long timeout_proxy = 5000;
|
||||
|
||||
/// Length of time to wait for socket post-initialization
|
||||
/**
|
||||
* Exactly what this includes depends on the socket policy in use.
|
||||
* Often this means the TLS handshake
|
||||
*/
|
||||
static const long timeout_socket_post_init = 5000;
|
||||
|
||||
/// Length of time to wait for dns resolution
|
||||
static const long timeout_dns_resolve = 5000;
|
||||
|
||||
/// Length of time to wait for TCP connect
|
||||
static const long timeout_connect = 5000;
|
||||
|
||||
/// Length of time to wait for socket shutdown
|
||||
static const long timeout_socket_shutdown = 5000;
|
||||
};
|
||||
|
||||
/// Transport Endpoint Component
|
||||
typedef websocketpp::transport::stub::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
/// User overridable Endpoint base class
|
||||
typedef websocketpp::endpoint_base endpoint_base;
|
||||
/// User overridable Connection base class
|
||||
typedef websocketpp::connection_base connection_base;
|
||||
|
||||
/// Default timer values (in ms)
|
||||
|
||||
/// Length of time before an opening handshake is aborted
|
||||
static const long timeout_open_handshake = 5000;
|
||||
/// Length of time before a closing handshake is aborted
|
||||
static const long timeout_close_handshake = 5000;
|
||||
/// Length of time to wait for a pong after a ping
|
||||
static const long timeout_pong = 5000;
|
||||
|
||||
/// WebSocket Protocol version to use as a client
|
||||
/**
|
||||
* What version of the WebSocket Protocol to use for outgoing client
|
||||
* connections. Setting this to a value other than 13 (RFC6455) is not
|
||||
* recommended.
|
||||
*/
|
||||
static const int client_version = 13; // RFC6455
|
||||
|
||||
/// Default static error logging channels
|
||||
/**
|
||||
* Which error logging channels to enable at compile time. Channels not
|
||||
* enabled here will be unable to be selected by programs using the library.
|
||||
* This option gives an optimizing compiler the ability to remove entirely
|
||||
* code to test whether or not to print out log messages on a certain
|
||||
* channel
|
||||
*
|
||||
* Default is all except for development/debug level errors
|
||||
*/
|
||||
static const websocketpp::log::level elog_level =
|
||||
websocketpp::log::elevel::none;
|
||||
|
||||
/// Default static access logging channels
|
||||
/**
|
||||
* Which access logging channels to enable at compile time. Channels not
|
||||
* enabled here will be unable to be selected by programs using the library.
|
||||
* This option gives an optimizing compiler the ability to remove entirely
|
||||
* code to test whether or not to print out log messages on a certain
|
||||
* channel
|
||||
*
|
||||
* Default is all except for development/debug level access messages
|
||||
*/
|
||||
static const websocketpp::log::level alog_level =
|
||||
websocketpp::log::alevel::none;
|
||||
|
||||
///
|
||||
static const size_t connection_read_buffer_size = 16384;
|
||||
|
||||
/// Drop connections immediately on protocol error.
|
||||
/**
|
||||
* Drop connections on protocol error rather than sending a close frame.
|
||||
* Off by default. This may result in legit messages near the error being
|
||||
* dropped as well. It may free up resources otherwise spent dealing with
|
||||
* misbehaving clients.
|
||||
*/
|
||||
static const bool drop_on_protocol_error = false;
|
||||
|
||||
/// Suppresses the return of detailed connection close information
|
||||
/**
|
||||
* Silence close suppresses the return of detailed connection close
|
||||
* information during the closing handshake. This information is useful
|
||||
* for debugging and presenting useful errors to end users but may be
|
||||
* undesirable for security reasons in some production environments.
|
||||
* Close reasons could be used by an attacker to confirm that the endpoint
|
||||
* is out of resources or be used to identify the WebSocket implementation
|
||||
* in use.
|
||||
*
|
||||
* Note: this will suppress *all* close codes, including those explicitly
|
||||
* sent by local applications.
|
||||
*/
|
||||
static const bool silent_close = false;
|
||||
|
||||
/// Default maximum message size
|
||||
/**
|
||||
* Default value for the processor's maximum message size. Maximum message size
|
||||
* determines the point at which the library will fail a connection with the
|
||||
* message_too_big protocol error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.4.0-alpha1
|
||||
*/
|
||||
static const size_t max_message_size = 32000000;
|
||||
|
||||
/// Default maximum http body size
|
||||
/**
|
||||
* Default value for the http parser's maximum body size. Maximum body size
|
||||
* determines the point at which the library will abort reading an HTTP
|
||||
* connection with the 413/request entity too large error.
|
||||
*
|
||||
* The default is 32MB
|
||||
*
|
||||
* @since 0.5.0
|
||||
*/
|
||||
static const size_t max_http_body_size = 32000000;
|
||||
|
||||
/// Global flag for enabling/disabling extensions
|
||||
static const bool enable_extensions = true;
|
||||
|
||||
/// Extension specific settings:
|
||||
|
||||
/// permessage_compress extension
|
||||
struct permessage_deflate_config {
|
||||
typedef core::request_type request_type;
|
||||
|
||||
/// If the remote endpoint requests that we reset the compression
|
||||
/// context after each message should we honor the request?
|
||||
static const bool allow_disabling_context_takeover = true;
|
||||
|
||||
/// If the remote endpoint requests that we reduce the size of the
|
||||
/// LZ77 sliding window size this is the lowest value that will be
|
||||
/// allowed. Values range from 8 to 15. A value of 8 means we will
|
||||
/// allow any possible window size. A value of 15 means do not allow
|
||||
/// negotiation of the window size (ie require the default).
|
||||
static const uint8_t minimum_outgoing_window_bits = 8;
|
||||
};
|
||||
|
||||
typedef websocketpp::extensions::permessage_deflate::disabled
|
||||
<permessage_deflate_config> permessage_deflate_type;
|
||||
|
||||
/// Autonegotiate permessage-deflate
|
||||
/**
|
||||
* Automatically enables the permessage-deflate extension.
|
||||
*
|
||||
* For clients this results in a permessage-deflate extension request being
|
||||
* sent with every request rather than requiring it to be requested manually
|
||||
*
|
||||
* For servers this results in accepting the first set of extension settings
|
||||
* requested by the client that we understand being used. The alternative is
|
||||
* requiring the extension to be manually negotiated in `validate`. With
|
||||
* auto-negotiate on, you may still override the auto-negotiate manually if
|
||||
* needed.
|
||||
*/
|
||||
//static const bool autonegotiate_compression = false;
|
||||
};
|
||||
|
||||
} // namespace config
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_CONFIG_MINIMAL_HPP
|
||||
+313
-93
@@ -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,19 +29,20 @@
|
||||
#define WEBSOCKETPP_CONNECTION_HPP
|
||||
|
||||
#include <websocketpp/close.hpp>
|
||||
#include <websocketpp/common/connection_hdl.hpp>
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
#include <websocketpp/error.hpp>
|
||||
#include <websocketpp/frame.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
#include <websocketpp/processors/processor.hpp>
|
||||
#include <websocketpp/transport/base/connection.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
|
||||
#include <websocketpp/common/connection_hdl.hpp>
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -118,7 +119,7 @@ typedef lib::function<void(connection_hdl,std::string)> pong_timeout_handler;
|
||||
/**
|
||||
* The validate handler is called after a WebSocket handshake has been received
|
||||
* and processed but before it has been accepted. This gives the application a
|
||||
* chance to impliment connection details specific policies for accepting
|
||||
* chance to implement connection details specific policies for accepting
|
||||
* connections and the ability to negotiate extensions and subprotocols.
|
||||
*
|
||||
* The validate handler return value indicates whether or not the connection
|
||||
@@ -213,6 +214,20 @@ namespace internal_state {
|
||||
PROCESS_CONNECTION = 7
|
||||
};
|
||||
} // namespace internal_state
|
||||
|
||||
|
||||
namespace http_state {
|
||||
// states to keep track of the progress of http connections
|
||||
|
||||
enum value {
|
||||
init = 0,
|
||||
deferred = 1,
|
||||
headers_written = 2,
|
||||
body_written = 3,
|
||||
closed = 4
|
||||
};
|
||||
} // namespace http_state
|
||||
|
||||
} // namespace session
|
||||
|
||||
/// Represents an individual WebSocket connection
|
||||
@@ -279,9 +294,9 @@ private:
|
||||
};
|
||||
public:
|
||||
|
||||
explicit connection(bool is_server, std::string const & ua, alog_type& alog,
|
||||
explicit connection(bool p_is_server, std::string const & ua, alog_type& alog,
|
||||
elog_type& elog, rng_type & rng)
|
||||
: transport_con_type(is_server,alog,elog)
|
||||
: transport_con_type(p_is_server, alog, elog)
|
||||
, m_handle_read_frame(lib::bind(
|
||||
&type::handle_read_frame,
|
||||
this,
|
||||
@@ -297,17 +312,21 @@ public:
|
||||
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
||||
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
||||
, m_pong_timeout_dur(config::timeout_pong)
|
||||
, m_max_message_size(config::max_message_size)
|
||||
, m_state(session::state::connecting)
|
||||
, m_internal_state(session::internal_state::USER_INIT)
|
||||
, m_msg_manager(new con_msg_manager_type())
|
||||
, m_send_buffer_size(0)
|
||||
, m_write_flag(false)
|
||||
, m_is_server(is_server)
|
||||
, m_read_flag(true)
|
||||
, m_is_server(p_is_server)
|
||||
, m_alog(alog)
|
||||
, m_elog(elog)
|
||||
, m_rng(rng)
|
||||
, m_local_close_code(close::status::abnormal_close)
|
||||
, m_remote_close_code(close::status::abnormal_close)
|
||||
, m_is_http(false)
|
||||
, m_http_state(session::http_state::init)
|
||||
, m_was_clean(false)
|
||||
{
|
||||
m_alog.write(log::alevel::devel,"connection constructor");
|
||||
@@ -455,9 +474,9 @@ public:
|
||||
m_message_handler = h;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Connection timeouts //
|
||||
/////////////////////////
|
||||
//////////////////////////////////////////
|
||||
// Connection timeouts and other limits //
|
||||
//////////////////////////////////////////
|
||||
|
||||
/// Set open handshake timeout
|
||||
/**
|
||||
@@ -528,6 +547,70 @@ public:
|
||||
m_pong_timeout_dur = dur;
|
||||
}
|
||||
|
||||
/// Get maximum message size
|
||||
/**
|
||||
* Get maximum message size. Maximum message size determines the point at
|
||||
* which the connection will fail with the message_too_big protocol error.
|
||||
*
|
||||
* The default is set by the endpoint that creates the connection.
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
size_t get_max_message_size() const {
|
||||
return m_max_message_size;
|
||||
}
|
||||
|
||||
/// Set maximum message size
|
||||
/**
|
||||
* Set maximum message size. Maximum message size determines the point at
|
||||
* which the connection will fail with the message_too_big protocol error.
|
||||
* This value may be changed during the connection.
|
||||
*
|
||||
* The default is set by the endpoint that creates the connection.
|
||||
*
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @param new_value The value to set as the maximum message size.
|
||||
*/
|
||||
void set_max_message_size(size_t new_value) {
|
||||
m_max_message_size = new_value;
|
||||
if (m_processor) {
|
||||
m_processor->set_max_message_size(new_value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get maximum HTTP message body size
|
||||
/**
|
||||
* Get maximum HTTP message body size. Maximum message body size determines
|
||||
* the point at which the connection will stop reading an HTTP request whose
|
||||
* body is too large.
|
||||
*
|
||||
* The default is set by the endpoint that creates the connection.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return The maximum HTTP message body size
|
||||
*/
|
||||
size_t get_max_http_body_size() const {
|
||||
return m_request.get_max_body_size();
|
||||
}
|
||||
|
||||
/// Set maximum HTTP message body size
|
||||
/**
|
||||
* Set maximum HTTP message body size. Maximum message body size determines
|
||||
* the point at which the connection will stop reading an HTTP request whose
|
||||
* body is too large.
|
||||
*
|
||||
* The default is set by the endpoint that creates the connection.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @param new_value The value to set as the maximum message size.
|
||||
*/
|
||||
void set_max_http_body_size(size_t new_value) {
|
||||
m_request.set_max_body_size(new_value);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// Uncategorized public methods //
|
||||
//////////////////////////////////
|
||||
@@ -545,7 +628,10 @@ public:
|
||||
*/
|
||||
size_t get_buffered_amount() const;
|
||||
|
||||
/// DEPRECATED: use get_buffered_amount instead
|
||||
/// Get the size of the outgoing write buffer (in payload bytes)
|
||||
/**
|
||||
* @deprecated use `get_buffered_amount` instead
|
||||
*/
|
||||
size_t buffered_amount() const {
|
||||
return get_buffered_amount();
|
||||
}
|
||||
@@ -615,9 +701,46 @@ public:
|
||||
* @return An error code
|
||||
*/
|
||||
lib::error_code interrupt();
|
||||
|
||||
|
||||
/// Transport inturrupt callback
|
||||
void handle_interrupt();
|
||||
|
||||
/// Pause reading of new data
|
||||
/**
|
||||
* Signals to the connection to halt reading of new data. While reading is paused,
|
||||
* the connection will stop reading from its associated socket. In turn this will
|
||||
* result in TCP based flow control kicking in and slowing data flow from the remote
|
||||
* endpoint.
|
||||
*
|
||||
* This is useful for applications that push new requests to a queue to be processed
|
||||
* by another thread and need a way to signal when their request queue is full without
|
||||
* blocking the network processing thread.
|
||||
*
|
||||
* Use `resume_reading()` to resume.
|
||||
*
|
||||
* If supported by the transport this is done asynchronously. As such reading may not
|
||||
* stop until the current read operation completes. Typically you can expect to
|
||||
* receive no more bytes after initiating a read pause than the size of the read
|
||||
* buffer.
|
||||
*
|
||||
* If reading is paused for this connection already nothing is changed.
|
||||
*/
|
||||
lib::error_code pause_reading();
|
||||
|
||||
/// Pause reading callback
|
||||
void handle_pause_reading();
|
||||
|
||||
/// Resume reading of new data
|
||||
/**
|
||||
* Signals to the connection to resume reading of new data after it was paused by
|
||||
* `pause_reading()`.
|
||||
*
|
||||
* If reading is not paused for this connection already nothing is changed.
|
||||
*/
|
||||
lib::error_code resume_reading();
|
||||
|
||||
/// Resume reading callback
|
||||
void handle_resume_reading();
|
||||
|
||||
/// Send a ping
|
||||
/**
|
||||
@@ -827,7 +950,18 @@ public:
|
||||
* @param key Name of the header to get
|
||||
* @return The value of the header
|
||||
*/
|
||||
std::string const & get_request_header(std::string const & key);
|
||||
std::string const & get_request_header(std::string const & key) const;
|
||||
|
||||
/// Retrieve a request body
|
||||
/**
|
||||
* Retrieve the value of the request body. This value is typically used with
|
||||
* PUT and POST requests to upload files or other data. Only HTTP
|
||||
* connections will ever have bodies. WebSocket connection's will always
|
||||
* have blank bodies.
|
||||
*
|
||||
* @return The value of the request body.
|
||||
*/
|
||||
std::string const & get_request_body() const;
|
||||
|
||||
/// Retrieve a response header
|
||||
/**
|
||||
@@ -836,8 +970,32 @@ public:
|
||||
* @param key Name of the header to get
|
||||
* @return The value of the header
|
||||
*/
|
||||
std::string const & get_response_header(std::string const & key);
|
||||
std::string const & get_response_header(std::string const & key) const;
|
||||
|
||||
/// Get response HTTP status code
|
||||
/**
|
||||
* Gets the response status code
|
||||
*
|
||||
* @since 0.7.0
|
||||
*
|
||||
* @return The response status code sent
|
||||
*/
|
||||
http::status_code::value get_response_code() const {
|
||||
return m_response.get_status_code();
|
||||
}
|
||||
|
||||
/// Get response HTTP status message
|
||||
/**
|
||||
* Gets the response status message
|
||||
*
|
||||
* @since 0.7.0
|
||||
*
|
||||
* @return The response status message sent
|
||||
*/
|
||||
std::string const & get_response_msg() const {
|
||||
return m_response.get_status_msg();
|
||||
}
|
||||
|
||||
/// Set response status code and message
|
||||
/**
|
||||
* Sets the response status code to `code` and looks up the corresponding
|
||||
@@ -944,6 +1102,71 @@ public:
|
||||
request_type const & get_request() const {
|
||||
return m_request;
|
||||
}
|
||||
|
||||
/// Get response object
|
||||
/**
|
||||
* Direct access to the HTTP response sent or received as a part of the
|
||||
* opening handshake. This can be used to call methods of the response
|
||||
* object that are not part of the standard request API that connection
|
||||
* wraps.
|
||||
*
|
||||
* Note use of this method involves using behavior specific to the
|
||||
* configured HTTP policy. Such behavior may not work with alternate HTTP
|
||||
* policies.
|
||||
*
|
||||
* @since 0.7.0
|
||||
*
|
||||
* @return A const reference to the raw response object
|
||||
*/
|
||||
response_type const & get_response() const {
|
||||
return m_response;
|
||||
}
|
||||
|
||||
/// Defer HTTP Response until later (Exception free)
|
||||
/**
|
||||
* Used in the http handler to defer the HTTP response for this connection
|
||||
* until later. Handshake timers will be canceled and the connection will be
|
||||
* left open until `send_http_response` or an equivalent is called.
|
||||
*
|
||||
* Warning: deferred connections won't time out and as a result can tie up
|
||||
* resources.
|
||||
*
|
||||
* @since 0.6.0
|
||||
*
|
||||
* @return A status code, zero on success, non-zero otherwise
|
||||
*/
|
||||
lib::error_code defer_http_response();
|
||||
|
||||
/// Send deferred HTTP Response (exception free)
|
||||
/**
|
||||
* Sends an http response to an HTTP connection that was deferred. This will
|
||||
* send a complete response including all headers, status line, and body
|
||||
* text. The connection will be closed afterwards.
|
||||
*
|
||||
* @since 0.6.0
|
||||
*
|
||||
* @param ec A status code, zero on success, non-zero otherwise
|
||||
*/
|
||||
void send_http_response(lib::error_code & ec);
|
||||
|
||||
/// Send deferred HTTP Response
|
||||
void send_http_response();
|
||||
|
||||
// TODO HTTPNBIO: write_headers
|
||||
// function that processes headers + status so far and writes it to the wire
|
||||
// beginning the HTTP response body state. This method will ignore anything
|
||||
// in the response body.
|
||||
|
||||
// TODO HTTPNBIO: write_body_message
|
||||
// queues the specified message_buffer for async writing
|
||||
|
||||
// TODO HTTPNBIO: finish connection
|
||||
//
|
||||
|
||||
// TODO HTTPNBIO: write_response
|
||||
// Writes the whole response, headers + body and closes the connection
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Pass-through access to the other connection information //
|
||||
@@ -1032,26 +1255,6 @@ public:
|
||||
return m_ec;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// The remaining public member functions are for internal/policy use //
|
||||
// only. Do not call from application code unless you understand what //
|
||||
// you are doing. //
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Set Connection Handle
|
||||
/**
|
||||
* The connection handle is a token that can be shared outside the
|
||||
* WebSocket++ core for the purposes of identifying a connection and
|
||||
* sending it messages.
|
||||
*
|
||||
* @param hdl A connection_hdl that the connection will use to refer
|
||||
* to itself.
|
||||
*/
|
||||
void set_handle(connection_hdl hdl) {
|
||||
m_connection_hdl = hdl;
|
||||
transport_con_type::set_handle(hdl);
|
||||
}
|
||||
|
||||
/// Get a message buffer
|
||||
/**
|
||||
* Warning: The API related to directly sending message buffers may change
|
||||
@@ -1077,7 +1280,13 @@ public:
|
||||
return m_msg_manager->get_message(op, size);
|
||||
}
|
||||
|
||||
void start();
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// The remaining public member functions are for internal/policy use //
|
||||
// only. Do not call from application code unless you understand what //
|
||||
// you are doing. //
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
void read_handshake(size_t num_bytes);
|
||||
|
||||
@@ -1086,17 +1295,18 @@ public:
|
||||
void handle_read_http_response(lib::error_code const & ec,
|
||||
size_t bytes_transferred);
|
||||
|
||||
void handle_send_http_response(lib::error_code const & ec);
|
||||
|
||||
void handle_write_http_response(lib::error_code const & ec);
|
||||
void handle_send_http_request(lib::error_code const & ec);
|
||||
|
||||
void handle_open_handshake_timeout(lib::error_code const & ec);
|
||||
void handle_close_handshake_timeout(lib::error_code const & ec);
|
||||
|
||||
void handle_read_frame(lib::error_code const & ec,
|
||||
size_t bytes_transferred);
|
||||
void handle_read_frame(lib::error_code const & ec, size_t bytes_transferred);
|
||||
void read_frame();
|
||||
|
||||
/// Get array of WebSocket protocol versions that this connection supports.
|
||||
const std::vector<int>& get_supported_versions() const;
|
||||
std::vector<int> const & get_supported_versions() const;
|
||||
|
||||
/// Sets the handler for a terminating connection. Should only be used
|
||||
/// internally by the endpoint class.
|
||||
@@ -1126,64 +1336,48 @@ public:
|
||||
* non-zero otherwise.
|
||||
*/
|
||||
void handle_write_frame(lib::error_code const & ec);
|
||||
// protected:
|
||||
// This set of methods would really like to be protected, but doing so
|
||||
// requires that the endpoint be able to friend the connection. This is
|
||||
// allowed with C++11, but not prior versions
|
||||
|
||||
/// Start the connection state machine
|
||||
void start();
|
||||
|
||||
/// Set Connection Handle
|
||||
/**
|
||||
* The connection handle is a token that can be shared outside the
|
||||
* WebSocket++ core for the purposes of identifying a connection and
|
||||
* sending it messages.
|
||||
*
|
||||
* @param hdl A connection_hdl that the connection will use to refer
|
||||
* to itself.
|
||||
*/
|
||||
void set_handle(connection_hdl hdl) {
|
||||
m_connection_hdl = hdl;
|
||||
transport_con_type::set_handle(hdl);
|
||||
}
|
||||
protected:
|
||||
void handle_transport_init(lib::error_code const & ec);
|
||||
|
||||
/// Set m_processor based on information in m_request. Set m_response
|
||||
/// status and return false on error.
|
||||
bool initialize_processor();
|
||||
/// status and return an error code indicating status.
|
||||
lib::error_code initialize_processor();
|
||||
|
||||
/// Perform WebSocket handshake validation of m_request using m_processor.
|
||||
/// set m_response and return false on error.
|
||||
bool process_handshake_request();
|
||||
|
||||
/// Atomically change the internal connection state.
|
||||
/**
|
||||
* @param req The required starting state. If the internal state does not
|
||||
* match req an exception is thrown.
|
||||
*
|
||||
* @param dest The state to change to.
|
||||
*
|
||||
* @param msg The message to include in the exception thrown
|
||||
*/
|
||||
void atomic_state_change(istate_type req, istate_type dest,
|
||||
std::string msg);
|
||||
|
||||
/// Atomically change the internal and external connection state.
|
||||
/**
|
||||
* @param ireq The required starting internal state. If the internal state
|
||||
* does not match ireq an exception is thrown.
|
||||
*
|
||||
* @param idest The internal state to change to.
|
||||
*
|
||||
* @param ereq The required starting external state. If the external state
|
||||
* does not match ereq an exception is thrown.
|
||||
*
|
||||
* @param edest The external state to change to.
|
||||
*
|
||||
* @param msg The message to include in the exception thrown
|
||||
*/
|
||||
void atomic_state_change(istate_type ireq, istate_type idest,
|
||||
session::state::value ereq, session::state::value edest,
|
||||
std::string msg);
|
||||
|
||||
/// Atomically read and compared the internal state.
|
||||
/**
|
||||
* @param req The state to test against. If the internal state does not
|
||||
* match req an exception is thrown.
|
||||
*
|
||||
* @param msg The message to include in the exception thrown
|
||||
*/
|
||||
void atomic_state_check(istate_type req, std::string msg);
|
||||
/// set m_response and return an error code indicating status.
|
||||
lib::error_code process_handshake_request();
|
||||
private:
|
||||
|
||||
|
||||
/// Completes m_response, serializes it, and sends it out on the wire.
|
||||
void send_http_response();
|
||||
void write_http_response(lib::error_code const & ec);
|
||||
|
||||
/// Sends an opening WebSocket connect request
|
||||
void send_http_request();
|
||||
|
||||
/// Alternate path for send_http_response in error conditions
|
||||
void send_http_response_error();
|
||||
/// Alternate path for write_http_response in error conditions
|
||||
void write_http_response_error(lib::error_code const & ec);
|
||||
|
||||
/// Process control message
|
||||
/**
|
||||
@@ -1203,7 +1397,7 @@ private:
|
||||
* @return A status code, zero on success, non-zero otherwise
|
||||
*/
|
||||
lib::error_code send_close_ack(close::status::value code =
|
||||
close::status::blank, std::string const & reason = "");
|
||||
close::status::blank, std::string const & reason = std::string());
|
||||
|
||||
/// Send close frame
|
||||
/**
|
||||
@@ -1221,7 +1415,7 @@ private:
|
||||
* @return A status code, zero on success, non-zero otherwise
|
||||
*/
|
||||
lib::error_code send_close_frame(close::status::value code =
|
||||
close::status::blank, std::string const & reason = "", bool ack = false,
|
||||
close::status::blank, std::string const & reason = std::string(), bool ack = false,
|
||||
bool terminal = false);
|
||||
|
||||
/// Get a pointer to a new WebSocket protocol processor for a given version
|
||||
@@ -1280,6 +1474,20 @@ private:
|
||||
* Includes: error code and message for why it was failed
|
||||
*/
|
||||
void log_fail_result();
|
||||
|
||||
/// Prints information about HTTP connections
|
||||
/**
|
||||
* Includes: TODO
|
||||
*/
|
||||
void log_http_result();
|
||||
|
||||
/// Prints information about an arbitrary error code on the specified channel
|
||||
template <typename error_type>
|
||||
void log_err(log::level l, char const * msg, error_type const & ec) {
|
||||
std::stringstream s;
|
||||
s << msg << " error: " << ec << " (" << ec.message() << ")";
|
||||
m_elog.write(l, s.str());
|
||||
}
|
||||
|
||||
// internal handler functions
|
||||
read_handler m_handle_read_frame;
|
||||
@@ -1307,6 +1515,7 @@ private:
|
||||
long m_open_handshake_timeout_dur;
|
||||
long m_close_handshake_timeout_dur;
|
||||
long m_pong_timeout_dur;
|
||||
size_t m_max_message_size;
|
||||
|
||||
/// External connection state
|
||||
/**
|
||||
@@ -1370,9 +1579,9 @@ private:
|
||||
*/
|
||||
std::vector<transport::buffer> m_send_buffer;
|
||||
|
||||
/// a pointer to hold on to the current message being written to keep it
|
||||
/// a list of pointers to hold on to the messages being written to keep them
|
||||
/// from going out of scope before the write is complete.
|
||||
message_ptr m_current_msg;
|
||||
std::vector<message_ptr> m_current_msgs;
|
||||
|
||||
/// True if there is currently an outstanding transport write
|
||||
/**
|
||||
@@ -1380,6 +1589,9 @@ private:
|
||||
*/
|
||||
bool m_write_flag;
|
||||
|
||||
/// True if this connection is presently reading new data
|
||||
bool m_read_flag;
|
||||
|
||||
// connection data
|
||||
request_type m_request;
|
||||
response_type m_response;
|
||||
@@ -1411,6 +1623,14 @@ private:
|
||||
|
||||
/// Detailed internal error code
|
||||
lib::error_code m_ec;
|
||||
|
||||
/// A flag that gets set once it is determined that the connection is an
|
||||
/// HTTP connection and not a WebSocket one.
|
||||
bool m_is_http;
|
||||
|
||||
/// A flag that gets set when the completion of an http connection is
|
||||
/// deferred until later.
|
||||
session::http_state::value m_http_state;
|
||||
|
||||
bool m_was_clean;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
+201
-15
@@ -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,11 +29,11 @@
|
||||
#define WEBSOCKETPP_ENDPOINT_HPP
|
||||
|
||||
#include <websocketpp/connection.hpp>
|
||||
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
#include <websocketpp/version.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
@@ -85,25 +85,78 @@ public:
|
||||
// TODO: organize these
|
||||
typedef typename connection_type::termination_handler termination_handler;
|
||||
|
||||
typedef lib::shared_ptr<connection_weak_ptr> hdl_type;
|
||||
// This would be ideal. Requires C++11 though
|
||||
//friend connection;
|
||||
|
||||
explicit endpoint(bool is_server)
|
||||
: m_alog(config::alog_level, &std::cout)
|
||||
, m_elog(config::elog_level, &std::cerr)
|
||||
explicit endpoint(bool p_is_server)
|
||||
: m_alog(config::alog_level, log::channel_type_hint::access)
|
||||
, m_elog(config::elog_level, log::channel_type_hint::error)
|
||||
, m_user_agent(::websocketpp::user_agent)
|
||||
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
||||
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
||||
, m_pong_timeout_dur(config::timeout_pong)
|
||||
, m_is_server(is_server)
|
||||
, m_max_message_size(config::max_message_size)
|
||||
, m_max_http_body_size(config::max_http_body_size)
|
||||
, m_is_server(p_is_server)
|
||||
{
|
||||
m_alog.set_channels(config::alog_level);
|
||||
m_elog.set_channels(config::elog_level);
|
||||
|
||||
m_alog.write(log::alevel::devel,"endpoint constructor");
|
||||
m_alog.write(log::alevel::devel, "endpoint constructor");
|
||||
|
||||
transport_type::init_logging(&m_alog,&m_elog);
|
||||
transport_type::init_logging(&m_alog, &m_elog);
|
||||
}
|
||||
|
||||
|
||||
/// Destructor
|
||||
~endpoint<connection,config>() {}
|
||||
|
||||
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
// no copy constructor because endpoints are not copyable
|
||||
endpoint(endpoint &) = delete;
|
||||
|
||||
// no copy assignment operator because endpoints are not copyable
|
||||
endpoint & operator=(endpoint const &) = delete;
|
||||
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
|
||||
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
/// Move constructor
|
||||
endpoint(endpoint && o)
|
||||
: config::transport_type(std::move(o))
|
||||
, config::endpoint_base(std::move(o))
|
||||
, m_alog(std::move(o.m_alog))
|
||||
, m_elog(std::move(o.m_elog))
|
||||
, m_user_agent(std::move(o.m_user_agent))
|
||||
, m_open_handler(std::move(o.m_open_handler))
|
||||
|
||||
, m_close_handler(std::move(o.m_close_handler))
|
||||
, m_fail_handler(std::move(o.m_fail_handler))
|
||||
, m_ping_handler(std::move(o.m_ping_handler))
|
||||
, m_pong_handler(std::move(o.m_pong_handler))
|
||||
, m_pong_timeout_handler(std::move(o.m_pong_timeout_handler))
|
||||
, m_interrupt_handler(std::move(o.m_interrupt_handler))
|
||||
, m_http_handler(std::move(o.m_http_handler))
|
||||
, m_validate_handler(std::move(o.m_validate_handler))
|
||||
, m_message_handler(std::move(o.m_message_handler))
|
||||
|
||||
, m_open_handshake_timeout_dur(o.m_open_handshake_timeout_dur)
|
||||
, m_close_handshake_timeout_dur(o.m_close_handshake_timeout_dur)
|
||||
, m_pong_timeout_dur(o.m_pong_timeout_dur)
|
||||
, m_max_message_size(o.m_max_message_size)
|
||||
, m_max_http_body_size(o.m_max_http_body_size)
|
||||
|
||||
, m_rng(std::move(o.m_rng))
|
||||
, m_is_server(o.m_is_server)
|
||||
{}
|
||||
|
||||
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
// no move assignment operator because of const member variables
|
||||
endpoint & operator=(endpoint &&) = delete;
|
||||
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
|
||||
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
|
||||
|
||||
/// Returns the user agent string that this endpoint will use
|
||||
/**
|
||||
* Returns the user agent string that this endpoint will use when creating
|
||||
@@ -272,9 +325,9 @@ public:
|
||||
m_message_handler = h;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Connection timeouts //
|
||||
/////////////////////////
|
||||
//////////////////////////////////////////
|
||||
// Connection timeouts and other limits //
|
||||
//////////////////////////////////////////
|
||||
|
||||
/// Set open handshake timeout
|
||||
/**
|
||||
@@ -348,6 +401,72 @@ public:
|
||||
m_pong_timeout_dur = dur;
|
||||
}
|
||||
|
||||
/// Get default maximum message size
|
||||
/**
|
||||
* Get the default maximum message size that will be used for new
|
||||
* connections created by this endpoint. The maximum message size determines
|
||||
* the point at which the connection will fail a connection with the
|
||||
* message_too_big protocol error.
|
||||
*
|
||||
* The default is set by the max_message_size value from the template config
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
size_t get_max_message_size() const {
|
||||
return m_max_message_size;
|
||||
}
|
||||
|
||||
/// Set default maximum message size
|
||||
/**
|
||||
* Set the default maximum message size that will be used for new
|
||||
* connections created by this endpoint. Maximum message size determines the
|
||||
* point at which the connection will fail a connection with the
|
||||
* message_too_big protocol error.
|
||||
*
|
||||
* The default is set by the max_message_size value from the template config
|
||||
*
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @param new_value The value to set as the maximum message size.
|
||||
*/
|
||||
void set_max_message_size(size_t new_value) {
|
||||
m_max_message_size = new_value;
|
||||
}
|
||||
|
||||
/// Get maximum HTTP message body size
|
||||
/**
|
||||
* Get maximum HTTP message body size. Maximum message body size determines
|
||||
* the point at which the connection will stop reading an HTTP request whose
|
||||
* body is too large.
|
||||
*
|
||||
* The default is set by the max_http_body_size value from the template
|
||||
* config
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return The maximum HTTP message body size
|
||||
*/
|
||||
size_t get_max_http_body_size() const {
|
||||
return m_max_http_body_size;
|
||||
}
|
||||
|
||||
/// Set maximum HTTP message body size
|
||||
/**
|
||||
* Set maximum HTTP message body size. Maximum message body size determines
|
||||
* the point at which the connection will stop reading an HTTP request whose
|
||||
* body is too large.
|
||||
*
|
||||
* The default is set by the max_http_body_size value from the template
|
||||
* config
|
||||
*
|
||||
* @since 0.5.1
|
||||
*
|
||||
* @param new_value The value to set as the maximum message size.
|
||||
*/
|
||||
void set_max_http_body_size(size_t new_value) {
|
||||
m_max_http_body_size = new_value;
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
/* Connection pass through functions */
|
||||
/*************************************/
|
||||
@@ -363,6 +482,72 @@ public:
|
||||
void interrupt(connection_hdl hdl, lib::error_code & ec);
|
||||
void interrupt(connection_hdl hdl);
|
||||
|
||||
/// Pause reading of new data (exception free)
|
||||
/**
|
||||
* Signals to the connection to halt reading of new data. While reading is
|
||||
* paused, the connection will stop reading from its associated socket. In
|
||||
* turn this will result in TCP based flow control kicking in and slowing
|
||||
* data flow from the remote endpoint.
|
||||
*
|
||||
* This is useful for applications that push new requests to a queue to be
|
||||
* processed by another thread and need a way to signal when their request
|
||||
* queue is full without blocking the network processing thread.
|
||||
*
|
||||
* Use `resume_reading()` to resume.
|
||||
*
|
||||
* If supported by the transport this is done asynchronously. As such
|
||||
* reading may not stop until the current read operation completes.
|
||||
* Typically you can expect to receive no more bytes after initiating a read
|
||||
* pause than the size of the read buffer.
|
||||
*
|
||||
* If reading is paused for this connection already nothing is changed.
|
||||
*/
|
||||
void pause_reading(connection_hdl hdl, lib::error_code & ec);
|
||||
|
||||
/// Pause reading of new data
|
||||
void pause_reading(connection_hdl hdl);
|
||||
|
||||
/// Resume reading of new data (exception free)
|
||||
/**
|
||||
* Signals to the connection to resume reading of new data after it was
|
||||
* paused by `pause_reading()`.
|
||||
*
|
||||
* If reading is not paused for this connection already nothing is changed.
|
||||
*/
|
||||
void resume_reading(connection_hdl hdl, lib::error_code & ec);
|
||||
|
||||
/// Resume reading of new data
|
||||
void resume_reading(connection_hdl hdl);
|
||||
|
||||
/// Send deferred HTTP Response
|
||||
/**
|
||||
* Sends an http response to an HTTP connection that was deferred. This will
|
||||
* send a complete response including all headers, status line, and body
|
||||
* text. The connection will be closed afterwards.
|
||||
*
|
||||
* Exception free variant
|
||||
*
|
||||
* @since 0.6.0
|
||||
*
|
||||
* @param hdl The connection to send the response on
|
||||
* @param ec A status code, zero on success, non-zero otherwise
|
||||
*/
|
||||
void send_http_response(connection_hdl hdl, lib::error_code & ec);
|
||||
|
||||
/// Send deferred HTTP Response (exception free)
|
||||
/**
|
||||
* Sends an http response to an HTTP connection that was deferred. This will
|
||||
* send a complete response including all headers, status line, and body
|
||||
* text. The connection will be closed afterwards.
|
||||
*
|
||||
* Exception variant
|
||||
*
|
||||
* @since 0.6.0
|
||||
*
|
||||
* @param hdl The connection to send the response on
|
||||
*/
|
||||
void send_http_response(connection_hdl hdl);
|
||||
|
||||
/// Create a message and add it to the outgoing send queue (exception free)
|
||||
/**
|
||||
* Convenience method to send a message given a payload string and an opcode
|
||||
@@ -456,7 +641,6 @@ public:
|
||||
* @return the connection_ptr. May be NULL if the handle was invalid.
|
||||
*/
|
||||
connection_ptr get_con_from_hdl(connection_hdl hdl, lib::error_code & ec) {
|
||||
scoped_lock_type lock(m_mutex);
|
||||
connection_ptr con = lib::static_pointer_cast<connection_type>(
|
||||
hdl.lock());
|
||||
if (!con) {
|
||||
@@ -470,7 +654,7 @@ public:
|
||||
lib::error_code ec;
|
||||
connection_ptr con = this->get_con_from_hdl(hdl,ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
throw exception(ec);
|
||||
}
|
||||
return con;
|
||||
}
|
||||
@@ -497,6 +681,8 @@ private:
|
||||
long m_open_handshake_timeout_dur;
|
||||
long m_close_handshake_timeout_dur;
|
||||
long m_pong_timeout_dur;
|
||||
size_t m_max_message_size;
|
||||
size_t m_max_http_body_size;
|
||||
|
||||
rng_type m_rng;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
+60
-10
@@ -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:
|
||||
@@ -28,7 +28,9 @@
|
||||
#ifndef WEBSOCKETPP_ERROR_HPP
|
||||
#define WEBSOCKETPP_ERROR_HPP
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
@@ -38,7 +40,7 @@ namespace websocketpp {
|
||||
/// Combination error code / string type for returning two values
|
||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||
|
||||
// setup for errors that should be propogated back to the user.
|
||||
/// Library level error codes
|
||||
namespace error {
|
||||
enum value {
|
||||
/// Catch-all library error
|
||||
@@ -86,7 +88,8 @@ enum value {
|
||||
/// Invalid subprotocol
|
||||
invalid_subprotocol,
|
||||
|
||||
/// Bad or unknown connection
|
||||
/// An operation was attempted on a connection that did not exist or was
|
||||
/// already deleted.
|
||||
bad_connection,
|
||||
|
||||
/// Unit testing utility error code
|
||||
@@ -114,7 +117,33 @@ enum value {
|
||||
close_handshake_timeout,
|
||||
|
||||
/// Invalid port in URI
|
||||
invalid_port
|
||||
invalid_port,
|
||||
|
||||
/// An async accept operation failed because the underlying transport has been
|
||||
/// requested to not listen for new connections anymore.
|
||||
async_accept_not_listening,
|
||||
|
||||
/// The requested operation was canceled
|
||||
operation_canceled,
|
||||
|
||||
/// Connection rejected
|
||||
rejected,
|
||||
|
||||
/// Upgrade Required. This happens if an HTTP request is made to a
|
||||
/// WebSocket++ server that doesn't implement an http handler
|
||||
upgrade_required,
|
||||
|
||||
/// Invalid WebSocket protocol version
|
||||
invalid_version,
|
||||
|
||||
/// Unsupported WebSocket protocol version
|
||||
unsupported_version,
|
||||
|
||||
/// HTTP parse error
|
||||
http_parse_error,
|
||||
|
||||
/// Extension negotiation failed
|
||||
extension_neg_failed
|
||||
}; // enum value
|
||||
|
||||
|
||||
@@ -176,6 +205,22 @@ public:
|
||||
return "The closing handshake timed out";
|
||||
case error::invalid_port:
|
||||
return "Invalid URI port";
|
||||
case error::async_accept_not_listening:
|
||||
return "Async Accept not listening";
|
||||
case error::operation_canceled:
|
||||
return "Operation canceled";
|
||||
case error::rejected:
|
||||
return "Connection rejected";
|
||||
case error::upgrade_required:
|
||||
return "Upgrade required";
|
||||
case error::invalid_version:
|
||||
return "Invalid version";
|
||||
case error::unsupported_version:
|
||||
return "Unsupported version";
|
||||
case error::http_parse_error:
|
||||
return "HTTP parse error";
|
||||
case error::extension_neg_failed:
|
||||
return "Extension negotiation failed";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -205,21 +250,26 @@ namespace websocketpp {
|
||||
|
||||
class exception : public std::exception {
|
||||
public:
|
||||
exception(std::string const & msg,
|
||||
error::value code = error::general)
|
||||
: m_msg(msg),m_code(code) {}
|
||||
exception(std::string const & msg, lib::error_code ec = make_error_code(error::general))
|
||||
: m_msg(msg.empty() ? ec.message() : msg), m_code(ec)
|
||||
{}
|
||||
|
||||
explicit exception(lib::error_code ec)
|
||||
: m_msg(ec.message()), m_code(ec)
|
||||
{}
|
||||
|
||||
~exception() throw() {}
|
||||
|
||||
virtual char const * what() const throw() {
|
||||
return m_msg.c_str();
|
||||
}
|
||||
|
||||
error::value code() const throw() {
|
||||
lib::error_code code() const throw() {
|
||||
return m_code;
|
||||
}
|
||||
|
||||
std::string m_msg;
|
||||
error::value m_code;
|
||||
const std::string m_msg;
|
||||
lib::error_code m_code;
|
||||
};
|
||||
|
||||
} // namespace websocketpp
|
||||
|
||||
@@ -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:
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline const lib::error_category& get_category() {
|
||||
inline lib::error_category const & get_category() {
|
||||
static category instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
+47
-10
@@ -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:
|
||||
@@ -53,10 +53,29 @@ class disabled {
|
||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||
|
||||
public:
|
||||
err_str_pair negotiate(http::attribute_list const & attributes) {
|
||||
/// Negotiate extension
|
||||
/**
|
||||
* The disabled extension always fails the negotiation with a disabled
|
||||
* error.
|
||||
*
|
||||
* @param offer Attribute from client's offer
|
||||
* @return Status code and value to return to remote endpoint
|
||||
*/
|
||||
err_str_pair negotiate(http::attribute_list const &) {
|
||||
return make_pair(make_error_code(error::disabled),std::string());
|
||||
}
|
||||
|
||||
/// Initialize state
|
||||
/**
|
||||
* For the disabled extension state initialization is a no-op.
|
||||
*
|
||||
* @param is_server True to initialize as a server, false for a client.
|
||||
* @return A code representing the error that occurred, if any
|
||||
*/
|
||||
lib::error_code init(bool) {
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
/// Returns true if the extension is capable of providing
|
||||
/// permessage_deflate functionality
|
||||
bool is_implemented() const {
|
||||
@@ -69,17 +88,35 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
lib::error_code compress(std::string const & in, std::string & out) {
|
||||
/// Generate extension offer
|
||||
/**
|
||||
* Creates an offer string to include in the Sec-WebSocket-Extensions
|
||||
* header of outgoing client requests.
|
||||
*
|
||||
* @return A WebSocket extension offer string for this extension
|
||||
*/
|
||||
std::string generate_offer() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Compress bytes
|
||||
/**
|
||||
* @param [in] in String to compress
|
||||
* @param [out] out String to append compressed bytes to
|
||||
* @return Error or status code
|
||||
*/
|
||||
lib::error_code compress(std::string const &, std::string &) {
|
||||
return make_error_code(error::disabled);
|
||||
}
|
||||
|
||||
lib::error_code decompress(uint8_t const * buf, size_t len,
|
||||
std::string & out)
|
||||
{
|
||||
return make_error_code(error::disabled);
|
||||
}
|
||||
|
||||
lib::error_code decompress(std::string const & in, std::string & out) {
|
||||
/// Decompress bytes
|
||||
/**
|
||||
* @param buf Byte buffer to decompress
|
||||
* @param len Length of buf
|
||||
* @param out String to append decompressed bytes to
|
||||
* @return Error or status code
|
||||
*/
|
||||
lib::error_code decompress(uint8_t const *, size_t, std::string &) {
|
||||
return make_error_code(error::disabled);
|
||||
}
|
||||
};
|
||||
|
||||
+136
-108
@@ -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:
|
||||
@@ -28,8 +28,10 @@
|
||||
#ifndef WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
||||
#define WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
||||
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/error.hpp>
|
||||
|
||||
@@ -44,10 +46,14 @@
|
||||
namespace websocketpp {
|
||||
namespace extensions {
|
||||
|
||||
/// Implimentation of the draft permessage-deflate WebSocket extension
|
||||
/// Implementation of the draft permessage-deflate WebSocket extension
|
||||
/**
|
||||
* ### permessage-deflate interface
|
||||
*
|
||||
* **init**\n
|
||||
* `lib::error_code init(bool is_server)`\n
|
||||
* Performs initialization
|
||||
*
|
||||
* **is_implimented**\n
|
||||
* `bool is_implimented()`\n
|
||||
* Returns whether or not the object impliments the extension or not
|
||||
@@ -134,7 +140,7 @@ public:
|
||||
case zlib_error:
|
||||
return "A zlib function returned an error";
|
||||
case uninitialized:
|
||||
return "Object must be initialized before use";
|
||||
return "Deflate extension must be initialized before use";
|
||||
default:
|
||||
return "Unknown permessage-compress error";
|
||||
}
|
||||
@@ -142,13 +148,13 @@ public:
|
||||
};
|
||||
|
||||
/// Get a reference to a static copy of the permessage-deflate error category
|
||||
lib::error_category const & get_category() {
|
||||
inline lib::error_category const & get_category() {
|
||||
static category instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// Create an error code in the permessage-deflate category
|
||||
lib::error_code make_error_code(error::value e) {
|
||||
inline lib::error_code make_error_code(error::value e) {
|
||||
return lib::error_code(static_cast<int>(e), get_category());
|
||||
}
|
||||
|
||||
@@ -168,19 +174,19 @@ namespace websocketpp {
|
||||
namespace extensions {
|
||||
namespace permessage_deflate {
|
||||
|
||||
/// Default value for s2c_max_window_bits as defined by RFC6455
|
||||
static uint8_t const default_s2c_max_window_bits = 15;
|
||||
/// Minimum value for s2c_max_window_bits as defined by RFC6455
|
||||
static uint8_t const min_s2c_max_window_bits = 8;
|
||||
/// Maximum value for s2c_max_window_bits as defined by RFC6455
|
||||
static uint8_t const max_s2c_max_window_bits = 15;
|
||||
/// Default value for server_max_window_bits as defined by draft 17
|
||||
static uint8_t const default_server_max_window_bits = 15;
|
||||
/// Minimum value for server_max_window_bits as defined by draft 17
|
||||
static uint8_t const min_server_max_window_bits = 8;
|
||||
/// Maximum value for server_max_window_bits as defined by draft 17
|
||||
static uint8_t const max_server_max_window_bits = 15;
|
||||
|
||||
/// Default value for c2s_max_window_bits as defined by RFC6455
|
||||
static uint8_t const default_c2s_max_window_bits = 15;
|
||||
/// Minimum value for c2s_max_window_bits as defined by RFC6455
|
||||
static uint8_t const min_c2s_max_window_bits = 8;
|
||||
/// Maximum value for c2s_max_window_bits as defined by RFC6455
|
||||
static uint8_t const max_c2s_max_window_bits = 15;
|
||||
/// Default value for client_max_window_bits as defined by draft 17
|
||||
static uint8_t const default_client_max_window_bits = 15;
|
||||
/// Minimum value for client_max_window_bits as defined by draft 17
|
||||
static uint8_t const min_client_max_window_bits = 8;
|
||||
/// Maximum value for client_max_window_bits as defined by draft 17
|
||||
static uint8_t const max_client_max_window_bits = 15;
|
||||
|
||||
namespace mode {
|
||||
enum value {
|
||||
@@ -200,12 +206,12 @@ class enabled {
|
||||
public:
|
||||
enabled()
|
||||
: m_enabled(false)
|
||||
, m_s2c_no_context_takeover(false)
|
||||
, m_c2s_no_context_takeover(false)
|
||||
, m_s2c_max_window_bits(15)
|
||||
, m_c2s_max_window_bits(15)
|
||||
, m_s2c_max_window_bits_mode(mode::accept)
|
||||
, m_c2s_max_window_bits_mode(mode::accept)
|
||||
, m_server_no_context_takeover(false)
|
||||
, m_client_no_context_takeover(false)
|
||||
, m_server_max_window_bits(15)
|
||||
, m_client_max_window_bits(15)
|
||||
, m_server_max_window_bits_mode(mode::accept)
|
||||
, m_client_max_window_bits_mode(mode::accept)
|
||||
, m_initialized(false)
|
||||
, m_compress_buffer_size(16384)
|
||||
{
|
||||
@@ -242,20 +248,25 @@ public:
|
||||
|
||||
/// Initialize zlib state
|
||||
/**
|
||||
* Note: this should be called *after* the negotiation methods. It will use
|
||||
* information from the negotiation to determine how to initialize the zlib
|
||||
* data structures.
|
||||
*
|
||||
* @todo memory level, strategy, etc are hardcoded
|
||||
* @todo server detection is hardcoded
|
||||
*
|
||||
* @param is_server True to initialize as a server, false for a client.
|
||||
* @return A code representing the error that occurred, if any
|
||||
*/
|
||||
lib::error_code init() {
|
||||
lib::error_code init(bool is_server) {
|
||||
uint8_t deflate_bits;
|
||||
uint8_t inflate_bits;
|
||||
|
||||
if (true /*is_server*/) {
|
||||
deflate_bits = m_s2c_max_window_bits;
|
||||
inflate_bits = m_c2s_max_window_bits;
|
||||
if (is_server) {
|
||||
deflate_bits = m_server_max_window_bits;
|
||||
inflate_bits = m_client_max_window_bits;
|
||||
} else {
|
||||
deflate_bits = m_c2s_max_window_bits;
|
||||
inflate_bits = m_s2c_max_window_bits;
|
||||
deflate_bits = m_client_max_window_bits;
|
||||
inflate_bits = m_server_max_window_bits;
|
||||
}
|
||||
|
||||
int ret = deflateInit2(
|
||||
@@ -263,8 +274,8 @@ public:
|
||||
Z_DEFAULT_COMPRESSION,
|
||||
Z_DEFLATED,
|
||||
-1*deflate_bits,
|
||||
8, // memory level 1-9
|
||||
/*Z_DEFAULT_STRATEGY*/Z_FIXED
|
||||
4, // memory level 1-9
|
||||
Z_DEFAULT_STRATEGY
|
||||
);
|
||||
|
||||
if (ret != Z_OK) {
|
||||
@@ -281,15 +292,22 @@ public:
|
||||
}
|
||||
|
||||
m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]);
|
||||
if ((m_server_no_context_takeover && is_server) ||
|
||||
(m_client_no_context_takeover && !is_server))
|
||||
{
|
||||
m_flush = Z_FULL_FLUSH;
|
||||
} else {
|
||||
m_flush = Z_SYNC_FLUSH;
|
||||
}
|
||||
m_initialized = true;
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
/// Test if this object impliments the permessage-deflate specification
|
||||
/// Test if this object implements the permessage-deflate specification
|
||||
/**
|
||||
* Because this object does impliment it, it will always return true.
|
||||
* Because this object does implieent it, it will always return true.
|
||||
*
|
||||
* @return Whether or not this object impliments permessage-deflate
|
||||
* @return Whether or not this object implements permessage-deflate
|
||||
*/
|
||||
bool is_implemented() const {
|
||||
return true;
|
||||
@@ -327,8 +345,8 @@ public:
|
||||
* the option will be in use so they can optimize resource usage if they
|
||||
* are able.
|
||||
*/
|
||||
void enable_s2c_no_context_takeover() {
|
||||
m_s2c_no_context_takeover = true;
|
||||
void enable_server_no_context_takeover() {
|
||||
m_server_no_context_takeover = true;
|
||||
}
|
||||
|
||||
/// Reset client's outgoing LZ77 sliding window for each new message
|
||||
@@ -346,8 +364,8 @@ public:
|
||||
* This option is supported by all compliant clients and servers. Enabling
|
||||
* it via either endpoint should be sufficient to ensure it is used.
|
||||
*/
|
||||
void enable_c2s_no_context_takeover() {
|
||||
m_c2s_no_context_takeover = true;
|
||||
void enable_client_no_context_takeover() {
|
||||
m_client_no_context_takeover = true;
|
||||
}
|
||||
|
||||
/// Limit server LZ77 sliding window size
|
||||
@@ -372,12 +390,12 @@ public:
|
||||
* @param mode The mode to use for negotiating this parameter
|
||||
* @return A status code
|
||||
*/
|
||||
lib::error_code set_s2c_max_window_bits(uint8_t bits, mode::value mode) {
|
||||
if (bits < min_s2c_max_window_bits || bits > max_s2c_max_window_bits) {
|
||||
lib::error_code set_server_max_window_bits(uint8_t bits, mode::value mode) {
|
||||
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
|
||||
return error::make_error_code(error::invalid_max_window_bits);
|
||||
}
|
||||
m_s2c_max_window_bits = bits;
|
||||
m_s2c_max_window_bits_mode = mode;
|
||||
m_server_max_window_bits = bits;
|
||||
m_server_max_window_bits_mode = mode;
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
@@ -403,12 +421,12 @@ public:
|
||||
* @param mode The mode to use for negotiating this parameter
|
||||
* @return A status code
|
||||
*/
|
||||
lib::error_code set_c2s_max_window_bits(uint8_t bits, mode::value mode) {
|
||||
if (bits < min_c2s_max_window_bits || bits > max_c2s_max_window_bits) {
|
||||
lib::error_code set_client_max_window_bits(uint8_t bits, mode::value mode) {
|
||||
if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
|
||||
return error::make_error_code(error::invalid_max_window_bits);
|
||||
}
|
||||
m_c2s_max_window_bits = bits;
|
||||
m_c2s_max_window_bits_mode = mode;
|
||||
m_client_max_window_bits = bits;
|
||||
m_client_max_window_bits_mode = mode;
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
@@ -421,7 +439,8 @@ public:
|
||||
* @return A WebSocket extension offer string for this extension
|
||||
*/
|
||||
std::string generate_offer() const {
|
||||
return "";
|
||||
// TODO: this should be dynamically generated based on user settings
|
||||
return "permessage-deflate; client_no_context_takeover; client_max_window_bits";
|
||||
}
|
||||
|
||||
/// Validate extension response
|
||||
@@ -432,8 +451,8 @@ public:
|
||||
* @param response The server response attribute list to validate
|
||||
* @return Validation error or 0 on success
|
||||
*/
|
||||
lib::error_code validate_offer(http::attribute_list const & response) {
|
||||
|
||||
lib::error_code validate_offer(http::attribute_list const &) {
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
/// Negotiate extension
|
||||
@@ -450,14 +469,14 @@ public:
|
||||
|
||||
http::attribute_list::const_iterator it;
|
||||
for (it = offer.begin(); it != offer.end(); ++it) {
|
||||
if (it->first == "s2c_no_context_takeover") {
|
||||
negotiate_s2c_no_context_takeover(it->second,ret.first);
|
||||
} else if (it->first == "c2s_no_context_takeover") {
|
||||
negotiate_c2s_no_context_takeover(it->second,ret.first);
|
||||
} else if (it->first == "s2c_max_window_bits") {
|
||||
negotiate_s2c_max_window_bits(it->second,ret.first);
|
||||
} else if (it->first == "c2s_max_window_bits") {
|
||||
negotiate_c2s_max_window_bits(it->second,ret.first);
|
||||
if (it->first == "server_no_context_takeover") {
|
||||
negotiate_server_no_context_takeover(it->second,ret.first);
|
||||
} else if (it->first == "client_no_context_takeover") {
|
||||
negotiate_client_no_context_takeover(it->second,ret.first);
|
||||
} else if (it->first == "server_max_window_bits") {
|
||||
negotiate_server_max_window_bits(it->second,ret.first);
|
||||
} else if (it->first == "client_max_window_bits") {
|
||||
negotiate_client_max_window_bits(it->second,ret.first);
|
||||
} else {
|
||||
ret.first = make_error_code(error::invalid_attributes);
|
||||
}
|
||||
@@ -477,6 +496,9 @@ public:
|
||||
|
||||
/// Compress bytes
|
||||
/**
|
||||
* @todo: avail_in/out is 32 bit, need to fix for cases of >32 bit frames
|
||||
* on 64 bit machines.
|
||||
*
|
||||
* @param [in] in String to compress
|
||||
* @param [out] out String to append compressed bytes to
|
||||
* @return Error or status code
|
||||
@@ -487,9 +509,14 @@ public:
|
||||
}
|
||||
|
||||
size_t output;
|
||||
int ret;
|
||||
|
||||
m_dstate.avail_out = m_compress_buffer_size;
|
||||
if (in.empty()) {
|
||||
uint8_t buf[6] = {0x02, 0x00, 0x00, 0x00, 0xff, 0xff};
|
||||
out.append((char *)(buf),6);
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
m_dstate.avail_in = in.size();
|
||||
m_dstate.next_in = (unsigned char *)(const_cast<char *>(in.data()));
|
||||
|
||||
do {
|
||||
@@ -497,7 +524,7 @@ public:
|
||||
m_dstate.avail_out = m_compress_buffer_size;
|
||||
m_dstate.next_out = m_compress_buffer.get();
|
||||
|
||||
ret = deflate(&m_dstate, Z_SYNC_FLUSH);
|
||||
deflate(&m_dstate, m_flush);
|
||||
|
||||
output = m_compress_buffer_size - m_dstate.avail_out;
|
||||
|
||||
@@ -552,35 +579,35 @@ private:
|
||||
std::string generate_response() {
|
||||
std::string ret = "permessage-deflate";
|
||||
|
||||
if (m_s2c_no_context_takeover) {
|
||||
ret += "; s2c_no_context_takeover";
|
||||
if (m_server_no_context_takeover) {
|
||||
ret += "; server_no_context_takeover";
|
||||
}
|
||||
|
||||
if (m_c2s_no_context_takeover) {
|
||||
ret += "; c2s_no_context_takeover";
|
||||
if (m_client_no_context_takeover) {
|
||||
ret += "; client_no_context_takeover";
|
||||
}
|
||||
|
||||
if (m_s2c_max_window_bits < default_s2c_max_window_bits) {
|
||||
if (m_server_max_window_bits < default_server_max_window_bits) {
|
||||
std::stringstream s;
|
||||
s << int(m_s2c_max_window_bits);
|
||||
ret += "; s2c_max_window_bits="+s.str();
|
||||
s << int(m_server_max_window_bits);
|
||||
ret += "; server_max_window_bits="+s.str();
|
||||
}
|
||||
|
||||
if (m_c2s_max_window_bits < default_c2s_max_window_bits) {
|
||||
if (m_client_max_window_bits < default_client_max_window_bits) {
|
||||
std::stringstream s;
|
||||
s << int(m_c2s_max_window_bits);
|
||||
ret += "; c2s_max_window_bits="+s.str();
|
||||
s << int(m_client_max_window_bits);
|
||||
ret += "; client_max_window_bits="+s.str();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Negotiate s2c_no_context_takeover attribute
|
||||
/// Negotiate server_no_context_takeover attribute
|
||||
/**
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
void negotiate_s2c_no_context_takeover(std::string const & value,
|
||||
void negotiate_server_no_context_takeover(std::string const & value,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
if (!value.empty()) {
|
||||
@@ -588,15 +615,15 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
m_s2c_no_context_takeover = true;
|
||||
m_server_no_context_takeover = true;
|
||||
}
|
||||
|
||||
/// Negotiate c2s_no_context_takeover attribute
|
||||
/// Negotiate client_no_context_takeover attribute
|
||||
/**
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
void negotiate_c2s_no_context_takeover(std::string const & value,
|
||||
void negotiate_client_no_context_takeover(std::string const & value,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
if (!value.empty()) {
|
||||
@@ -604,13 +631,13 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
m_c2s_no_context_takeover = true;
|
||||
m_client_no_context_takeover = true;
|
||||
}
|
||||
|
||||
/// Negotiate s2c_max_window_bits attribute
|
||||
/// Negotiate server_max_window_bits attribute
|
||||
/**
|
||||
* When this method starts, m_s2c_max_window_bits will contain the server's
|
||||
* preferred value and m_s2c_max_window_bits_mode will contain the mode the
|
||||
* When this method starts, m_server_max_window_bits will contain the server's
|
||||
* preferred value and m_server_max_window_bits_mode will contain the mode the
|
||||
* server wants to use to for negotiation. `value` contains the value the
|
||||
* client requested that we use.
|
||||
*
|
||||
@@ -623,39 +650,39 @@ private:
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
void negotiate_s2c_max_window_bits(std::string const & value,
|
||||
void negotiate_server_max_window_bits(std::string const & value,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
uint8_t bits = uint8_t(atoi(value.c_str()));
|
||||
|
||||
if (bits < min_s2c_max_window_bits || bits > max_s2c_max_window_bits) {
|
||||
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
|
||||
ec = make_error_code(error::invalid_attribute_value);
|
||||
m_s2c_max_window_bits = default_s2c_max_window_bits;
|
||||
m_server_max_window_bits = default_server_max_window_bits;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_s2c_max_window_bits_mode) {
|
||||
switch (m_server_max_window_bits_mode) {
|
||||
case mode::decline:
|
||||
m_s2c_max_window_bits = default_s2c_max_window_bits;
|
||||
m_server_max_window_bits = default_server_max_window_bits;
|
||||
break;
|
||||
case mode::accept:
|
||||
m_s2c_max_window_bits = bits;
|
||||
m_server_max_window_bits = bits;
|
||||
break;
|
||||
case mode::largest:
|
||||
m_s2c_max_window_bits = std::min(bits,m_s2c_max_window_bits);
|
||||
m_server_max_window_bits = std::min(bits,m_server_max_window_bits);
|
||||
break;
|
||||
case mode::smallest:
|
||||
m_s2c_max_window_bits = min_s2c_max_window_bits;
|
||||
m_server_max_window_bits = min_server_max_window_bits;
|
||||
break;
|
||||
default:
|
||||
ec = make_error_code(error::invalid_mode);
|
||||
m_s2c_max_window_bits = default_s2c_max_window_bits;
|
||||
m_server_max_window_bits = default_server_max_window_bits;
|
||||
}
|
||||
}
|
||||
|
||||
/// Negotiate c2s_max_window_bits attribute
|
||||
/// Negotiate client_max_window_bits attribute
|
||||
/**
|
||||
* When this method starts, m_c2s_max_window_bits and m_c2s_max_window_mode
|
||||
* When this method starts, m_client_max_window_bits and m_c2s_max_window_mode
|
||||
* will contain the server's preferred values for window size and
|
||||
* negotiation mode.
|
||||
*
|
||||
@@ -668,49 +695,50 @@ private:
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
void negotiate_c2s_max_window_bits(std::string const & value,
|
||||
void negotiate_client_max_window_bits(std::string const & value,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
uint8_t bits = uint8_t(atoi(value.c_str()));
|
||||
|
||||
if (value.empty()) {
|
||||
bits = default_c2s_max_window_bits;
|
||||
} else if (bits < min_c2s_max_window_bits ||
|
||||
bits > max_c2s_max_window_bits)
|
||||
bits = default_client_max_window_bits;
|
||||
} else if (bits < min_client_max_window_bits ||
|
||||
bits > max_client_max_window_bits)
|
||||
{
|
||||
ec = make_error_code(error::invalid_attribute_value);
|
||||
m_c2s_max_window_bits = default_c2s_max_window_bits;
|
||||
m_client_max_window_bits = default_client_max_window_bits;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_c2s_max_window_bits_mode) {
|
||||
switch (m_client_max_window_bits_mode) {
|
||||
case mode::decline:
|
||||
m_c2s_max_window_bits = default_c2s_max_window_bits;
|
||||
m_client_max_window_bits = default_client_max_window_bits;
|
||||
break;
|
||||
case mode::accept:
|
||||
m_c2s_max_window_bits = bits;
|
||||
m_client_max_window_bits = bits;
|
||||
break;
|
||||
case mode::largest:
|
||||
m_c2s_max_window_bits = std::min(bits,m_c2s_max_window_bits);
|
||||
m_client_max_window_bits = std::min(bits,m_client_max_window_bits);
|
||||
break;
|
||||
case mode::smallest:
|
||||
m_c2s_max_window_bits = min_c2s_max_window_bits;
|
||||
m_client_max_window_bits = min_client_max_window_bits;
|
||||
break;
|
||||
default:
|
||||
ec = make_error_code(error::invalid_mode);
|
||||
m_c2s_max_window_bits = default_c2s_max_window_bits;
|
||||
m_client_max_window_bits = default_client_max_window_bits;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_enabled;
|
||||
bool m_s2c_no_context_takeover;
|
||||
bool m_c2s_no_context_takeover;
|
||||
uint8_t m_s2c_max_window_bits;
|
||||
uint8_t m_c2s_max_window_bits;
|
||||
mode::value m_s2c_max_window_bits_mode;
|
||||
mode::value m_c2s_max_window_bits_mode;
|
||||
bool m_server_no_context_takeover;
|
||||
bool m_client_no_context_takeover;
|
||||
uint8_t m_server_max_window_bits;
|
||||
uint8_t m_client_max_window_bits;
|
||||
mode::value m_server_max_window_bits_mode;
|
||||
mode::value m_client_max_window_bits_mode;
|
||||
|
||||
bool m_initialized;
|
||||
int m_flush;
|
||||
size_t m_compress_buffer_size;
|
||||
lib::unique_ptr_uchar_array m_compress_buffer;
|
||||
z_stream m_dstate;
|
||||
|
||||
+4
-32
@@ -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,6 +29,7 @@
|
||||
#define WEBSOCKETPP_FRAME_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/common/network.hpp>
|
||||
@@ -266,7 +267,7 @@ private:
|
||||
}
|
||||
|
||||
uint64_converter temp64;
|
||||
temp64.i = lib::net::htonll(payload_size);
|
||||
temp64.i = lib::net::_htonll(payload_size);
|
||||
std::copy(temp64.c+payload_offset,temp64.c+8,bytes);
|
||||
|
||||
return 8-payload_offset;
|
||||
@@ -456,35 +457,6 @@ inline size_t get_header_len(basic_header const & h) {
|
||||
return size;
|
||||
}
|
||||
|
||||
/// Set the frame's size
|
||||
/**
|
||||
* @param [out] h The basic header to set.
|
||||
* @param [out] eh The extended header to set.
|
||||
* @param [in] The size to set.
|
||||
* @return What error occurred, if any.
|
||||
*/
|
||||
inline lib::error_code set_size(basic_header & h, extended_header & eh, uint64_t
|
||||
size)
|
||||
{
|
||||
// make sure value isn't too big
|
||||
uint8_t basic_value;
|
||||
|
||||
if (size <= limits::payload_size_basic) {
|
||||
basic_value = static_cast<uint8_t>(size);
|
||||
} else if (size <= limits::payload_size_extended) {
|
||||
basic_value = payload_size_code_16bit;
|
||||
} else if (size <= limits::payload_size_jumbo) {
|
||||
basic_value = payload_size_code_64bit;
|
||||
} else {
|
||||
// error
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
h.b1 = (basic_value & BHB1_PAYLOAD) | (h.b1 & BHB1_MASK);
|
||||
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
/// Calculate the offset location of the masking key within the extended header
|
||||
/**
|
||||
* Calculate the offset location of the masking key within the extended header
|
||||
@@ -583,7 +555,7 @@ inline uint16_t get_extended_size(const extended_header &e) {
|
||||
inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||
uint64_converter temp64;
|
||||
std::copy(e.bytes,e.bytes+8,temp64.c);
|
||||
return lib::net::ntohll(temp64.i);
|
||||
return lib::net::_ntohll(temp64.i);
|
||||
}
|
||||
|
||||
/// Extract the full payload size field from a WebSocket header
|
||||
|
||||
+11
-5
@@ -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:
|
||||
@@ -28,11 +28,14 @@
|
||||
#ifndef HTTP_CONSTANTS_HPP
|
||||
#define HTTP_CONSTANTS_HPP
|
||||
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace websocketpp {
|
||||
/// HTTP handling support
|
||||
namespace http {
|
||||
/// The type of an HTTP attribute list
|
||||
/**
|
||||
@@ -56,10 +59,13 @@ namespace http {
|
||||
static char const header_separator[] = ":";
|
||||
|
||||
/// Literal value of an empty header
|
||||
static std::string const empty_header = "";
|
||||
static std::string const empty_header;
|
||||
|
||||
/// Maximum size in bytes before rejecting an HTTP header as too big.
|
||||
size_t const max_header_size = 16000;
|
||||
|
||||
/// Default Maximum size in bytes for HTTP message bodies.
|
||||
size_t const max_body_size = 32000000;
|
||||
|
||||
/// Number of bytes to use for temporary istream read buffers
|
||||
size_t const istream_buffer = 512;
|
||||
@@ -255,7 +261,7 @@ namespace http {
|
||||
case internal_server_error:
|
||||
return "Internal Server Error";
|
||||
case not_implemented:
|
||||
return "Not Implimented";
|
||||
return "Not Implemented";
|
||||
case bad_gateway:
|
||||
return "Bad Gateway";
|
||||
case service_unavailable:
|
||||
@@ -278,8 +284,8 @@ namespace http {
|
||||
public:
|
||||
exception(const std::string& log_msg,
|
||||
status_code::value error_code,
|
||||
const std::string& error_msg = "",
|
||||
const std::string& body = "")
|
||||
const std::string& error_msg = std::string(),
|
||||
const std::string& body = std::string())
|
||||
: m_msg(log_msg)
|
||||
, m_error_msg(error_msg)
|
||||
, m_body(body)
|
||||
|
||||
+45
-20
@@ -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,6 +29,8 @@
|
||||
#define HTTP_PARSER_IMPL_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
@@ -69,7 +71,7 @@ inline void parser::append_header(std::string const & key, std::string const &
|
||||
throw exception("Invalid header name",status_code::bad_request);
|
||||
}
|
||||
|
||||
if (this->get_header(key) == "") {
|
||||
if (this->get_header(key).empty()) {
|
||||
m_headers[key] = val;
|
||||
} else {
|
||||
m_headers[key] += ", " + val;
|
||||
@@ -89,10 +91,13 @@ inline void parser::remove_header(std::string const & key) {
|
||||
inline void parser::set_body(std::string const & value) {
|
||||
if (value.size() == 0) {
|
||||
remove_header("Content-Length");
|
||||
m_body = "";
|
||||
m_body.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: should this method respect the max size? If so how should errors
|
||||
// be indicated?
|
||||
|
||||
std::stringstream len;
|
||||
len << value.size();
|
||||
replace_header("Content-Length", len.str());
|
||||
@@ -111,26 +116,46 @@ inline bool parser::parse_parameter_list(std::string const & in,
|
||||
return (it == in.begin());
|
||||
}
|
||||
|
||||
inline bool parser::parse_headers(std::istream & s) {
|
||||
std::string header;
|
||||
std::string::size_type end;
|
||||
|
||||
// get headers
|
||||
while (std::getline(s, header) && header != "\r") {
|
||||
if (header[header.size()-1] != '\r') {
|
||||
continue; // ignore malformed header lines?
|
||||
} else {
|
||||
header.erase(header.end()-1);
|
||||
}
|
||||
|
||||
end = header.find(header_separator,0);
|
||||
|
||||
if (end != std::string::npos) {
|
||||
append_header(header.substr(0,end),header.substr(end+2));
|
||||
inline bool parser::prepare_body() {
|
||||
if (!get_header("Content-Length").empty()) {
|
||||
std::string const & cl_header = get_header("Content-Length");
|
||||
char * end;
|
||||
|
||||
// TODO: not 100% sure what the compatibility of this method is. Also,
|
||||
// I believe this will only work up to 32bit sizes. Is there a need for
|
||||
// > 4GiB HTTP payloads?
|
||||
m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10);
|
||||
|
||||
if (m_body_bytes_needed > m_body_bytes_max) {
|
||||
throw exception("HTTP message body too large",
|
||||
status_code::request_entity_too_large);
|
||||
}
|
||||
|
||||
m_body_encoding = body_encoding::plain;
|
||||
return true;
|
||||
} else if (get_header("Transfer-Encoding") == "chunked") {
|
||||
// TODO
|
||||
//m_body_encoding = body_encoding::chunked;
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
inline size_t parser::process_body(char const * buf, size_t len) {
|
||||
if (m_body_encoding == body_encoding::plain) {
|
||||
size_t processed = (std::min)(m_body_bytes_needed,len);
|
||||
m_body.append(buf,processed);
|
||||
m_body_bytes_needed -= processed;
|
||||
return processed;
|
||||
} else if (m_body_encoding == body_encoding::chunked) {
|
||||
// TODO:
|
||||
throw exception("Unexpected body encoding",
|
||||
status_code::internal_server_error);
|
||||
} else {
|
||||
throw exception("Unexpected body encoding",
|
||||
status_code::internal_server_error);
|
||||
}
|
||||
}
|
||||
|
||||
inline void parser::process_header(std::string::iterator begin,
|
||||
|
||||
+57
-57
@@ -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:
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
@@ -37,40 +38,17 @@ namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
inline bool request::parse_complete(std::istream& s) {
|
||||
std::string request;
|
||||
|
||||
// get status line
|
||||
std::getline(s, request);
|
||||
|
||||
if (request[request.size()-1] == '\r') {
|
||||
request.erase(request.end()-1);
|
||||
|
||||
std::stringstream ss(request);
|
||||
std::string val;
|
||||
|
||||
ss >> val;
|
||||
set_method(val);
|
||||
|
||||
ss >> val;
|
||||
set_uri(val);
|
||||
|
||||
ss >> val;
|
||||
set_version(val);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parse_headers(s);
|
||||
}
|
||||
|
||||
inline size_t request::consume(const char *buf, size_t len) {
|
||||
inline size_t request::consume(char const * buf, size_t len) {
|
||||
size_t bytes_processed;
|
||||
|
||||
if (m_ready) {return 0;}
|
||||
|
||||
if (m_buf->size() + len > max_header_size) {
|
||||
// exceeded max header size
|
||||
throw exception("Maximum header size exceeded.",
|
||||
status_code::request_header_fields_too_large);
|
||||
|
||||
if (m_body_bytes_needed > 0) {
|
||||
bytes_processed = process_body(buf,len);
|
||||
if (body_ready()) {
|
||||
m_ready = true;
|
||||
}
|
||||
return bytes_processed;
|
||||
}
|
||||
|
||||
// copy new header bytes into buffer
|
||||
@@ -88,15 +66,21 @@ inline size_t request::consume(const char *buf, size_t len) {
|
||||
header_delimiter,
|
||||
header_delimiter+sizeof(header_delimiter)-1
|
||||
);
|
||||
|
||||
//std::cout << "mark5: " << end-begin << std::endl;
|
||||
//std::cout << "mark6: " << sizeof(header_delimiter) << std::endl;
|
||||
|
||||
m_header_bytes += (end-begin+sizeof(header_delimiter));
|
||||
|
||||
if (m_header_bytes > max_header_size) {
|
||||
// exceeded max header size
|
||||
throw exception("Maximum header size exceeded.",
|
||||
status_code::request_header_fields_too_large);
|
||||
}
|
||||
|
||||
if (end == m_buf->end()) {
|
||||
// we are out of bytes. Discard the processed bytes and copy the
|
||||
// remaining unprecessed bytes to the beginning of the buffer
|
||||
std::copy(begin,end,m_buf->begin());
|
||||
m_buf->resize(static_cast<std::string::size_type>(end-begin));
|
||||
m_header_bytes -= m_buf->size();
|
||||
|
||||
return len;
|
||||
}
|
||||
@@ -104,12 +88,11 @@ inline size_t request::consume(const char *buf, size_t len) {
|
||||
//the range [begin,end) now represents a line to be processed.
|
||||
if (end-begin == 0) {
|
||||
// we got a blank line
|
||||
if (m_method.empty() || get_header("Host") == "") {
|
||||
if (m_method.empty() || get_header("Host").empty()) {
|
||||
throw exception("Incomplete Request",status_code::bad_request);
|
||||
}
|
||||
m_ready = true;
|
||||
|
||||
size_t bytes_processed = (
|
||||
bytes_processed = (
|
||||
len - static_cast<std::string::size_type>(m_buf->end()-end)
|
||||
+ sizeof(header_delimiter) - 1
|
||||
);
|
||||
@@ -117,8 +100,22 @@ inline size_t request::consume(const char *buf, size_t len) {
|
||||
// frees memory used temporarily during request parsing
|
||||
m_buf.reset();
|
||||
|
||||
// return number of bytes processed (starting bytes - bytes left)
|
||||
return bytes_processed;
|
||||
// if this was not an upgrade request and has a content length
|
||||
// continue capturing content-length bytes and expose them as a
|
||||
// request body.
|
||||
|
||||
if (prepare_body()) {
|
||||
bytes_processed += process_body(buf+bytes_processed,len-bytes_processed);
|
||||
if (body_ready()) {
|
||||
m_ready = true;
|
||||
}
|
||||
return bytes_processed;
|
||||
} else {
|
||||
m_ready = true;
|
||||
|
||||
// return number of bytes processed (starting bytes - bytes left)
|
||||
return bytes_processed;
|
||||
}
|
||||
} else {
|
||||
if (m_method.empty()) {
|
||||
this->process(begin,end);
|
||||
@@ -127,21 +124,31 @@ inline size_t request::consume(const char *buf, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
begin = end+sizeof(header_delimiter)-1;
|
||||
begin = end+(sizeof(header_delimiter)-1);
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string request::raw() {
|
||||
inline std::string request::raw() const {
|
||||
// TODO: validation. Make sure all required fields have been set?
|
||||
std::stringstream raw;
|
||||
std::stringstream ret;
|
||||
|
||||
raw << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
||||
raw << raw_headers() << "\r\n" << m_body;
|
||||
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
||||
ret << raw_headers() << "\r\n" << m_body;
|
||||
|
||||
return raw.str();
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
inline void request::set_method(const std::string& method) {
|
||||
inline std::string request::raw_head() const {
|
||||
// TODO: validation. Make sure all required fields have been set?
|
||||
std::stringstream ret;
|
||||
|
||||
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
||||
ret << raw_headers() << "\r\n";
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
inline void request::set_method(std::string const & method) {
|
||||
if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) {
|
||||
throw exception("Invalid method token.",status_code::bad_request);
|
||||
}
|
||||
@@ -149,14 +156,7 @@ inline void request::set_method(const std::string& method) {
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
/// Set HTTP body
|
||||
/**
|
||||
* Sets the body of the HTTP object and fills in the appropriate content length
|
||||
* header
|
||||
*
|
||||
* @param value The value to set the body to.
|
||||
*/
|
||||
inline void request::set_uri(const std::string& uri) {
|
||||
inline void request::set_uri(std::string const & uri) {
|
||||
// TODO: validation?
|
||||
m_uri = uri;
|
||||
}
|
||||
|
||||
+22
-45
@@ -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,9 @@
|
||||
#define HTTP_PARSER_RESPONSE_IMPL_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
@@ -37,19 +39,13 @@ namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
inline size_t response::consume(const char *buf, size_t len) {
|
||||
inline size_t response::consume(char const * buf, size_t len) {
|
||||
if (m_state == DONE) {return 0;}
|
||||
|
||||
if (m_state == BODY) {
|
||||
return this->process_body(buf,len);
|
||||
}
|
||||
|
||||
if (m_read + len > max_header_size) {
|
||||
// exceeded max header size
|
||||
throw exception("Maximum header size exceeded.",
|
||||
status_code::request_header_fields_too_large);
|
||||
}
|
||||
|
||||
// copy new header bytes into buffer
|
||||
m_buf->append(buf,len);
|
||||
|
||||
@@ -67,13 +63,22 @@ inline size_t response::consume(const char *buf, size_t len) {
|
||||
header_delimiter + sizeof(header_delimiter) - 1
|
||||
);
|
||||
|
||||
m_header_bytes += (end-begin+sizeof(header_delimiter));
|
||||
|
||||
if (m_header_bytes > max_header_size) {
|
||||
// exceeded max header size
|
||||
throw exception("Maximum header size exceeded.",
|
||||
status_code::request_header_fields_too_large);
|
||||
}
|
||||
|
||||
if (end == m_buf->end()) {
|
||||
// we are out of bytes. Discard the processed bytes and copy the
|
||||
// remaining unprecessed bytes to the beginning of the buffer
|
||||
std::copy(begin,end,m_buf->begin());
|
||||
m_buf->resize(static_cast<std::string::size_type>(end-begin));
|
||||
|
||||
m_read +=len;
|
||||
m_read += len;
|
||||
m_header_bytes -= m_buf->size();
|
||||
|
||||
return len;
|
||||
}
|
||||
@@ -89,7 +94,7 @@ inline size_t response::consume(const char *buf, size_t len) {
|
||||
// TODO: grab content-length
|
||||
std::string length = get_header("Content-Length");
|
||||
|
||||
if (length == "") {
|
||||
if (length.empty()) {
|
||||
// no content length found, read indefinitely
|
||||
m_read = 0;
|
||||
} else {
|
||||
@@ -170,45 +175,17 @@ inline size_t response::consume(std::istream & s) {
|
||||
return total;
|
||||
}
|
||||
|
||||
inline bool response::parse_complete(std::istream& s) {
|
||||
// parse a complete header (ie \r\n\r\n MUST be in the input stream)
|
||||
std::string response;
|
||||
|
||||
// get status line
|
||||
std::getline(s, response);
|
||||
|
||||
if (response[response.size()-1] == '\r') {
|
||||
response.erase(response.end()-1);
|
||||
|
||||
std::stringstream ss(response);
|
||||
std::string str_val;
|
||||
int int_val;
|
||||
char char_val[256];
|
||||
|
||||
ss >> str_val;
|
||||
set_version(str_val);
|
||||
|
||||
ss >> int_val;
|
||||
ss.getline(char_val,256);
|
||||
set_status(status_code::value(int_val),std::string(char_val));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parse_headers(s);
|
||||
}
|
||||
|
||||
inline std::string response::raw() const {
|
||||
// TODO: validation. Make sure all required fields have been set?
|
||||
|
||||
std::stringstream raw;
|
||||
std::stringstream ret;
|
||||
|
||||
raw << get_version() << " " << m_status_code << " " << m_status_msg;
|
||||
raw << "\r\n" << raw_headers() << "\r\n";
|
||||
ret << get_version() << " " << m_status_code << " " << m_status_msg;
|
||||
ret << "\r\n" << raw_headers() << "\r\n";
|
||||
|
||||
raw << m_body;
|
||||
ret << m_body;
|
||||
|
||||
return raw.str();
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
inline void response::set_status(status_code::value code) {
|
||||
@@ -217,7 +194,7 @@ inline void response::set_status(status_code::value code) {
|
||||
m_status_msg = get_string(code);
|
||||
}
|
||||
|
||||
inline void response::set_status(status_code::value code, const std::string&
|
||||
inline void response::set_status(status_code::value code, std::string const &
|
||||
msg)
|
||||
{
|
||||
// TODO: validation?
|
||||
@@ -255,7 +232,7 @@ inline void response::process(std::string::iterator begin,
|
||||
set_status(status_code::value(code),std::string(cursor_end+1,end));
|
||||
}
|
||||
|
||||
inline size_t response::process_body(const char *buf, size_t len) {
|
||||
inline size_t response::process_body(char const * buf, size_t len) {
|
||||
// If no content length was set then we read forever and never set m_ready
|
||||
if (m_read == 0) {
|
||||
//m_body.append(buf,len);
|
||||
|
||||
+105
-21
@@ -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,8 +29,9 @@
|
||||
#define HTTP_PARSER_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <websocketpp/utilities.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
@@ -48,6 +49,14 @@ namespace state {
|
||||
};
|
||||
}
|
||||
|
||||
namespace body_encoding {
|
||||
enum value {
|
||||
unknown,
|
||||
plain,
|
||||
chunked
|
||||
};
|
||||
}
|
||||
|
||||
typedef std::map<std::string, std::string, utility::ci_less > header_list;
|
||||
|
||||
/// Read and return the next token in the stream
|
||||
@@ -221,7 +230,7 @@ InputIterator extract_attributes(InputIterator begin, InputIterator end,
|
||||
cursor = http::parser::extract_all_lws(cursor,end);
|
||||
ret = http::parser::extract_token(cursor,end);
|
||||
|
||||
if (ret.first == "") {
|
||||
if (ret.first.empty()) {
|
||||
// error: expected a token
|
||||
return begin;
|
||||
} else {
|
||||
@@ -233,7 +242,7 @@ InputIterator extract_attributes(InputIterator begin, InputIterator end,
|
||||
if (cursor == end || *cursor != '=') {
|
||||
// if there is an equals sign, read the attribute value. Otherwise
|
||||
// record a blank value and continue
|
||||
attributes[name] = "";
|
||||
attributes[name].clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -254,7 +263,7 @@ InputIterator extract_attributes(InputIterator begin, InputIterator end,
|
||||
}
|
||||
|
||||
ret = http::parser::extract_token(cursor,end);
|
||||
if (ret.first == "") {
|
||||
if (ret.first.empty()) {
|
||||
// error : expected token or quoted string
|
||||
return begin;
|
||||
} else {
|
||||
@@ -312,7 +321,7 @@ InputIterator extract_parameters(InputIterator begin, InputIterator end,
|
||||
|
||||
ret = http::parser::extract_token(cursor,end);
|
||||
|
||||
if (ret.first == "") {
|
||||
if (ret.first.empty()) {
|
||||
// error: expected a token
|
||||
return begin;
|
||||
} else {
|
||||
@@ -369,9 +378,16 @@ InputIterator extract_parameters(InputIterator begin, InputIterator end,
|
||||
|
||||
inline std::string strip_lws(std::string const & input) {
|
||||
std::string::const_iterator begin = extract_all_lws(input.begin(),input.end());
|
||||
std::string::const_reverse_iterator end = extract_all_lws(input.rbegin(),input.rend());
|
||||
if (begin == input.end()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return std::string(begin,end.base());
|
||||
std::string::const_reverse_iterator rbegin = extract_all_lws(input.rbegin(),input.rend());
|
||||
if (rbegin == input.rend()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return std::string(begin,rbegin.base());
|
||||
}
|
||||
|
||||
/// Base HTTP parser
|
||||
@@ -381,6 +397,12 @@ inline std::string strip_lws(std::string const & input) {
|
||||
*/
|
||||
class parser {
|
||||
public:
|
||||
parser()
|
||||
: m_header_bytes(0)
|
||||
, m_body_bytes_needed(0)
|
||||
, m_body_bytes_max(max_body_size)
|
||||
, m_body_encoding(body_encoding::unknown) {}
|
||||
|
||||
/// Get the HTTP version string
|
||||
/**
|
||||
* @return The version string for this parser
|
||||
@@ -464,12 +486,11 @@ public:
|
||||
*/
|
||||
void remove_header(std::string const & key);
|
||||
|
||||
/// Set HTTP body
|
||||
/// Get HTTP body
|
||||
/**
|
||||
* Sets the body of the HTTP object and fills in the appropriate content
|
||||
* length header.
|
||||
* Gets the body of the HTTP object
|
||||
*
|
||||
* @param [in] value The value to set the body to.
|
||||
* @return The body of the HTTP message.
|
||||
*/
|
||||
std::string const & get_body() const {
|
||||
return m_body;
|
||||
@@ -486,6 +507,32 @@ public:
|
||||
*/
|
||||
void set_body(std::string const & value);
|
||||
|
||||
/// Get body size limit
|
||||
/**
|
||||
* Retrieves the maximum number of bytes to parse & buffer before canceling
|
||||
* a request.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return The maximum length of a message body.
|
||||
*/
|
||||
size_t get_max_body_size() const {
|
||||
return m_body_bytes_max;
|
||||
}
|
||||
|
||||
/// Set body size limit
|
||||
/**
|
||||
* Set the maximum number of bytes to parse and buffer before canceling a
|
||||
* request.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @param value The size to set the max body length to.
|
||||
*/
|
||||
void set_max_body_size(size_t value) {
|
||||
m_body_bytes_max = value;
|
||||
}
|
||||
|
||||
/// Extract an HTTP parameter list from a string.
|
||||
/**
|
||||
* @param [in] in The input string.
|
||||
@@ -495,14 +542,6 @@ public:
|
||||
bool parse_parameter_list(std::string const & in, parameter_list & out)
|
||||
const;
|
||||
protected:
|
||||
/// Parse headers from an istream
|
||||
/**
|
||||
* @deprecated Use process_header instead.
|
||||
*
|
||||
* @param [in] s The istream to extract headers from.
|
||||
*/
|
||||
bool parse_headers(std::istream & s);
|
||||
|
||||
/// Process a header line
|
||||
/**
|
||||
* @todo Update this method to be exception free.
|
||||
@@ -512,6 +551,45 @@ protected:
|
||||
*/
|
||||
void process_header(std::string::iterator begin, std::string::iterator end);
|
||||
|
||||
/// Prepare the parser to begin parsing body data
|
||||
/**
|
||||
* Inspects headers to determine if the message has a body that needs to be
|
||||
* read. If so, sets up the necessary state, otherwise returns false. If
|
||||
* this method returns true and loading the message body is desired call
|
||||
* `process_body` until it returns zero bytes or an error.
|
||||
*
|
||||
* Must not be called until after all headers have been processed.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return True if more bytes are needed to load the body, false otherwise.
|
||||
*/
|
||||
bool prepare_body();
|
||||
|
||||
/// Process body data
|
||||
/**
|
||||
* Parses body data.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @param [in] begin An iterator to the beginning of the sequence.
|
||||
* @param [in] end An iterator to the end of the sequence.
|
||||
* @return The number of bytes processed
|
||||
*/
|
||||
size_t process_body(char const * buf, size_t len);
|
||||
|
||||
/// Check if the parser is done parsing the body
|
||||
/**
|
||||
* Behavior before a call to `prepare_body` is undefined.
|
||||
*
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @return True if the message body has been completed loaded.
|
||||
*/
|
||||
bool body_ready() const {
|
||||
return (m_body_bytes_needed == 0);
|
||||
}
|
||||
|
||||
/// Generate and return the HTTP headers as a string
|
||||
/**
|
||||
* Each headers will be followed by the \r\n sequence including the last one.
|
||||
@@ -523,7 +601,13 @@ protected:
|
||||
|
||||
std::string m_version;
|
||||
header_list m_headers;
|
||||
std::string m_body;
|
||||
|
||||
size_t m_header_bytes;
|
||||
|
||||
std::string m_body;
|
||||
size_t m_body_bytes_needed;
|
||||
size_t m_body_bytes_max;
|
||||
body_encoding::value m_body_encoding;
|
||||
};
|
||||
|
||||
} // namespace parser
|
||||
|
||||
+14
-12
@@ -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:
|
||||
@@ -28,6 +28,8 @@
|
||||
#ifndef HTTP_PARSER_REQUEST_HPP
|
||||
#define HTTP_PARSER_REQUEST_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
@@ -51,12 +53,9 @@ public:
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
|
||||
request()
|
||||
: m_buf(new std::string())
|
||||
: m_buf(lib::make_shared<std::string>())
|
||||
, m_ready(false) {}
|
||||
|
||||
/// DEPRECATED parse a complete header (\r\n\r\n MUST be in the istream)
|
||||
bool parse_complete(std::istream& s);
|
||||
|
||||
/// Process bytes in the input buffer
|
||||
/**
|
||||
* Process up to len bytes from input buffer buf. Returns the number of
|
||||
@@ -77,29 +76,32 @@ public:
|
||||
* @param len Size of byte buffer
|
||||
* @return Number of bytes processed.
|
||||
*/
|
||||
size_t consume(const char *buf, size_t len);
|
||||
size_t consume(char const * buf, size_t len);
|
||||
|
||||
/// Returns whether or not the request is ready for reading.
|
||||
bool ready() const {
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
/// Returns the full raw request
|
||||
std::string raw();
|
||||
/// Returns the full raw request (including the body)
|
||||
std::string raw() const;
|
||||
|
||||
/// Returns the raw request headers only (similar to an HTTP HEAD request)
|
||||
std::string raw_head() const;
|
||||
|
||||
/// Set the HTTP method. Must be a valid HTTP token
|
||||
void set_method(const std::string& method);
|
||||
void set_method(std::string const & method);
|
||||
|
||||
/// Return the request method
|
||||
const std::string& get_method() const {
|
||||
std::string const & get_method() const {
|
||||
return m_method;
|
||||
}
|
||||
|
||||
/// Set the HTTP uri. Must be a valid HTTP uri
|
||||
void set_uri(const std::string& uri);
|
||||
void set_uri(std::string const & uri);
|
||||
|
||||
/// Return the requested URI
|
||||
const std::string& get_uri() const {
|
||||
std::string const & get_uri() const {
|
||||
return m_uri;
|
||||
}
|
||||
|
||||
|
||||
+28
-8
@@ -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:
|
||||
@@ -28,6 +28,9 @@
|
||||
#ifndef HTTP_PARSER_RESPONSE_HPP
|
||||
#define HTTP_PARSER_RESPONSE_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/http/parser.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
@@ -58,7 +61,7 @@ public:
|
||||
|
||||
response()
|
||||
: m_read(0)
|
||||
, m_buf(new std::string())
|
||||
, m_buf(lib::make_shared<std::string>())
|
||||
, m_status_code(status_code::uninitialized)
|
||||
, m_state(RESPONSE_LINE) {}
|
||||
|
||||
@@ -82,8 +85,28 @@ public:
|
||||
* @param len Size of byte buffer
|
||||
* @return Number of bytes processed.
|
||||
*/
|
||||
size_t consume(const char *buf, size_t len);
|
||||
size_t consume(char const * buf, size_t len);
|
||||
|
||||
/// Process bytes in the input buffer (istream version)
|
||||
/**
|
||||
* Process bytes from istream s. Returns the number of bytes processed.
|
||||
* Bytes left unprocessed means bytes left over after the final header
|
||||
* delimiters.
|
||||
*
|
||||
* Consume is a streaming processor. It may be called multiple times on one
|
||||
* response and the full headers need not be available before processing can
|
||||
* begin. If the end of the response was reached during this call to consume
|
||||
* the ready flag will be set. Further calls to consume once ready will be
|
||||
* ignored.
|
||||
*
|
||||
* Consume will throw an http::exception in the case of an error. Typical
|
||||
* error reasons include malformed responses, incomplete responses, and max
|
||||
* header size being reached.
|
||||
*
|
||||
* @param buf Pointer to byte buffer
|
||||
* @param len Size of byte buffer
|
||||
* @return Number of bytes processed.
|
||||
*/
|
||||
size_t consume(std::istream & s);
|
||||
|
||||
/// Returns true if the response is ready.
|
||||
@@ -99,9 +122,6 @@ public:
|
||||
return (m_state == BODY || m_state == DONE);
|
||||
}
|
||||
|
||||
/// DEPRECATED parse a complete response from a pre-delimited istream
|
||||
bool parse_complete(std::istream& s);
|
||||
|
||||
/// Returns the full raw response
|
||||
std::string raw() const;
|
||||
|
||||
@@ -126,7 +146,7 @@ public:
|
||||
* @param code Code to set
|
||||
* @param msg Message to set
|
||||
*/
|
||||
void set_status(status_code::value code, const std::string& msg);
|
||||
void set_status(status_code::value code, std::string const & msg);
|
||||
|
||||
/// Return the response status code
|
||||
status_code::value get_status_code() const {
|
||||
@@ -142,7 +162,7 @@ private:
|
||||
void process(std::string::iterator begin, std::string::iterator end);
|
||||
|
||||
/// Helper function for processing body bytes
|
||||
size_t process_body(const char *buf, size_t len);
|
||||
size_t process_body(char const * buf, size_t len);
|
||||
|
||||
enum state {
|
||||
RESPONSE_LINE = 0,
|
||||
|
||||
+768
-452
File diff suppressed because it is too large.
Load diff
+77
-26
@@ -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:
|
||||
@@ -28,6 +28,8 @@
|
||||
#ifndef WEBSOCKETPP_ENDPOINT_IMPL_HPP
|
||||
#define WEBSOCKETPP_ENDPOINT_IMPL_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
template <typename connection, typename config>
|
||||
@@ -42,8 +44,8 @@ endpoint<connection,config>::create_connection() {
|
||||
|
||||
//scoped_lock_type guard(m_mutex);
|
||||
// Create a connection on the heap and manage it using a shared pointer
|
||||
connection_ptr con(new connection_type(m_is_server,m_user_agent,m_alog,
|
||||
m_elog, m_rng));
|
||||
connection_ptr con = lib::make_shared<connection_type>(m_is_server,
|
||||
m_user_agent, lib::ref(m_alog), lib::ref(m_elog), lib::ref(m_rng));
|
||||
|
||||
connection_weak_ptr w(con);
|
||||
|
||||
@@ -64,16 +66,20 @@ endpoint<connection,config>::create_connection() {
|
||||
con->set_http_handler(m_http_handler);
|
||||
con->set_validate_handler(m_validate_handler);
|
||||
con->set_message_handler(m_message_handler);
|
||||
|
||||
if (m_open_handshake_timeout_dur == config::timeout_open_handshake) {
|
||||
|
||||
if (m_open_handshake_timeout_dur != config::timeout_open_handshake) {
|
||||
con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
|
||||
}
|
||||
if (m_close_handshake_timeout_dur == config::timeout_close_handshake) {
|
||||
if (m_close_handshake_timeout_dur != config::timeout_close_handshake) {
|
||||
con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
|
||||
}
|
||||
if (m_pong_timeout_dur == config::timeout_pong) {
|
||||
if (m_pong_timeout_dur != config::timeout_pong) {
|
||||
con->set_pong_timeout(m_pong_timeout_dur);
|
||||
}
|
||||
if (m_max_message_size != config::max_message_size) {
|
||||
con->set_max_message_size(m_max_message_size);
|
||||
}
|
||||
con->set_max_http_body_size(m_max_http_body_size);
|
||||
|
||||
lib::error_code ec;
|
||||
|
||||
@@ -87,8 +93,7 @@ endpoint<connection,config>::create_connection() {
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::interrupt(connection_hdl hdl,
|
||||
lib::error_code & ec)
|
||||
void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
@@ -102,12 +107,60 @@ template <typename connection, typename config>
|
||||
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
|
||||
lib::error_code ec;
|
||||
interrupt(hdl,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
||||
payload, frame::opcode::value op, lib::error_code & ec)
|
||||
void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
|
||||
ec = con->pause_reading();
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::pause_reading(connection_hdl hdl) {
|
||||
lib::error_code ec;
|
||||
pause_reading(hdl,ec);
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
|
||||
ec = con->resume_reading();
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::resume_reading(connection_hdl hdl) {
|
||||
lib::error_code ec;
|
||||
resume_reading(hdl,ec);
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::send_http_response(connection_hdl hdl,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
con->send_http_response(ec);
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::send_http_response(connection_hdl hdl) {
|
||||
lib::error_code ec;
|
||||
send_http_response(hdl,ec);
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
|
||||
frame::opcode::value op, lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
@@ -116,12 +169,12 @@ void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
||||
payload, frame::opcode::value op)
|
||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
|
||||
frame::opcode::value op)
|
||||
{
|
||||
lib::error_code ec;
|
||||
send(hdl,payload,op,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
@@ -139,7 +192,7 @@ void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
|
||||
{
|
||||
lib::error_code ec;
|
||||
send(hdl,payload,len,op,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
@@ -155,7 +208,7 @@ template <typename connection, typename config>
|
||||
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
|
||||
lib::error_code ec;
|
||||
send(hdl,msg,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
@@ -174,7 +227,7 @@ void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
|
||||
{
|
||||
lib::error_code ec;
|
||||
close(hdl,code,reason,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
@@ -187,17 +240,16 @@ void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
|
||||
payload)
|
||||
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
|
||||
{
|
||||
lib::error_code ec;
|
||||
ping(hdl,payload,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
||||
payload, lib::error_code & ec)
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
@@ -205,12 +257,11 @@ void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
||||
payload)
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
|
||||
{
|
||||
lib::error_code ec;
|
||||
pong(hdl,payload,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
} // namespace websocketpp
|
||||
|
||||
@@ -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:
|
||||
@@ -28,6 +28,9 @@
|
||||
#ifndef WEBSOCKETPP_UTILITIES_IMPL_HPP
|
||||
#define WEBSOCKETPP_UTILITIES_IMPL_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace utility {
|
||||
|
||||
@@ -37,7 +40,7 @@ inline std::string to_lower(std::string const & in) {
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::string to_hex(const std::string& input) {
|
||||
inline std::string to_hex(std::string const & input) {
|
||||
std::string output;
|
||||
std::string hex = "0123456789ABCDEF";
|
||||
|
||||
@@ -50,7 +53,7 @@ inline std::string to_hex(const std::string& input) {
|
||||
return output;
|
||||
}
|
||||
|
||||
inline std::string to_hex(const uint8_t* input,size_t length) {
|
||||
inline std::string to_hex(uint8_t const * input, size_t length) {
|
||||
std::string output;
|
||||
std::string hex = "0123456789ABCDEF";
|
||||
|
||||
@@ -67,8 +70,8 @@ inline std::string to_hex(const char* input,size_t length) {
|
||||
return to_hex(reinterpret_cast<const uint8_t*>(input),length);
|
||||
}
|
||||
|
||||
inline std::string string_replace_all(std::string subject, const std::string&
|
||||
search, const std::string& replace)
|
||||
inline std::string string_replace_all(std::string subject, std::string const &
|
||||
search, std::string const & replace)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = subject.find(search, pos)) != std::string::npos) {
|
||||
|
||||
+71
-15
@@ -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:
|
||||
@@ -40,13 +40,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
#include <websocketpp/common/time.hpp>
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace log {
|
||||
@@ -55,16 +58,58 @@ namespace log {
|
||||
template <typename concurrency, typename names>
|
||||
class basic {
|
||||
public:
|
||||
basic<concurrency,names>(std::ostream * out = &std::cout)
|
||||
basic<concurrency,names>(channel_type_hint::value h =
|
||||
channel_type_hint::access)
|
||||
: m_static_channels(0xffffffff)
|
||||
, m_dynamic_channels(0)
|
||||
, m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
|
||||
|
||||
basic<concurrency,names>(std::ostream * out)
|
||||
: m_static_channels(0xffffffff)
|
||||
, m_dynamic_channels(0)
|
||||
, m_out(out) {}
|
||||
|
||||
basic<concurrency,names>(level c, std::ostream * out = &std::cout)
|
||||
basic<concurrency,names>(level c, channel_type_hint::value h =
|
||||
channel_type_hint::access)
|
||||
: m_static_channels(c)
|
||||
, m_dynamic_channels(0)
|
||||
, m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
|
||||
|
||||
basic<concurrency,names>(level c, std::ostream * out)
|
||||
: m_static_channels(c)
|
||||
, m_dynamic_channels(0)
|
||||
, m_out(out) {}
|
||||
|
||||
/// Destructor
|
||||
~basic<concurrency,names>() {}
|
||||
|
||||
/// Copy constructor
|
||||
basic<concurrency,names>(basic<concurrency,names> const & other)
|
||||
: m_static_channels(other.m_static_channels)
|
||||
, m_dynamic_channels(other.m_dynamic_channels)
|
||||
, m_out(other.m_out)
|
||||
{}
|
||||
|
||||
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
// no copy assignment operator because of const member variables
|
||||
basic<concurrency,names> & operator=(basic<concurrency,names> const &) = delete;
|
||||
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
|
||||
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
/// Move constructor
|
||||
basic<concurrency,names>(basic<concurrency,names> && other)
|
||||
: m_static_channels(other.m_static_channels)
|
||||
, m_dynamic_channels(other.m_dynamic_channels)
|
||||
, m_out(other.m_out)
|
||||
{}
|
||||
|
||||
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
// no move assignment operator because of const member variables
|
||||
basic<concurrency,names> & operator=(basic<concurrency,names> &&) = delete;
|
||||
#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
|
||||
|
||||
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
|
||||
|
||||
void set_ostream(std::ostream * out = &std::cout) {
|
||||
m_out = out;
|
||||
}
|
||||
@@ -84,6 +129,11 @@ public:
|
||||
m_dynamic_channels &= ~channels;
|
||||
}
|
||||
|
||||
/// Write a string message to the given channel
|
||||
/**
|
||||
* @param channel The channel to write to
|
||||
* @param msg The message to write
|
||||
*/
|
||||
void write(level channel, std::string const & msg) {
|
||||
scoped_lock_type lock(m_lock);
|
||||
if (!this->dynamic_test(channel)) { return; }
|
||||
@@ -93,6 +143,11 @@ public:
|
||||
m_out->flush();
|
||||
}
|
||||
|
||||
/// Write a cstring message to the given channel
|
||||
/**
|
||||
* @param channel The channel to write to
|
||||
* @param msg The message to write
|
||||
*/
|
||||
void write(level channel, char const * msg) {
|
||||
scoped_lock_type lock(m_lock);
|
||||
if (!this->dynamic_test(channel)) { return; }
|
||||
@@ -109,10 +164,13 @@ public:
|
||||
bool dynamic_test(level channel) {
|
||||
return ((channel & m_dynamic_channels) != 0);
|
||||
}
|
||||
private:
|
||||
|
||||
protected:
|
||||
typedef typename concurrency::scoped_lock_type scoped_lock_type;
|
||||
typedef typename concurrency::mutex_type mutex_type;
|
||||
mutex_type m_lock;
|
||||
|
||||
private:
|
||||
// The timestamp does not include the time zone, because on Windows with the
|
||||
// default registry settings, the time zone would be written out in full,
|
||||
// which would be obnoxiously verbose.
|
||||
@@ -120,18 +178,16 @@ private:
|
||||
// TODO: find a workaround for this or make this format user settable
|
||||
static std::ostream & timestamp(std::ostream & os) {
|
||||
std::time_t t = std::time(NULL);
|
||||
std::tm* lt = std::localtime(&t);
|
||||
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
|
||||
return os << std::put_time(lt,"%Y-%m-%d %H:%M:%S");
|
||||
std::tm lt = lib::localtime(t);
|
||||
#ifdef _WEBSOCKETPP_PUTTIME_
|
||||
return os << std::put_time(<,"%Y-%m-%d %H:%M:%S");
|
||||
#else // Falls back to strftime, which requires a temporary copy of the string.
|
||||
char buffer[20];
|
||||
std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",lt);
|
||||
return os << buffer;
|
||||
size_t result = std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",<);
|
||||
return os << (result == 0 ? "Unknown" : buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
mutex_type m_lock;
|
||||
|
||||
level const m_static_channels;
|
||||
level m_dynamic_channels;
|
||||
std::ostream * m_out;
|
||||
|
||||
+31
-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:
|
||||
@@ -36,6 +36,25 @@ namespace log {
|
||||
/// Type of a channel package
|
||||
typedef uint32_t level;
|
||||
|
||||
/// Package of values for hinting at the nature of a given logger.
|
||||
/**
|
||||
* Used by the library to signal to the logging class a hint that it can use to
|
||||
* set itself up. For example, the `access` hint indicates that it is an access
|
||||
* log that might be suitable for being printed to an access log file or to cout
|
||||
* whereas `error` might be suitable for an error log file or cerr.
|
||||
*/
|
||||
struct channel_type_hint {
|
||||
/// Type of a channel type hint value
|
||||
typedef uint32_t value;
|
||||
|
||||
/// No information
|
||||
static value const none = 0;
|
||||
/// Access log
|
||||
static value const access = 1;
|
||||
/// Error log
|
||||
static value const error = 2;
|
||||
};
|
||||
|
||||
/// Package of log levels for logging errors
|
||||
struct elevel {
|
||||
/// Special aggregate value representing "no levels"
|
||||
@@ -122,6 +141,13 @@ struct alevel {
|
||||
static level const devel = 0x400;
|
||||
/// Special channel for application specific logs. Not used by the library.
|
||||
static level const app = 0x800;
|
||||
/// Access related to HTTP requests
|
||||
static level const http = 0x1000;
|
||||
/// One line for each failed WebSocket connection with details
|
||||
static level const fail = 0x2000;
|
||||
/// Aggregate package representing the commonly used core access channels
|
||||
/// Connect, Disconnect, Fail, and HTTP
|
||||
static level const access_core = 0x00003003;
|
||||
/// Special aggregate value representing "all levels"
|
||||
static level const all = 0xffffffff;
|
||||
|
||||
@@ -161,6 +187,10 @@ struct alevel {
|
||||
return "devel";
|
||||
case app:
|
||||
return "application";
|
||||
case http:
|
||||
return "http";
|
||||
case fail:
|
||||
return "fail";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
+67
-11
@@ -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:
|
||||
@@ -28,10 +28,11 @@
|
||||
#ifndef WEBSOCKETPP_LOGGER_STUB_HPP
|
||||
#define WEBSOCKETPP_LOGGER_STUB_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace log {
|
||||
@@ -39,20 +40,75 @@ namespace log {
|
||||
/// Stub logger that ignores all input
|
||||
class stub {
|
||||
public:
|
||||
explicit stub(std::ostream * out) {}
|
||||
stub(level c, std::ostream * out) {}
|
||||
/// Construct the logger
|
||||
/**
|
||||
* @param hint A channel type specific hint for how to construct the logger
|
||||
*/
|
||||
explicit stub(channel_type_hint::value) {}
|
||||
|
||||
/// Construct the logger
|
||||
/**
|
||||
* @param default_channels A set of channels to statically enable
|
||||
* @param hint A channel type specific hint for how to construct the logger
|
||||
*/
|
||||
stub(level, channel_type_hint::value) {}
|
||||
_WEBSOCKETPP_CONSTEXPR_TOKEN_ stub() {}
|
||||
|
||||
void set_channels(level channels) {}
|
||||
void clear_channels(level channels) {}
|
||||
/// Dynamically enable the given list of channels
|
||||
/**
|
||||
* All operations on the stub logger are no-ops and all arguments are
|
||||
* ignored
|
||||
*
|
||||
* @param channels The package of channels to enable
|
||||
*/
|
||||
void set_channels(level) {}
|
||||
|
||||
void write(level channel, std::string const & msg) {}
|
||||
void write(level channel, char const * msg) {}
|
||||
/// Dynamically disable the given list of channels
|
||||
/**
|
||||
* All operations on the stub logger are no-ops and all arguments are
|
||||
* ignored
|
||||
*
|
||||
* @param channels The package of channels to disable
|
||||
*/
|
||||
void clear_channels(level) {}
|
||||
|
||||
_WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) const {
|
||||
/// Write a string message to the given channel
|
||||
/**
|
||||
* Writing on the stub logger is a no-op and all arguments are ignored
|
||||
*
|
||||
* @param channel The channel to write to
|
||||
* @param msg The message to write
|
||||
*/
|
||||
void write(level, std::string const &) {}
|
||||
|
||||
/// Write a cstring message to the given channel
|
||||
/**
|
||||
* Writing on the stub logger is a no-op and all arguments are ignored
|
||||
*
|
||||
* @param channel The channel to write to
|
||||
* @param msg The message to write
|
||||
*/
|
||||
void write(level, char const *) {}
|
||||
|
||||
/// Test whether a channel is statically enabled
|
||||
/**
|
||||
* The stub logger has no channels so all arguments are ignored and
|
||||
* `static_test` always returns false.
|
||||
*
|
||||
* @param channel The package of channels to test
|
||||
*/
|
||||
_WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level) const {
|
||||
return false;
|
||||
}
|
||||
bool dynamic_test(level channel) {
|
||||
|
||||
/// Test whether a channel is dynamically enabled
|
||||
/**
|
||||
* The stub logger has no channels so all arguments are ignored and
|
||||
* `dynamic_test` always returns false.
|
||||
*
|
||||
* @param channel The package of channels to test
|
||||
*/
|
||||
bool dynamic_test(level) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The initial version of this logging policy was contributed to the WebSocket++
|
||||
* project by Tom Hughes.
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_LOGGER_SYSLOG_HPP
|
||||
#define WEBSOCKETPP_LOGGER_SYSLOG_HPP
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include <websocketpp/logger/basic.hpp>
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace log {
|
||||
|
||||
/// Basic logger that outputs to syslog
|
||||
template <typename concurrency, typename names>
|
||||
class syslog : public basic<concurrency, names> {
|
||||
public:
|
||||
typedef basic<concurrency, names> base;
|
||||
|
||||
/// Construct the logger
|
||||
/**
|
||||
* @param hint A channel type specific hint for how to construct the logger
|
||||
*/
|
||||
syslog<concurrency,names>(channel_type_hint::value hint =
|
||||
channel_type_hint::access)
|
||||
: basic<concurrency,names>(hint), m_channel_type_hint(hint) {}
|
||||
|
||||
/// Construct the logger
|
||||
/**
|
||||
* @param channels A set of channels to statically enable
|
||||
* @param hint A channel type specific hint for how to construct the logger
|
||||
*/
|
||||
syslog<concurrency,names>(level channels, channel_type_hint::value hint =
|
||||
channel_type_hint::access)
|
||||
: basic<concurrency,names>(channels, hint), m_channel_type_hint(hint) {}
|
||||
|
||||
/// Write a string message to the given channel
|
||||
/**
|
||||
* @param channel The channel to write to
|
||||
* @param msg The message to write
|
||||
*/
|
||||
void write(level channel, std::string const & msg) {
|
||||
write(channel, msg.c_str());
|
||||
}
|
||||
|
||||
/// Write a cstring message to the given channel
|
||||
/**
|
||||
* @param channel The channel to write to
|
||||
* @param msg The message to write
|
||||
*/
|
||||
void write(level channel, char const * msg) {
|
||||
scoped_lock_type lock(base::m_lock);
|
||||
if (!this->dynamic_test(channel)) { return; }
|
||||
::syslog(syslog_priority(channel), "[%s] %s",
|
||||
names::channel_name(channel), msg);
|
||||
}
|
||||
private:
|
||||
typedef typename base::scoped_lock_type scoped_lock_type;
|
||||
|
||||
/// The default level is used for all access logs and any error logs that
|
||||
/// don't trivially map to one of the standard syslog levels.
|
||||
static int const default_level = LOG_INFO;
|
||||
|
||||
/// retrieve the syslog priority code given a WebSocket++ channel
|
||||
/**
|
||||
* @param channel The level to look up
|
||||
* @return The syslog level associated with `channel`
|
||||
*/
|
||||
int syslog_priority(level channel) const {
|
||||
if (m_channel_type_hint == channel_type_hint::access) {
|
||||
return syslog_priority_access(channel);
|
||||
} else {
|
||||
return syslog_priority_error(channel);
|
||||
}
|
||||
}
|
||||
|
||||
/// retrieve the syslog priority code given a WebSocket++ error channel
|
||||
/**
|
||||
* @param channel The level to look up
|
||||
* @return The syslog level associated with `channel`
|
||||
*/
|
||||
int syslog_priority_error(level channel) const {
|
||||
switch (channel) {
|
||||
case elevel::devel:
|
||||
return LOG_DEBUG;
|
||||
case elevel::library:
|
||||
return LOG_DEBUG;
|
||||
case elevel::info:
|
||||
return LOG_INFO;
|
||||
case elevel::warn:
|
||||
return LOG_WARNING;
|
||||
case elevel::rerror:
|
||||
return LOG_ERR;
|
||||
case elevel::fatal:
|
||||
return LOG_CRIT;
|
||||
default:
|
||||
return default_level;
|
||||
}
|
||||
}
|
||||
|
||||
/// retrieve the syslog priority code given a WebSocket++ access channel
|
||||
/**
|
||||
* @param channel The level to look up
|
||||
* @return The syslog level associated with `channel`
|
||||
*/
|
||||
_WEBSOCKETPP_CONSTEXPR_TOKEN_ int syslog_priority_access(level) const {
|
||||
return default_level;
|
||||
}
|
||||
|
||||
channel_type_hint::value m_channel_type_hint;
|
||||
};
|
||||
|
||||
} // log
|
||||
} // websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_LOGGER_SYSLOG_HPP
|
||||
@@ -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:
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
* @return A shared pointer to an empty new message
|
||||
*/
|
||||
message_ptr get_message() {
|
||||
return message_ptr(new message(type::shared_from_this()));
|
||||
return message_ptr(lib::make_shared<message>(type::shared_from_this()));
|
||||
}
|
||||
|
||||
/// Get a message buffer with specified size and opcode
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
* @return A shared pointer to a new message with specified size.
|
||||
*/
|
||||
message_ptr get_message(frame::opcode::value op,size_t size) {
|
||||
return message_ptr(new message(type::shared_from_this(),op,size));
|
||||
return message_ptr(lib::make_shared<message>(type::shared_from_this(),op,size));
|
||||
}
|
||||
|
||||
/// Recycle a message
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
*
|
||||
* @return true if the message was successfully recycled, false otherwse.
|
||||
*/
|
||||
bool recycle(message * msg) {
|
||||
bool recycle(message *) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
* @return A pointer to the requested connection message manager.
|
||||
*/
|
||||
con_msg_man_ptr get_manager() const {
|
||||
return con_msg_man_ptr(new con_msg_manager());
|
||||
return con_msg_man_ptr(lib::make_shared<con_msg_manager>());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -43,7 +43,7 @@ namespace message_buffer {
|
||||
*
|
||||
* # connection_message_manager:
|
||||
* An object that manages all of the message_buffers associated with a given
|
||||
* connection. Impliments the get_message_buffer(size) method that returns
|
||||
* connection. Implements the get_message_buffer(size) method that returns
|
||||
* a message buffer at least size bytes long.
|
||||
*
|
||||
* Message buffers are reference counted with shared ownership semantics. Once
|
||||
@@ -54,7 +54,7 @@ namespace message_buffer {
|
||||
* in the manager.
|
||||
*
|
||||
* # endpoint_message_manager:
|
||||
* An object that manages connection_message_managers. Impliments the
|
||||
* An object that manages connection_message_managers. Implements the
|
||||
* get_message_manager() method. This is used once by each connection to
|
||||
* request the message manager that they are supposed to use to manage message
|
||||
* buffers for their own use.
|
||||
@@ -146,10 +146,10 @@ public:
|
||||
|
||||
/// Set or clear the compression flag
|
||||
/**
|
||||
* The compression flag is used to indicate whether or not the message is
|
||||
* or should be compressed. Compression is not guaranteed. Both endpoints
|
||||
* must support a compression extension and the connection must have had
|
||||
* that extension negotiated in its handshake.
|
||||
* Setting the compression flag indicates that the data in this message
|
||||
* would benefit from compression. If both endpoints negotiate a compression
|
||||
* extension WebSocket++ will attempt to compress messages with this flag.
|
||||
* Setting this flag does not guarantee that the message will be compressed.
|
||||
*
|
||||
* @param value The value to set the compressed flag to
|
||||
*/
|
||||
|
||||
@@ -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:
|
||||
@@ -42,7 +42,7 @@ namespace message_buffer {
|
||||
*
|
||||
* # connection_message_manager:
|
||||
* An object that manages all of the message_buffers associated with a given
|
||||
* connection. Impliments the get_message_buffer(size) method that returns
|
||||
* connection. Implements the get_message_buffer(size) method that returns
|
||||
* a message buffer at least size bytes long.
|
||||
*
|
||||
* Message buffers are reference counted with shared ownership semantics. Once
|
||||
@@ -53,7 +53,7 @@ namespace message_buffer {
|
||||
* in the manager.
|
||||
*
|
||||
* # endpoint_message_manager:
|
||||
* An object that manages connection_message_managers. Impliments the
|
||||
* An object that manages connection_message_managers. Implements the
|
||||
* get_message_manager() method. This is used once by each connection to
|
||||
* request the message manager that they are supposed to use to manage message
|
||||
* buffers for their own use.
|
||||
@@ -171,7 +171,7 @@ public:
|
||||
* @return A shared pointer to a new message with specified size.
|
||||
*/
|
||||
message_ptr get_message(size_t size) const {
|
||||
return message_ptr(new message(size));
|
||||
return lib::make_shared<message>(size);
|
||||
}
|
||||
|
||||
/// Recycle a message
|
||||
@@ -201,7 +201,7 @@ public:
|
||||
* @return A pointer to the requested connection message manager.
|
||||
*/
|
||||
con_msg_man_ptr get_manager() const {
|
||||
return con_msg_man_ptr(new con_msg_manager());
|
||||
return lib::make_shared<con_msg_manager>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loaded 100 of 133 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user