Пример #1
0
void
websocket_info::parse_sec_keys(request_impl const &req) {

	std::string const &key1 = req.header(WS_STR_SEC_WEBSOCKET_KEY1);
	if (key1.empty()) {
		return;
	}
	std::string const &key2 = req.header(WS_STR_SEC_WEBSOCKET_KEY2);
	if (key2.empty()) {
		return;
	}

	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_);
}
Пример #2
0
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;
}
Пример #3
0
void
websocket_info::parse_sec_key(request_impl const &req) {

	std::string const &key = req.header(WS_STR_SEC_WEBSOCKET_KEY);
	if (key.empty()) {
		throw std::runtime_error("can not find key in websocket request");
	}

	enum { SHA_OUTPUT_SIZE = 20 };
	unsigned char obuf[SHA_OUTPUT_SIZE];

	std::string const key_data = key + WS_STR_SECRET_WORD;
	SHA1((const unsigned char*)key_data.c_str(), key_data.size(), obuf);

	BIO *b64 = BIO_new(BIO_f_base64());
	if (NULL == b64) {
		throw std::bad_alloc();
	}

	cleanup_bio cleaner(b64);
	BIO *bmem = BIO_new(BIO_s_mem());
	if (NULL == bmem) {
		throw std::bad_alloc();
	}

	cleaner.bio_ = b64 = BIO_push(b64, bmem);

	BIO_write(b64, obuf, sizeof(obuf));
	BIO_flush(b64);

	BUF_MEM *bptr = NULL;
        BIO_get_mem_ptr(b64, &bptr);

	if (NULL == bptr || NULL == bptr->data || bptr->length != (BASE64_LENGTH(SHA_OUTPUT_SIZE) + 1)) { 
		throw std::runtime_error("can not create accept data in websocket request");
	}
	sec_data_.assign((const char*)bptr->data, bptr->length - 1);
}
Пример #4
0
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);
}
Пример #5
0
void
connection_base::init(request_impl &req, bool secure) {
	if (ws_info_.parse(req, secure)) {
		req.set_websocket();
	}
}
Пример #6
0
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;
}