bool websocket_info::parse(request_impl const &req, bool secure) { if (req.header(WS_STR_CONNECTION) != WS_STR_UPGRADE || req.header(WS_STR_UPGRADE) != WS_STR_WEBSOCKET) { return false; } empty_ = false; std::string const &host = req.header(WS_STR_HOST); if (host.empty()) { throw std::runtime_error("can not find Host in websocket request"); } std::string const &key1 = req.header(WS_STR_SEC_WEBSOCKET_KEY1); std::string const &key2 = req.header(WS_STR_SEC_WEBSOCKET_KEY2); if (!key1.empty() && !key2.empty()) { if (req.body().size() < 8) { throw std::runtime_error("can not find data in websocket request"); } boost::int32_t v1 = get_websocket_key_value(key1.c_str(), WS_STR_SEC_WEBSOCKET_KEY1); boost::int32_t v2 = get_websocket_key_value(key2.c_str(), WS_STR_SEC_WEBSOCKET_KEY2); MD5_CTX md5handler; MD5_Init(&md5handler); MD5_Update(&md5handler, &v1, sizeof(v1)); MD5_Update(&md5handler, &v2, sizeof(v2)); MD5_Update(&md5handler, req.body().data(), 8); std::string str; str.resize(16); MD5_Final((unsigned char*)&str[0], &md5handler); str.swap(sec_data_); } std::string const &uri = req.uri(); if (secure) { location_.reserve(WS_STR_SECURE_SCHEME_DELIMITER.size() + host.size() + uri.size() + 1); location_.assign(WS_STR_SECURE_SCHEME_DELIMITER).append(host).append(uri); } else { location_.reserve(WS_STR_SCHEME_DELIMITER.size() + host.size() + uri.size() + 1); location_.assign(WS_STR_SCHEME_DELIMITER).append(host).append(uri); } origin_ = req.header(WS_STR_ORIGIN); protocol_ = req.header(WS_STR_WEBSOCKET_PROTOCOL); return true; }
void websocket_info::parse(request_impl const &req) { if (req.header(WS_STR_CONNECTION) != WS_STR_UPGRADE || req.header(WS_STR_UPGRADE) != WS_STR_WEBSOCKET) { return; } empty_ = false; std::string const &host = req.header(WS_STR_HOST); if (host.empty()) { throw std::runtime_error("can not find Host in websocket request"); } std::string const &uri = req.uri(); location_.reserve(WS_STR_SCHEME_DELIMITER.size() + host.size() + uri.size() + 1); location_.assign(WS_STR_SCHEME_DELIMITER).append(host).append(uri); origin_ = req.header(WS_STR_ORIGIN); protocol_ = req.header(WS_STR_PROTOCOL); }
bool websocket_info::parse(request_impl const &req, bool secure) { if (req.header(WS_STR_CONNECTION) != WS_STR_UPGRADE) { return false; } std::string const &upgrade_hdr = req.header(WS_STR_UPGRADE); if (upgrade_hdr == WS_STR_WEBSOCKET_LOWERCASE) { std::string const &version_hdr = req.header(WS_STR_SEC_WEBSOCKET_VERSION); if (version_hdr == "13") { proto_13_ = true; } else if (version_hdr != "7" && version_hdr != "8") { throw std::runtime_error("not supported websocket protocol version: " + version_hdr); } proto_newsec_ = true; } else if (upgrade_hdr != WS_STR_WEBSOCKET) { return false; } empty_ = false; std::string const &host = req.header(WS_STR_HOST); if (host.empty()) { throw std::runtime_error("can not find Host in websocket request"); } if (proto_newsec_) { parse_sec_key(req); } else { parse_sec_keys(req); } std::string const &uri = req.uri(); if (secure) { location_.reserve(WS_STR_SECURE_SCHEME_DELIMITER.size() + host.size() + uri.size() + 1); location_.assign(WS_STR_SECURE_SCHEME_DELIMITER).append(host).append(uri); } else { location_.reserve(WS_STR_SCHEME_DELIMITER.size() + host.size() + uri.size() + 1); location_.assign(WS_STR_SCHEME_DELIMITER).append(host).append(uri); } if (proto_newsec_ && !proto_13_) { // 7 or 8 origin_ = req.header(WS_STR_SEC_WEBSOCKET_ORIGIN); if (origin_.empty()) { // draft 11,12 ? origin_ = req.header(WS_STR_ORIGIN); } } else { origin_ = req.header(WS_STR_ORIGIN); } protocol_ = req.header(WS_STR_WEBSOCKET_PROTOCOL); if (proto_newsec_) { size_t pos = protocol_.find(','); if (std::string::npos != pos) { protocol_.erase(pos); } } return true; }