00001 #include "async_web_server_cpp/websocket_message.hpp" 00002 00003 namespace async_web_server_cpp 00004 { 00005 00006 bool WebsocketFrame::fromMessage(const WebsocketMessage& message) 00007 { 00008 switch (message.type) 00009 { 00010 case WebsocketMessage::type_text: 00011 header.opcode = WebsocketFrame::Header::opcode_text; 00012 break; 00013 case WebsocketMessage::type_binary: 00014 header.opcode = WebsocketFrame::Header::opcode_binary; 00015 break; 00016 case WebsocketMessage::type_close: 00017 header.opcode = WebsocketFrame::Header::opcode_close; 00018 break; 00019 case WebsocketMessage::type_ping: 00020 header.opcode = WebsocketFrame::Header::opcode_ping; 00021 break; 00022 case WebsocketMessage::type_pong: 00023 header.opcode = WebsocketFrame::Header::opcode_pong; 00024 break; 00025 default: 00026 return false; 00027 } 00028 header.fin = true; 00029 header.rsv1 = false; 00030 header.rsv2 = false; 00031 header.rsv3 = false; 00032 content = message.content; 00033 length = message.content.size(); 00034 return true; 00035 } 00036 00037 bool WebsocketFrame::serialize(std::vector<unsigned char>& buffer) 00038 { 00039 int header_size = 2; // first two bytes of header 00040 if (length < 126) 00041 { 00042 header.len = length; 00043 } 00044 else if (length <= std::numeric_limits<uint16_t>::max()) 00045 { 00046 header.len = 126; 00047 header_size += 2; 00048 } 00049 else if (length <= std::numeric_limits<uint64_t>::max()) 00050 { 00051 header.len = 127; 00052 header_size += 8; 00053 } 00054 else 00055 return false; // Message too big 00056 header.mask = false; // sending from server 00057 00058 buffer.resize(header_size + content.size()); 00059 buffer[0] = header_bytes[0]; 00060 buffer[1] = header_bytes[1]; 00061 00062 if (length < 126) 00063 { 00064 // already copied in header bytes 00065 } 00066 else if (length <= std::numeric_limits<uint16_t>::max()) 00067 { 00068 buffer[2] = (length >> 8) & 0xFF; 00069 buffer[3] = (length >> 0) & 0xFF; 00070 } 00071 else if (length <= std::numeric_limits<uint64_t>::max()) 00072 { 00073 buffer[2] = (length >> 56) & 0xFF; 00074 buffer[3] = (length >> 48) & 0xFF; 00075 buffer[4] = (length >> 40) & 0xFF; 00076 buffer[5] = (length >> 32) & 0xFF; 00077 buffer[6] = (length >> 24) & 0xFF; 00078 buffer[7] = (length >> 16) & 0xFF; 00079 buffer[8] = (length >> 8) & 0xFF; 00080 buffer[9] = (length >> 0) & 0xFF; 00081 } 00082 content.copy((char*)&buffer[header_size], content.size()); 00083 return true; 00084 } 00085 00086 00087 WebsocketFrameParser::WebsocketFrameParser() 00088 { 00089 reset(); 00090 } 00091 00092 void WebsocketFrameParser::reset() 00093 { 00094 state_ = header_byte1; 00095 } 00096 00097 boost::tribool WebsocketFrameParser::consume(WebsocketFrame& frame, char input) 00098 { 00099 switch (state_) 00100 { 00101 case header_byte1: 00102 frame.header_bytes[0] = input; 00103 state_ = header_byte2; 00104 return boost::indeterminate; 00105 case header_byte2: 00106 frame.header_bytes[1] = input; 00107 if (frame.header.len < 126) 00108 { 00109 frame.length = frame.header.len; 00110 frame.content.reserve(frame.length); 00111 frame.content.resize(0); 00112 if (frame.header.mask) 00113 state_ = mask_byte1; 00114 else if (frame.length > 0) 00115 state_ = body; 00116 else 00117 return true; 00118 } 00119 else if (frame.header.len == 126) 00120 { 00121 frame.length = 0; 00122 state_ = length_2bytes_left; 00123 } 00124 else 00125 { 00126 frame.length = 0; 00127 state_ = length_8bytes_left; 00128 } 00129 return boost::indeterminate; 00130 00131 case length_8bytes_left: 00132 frame.length |= ((uint64_t)(input & 0xFF) << 56); 00133 state_ = length_7bytes_left; 00134 return boost::indeterminate; 00135 case length_7bytes_left: 00136 frame.length |= ((uint64_t)(input & 0xFF) << 48); 00137 state_ = length_6bytes_left; 00138 return boost::indeterminate; 00139 case length_6bytes_left: 00140 frame.length |= ((uint64_t)(input & 0xFF) << 40); 00141 state_ = length_5bytes_left; 00142 return boost::indeterminate; 00143 case length_5bytes_left: 00144 frame.length |= ((uint64_t)(input & 0xFF) << 32); 00145 state_ = length_4bytes_left; 00146 return boost::indeterminate; 00147 case length_4bytes_left: 00148 frame.length |= ((uint64_t)(input & 0xFF) << 24); 00149 state_ = length_3bytes_left; 00150 return boost::indeterminate; 00151 case length_3bytes_left: 00152 frame.length |= ((uint64_t)(input & 0xFF) << 16); 00153 state_ = length_2bytes_left; 00154 return boost::indeterminate; 00155 case length_2bytes_left: 00156 frame.length |= ((uint64_t)(input & 0xFF) << 8); 00157 state_ = length_1bytes_left; 00158 return boost::indeterminate; 00159 case length_1bytes_left: 00160 frame.length |= ((uint64_t)(input & 0xFF) << 0); 00161 frame.content.reserve(frame.length); 00162 frame.content.resize(0); 00163 if (frame.header.mask) 00164 state_ = mask_byte1; 00165 else 00166 state_ = body; 00167 return boost::indeterminate; 00168 00169 00170 case mask_byte1: 00171 frame.mask[0] = input; 00172 state_ = mask_byte2; 00173 return boost::indeterminate; 00174 case mask_byte2: 00175 frame.mask[1] = input; 00176 state_ = mask_byte3; 00177 return boost::indeterminate; 00178 case mask_byte3: 00179 frame.mask[2] = input; 00180 state_ = mask_byte4; 00181 return boost::indeterminate; 00182 case mask_byte4: 00183 frame.mask[3] = input; 00184 if (frame.length > 0) 00185 state_ = body; 00186 else 00187 return true; 00188 return boost::indeterminate; 00189 00190 case body: 00191 frame.content += input; 00192 if (frame.content.size() < frame.length) 00193 return boost::indeterminate; 00194 //unmask the frame 00195 if (frame.header.mask) 00196 { 00197 for (int i = 0; i < frame.length; ++i) 00198 { 00199 frame.content[i] = frame.content[i] ^ frame.mask[i % 4]; 00200 } 00201 } 00202 return true; 00203 default: 00204 return false; 00205 } 00206 } 00207 00208 WebsocketMessage::WebsocketMessage() : type(type_unknown) {} 00209 00210 boost::tribool WebsocketFrameBuffer::consume(WebsocketMessage& message, WebsocketFrame& frame) 00211 { 00212 if (frame.header.opcode == WebsocketFrame::Header::opcode_continuation) 00213 { 00214 if (message.type == WebsocketMessage::type_unknown) 00215 return false; 00216 else 00217 message.content.append(frame.content); 00218 } 00219 else 00220 { 00221 switch (frame.header.opcode) 00222 { 00223 case WebsocketFrame::Header::opcode_text: 00224 message.type = WebsocketMessage::type_text; 00225 break; 00226 case WebsocketFrame::Header::opcode_binary: 00227 message.type = WebsocketMessage::type_binary; 00228 break; 00229 case WebsocketFrame::Header::opcode_close: 00230 message.type = WebsocketMessage::type_close; 00231 break; 00232 case WebsocketFrame::Header::opcode_ping: 00233 message.type = WebsocketMessage::type_ping; 00234 break; 00235 case WebsocketFrame::Header::opcode_pong: 00236 message.type = WebsocketMessage::type_pong; 00237 break; 00238 default: 00239 message.type = WebsocketMessage::type_unknown; 00240 return false; 00241 } 00242 message.content = frame.content; 00243 } 00244 if (frame.header.fin) 00245 return true; 00246 else 00247 return boost::indeterminate; 00248 } 00249 00250 00251 }