lib::error_code process_handshake(request_type const & req, std::string const & subprotocol, response_type & res) const { std::array<char, 16> key_final; // copy key1 into final key decode_client_key(req.get_header("Sec-WebSocket-Key1"), &key_final[0]); // copy key2 into final key decode_client_key(req.get_header("Sec-WebSocket-Key2"), &key_final[4]); // copy key3 into final key // key3 should be exactly 8 bytes. If it is more it will be truncated // if it is less the final key will almost certainly be wrong. // TODO: decide if it is best to silently fail here or produce some sort // of warning or exception. const std::string& key3 = req.get_header("Sec-WebSocket-Key3"); auto sz = std::min(size_t(8), key3.size()); std::copy(key3.begin(), key3.begin() + sz, key_final.begin() + 8); res.append_header( "Sec-WebSocket-Key3", md5::md5_hash_string(std::string(key_final.begin(), key_final.end())) ); res.append_header("Upgrade","WebSocket"); res.append_header("Connection","Upgrade"); // Echo back client's origin unless our local application set a // more restrictive one. if (res.get_header("Sec-WebSocket-Origin") == "") { res.append_header("Sec-WebSocket-Origin",req.get_header("Origin")); } // Echo back the client's request host unless our local application // set a different one. if (res.get_header("Sec-WebSocket-Location") == "") { uri_ptr uri = get_uri(req); res.append_header("Sec-WebSocket-Location",uri->str()); } if (subprotocol != "") { res.replace_header("Sec-WebSocket-Protocol",subprotocol); } return lib::error_code(); }
void handshake_response(const http::parser::request& request,http::parser::response& response) { char key_final[16]; // copy key1 into final key decode_client_key(request.header("Sec-WebSocket-Key1"), &key_final[0]); // copy key2 into final key decode_client_key(request.header("Sec-WebSocket-Key2"), &key_final[4]); // copy key3 into final key // key3 should be exactly 8 bytes. If it is more it will be truncated // if it is less the final key will almost certainly be wrong. // TODO: decide if it is best to silently fail here or produce some sort // of warning or exception. const std::string& key3 = request.header("Sec-WebSocket-Key3"); std::copy(key3.c_str(), key3.c_str()+std::min(static_cast<size_t>(8), key3.size()), &key_final[8]); m_key3 = md5_hash_string(std::string(key_final,16)); response.add_header("Upgrade","websocket"); response.add_header("Connection","Upgrade"); // TODO: require headers that need application specific information? // Echo back client's origin unless our local application set a // more restrictive one. if (response.header("Sec-WebSocket-Origin") == "") { response.add_header("Sec-WebSocket-Origin",request.header("Origin")); } // Echo back the client's request host unless our local application // set a different one. if (response.header("Sec-WebSocket-Location") == "") { // TODO: extract from host header rather than hard code uri_ptr uri = get_uri(request); response.add_header("Sec-WebSocket-Location",uri->str()); } }