/** * Performs validation, masking, compression, etc. will return an error if * there was an error, otherwise msg will be ready to be written */ virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) { if (!in || !out) { return make_error_code(error::invalid_arguments); } // TODO: check if the message is prepared already // validate opcode if (in->get_opcode() != frame::opcode::text) { 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 (!utf8_validator::validate(i)) { return make_error_code(error::invalid_payload); } // generate header out->set_header(std::string(reinterpret_cast<char const *>(&msg_hdr),1)); // process payload out->set_payload(i); out->append_payload(std::string(reinterpret_cast<char const *>(&msg_ftr),1)); // hybi00 doesn't support compression // hybi00 doesn't have masking out->set_prepared(true); return lib::error_code(); }
/** * Performs validation, masking, compression, etc. will return an error if * there was an error, otherwise msg will be ready to be written * * 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)); key.i = 0; } // 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); out->set_opcode(op); return lib::error_code(); }