Skip to content

Commit

Permalink
Merge f8bbab0 into 1e3543f
Browse files Browse the repository at this point in the history
  • Loading branch information
vinniefalco committed Nov 3, 2016
2 parents 1e3543f + f8bbab0 commit a09a6d2
Show file tree
Hide file tree
Showing 34 changed files with 2,309 additions and 1,824 deletions.
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
1.0.0-b18

* Increase optimization settings for MSVC builds

HTTP

* Check invariants in parse_op:
* Clean up message docs

WebSocket

* Write buffer option does not change capacity
* Close connection during async_read on close frame
* Add pong, async pong to stream

Core

* Meet DynamicBuffer requirements for static_streambuf
* Fix write_frame masking and auto-fragment handling

Extras

* unit_test::suite fixes:
- New overload of fail() specifies file and line
- BEAST_EXPECTS only evaluates the reason string on a failure

--------------------------------------------------------------------------------

1.0.0-b17

* Change implicit to default value in example
Expand Down
20 changes: 16 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,33 @@ project (Beast)
set_property (GLOBAL PROPERTY USE_FOLDERS ON)

if (MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W4 /wd4100 /bigobj /D _WIN32_WINNT=0x0601 /D_SCL_SECURE_NO_WARNINGS=1 /D_CRT_SECURE_NO_WARNINGS=1")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W4 /wd4100 /bigobj /D _WIN32_WINNT=0x0601 /D _SCL_SECURE_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GL /MT")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi /Ot /MT")

set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")

# for RelWithDebInfo builds, disable incremental linking
# since CMake sets it ON by default for that build type and it
# causes warnings
string (REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" replacement_flags
${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO})
set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacement_flags})

else()
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost REQUIRED COMPONENTS coroutine context thread filesystem program_options system)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIR})

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)

set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wpedantic")
"${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-parameter")
endif()

if (APPLE AND NOT DEFINED ENV{OPENSSL_ROOT_DIR})
Expand Down Expand Up @@ -68,7 +81,6 @@ function(DoGroupSources curdir rootdir folder)
source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
else()
string(REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir})
#set(groupname ${curdir})
string(REPLACE "/" "\\" groupname ${groupname})
source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
endif()
Expand Down
4 changes: 3 additions & 1 deletion Jamroot
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@ project beast
<toolset>gcc:<cxxflags>-std=c++11
<toolset>gcc:<cxxflags>-Wno-unused-variable
<toolset>clang:<cxxflags>-std=c++11
<toolset>clang:<cxxflags>-Wno-unused-variable
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS=1
<toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS=1
<toolset>msvc:<cxxflags>-bigobj
<toolset>msvc:<cxxflags>"/wd4100 /bigobj"
<toolset>msvc,<variant>release:<cxxflags>"/Ob2 /Oi /Ot"
<os>LINUX:<define>_XOPEN_SOURCE=600
<os>LINUX:<define>_GNU_SOURCE=1
<os>SOLARIS:<define>_XOPEN_SOURCE=500
Expand Down
110 changes: 75 additions & 35 deletions doc/websocket.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
<member><link linkend="beast.websocket.handshaking">Handshaking</link></member>
<member><link linkend="beast.websocket.messages">Messages</link></member>
<member><link linkend="beast.websocket.frames">Frames</link></member>
<member><link linkend="beast.websocket.controlframes">Control frames</link></member>
<member><link linkend="beast.websocket.pongs">Pong messages</link></member>
<member><link linkend="beast.websocket.control">Control Frames</link></member>
<member><link linkend="beast.websocket.buffers">Buffers</link></member>
<member><link linkend="beast.websocket.async">Asynchronous interface</link></member>
<member><link linkend="beast.websocket.io_service">The io_service</link></member>
Expand Down Expand Up @@ -292,42 +291,45 @@ void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws)



[section:controlframes Control frames]
[section:control Control Frames]

