Go to the documentation of this file.00001 #ifndef CPP_WEB_SERVER_WEBSOCKET_MESSAGE_HPP
00002 #define CPP_WEB_SERVER_WEBSOCKET_MESSAGE_HPP
00003
00004 #include <boost/asio.hpp>
00005 #include <boost/shared_ptr.hpp>
00006 #include <boost/logic/tribool.hpp>
00007 #include <boost/tuple/tuple.hpp>
00008
00009 namespace async_web_server_cpp
00010 {
00011
00012 class WebsocketMessage;
00013
00017 class WebsocketFrame
00018 {
00019 public:
00020 struct Header
00021 {
00022 enum opcode
00023 {
00024 opcode_continuation = 0,
00025 opcode_text = 1,
00026 opcode_binary = 2,
00027 opcode_close = 8,
00028 opcode_ping = 9,
00029 opcode_pong = 10,
00030 } opcode : 4;
00031 bool rsv3 : 1;
00032 bool rsv2 : 1;
00033 bool rsv1 : 1;
00034 bool fin : 1;
00035
00036 unsigned int len : 7;
00037 bool mask : 1;
00038 } __attribute__((__packed__));
00039 union
00040 {
00041 Header header;
00042 char header_bytes[2];
00043 };
00044 uint64_t length;
00045 unsigned char mask[4];
00046 std::string content;
00047
00048 bool fromMessage(const WebsocketMessage& message);
00049 bool serialize(std::vector<unsigned char>& buffer);
00050 };
00051
00052 class WebsocketFrameParser
00053 {
00054 public:
00055 WebsocketFrameParser();
00056 void reset();
00057 boost::tribool consume(WebsocketFrame& frame, char input);
00058 template<typename InputIterator>
00059 boost::tuple<boost::tribool, InputIterator> parse(WebsocketFrame& frame,
00060 InputIterator begin, InputIterator end)
00061 {
00062 while (begin != end)
00063 {
00064 boost::tribool result = consume(frame, *begin++);
00065 if (result || !result)
00066 return boost::make_tuple(result, begin);
00067 }
00068 boost::tribool result = boost::indeterminate;
00069 return boost::make_tuple(result, begin);
00070 }
00071
00072 private:
00073 enum state
00074 {
00075 header_byte1,
00076 header_byte2,
00077 length_8bytes_left,
00078 length_7bytes_left,
00079 length_6bytes_left,
00080 length_5bytes_left,
00081 length_4bytes_left,
00082 length_3bytes_left,
00083 length_2bytes_left,
00084 length_1bytes_left,
00085 mask_byte1,
00086 mask_byte2,
00087 mask_byte3,
00088 mask_byte4,
00089 body
00090 } state_;
00091
00092 };
00093
00098 class WebsocketMessage
00099 {
00100 public:
00101 WebsocketMessage();
00102 enum type
00103 {
00104 type_unknown,
00105 type_text,
00106 type_binary,
00107 type_close,
00108 type_ping,
00109 type_pong,
00110 } type;
00111 std::string content;
00112 };
00113
00114 class WebsocketFrameBuffer
00115 {
00116 public:
00117 boost::tribool consume(WebsocketMessage& message, WebsocketFrame& frame);
00118 };
00119
00120
00121 }
00122
00123 #endif