Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9161119b4d | |||
| 7db60e3429 | |||
| 3c0b8a81b0 | |||
| b812fd001b | |||
| 3a43986d9e | |||
| 64b1b52297 | |||
| dc048ed021 | |||
| 60b167bcb7 | |||
| e680ca1ef4 | |||
| 21d79e28c6 | |||
| d25a254e81 | |||
| 3e144cfd75 | |||
| 096a7dbaa8 | |||
| 577591aaa1 | |||
| a401a4448d | |||
| ace76f54f9 | |||
| 1eaa1b790f |
+3
-1
@@ -10,6 +10,8 @@ env:
|
||||
script: scons -j 2 && scons test
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- permessage-deflate
|
||||
- experimental
|
||||
- 0.3.x-cmake
|
||||
notifications:
|
||||
@@ -17,4 +19,4 @@ notifications:
|
||||
- travis@zaphoyd.com
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_failure: always
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ project (websocketpp)
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
set (WEBSOCKETPP_MAJOR_VERSION 0)
|
||||
set (WEBSOCKETPP_MINOR_VERSION 2)
|
||||
set (WEBSOCKETPP_PATCH_VERSION 99)
|
||||
set (WEBSOCKETPP_MINOR_VERSION 3)
|
||||
set (WEBSOCKETPP_PATCH_VERSION 0)
|
||||
set (WEBSOCKETPP_VERSION ${WEBSOCKETPP_MAJOR_VERSION}.${WEBSOCKETPP_MINOR_VERSION}.${WEBSOCKETPP_PATCH_VERSION})
|
||||
|
||||
set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files")
|
||||
|
||||
@@ -33,7 +33,7 @@ PROJECT_NAME = "websocketpp"
|
||||
# if some version control system is used.
|
||||
|
||||
|
||||
PROJECT_NUMBER = "0.3.0-dev"
|
||||
PROJECT_NUMBER = "0.3.0-alpha2"
|
||||
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
|
||||
+15
-1
@@ -1,2 +1,16 @@
|
||||
0.3.0b1 - 2013-05-??
|
||||
0.3.0-alpha2 - 2013-06-09
|
||||
- Fixes a regression that caused servers being sent two close frames in a row
|
||||
to end a connection uncleanly. #259
|
||||
- Fixes a regression that caused spurious frames following a legitimate close
|
||||
frames to erroneously trigger handlers. #258
|
||||
- Changes default HTTP response error code when no http_handler is defined from
|
||||
500/Internal Server Error to 426/Upgrade Required
|
||||
- Removes timezone from logger timestamp to work around issues with the Windows
|
||||
implimentation of strftime. Thank you breyed for testing and code. #257
|
||||
- Switches integer literals to char literals to improve VCPP compatibility.
|
||||
Thank you breyed for testing and code. #257
|
||||
- Adds MSVCPP warning suppression for the bundled SHA1 library. Thank you breyed
|
||||
for testing and code. #257
|
||||
|
||||
0.3.0-alpha1 - 2013-06-09
|
||||
- Initial Release
|
||||
@@ -61,7 +61,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
std::stringstream url;
|
||||
|
||||
url << uri << "/runCase?case=" << i << "&agent=WebSocket++/0.3.0-dev";
|
||||
url << uri << "/runCase?case=" << i << "&agent=WebSocketpp/0.3.0-alpha2";
|
||||
|
||||
con = echo_client.get_connection(url.str(), ec);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
WebSocket++ (0.3.x branch)
|
||||
WebSocket++ (0.3.0-alpha1)
|
||||
==========================
|
||||
|
||||
WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket
|
||||
@@ -6,18 +6,6 @@ Protocol. It allows integrating WebSocket client and server functionality into
|
||||
C++ programs. It uses interchangeable network transport modules including one
|
||||
based on C++ iostreams and one based on Boost Asio.
|
||||
|
||||
*This branch is no longer "experimental". It represents the current edge release
|
||||
of the WebSocket++ library. The API of 0.3.x has some significant changes from
|
||||
0.2.x, so care should be taken when upgrading.*
|
||||
|
||||
*This branch's API is relatively stable now. Features implemented so far are
|
||||
unlikely to change (except where explicitly noted). New features will be added
|
||||
regularly until parity with the 0.2 branch is reached.*
|
||||
|
||||
*This is the preferred branch for new projects, especially those that involve
|
||||
multithreaded servers. It is better tested and documented. The 0.3.x API will
|
||||
be the basis for the 1.0 release.*
|
||||
|
||||
Major Features
|
||||
==============
|
||||
* Full support for RFC6455
|
||||
@@ -26,7 +14,8 @@ Major Features
|
||||
* Supports secure WebSockets (TLS), IPv6, and explicit proxies.
|
||||
* Flexible dependency management (C++11 Standard Library or Boost)
|
||||
* Interchangeable network transport modules (iostream and Boost Asio)
|
||||
* Portable, cross platform and architecture design
|
||||
* Portable/cross platform (Posix/Windows, 32/64bit, Intel/ARM/PPC)
|
||||
* Thread-safe
|
||||
|
||||
Get Involved
|
||||
============
|
||||
@@ -46,7 +35,7 @@ https://github.com/zaphoyd/websocketpp/
|
||||
http://groups.google.com/group/websocketpp-announcements/
|
||||
|
||||
**IRC Channel**
|
||||
#websocketpp (freenode)
|
||||
#websocketpp (freenode)
|
||||
|
||||
**Discussion / Development / Support Mailing List / Forum**
|
||||
http://groups.google.com/group/websocketpp/
|
||||
|
||||
+5
-9
@@ -8,6 +8,8 @@ Complete & Tested:
|
||||
- GCC support
|
||||
- 64 bit support
|
||||
- 32 bit support
|
||||
- Logging
|
||||
- Client role
|
||||
|
||||
Implimented, needs more testing
|
||||
- TLS support
|
||||
@@ -20,26 +22,20 @@ Implimented, needs more testing
|
||||
- pong_handler
|
||||
- tcp_init_handler
|
||||
- exception/error handling
|
||||
- Logging
|
||||
- Client role
|
||||
- Subprotocol negotiation
|
||||
- Hybi 00/Hixie 76 legacy protocol support
|
||||
- Performance tuning
|
||||
- Outgoing Proxy Support
|
||||
- PowerPC support
|
||||
- Visual Studio / Windows support
|
||||
|
||||
Implimented, API not finalized
|
||||
- Timeouts
|
||||
- CMake build/install support
|
||||
- open_handler
|
||||
- close_handler
|
||||
- validate_handler
|
||||
- http_handler
|
||||
|
||||
Needs work:
|
||||
- Timeouts
|
||||
|
||||
Non-release blocking feature roadmap
|
||||
Future feature roadmap
|
||||
- Extension support
|
||||
- permessage_compress extension
|
||||
- Message buffer pool
|
||||
- CMake build/install support
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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_HPP
|
||||
#define WEBSOCKETPP_COMMON_HPP
|
||||
|
||||
// TODO/NOTE:
|
||||
// _WEBSOCKETPP_CPP11_MEMORY_ and _WEBSOCKETPP_CPP11_FUNCTIONAL_ presently
|
||||
// only work if either both or neither is defined. It might not make sense to
|
||||
// have separate options for them both.
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* _WEBSOCKETPP_CPP11_STL_ enables the use of a C++11 STL. Doing this requires
|
||||
* that you link to a C++11 STL, that your copy of boost be linked to that same
|
||||
* STL, and that your compiler supports a minimum set of C++11 features.
|
||||
*
|
||||
* Required Features:
|
||||
* - noexcept
|
||||
*/
|
||||
|
||||
// Optional C++11 support features
|
||||
#ifndef __has_feature // Optional of course.
|
||||
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
|
||||
#endif
|
||||
#ifndef __has_extension
|
||||
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
|
||||
#endif
|
||||
|
||||
// Enable initializer lists on clang when available.
|
||||
#if __has_feature(cxx_generalized_initializers)
|
||||
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||
#endif
|
||||
|
||||
// Enable deleted functions when available.
|
||||
#if __has_feature(cxx_deleted_functions)
|
||||
#define _WEBSOCKETPP_DELETED_FUNCTIONS_
|
||||
#endif
|
||||
|
||||
// Enable rvalue references when available.
|
||||
#if __has_feature(cxx_rvalue_references)
|
||||
#define _WEBSOCKETPP_RVALUE_REFERENCES_
|
||||
#endif
|
||||
|
||||
// Use C++11 native Alias Templates instead of a hack.
|
||||
//#define _WEBSOCKETPP_CPP11_ALIAS_TEMPLATES_
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_
|
||||
#define _WEBSOCKETPP_DELETED_FUNCTIONS_
|
||||
#define _WEBSOCKETPP_RVALUE_REFERENCES_
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
// Size of the transport read buffer. Increasing may improve performance for
|
||||
// large reads. Higher values will increase memory usage linearly with
|
||||
// connection count.
|
||||
|
||||
const size_t DEFAULT_READ_THRESHOLD = 1; // 512 would be a more sane value
|
||||
|
||||
// Maximum size in bytes before rejecting an HTTP header as too big.
|
||||
// Is defined in websocketpp/http/constants.hpp
|
||||
|
||||
// Default user agent.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace close {
|
||||
namespace status {
|
||||
enum value {
|
||||
INVALID_END = 999,
|
||||
NORMAL = 1000,
|
||||
GOING_AWAY = 1001,
|
||||
PROTOCOL_ERROR = 1002,
|
||||
UNSUPPORTED_DATA = 1003,
|
||||
RSV_ADHOC_1 = 1004,
|
||||
NO_STATUS = 1005,
|
||||
ABNORMAL_CLOSE = 1006,
|
||||
INVALID_PAYLOAD = 1007,
|
||||
POLICY_VIOLATION = 1008,
|
||||
MESSAGE_TOO_BIG = 1009,
|
||||
EXTENSION_REQUIRE = 1010,
|
||||
INTERNAL_ENDPOINT_ERROR = 1011,
|
||||
RSV_ADHOC_2 = 1012,
|
||||
RSV_ADHOC_3 = 1013,
|
||||
RSV_ADHOC_4 = 1014,
|
||||
TLS_HANDSHAKE = 1015,
|
||||
RSV_START = 1016,
|
||||
RSV_END = 2999,
|
||||
INVALID_START = 5000
|
||||
};
|
||||
|
||||
inline bool reserved(value s) {
|
||||
return ((s >= RSV_START && s <= RSV_END) || s == RSV_ADHOC_1
|
||||
|| s == RSV_ADHOC_2 || s == RSV_ADHOC_3 || s == RSV_ADHOC_4);
|
||||
}
|
||||
|
||||
// Codes invalid on the wire
|
||||
inline bool invalid(value s) {
|
||||
return ((s <= INVALID_END || s >= INVALID_START) ||
|
||||
s == NO_STATUS ||
|
||||
s == ABNORMAL_CLOSE ||
|
||||
s == TLS_HANDSHAKE);
|
||||
}
|
||||
|
||||
// TODO functions for application ranges?
|
||||
} // namespace status
|
||||
} // namespace close
|
||||
|
||||
|
||||
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
#include <websocketpp/common/regex.hpp>
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_HPP
|
||||
@@ -54,7 +54,7 @@ namespace lib {
|
||||
using boost::bind;
|
||||
using boost::ref;
|
||||
namespace placeholders {
|
||||
// TODO: there has got to be a better way than this
|
||||
/// \todo this feels hacky, is there a better way?
|
||||
using ::_1;
|
||||
using ::_2;
|
||||
}
|
||||
|
||||
@@ -193,6 +193,7 @@ public:
|
||||
, m_rng(rng)
|
||||
, m_local_close_code(close::status::abnormal_close)
|
||||
, m_remote_close_code(close::status::abnormal_close)
|
||||
, m_was_clean(false)
|
||||
{
|
||||
m_alog.write(log::alevel::devel,"connection constructor");
|
||||
}
|
||||
@@ -399,7 +400,7 @@ public:
|
||||
* and then added
|
||||
*
|
||||
* Errors are returned via an exception
|
||||
* TODO: make exception system_error rather than error_code
|
||||
* \todo make exception system_error rather than error_code
|
||||
*
|
||||
* This method invokes the m_write_lock mutex
|
||||
*
|
||||
@@ -871,7 +872,7 @@ public:
|
||||
|
||||
/// Checks if there are frames in the send queue and if there are sends one
|
||||
/**
|
||||
* TODO: unit tests
|
||||
* \todo unit tests
|
||||
*
|
||||
* This method locks the m_write_lock mutex
|
||||
*/
|
||||
@@ -879,7 +880,7 @@ public:
|
||||
|
||||
/// Process the results of a frame write operation and start the next write
|
||||
/**
|
||||
* TODO: unit tests
|
||||
* \todo unit tests
|
||||
*
|
||||
* This method locks the m_write_lock mutex
|
||||
*
|
||||
@@ -1011,7 +1012,7 @@ private:
|
||||
*
|
||||
* Must be called while holding m_write_lock
|
||||
*
|
||||
* TODO: unit tests
|
||||
* \todo unit tests
|
||||
*
|
||||
* @param msg The message to push
|
||||
*/
|
||||
@@ -1024,7 +1025,7 @@ private:
|
||||
*
|
||||
* Must be called while holding m_write_lock
|
||||
*
|
||||
* TODO: unit tests
|
||||
* \todo unit tests
|
||||
*
|
||||
* @return the message_ptr at the front of the queue
|
||||
*/
|
||||
@@ -1097,8 +1098,8 @@ private:
|
||||
timer_ptr m_handshake_timer;
|
||||
timer_ptr m_ping_timer;
|
||||
|
||||
// TODO: this is not memory efficient. this value is not used after the
|
||||
// handshake.
|
||||
/// \todo this is not memory efficient. this value is not used after the
|
||||
/// handshake.
|
||||
std::string m_handshake_buffer;
|
||||
|
||||
/// Pointer to the processor object for this connection
|
||||
@@ -1172,6 +1173,8 @@ private:
|
||||
/// Detailed internal error code
|
||||
lib::error_code m_ec;
|
||||
|
||||
bool m_was_clean;
|
||||
|
||||
/// Whether or not this endpoint initiated the closing handshake.
|
||||
bool m_closed_by_me;
|
||||
|
||||
|
||||
@@ -30,14 +30,13 @@
|
||||
|
||||
#include <websocketpp/connection.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
#include <websocketpp/version.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
static const char user_agent[] = "WebSocket++/0.3.0dev";
|
||||
|
||||
/// Creates and manages connections associated with a WebSocket endpoint
|
||||
template <typename connection, typename config>
|
||||
class endpoint : public config::transport_type, public config::endpoint_base {
|
||||
|
||||
@@ -35,8 +35,16 @@ namespace websocketpp {
|
||||
namespace http {
|
||||
namespace parser {
|
||||
|
||||
inline bool parser::parse_parameter_list(const std::string& in,
|
||||
parameter_list& out) const
|
||||
/// Extract an HTTP parameter list from a string.
|
||||
/**
|
||||
* @param [in] in The input string.
|
||||
*
|
||||
* @param [out] out The parameter list to store extracted parameters in.
|
||||
*
|
||||
* @return Whether or not the input was a valid parameter list.
|
||||
*/
|
||||
inline bool parser::parse_parameter_list(std::string const & in,
|
||||
parameter_list & out) const
|
||||
{
|
||||
if (in.size() == 0) {
|
||||
return false;
|
||||
@@ -47,33 +55,48 @@ inline bool parser::parse_parameter_list(const std::string& in,
|
||||
return (it == in.begin());
|
||||
}
|
||||
|
||||
inline bool parser::get_header_as_plist(const std::string& key,
|
||||
parameter_list& out) const
|
||||
/// Extract an HTTP parameter list from a parser header.
|
||||
/**
|
||||
* If the header requested doesn't exist or exists and is empty the parameter
|
||||
* list is valid (but empty).
|
||||
*
|
||||
* @param [in] key The name/key of the HTTP header to use as input.
|
||||
*
|
||||
* @param [out] out The parameter list to store extracted parameters in.
|
||||
*
|
||||
* @return Whether or not the input was a valid parameter list.
|
||||
*/
|
||||
inline bool parser::get_header_as_plist(std::string const & key,
|
||||
parameter_list & out) const
|
||||
{
|
||||
header_list::const_iterator it = m_headers.find(key);
|
||||
|
||||
// If this header doesn't exist it is valid
|
||||
if (it == m_headers.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this header exists but is empty it is valid
|
||||
if (it->second.size() == 0) {
|
||||
if (it == m_headers.end() || it->second.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->parse_parameter_list(it->second,out);
|
||||
}
|
||||
|
||||
inline void parser::set_version(const std::string& version) {
|
||||
// TODO: validation?
|
||||
|
||||
// first four chars == HTTP/
|
||||
|
||||
/// Set HTTP parser Version
|
||||
/**
|
||||
* \todo Does this method need any validation?
|
||||
*
|
||||
* @param [in] version The value to set the HTTP version to.
|
||||
*/
|
||||
inline void parser::set_version(std::string const & version) {
|
||||
m_version = version;
|
||||
}
|
||||
|
||||
inline const std::string& parser::get_header(const std::string& key) const {
|
||||
|
||||
/// Get the value of an HTTP header
|
||||
/**
|
||||
* \todo Make this method case insensitive.
|
||||
*
|
||||
* @param [in] key The name/key of the header to get.
|
||||
*
|
||||
* @return The value associated with the given HTTP header key.
|
||||
*/
|
||||
inline std::string const & parser::get_header(std::string const & key) const {
|
||||
header_list::const_iterator h = m_headers.find(key);
|
||||
|
||||
if (h == m_headers.end()) {
|
||||
@@ -82,15 +105,28 @@ inline const std::string& parser::get_header(const std::string& key) const {
|
||||
return h->second;
|
||||
}
|
||||
}
|
||||
|
||||
inline void parser::append_header(const std::string &key,const std::string
|
||||
&val)
|
||||
|
||||
/// Append a value to an existing HTTP header
|
||||
/**
|
||||
* This method will set the value of the HTTP header `key` with the indicated
|
||||
* value. If a header with the name `key` already exists, `val` will be appended
|
||||
* to the existing value.
|
||||
*
|
||||
* \todo Make this method case insensitive.
|
||||
* \todo Should there be any restrictions on which keys are allowed to be set?
|
||||
* \todo Exception free varient
|
||||
*
|
||||
* @param [in] key The name/key of the header to append to.
|
||||
*
|
||||
* @param [in] val The value to append.
|
||||
*/
|
||||
inline void parser::append_header(std::string const & key, std::string const &
|
||||
val)
|
||||
{
|
||||
if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
|
||||
throw exception("Invalid header name",status_code::bad_request);
|
||||
}
|
||||
|
||||
// TODO: prevent use of reserved headers?
|
||||
if (this->get_header(key) == "") {
|
||||
m_headers[key] = val;
|
||||
} else {
|
||||
@@ -98,29 +134,63 @@ inline void parser::append_header(const std::string &key,const std::string
|
||||
}
|
||||
}
|
||||
|
||||
inline void parser::replace_header(const std::string &key,const std::string
|
||||
&val)
|
||||
/// Set a value for an HTTP header, replacing an existing value
|
||||
/**
|
||||
* This method will set the value of the HTTP header `key` with the indicated
|
||||
* value. If a header with the name `key` already exists, `val` will replace the
|
||||
* existing value.
|
||||
*
|
||||
* \todo Make this method case insensitive.
|
||||
* \todo Should there be any restrictions on which keys are allowed to be set?
|
||||
* \todo Exception free varient
|
||||
*
|
||||
* @param [in] key The name/key of the header to append to.
|
||||
*
|
||||
* @param [in] val The value to append.
|
||||
*/
|
||||
inline void parser::replace_header(std::string const & key, std::string const &
|
||||
val)
|
||||
{
|
||||
m_headers[key] = val;
|
||||
}
|
||||
|
||||
inline void parser::remove_header(const std::string &key) {
|
||||
/// Remove a header from the parser
|
||||
/**
|
||||
* Removes the header entirely from the parser. This is different than setting
|
||||
* the value of the header to blank.
|
||||
*
|
||||
* \todo Make this method case insensitive.
|
||||
*
|
||||
* @param [in] key The name/key of the header to remove.
|
||||
*/
|
||||
inline void parser::remove_header(std::string const & key) {
|
||||
m_headers.erase(key);
|
||||
}
|
||||
|
||||
inline void parser::set_body(const std::string& value) {
|
||||
/// Set HTTP body
|
||||
/**
|
||||
* Sets the body of the HTTP object and fills in the appropriate content length
|
||||
* header
|
||||
*
|
||||
* @param [in] value The value to set the body to.
|
||||
*/
|
||||
inline void parser::set_body(std::string const & value) {
|
||||
if (value.size() == 0) {
|
||||
remove_header("Content-Length");
|
||||
m_body = "";
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream foo;
|
||||
foo << value.size();
|
||||
replace_header("Content-Length", foo.str());
|
||||
std::stringstream len;
|
||||
len << value.size();
|
||||
replace_header("Content-Length", len.str());
|
||||
m_body = value;
|
||||
}
|
||||
|
||||
/// Parse headers from an istream
|
||||
/**
|
||||
* @param [in] s The istream to extract headers from.
|
||||
*/
|
||||
inline bool parser::parse_headers(std::istream& s) {
|
||||
std::string header;
|
||||
std::string::size_type end;
|
||||
@@ -143,6 +213,13 @@ inline bool parser::parse_headers(std::istream& s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Generate and return the HTTP headers as a string
|
||||
/**
|
||||
* Each headers will be followed by the \r\n sequence including the last one.
|
||||
* A second \r\n sequence (blank header) is not appended by this method
|
||||
*
|
||||
* @return The HTTP headers as a string.
|
||||
*/
|
||||
inline std::string parser::raw_headers() const {
|
||||
std::stringstream raw;
|
||||
|
||||
@@ -154,6 +231,13 @@ inline std::string parser::raw_headers() const {
|
||||
return raw.str();
|
||||
}
|
||||
|
||||
/// Process a header
|
||||
/**
|
||||
*
|
||||
* \todo Update this method to be exception free.
|
||||
*
|
||||
* @param [in] s The istream to extract headers from.
|
||||
*/
|
||||
inline void parser::process_header(std::string::iterator begin,
|
||||
std::string::iterator end)
|
||||
{
|
||||
|
||||
@@ -148,7 +148,14 @@ 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) {
|
||||
// TODO: validation?
|
||||
m_uri = uri;
|
||||
|
||||
@@ -896,7 +896,10 @@ void connection<config>::handle_read_frame(const lib::error_code& ec,
|
||||
"null message from m_processor");
|
||||
} else if (!is_control(msg->get_opcode())) {
|
||||
// data message, dispatch to user
|
||||
if (m_message_handler) {
|
||||
if (m_state != session::state::open) {
|
||||
m_elog.write(log::elevel::warn,
|
||||
"got non-close data frame in state closing");
|
||||
} else if (m_message_handler) {
|
||||
m_message_handler(m_connection_hdl, msg);
|
||||
}
|
||||
} else {
|
||||
@@ -989,6 +992,8 @@ bool connection<config>::process_handshake_request() {
|
||||
|
||||
if (m_http_handler) {
|
||||
m_http_handler(m_connection_hdl);
|
||||
} else {
|
||||
set_status(http::status_code::upgrade_required);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1635,7 +1640,16 @@ void connection<config>::process_control_frame(typename
|
||||
std::stringstream s;
|
||||
s << "Control frame received with opcode " << op;
|
||||
m_alog.write(log::alevel::control,s.str());
|
||||
|
||||
|
||||
if (m_state == session::state::closed) {
|
||||
m_elog.write(log::elevel::warn,"got frame in state closed");
|
||||
return;
|
||||
}
|
||||
if (op != frame::opcode::CLOSE && m_state != session::state::open) {
|
||||
m_elog.write(log::elevel::warn,"got non-close frame in state closing");
|
||||
return;
|
||||
}
|
||||
|
||||
if (op == frame::opcode::PING) {
|
||||
bool pong = true;
|
||||
|
||||
@@ -1710,10 +1724,12 @@ void connection<config>::process_control_frame(typename
|
||||
m_elog.write(log::elevel::devel,
|
||||
"send_close_ack error: "+ec.message());
|
||||
}
|
||||
} else if (m_state == session::state::closing) {
|
||||
} else if (m_state == session::state::closing && !m_was_clean) {
|
||||
// ack of our close
|
||||
m_alog.write(log::alevel::devel,"Got acknowledgement of close");
|
||||
|
||||
m_was_clean = true;
|
||||
|
||||
// If we are a server terminate the connection now. Clients should
|
||||
// leave the connection open to give the server an opportunity to
|
||||
// initiate the TCP close. The client's timer will handle closing
|
||||
@@ -1801,6 +1817,10 @@ lib::error_code connection<config>::send_close_frame(close::status::value code,
|
||||
|
||||
m_state = session::state::closing;
|
||||
|
||||
if (ack) {
|
||||
m_was_clean = true;
|
||||
}
|
||||
|
||||
// Start a timer so we don't wait forever for the acknowledgement close
|
||||
// frame
|
||||
m_handshake_timer = transport_con_type::set_timer(
|
||||
|
||||
@@ -111,17 +111,21 @@ private:
|
||||
typedef typename concurrency::scoped_lock_type scoped_lock_type;
|
||||
typedef typename concurrency::mutex_type mutex_type;
|
||||
|
||||
// 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.
|
||||
std::string get_timestamp() {
|
||||
// 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.
|
||||
//
|
||||
// TODO: find a workaround for this or make this format user settable
|
||||
char const * get_timestamp() {
|
||||
std::time_t t = std::time(NULL);
|
||||
char buffer[40];
|
||||
std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",std::localtime(&t));
|
||||
return buffer;
|
||||
std::strftime(m_buffer,sizeof(m_buffer),"%Y-%m-%d %H:%M:%S",
|
||||
std::localtime(&t));
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
mutex_type m_lock;
|
||||
|
||||
|
||||
char m_buffer[20];
|
||||
const level m_static_channels;
|
||||
level m_dynamic_channels;
|
||||
std::ostream* m_out;
|
||||
|
||||
@@ -837,6 +837,8 @@ protected:
|
||||
/**
|
||||
* Validates an incoming hybi13 full header.
|
||||
*
|
||||
* \todo unit test for the >32 bit frames on 32 bit systems case
|
||||
*
|
||||
* @param h The basic header to validate
|
||||
*
|
||||
* @param e The extended header to validate
|
||||
@@ -864,7 +866,6 @@ protected:
|
||||
}
|
||||
|
||||
// Check for >32bit frames on 32 bit systems
|
||||
// TODO: unit test for this case
|
||||
if (sizeof(size_t) == 4 && (payload_size >> 32)) {
|
||||
return make_error_code(error::requires_64bit);
|
||||
}
|
||||
|
||||
@@ -102,13 +102,18 @@ class SHA1
|
||||
|
||||
while(length-- && !Corrupted)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(suppress: 6386) // Suppresses Visual Studio code analysis for write overrun. It doesn't know the index into Message_Block is protected by checking length.
|
||||
// Suppresses Visual Studio code analysis for write overrun. It doesn't know the
|
||||
// index into Message_Block is protected by checking length.
|
||||
//
|
||||
// TODO: is there a more compatible way to write the original code to avoid
|
||||
// this sort of warning?
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(suppress: 6386)
|
||||
#endif
|
||||
Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
Length_Low += 8;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Peter Thorson. All rights reserved.
|
||||
* Copyright (c) 2013, 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,51 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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_VERSION_HPP
|
||||
#define WEBSOCKETPP_VERSION_HPP
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
/*
|
||||
other places where version information is kept
|
||||
- echo_client
|
||||
- readme.md
|
||||
- changelog.md
|
||||
- Doxyfile
|
||||
- CMakeLists.txt
|
||||
*/
|
||||
|
||||
static int const major_version = 0;
|
||||
static int const minor_version = 3;
|
||||
static int const patch_version = 0;
|
||||
static char const prerelease_flag[] = "alpha2";
|
||||
|
||||
static char const user_agent[] = "WebSocket++/0.3.0-alpha2";
|
||||
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_VERSION_HPP
|
||||
Reference in New Issue
Block a user