/** * performs validation, masking, compression, etc. will return an error if * there was an error, otherwise msg will be ready to be written * * by default websocket++ performs block masking/unmasking in a manner that * makes assumptions about the nature of the machine and stl library used. * in particular the assumption is either a 32 or 64 bit word size and an * stl with std::string::data returning a contiguous char array. * * this method improves masking performance by 3-8x depending on the ratio * of small to large messages and the availability of a 64 bit processor. * * to disable this optimization (for use with alternative stl * implementations or processors) define websocketpp_strict_masking when * compiling the library. this will force the library to perform masking in * single byte chunks. * * todo: tests * * @param in an unprepared message to prepare * @param out a message to be overwritten with the prepared message * @return error code */ virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) { if (!in || !out) { return make_error_code(error::invalid_arguments); } frame::opcode::value op = in->get_opcode(); // validate opcode: only regular data frames if (frame::opcode::is_control(op)) { return make_error_code(error::invalid_opcode); } std::string& i = in->get_raw_payload(); std::string& o = out->get_raw_payload(); // validate payload utf8 if (op == frame::opcode::text && !utf8_validator::validate(i)) { return make_error_code(error::invalid_payload); } frame::masking_key_type key; bool masked = !base::m_server; bool compressed = m_permessage_deflate.is_enabled() && in->get_compressed(); bool fin = in->get_fin(); // generate header frame::basic_header h(op,i.size(),fin,masked,compressed); if (masked) { // generate masking key. key.i = m_rng(); frame::extended_header e(i.size(),key.i); out->set_header(frame::prepare_header(h,e)); } else { frame::extended_header e(i.size()); out->set_header(frame::prepare_header(h,e)); } // prepare payload if (compressed) { // compress and store in o after header. m_permessage_deflate.compress(i,o); // mask in place if necessary if (masked) { this->masked_copy(o,o,key); } } else { // no compression, just copy data into the output buffer o.resize(i.size()); // if we are masked, have the masking function write to the output // buffer directly to avoid another copy. if not masked, copy // directly without masking. if (masked) { this->masked_copy(i,o,key); } else { std::copy(i.begin(),i.end(),o.begin()); } } out->set_prepared(true); return lib::error_code(); }
void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg) { s->send(hdl, msg->get_payload(), msg->get_opcode()); }