During read operations, the implementation automatically reads and processes
WebSocket control frames such as ping, pong, and close. Pings are replied
to as soon as possible, pongs are delivered to the pong callback. The receipt
of a close frame initiates the WebSocket close procedure, eventually resulting
in the error code [link beast.ref.websocket__error `error::closed`] being
delivered to the caller in a subsequent read operation, assuming no other error
takes place.
Control frames are small (less than 128 bytes) messages entirely contained
in an individual WebSocket frame. They may be sent at any time by either
peer on an established connection, and can appear in between continuation
frames for a message. There are three types of control frames: ping, pong,
and close.

To ensure timely delivery of control frames, large messages can be broken up
into smaller sized frames. The automatic fragment option turns on this
feature, and the write buffer size option determines the maximum size of
the fragments:
```
...
ws.set_option(beast::websocket::auto_fragment{true});
ws.set_option(beast::websocket::write_buffer_size{16384});
```
A sent ping indicates a request that the sender wants to receive a pong. A
pong is a response to a ping. Pongs may be sent unsolicited, at any time.
One use for an unsolicited pong is to inform the remote peer that the
session is still active after a long period of inactivity. A close frame
indicates that the remote peer wishes to close the WebSocket connection.
The connection is considered gracefully closed when each side has sent
and received a close frame.

The WebSocket protocol defines a procedure and control message for initiating
a close of the session. Handling of close initiated by the remote end of the
connection is performed automatically. To manually initiate a close, use
[link beast.ref.websocket__stream.close `close`]:
```
ws.close();
```

[note To receive the [link beast.ref.websocket__error `error::closed`]
error, a read operation is required. ]

[endsect]
During read operations, Beast automatically reads and processes control
frames. Pings are replied to as soon as possible with a pong, received
pongs are delivered to the pong callback. The receipt of a close frame
initiates the WebSocket close procedure, eventually resulting in the error
code [link beast.ref.websocket__error `error::closed`] being delivered
to the caller in a subsequent read operation, assuming no other error
takes place.

A consequence of this automatic behavior is that caller-initiated read
operations can cause socket writes. However, these writes will not
compete with caller-initiated write operations. For the purposes of
correctness with respect to the stream invariants, caller-initiated
read operations still only count as a read. This means that callers can
have a simultaneous active read and write operation in progress, while
the implementation also automatically handles control frames.

[heading Ping and Pong Frames]

[section:pongs Pong messages]
Ping and pong messages are control frames which may be sent at any time
by either peer on an established WebSocket connection. They are sent
using the functions
[link beast.ref.websocket__stream.ping `ping`] and
[link beast.ref.websocket__stream.pong `pong`].

To receive pong control frames, callers may register a "pong callback" using
[link beast.ref.websocket__stream.set_option `set_option`]. The object provided
Expand All @@ -348,9 +350,47 @@ reset when a pong is received. The same callback is used for both synchronous
and asynchronous reads. The pong callback is passive; in order to receive
pongs, a synchronous or asynchronous stream read function must be active.

[note When an asynchronous read function receives a pong, the the pong callback
is invoked in the same manner as that used to invoke the final completion
handler of the corresponding read function.]
[note
When an asynchronous read function receives a pong, the the pong
callback is invoked in the same manner as that used to invoke the
final completion handler of the corresponding read function.
]

[heading Close Frames]

The WebSocket protocol defines a procedure and control message for initiating
a close of the session. Handling of close initiated by the remote end of the
connection is performed automatically. To manually initiate a close, use
the [link beast.ref.websocket__stream.close `close`] function:
```
ws.close();
```

When the remote peer initiates a close by sending a close frame, Beast
will handle it for you by causing the next read to return `error::closed`.
When this error code is delivered, it indicates to the application that
the WebSocket connection has been closed cleanly, and that the TCP/IP
connection has been closed. After initiating a close, it is necessary to
continue reading messages until receiving the error `error::closed`. This
is because the remote peer may still be sending message and control frames
before it receives and responds to the close frame.

