diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40698038..72e922bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
* CMake hide command lines in .vcxproj Output windows"
+WebSocket:
+
+* Add is_upgrade() free function
+
API Changes:
* Provide websocket::stream accept() overloads
diff --git a/doc/quickref.xml b/doc/quickref.xml
index a1afe585..f623a339 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -107,6 +107,7 @@
Functions
async_teardown
+ is_upgrade
teardown
Options
diff --git a/include/beast/websocket/impl/rfc6455.ipp b/include/beast/websocket/impl/rfc6455.ipp
new file mode 100644
index 00000000..684112bb
--- /dev/null
+++ b/include/beast/websocket/impl/rfc6455.ipp
@@ -0,0 +1,36 @@
+//
+// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BEAST_WEBSOCKET_IMPL_RFC6455_IPP
+#define BEAST_WEBSOCKET_IMPL_RFC6455_IPP
+
+#include
+
+namespace beast {
+namespace websocket {
+
+template
+bool
+is_upgrade(http::header const& req)
+{
+ if(req.version < 11)
+ return false;
+ if(req.method != "GET")
+ return false;
+ if(! http::is_upgrade(req))
+ return false;
+ if(! http::token_list{req.fields["Upgrade"]}.exists("websocket"))
+ return false;
+ if(! req.fields.exists("Sec-WebSocket-Version"))
+ return false;
+ return true;
+}
+
+} // websocket
+} // beast
+
+#endif
diff --git a/include/beast/websocket/rfc6455.hpp b/include/beast/websocket/rfc6455.hpp
index 6051ebff..6813ed3f 100644
--- a/include/beast/websocket/rfc6455.hpp
+++ b/include/beast/websocket/rfc6455.hpp
@@ -10,13 +10,34 @@
#include
#include
-#include
+#include
#include
#include
namespace beast {
namespace websocket {
+/** Returns `true` if the specified HTTP request is a WebSocket Upgrade.
+
+ This function returns `true` when the passed HTTP Request
+ indicates a WebSocket Upgrade. It does not validate the
+ contents of the fields: it just trivially accepts requests
+ which could only possibly be a valid or invalid WebSocket
+ Upgrade message.
+
+ Callers who wish to manually read HTTP requests in their
+ server implementation can use this function to determine if
+ the request should be routed to an instance of
+ @ref websocket::stream.
+
+ @param req The HTTP Request object to check.
+
+ @return `true` if the request is a WebSocket Upgrade.
+*/
+template
+bool
+is_upgrade(beast::http::header const& req);
+
/** WebSocket frame header opcodes. */
enum class opcode : std::uint8_t
{
@@ -186,4 +207,6 @@ struct close_reason
} // websocket
} // beast
+#include
+
#endif
diff --git a/test/websocket/rfc6455.cpp b/test/websocket/rfc6455.cpp
index c34daf31..080b5f43 100644
--- a/test/websocket/rfc6455.cpp
+++ b/test/websocket/rfc6455.cpp
@@ -7,3 +7,43 @@
// Test that header file is self-contained.
#include
+
+#include
+
+namespace beast {
+namespace websocket {
+
+class rfc6455_test
+ : public beast::unit_test::suite
+{
+public:
+ void
+ test_is_upgrade()
+ {
+ http::request_header req;
+ req.version = 10;
+ BEAST_EXPECT(! is_upgrade(req));
+ req.version = 11;
+ req.method = "POST";
+ req.url = "/";
+ BEAST_EXPECT(! is_upgrade(req));
+ req.method = "GET";
+ req.fields.insert("Connection", "upgrade");
+ BEAST_EXPECT(! is_upgrade(req));
+ req.fields.insert("Upgrade", "websocket");
+ BEAST_EXPECT(! is_upgrade(req));
+ req.fields.insert("Sec-WebSocket-Version", "13");
+ BEAST_EXPECT(is_upgrade(req));
+ }
+
+ void
+ run() override
+ {
+ test_is_upgrade();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(rfc6455,websocket,beast);
+
+} // websocket
+} // beast