[important
To receive the [link beast.ref.websocket__error `error::closed`]
error, a read operation is required.
]

[heading Auto-fragment]

To ensure timely delivery of control frames, large messages can be broken up
into smaller sized frames. The automatic fragment option turns on this
feature, and the write buffer size option determines the maximum size of
the fragments:
```
...
ws.set_option(beast::websocket::auto_fragment{true});
ws.set_option(beast::websocket::write_buffer_size{16384});
```

[endsect]

Expand Down
74 changes: 53 additions & 21 deletions extras/beast/unit_test/suite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,27 @@
namespace beast {
namespace unit_test {

namespace detail {

template<class String>
static
std::string
make_reason(String const& reason,
char const* file, int line)
{
std::string s(reason);
if(! s.empty())
s.append(": ");
namespace fs = boost::filesystem;
s.append(fs::path{file}.filename().string());
s.append("(");
s.append(std::to_string(line));
s.append(")");
return s;
}

} // detail

class thread;

enum abort_t
Expand Down Expand Up @@ -178,11 +199,21 @@ class suite

/** Record a failure.
@param reason
@param reason Optional text added to the output on a failure.
@param file The source code file where the test failed.
@param line The source code line number where the test failed.
*/
/** @{ */
template<class String>
void
fail(String const& reason, char const* file, int line);

template<class = void>
void
fail(std::string const& reason = "");
/** @} */

/** Evaluate a test condition.
Expand All @@ -206,25 +237,25 @@ class suite
bool
expect(Condition const& shouldBeTrue)
{
return expect(shouldBeTrue, {});
return expect(shouldBeTrue, "");
}

template<class Condition>
template<class Condition, class String>
bool
expect(Condition const& shouldBeTrue, std::string const& reason);
expect(Condition const& shouldBeTrue, String const& reason);

template<class Condition>
bool
expect(Condition const& shouldBeTrue,
char const* file, int line)
{
return expect(shouldBeTrue, {}, file, line);
return expect(shouldBeTrue, "", file, line);
}

template<class Condition>
template<class Condition, class String>
bool
expect(Condition const& shouldBeTrue,
std::string const& reason, char const* file, int line);
String const& reason, char const* file, int line);
/** @} */

//
Expand Down Expand Up @@ -402,11 +433,11 @@ operator()(runner& r)
}
}

template<class Condition>
template<class Condition, class String>
bool
suite::
expect(
Condition const& shouldBeTrue, std::string const& reason)
Condition const& shouldBeTrue, String const& reason)
{
if(shouldBeTrue)
{
Expand All @@ -417,26 +448,18 @@ expect(
return false;
}

template<class Condition>
template<class Condition, class String>
bool
suite::
expect(Condition const& shouldBeTrue,
std::string const& reason, char const* file, int line)
String const& reason, char const* file, int line)
{
if(shouldBeTrue)
{
pass();
return true;
}
std::string s;
if(! reason.empty())
{
s += reason;
s += " ";
}
s += boost::filesystem::path{file}.filename().string() +
"(" + std::to_string(line) + ")";
fail(s);
fail(detail::make_reason(reason, file, line));
return false;
}

Expand Down Expand Up @@ -535,6 +558,14 @@ fail(std::string const& reason)
}
}

template<class String>
void
suite::
fail(String const& reason, char const* file, int line)
{
fail(detail::make_reason(reason, file, line));
}

inline
void
suite::
Expand Down Expand Up @@ -583,7 +614,8 @@ run(runner& r)
If the condition is false, the file and line number are reported.
*/
#define BEAST_EXPECTS(cond, reason) expect(cond, reason, __FILE__, __LINE__)
#define BEAST_EXPECTS(cond, reason) ((cond) ? (pass(), true) : \
(fail((reason), __FILE__, __LINE__), false))
#endif

} // unit_test
Expand Down
Loading

0 comments on commit a09a6d2

Please sign in to comment.