Пример #1
0
bool ServerIOCallback::read_callback(char* data, int len)
{
    const char* myname = "read_callback";

    if (data == NULL || *data == 0 || len <= 0)
    {
        logger_warn("invalid data: %s, len: %d",
                    data ? data : "null", len);
        return false;
    }

    // 处理服务端发来的命令

    acl::url_coder coder;
    coder.decode(data);

    logger_debug(DEBUG_SVR, 1, "client: %s", data);

    const char* ptr = coder.get("count");
    if (ptr == NULL)
    {
        logger_warn("%s(%d), %s: no count", __FILE__, __LINE__, myname);
        return true;
    }

    unsigned int nconns = (unsigned int) atoi(ptr);
    conn_->set_nconns(nconns);

    // 尝试将服务端连接对象添加进服务端管理对象中
    ServerManager::get_instance().set(conn_);

    return true;
}
Пример #2
0
// VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDENCg==
// decode result:Version: 1
// XfrCount: 1
void CMsnDSClient::parse_xfr_ver(const char* data)
{
	acl::string buf;
	buf.base64_decode(data, strlen(data));
	if (buf.empty())
		return;
	const std::list<acl::string>& args = buf.split("\r\n");
	std::list<acl::string>::const_iterator cit = args.begin();
	for (; cit != args.end(); cit++)
	{
		acl::string line = *cit;
		char* name = line.c_str();
		char* value = strchr(name, ':');
		if (value == NULL || *(value + 1) == 0)
		{
			logger_warn("invalid line(%s)", name);
			continue;
		}
		*value++ = 0;
		while (*value == ' ' || *value == '\t')
			value++;
		if (*value == 0)
		{
			logger_warn("invalid line(%s: )", name);
			continue;
		}
		if (strcasecmp(name, "Version") == 0)
			xfr_ver_ = atoi(value);
		else if (strcasecmp(name, "XfrCount") == 0)
			xfr_cnt_ = atoi(value);
	}
}
Пример #3
0
const string& query::to_string()
{
	if (params_.empty())
		return sql_;
	if (sql_buf_ == NULL)
		sql_buf_ = NEW string(sql_.length() + 32);
	else
		sql_buf_->clear();

#define SKIP_WHILE(cond, ptr) { while(*ptr && (cond)) ptr++; }

	char last_ch;
	char* src = sql_.c_str(), *ptr, *key;
	while (*src != 0)
	{
		ptr = strchr(src, ':');
		if (ptr == NULL)
		{
			sql_buf_->append(src);
			break;
		}
		else if (*++ptr == 0)
		{
			sql_buf_->append(src);
			logger_warn("the last char is ':'");
			break;
		}

		sql_buf_->append(src, ptr - src - 1);
		key = ptr;

		SKIP_WHILE(*ptr != ',' && *ptr != ';'
			&& *ptr != ' ' && *ptr != '\t'
			&& *ptr != '(' && *ptr != ')'
			&& *ptr != '\r' && *ptr != '\n', ptr);
		if (ptr - key == 1)
		{
			logger_warn("only found: ':%c'", *ptr);
			sql_buf_->append(key, ptr - key + 1);
			src = ptr + 2;
			continue;
		}

		last_ch = *ptr;
		*ptr = 0;
		(void) append_key(*sql_buf_, key);
		*ptr = last_ch;

		if (last_ch == '\0')
			break;
		src = ptr;
	}

	return *sql_buf_;
}
Пример #4
0
bool http_servlet::doPost(request_t& req, response_t& res)
{
	// 如果需要 http session 控制,请打开下面注释,且需要保证
	// 在 master_service.cpp 的函数 thread_on_read 中设置的
	// memcached 服务正常工作
	/*
	const char* sid = req.getSession().getAttribute("sid");
	if (*sid == 0)
		req.getSession().setAttribute("sid", "xxxxxx");
	sid = req.getSession().getAttribute("sid");
	*/

	// 如果需要取得浏览器 cookie 请打开下面注释
	/*
	$<GET_COOKIES>
	*/

	const char* path = req.getPathInfo();
	if (path == NULL || *path == 0) {
		logger_error("path null");
		return false;
	}

	// 根据 uri path 查找对应的处理句柄,从而实现 HTTP 路由功能

	std::map<std::string, handler_t>::iterator it = handlers_.find(path);
	if (it == handlers_.end()) {
		logger_warn("not support, path=%s", path);
		return false;
	}

	return (this->*it->second)(req, res);
}
Пример #5
0
acl_int64 aio_timer_callback::del_task(unsigned int id)
{
	bool ok = false;
	std::list<aio_timer_task*>::iterator it = tasks_.begin();
	for (; it != tasks_.end(); ++it)
	{
		if ((*it)->id == id)
		{
			delete (*it);
			tasks_.erase(it);
			length_--;
			ok = true;
			break;
		}
	}

	if (!ok)
		logger_warn("timer id: %u not found", id);

	if (tasks_.empty())
		return TIMER_EMPTY;

	set_time();

	acl_int64 delay = tasks_.front()->when - present_;
	return delay < 0 ? 0 : delay;
}
Пример #6
0
redis_result* redis_client::get_redis_object(dbuf_pool* pool)
{
	char ch;
	if (conn_.read(ch) == false)
	{
		logger_warn("read char error: %s, server: %s, fd: %u",
			last_serror(), addr_, (unsigned) conn_.sock_handle());
		return NULL;
	}

	switch (ch)
	{
	case '-':	// ERROR
		return get_redis_error(pool);
	case '+':	// STATUS
		return get_redis_status(pool);
	case ':':	// INTEGER
		return get_redis_integer(pool);
	case '$':	// STRING
		return get_redis_string(pool);
	case '*':	// ARRAY
		return get_redis_array(pool);
	default:	// INVALID
		logger_error("invalid first char: %c, %d", ch, ch);
		return NULL;
	}
}
Пример #7
0
connect_pool* connect_manager::peek()
{
	connect_pool* pool;
	size_t service_size, n;

	lock_.lock();
	service_size = pools_.size();
	if (service_size == 0)
	{
		lock_.unlock();
		logger_warn("pools's size is 0!");
		return NULL;
	}

	// 遍历所有的连接池,找出一个可用的连接池
	for(size_t i = 0; i < service_size; i++)
	{
		n = service_idx_ % service_size;
		service_idx_++;
		pool = pools_[n];
		if (pool->aliving())
		{
			lock_.unlock();
			return pool;
		}
	}

	lock_.unlock();

	logger_error("all pool(size=%d) is dead!", (int) service_size);
	return NULL;
}
Пример #8
0
bool polarssl_io::on_close(bool alive)
{
#ifdef HAS_POLARSSL
	if (ssl_ == NULL)
	{
		logger_error("ssl_ null");
		return false;
	}
	if (stream_ == NULL)
	{
		logger_error("stream_ null");
		return false;
	}

	if (!alive)
		return false;

	int   ret;
	while((ret = ssl_close_notify((ssl_context*) ssl_ )) < 0)
	{
		if( ret != POLARSSL_ERR_NET_WANT_READ &&
			ret != POLARSSL_ERR_NET_WANT_WRITE )
		{
			logger_warn("ssl_close_notify error: -0x%04x", ret);
			return false;
		}
	}
#else
	(void) alive;
#endif

	return true;
}
Пример #9
0
connect_pool* connect_manager::peek(const char* key,
	bool exclusive /* = true */)
{
	if (key == NULL || *key == 0)
		return peek();

	size_t service_size;
	connect_pool* pool;
	unsigned n = acl_hash_crc32(key, strlen(key));

	if (exclusive)
		lock_.lock();
	service_size = pools_.size();
	if (service_size == 0)
	{
		if (exclusive)
			lock_.unlock();
		logger_warn("pools's size is 0!");
		return NULL;
	}
	pool = pools_[n % service_size];
	if (exclusive)
		lock_.unlock();

	return pool;
}
Пример #10
0
void redis_commands::add_cmdline(acl::string& line, size_t i)
{
	std::vector<acl::string>& tokens = line.split2(" \t|:,;");
	if (tokens.size() < 3)
	{
		logger_warn("skip line(%d): %s", (int) i, line.c_str());
		return;
	}

	acl::string cmd(tokens[0]);
	cmd.upper();

	if (cmd == "ALL")
	{
		all_cmds_perm_ = tokens[2];
		all_cmds_perm_.lower();
		if (all_cmds_perm_ == "warn" || all_cmds_perm_ == "no")
			return;
		return;
	}

	REDIS_CMD redis_cmd;
	redis_cmd.cmd = cmd;
	redis_cmd.broadcast = tokens[1].equal("yes", false) ? true : false;

	redis_cmd.perm = tokens[2];
	redis_cmd.perm.lower();
	if (redis_cmd.perm != "yes" && redis_cmd.perm != "warn")
		redis_cmd.perm = "no";

	redis_cmds_[cmd] = redis_cmd;
}
Пример #11
0
acl_int64 event_timer::del_task(unsigned int id)
{
	bool ok = false;
	std::list<event_task*>::iterator it = tasks_.begin();
	for (; it != tasks_.end(); ++it)
	{
		if ((*it)->id == id)
		{
			delete (*it);
			tasks_.erase(it);
			length_--;
			ok = true;
			break;
		}
	}

	if (!ok)
		logger_warn("timer id: %u not found", id);

	if (tasks_.empty())
		return TIMER_EMPTY;

	set_time();

	event_task* first = tasks_.front();
	acl_int64 delay = first->when - present_;

	if (delay < 0)
		return 0;
	else if (delay > first->delay)  /* xxx */
		return first->delay;
	else
		return delay;
}
Пример #12
0
void connect_manager::set_pools_status(const char* addr, bool alive)
{
	std::vector<connect_pool*>::iterator it;
	connect_pool* pool;
	const char* ptr;

	if (addr == NULL || *addr == 0)
	{
		logger_warn("addr null");
		return;
	}

	lock();
	it = pools_.begin();
	for (; it != pools_.end(); ++it)
	{
		pool = *it;
		ptr = pool->get_addr();
		if (ptr && strcasecmp(ptr, addr) == 0)
		{
			pool->set_alive(alive);
			break;
		}
	}
	unlock();
}
Пример #13
0
// 根据输入的目标地址进行重定向:打开与该地址的连接,如果连接失败,则随机
// 选取一个服务器地址进行连接
redis_client* redis_command::redirect(redis_client_cluster* cluster,
	const char* addr)
{
	redis_client_pool* conns;

	// 如果服务器地址不存在,则根据服务器地址动态创建连接池对象
	if ((conns = (redis_client_pool*) cluster->get(addr)) == NULL)
		conns = (redis_client_pool*) &cluster->set(addr, max_conns_);

	if (conns == NULL)
		return NULL;

	redis_client* conn;

	int i = 0;

	while (i++ < 5)
	{
		conn = (redis_client*) conns->peek();
		if (conn != NULL)
			return conn;

		conns->set_alive(false);
		conns = (redis_client_pool*) cluster->peek();
		if (conns == NULL)
		{
			logger_error("no connections availabble, "
				"i: %d, addr: %s", i, addr);
			return NULL;
		}
	}

	logger_warn("too many retry: %d, addr: %s", i, addr);
	return NULL;
}
Пример #14
0
queue_file* queue_manager::open_file(const char* filePath, bool no_cache /* = true */)
{
	string home, queueName, queueSub, partName, extName;
	if (queue_manager::parse_filePath(filePath, &home, &queueName, &queueSub,
		&partName, &extName) == false)
	{
		logger_error("filePath(%s) invalid", filePath);
		return NULL;
	}

	queue_file* fp;

	// 如果该文件存在于内存中则直接返回之
	fp = cache_find(partName);
	if (fp != NULL)
	{
		if (no_cache)
		{
			logger_warn("file: %s locked", filePath);
			return NULL;
		}
		return fp;
	}

	// 从磁盘打开已经存在的队列文件
	fp = NEW queue_file;
	if (fp->open(home.c_str(), queueName.c_str(), queueSub.c_str(),
		partName.c_str(), extName.c_str()) == false)
	{
		delete fp;
		return NULL;
	}
	cache_add(fp);
	return fp;
}
Пример #15
0
void db_pgsql::load(void)
{
#ifdef HAS_PGSQL_DLL
	acl_pthread_once(&__pgsql_once, __pgsql_dll_load);
#else
	logger_warn("link pgsql library in static way!");
#endif
}
Пример #16
0
bool istream::gets(string& s, bool nonl /* = true */, size_t max /* = 0 */)
{
	char buf[8192];
	size_t size;

	s.clear();

	if (max == 0)
	{
		while (!eof())
		{
			size = sizeof(buf);
			if (gets(buf, &size, nonl) == true)
			{
				if (size > 0)
					s.append(buf, size);

				return true;
			}

			if (size == 0)
				break;

			printf(">>>size: %d\r\n", (int) size);
			s.append(buf, size);
		}

		return false;
	}

	size_t saved_max = max;

	while (!eof())
	{
		size = sizeof(buf) > max ? max : sizeof(buf);
		if (gets(buf, &size, nonl) == true)
		{
			if (size > 0)
				s.append(buf, size);
			return true;
		}

		if (size == 0)
			break;

		s.append(buf, size);
		max -= size;

		if (max == 0)
		{
			logger_warn("reached the max limit: %d",
				(int) saved_max);
			return true;
		}
	}

	return false;
}
Пример #17
0
int  hsclient::get_id() const
{
	if (tbl_curr_ == NULL)
	{
		logger_warn("tbl not open!");
		return (-1);
	}
	return (tbl_curr_->id_);
}
Пример #18
0
bool queue_manager::rename_extname(queue_file* fp, const char* extName)
{
	if (cache_check(fp) == false)
	{
		logger_warn("file(%s)'s key(%s) not exist",
			fp->get_filePath(), fp->key());
		return false;
	}
	return fp->move_file(fp->get_queueName(), extName);
}
Пример #19
0
// 设置联系人列表中的成员的在线状态
Member* CMsnContactManager::SetUserStatus(const char* passportName,
	const char* status, const char* displayName)
{
	acl_assert(passportName && status && displayName);

	std::map<acl::string, Member*>::iterator it = users_.find(passportName);
	if (it == users_.end())
		return (NULL);

	Member* member = it->second;
	if (strcasecmp(status, "NLN") == 0)
		member->online_ = member_s_online;
	else if (strcasecmp(status, "IDL") == 0)
		member->online_ = member_s_idle;
	else if (strcasecmp(status, "BSY") == 0)
		member->online_ = member_s_busy;
	else if (strcasecmp(status, "AWY"))
		member->online_ = member_s_away;
	else
		logger_warn("unkown status: %s", status);

	acl::string buf;

	// 字符集转换成 GB18030
	bool ret = conv_.convert("UTF-8", "GB18030", displayName,
		strlen(displayName), &buf);
	if (ret == false)
	{
		logger_warn("convert from utf-8 to GB18030 error");
		return (member);
	}

	if (!STRING_IS_EMPTY(member->DisplayName))
		acl_myfree(member->DisplayName);
	member->DisplayName = acl_mystrdup(buf.c_str());

	return (member);
}
Пример #20
0
void status_manager::del_status(const char* key)
{
	acl_assert(key && *key);
	std::map<acl::string, server_status*>::iterator it =
		servers_status_.find(key);
	if (it == servers_status_.end())
	{
		logger_warn("key: %s not found", key);
		return;
	}

	delete it->second;
	servers_status_.erase(it);
}
Пример #21
0
void ipc_client::trigger(int nMsg, void* data, int dlen)
{
	std::list<int>::iterator it = messages_.begin();

	// 该消息是否已经存在于已经注册的消息集合中
	for (; it != messages_.end(); ++it)
	{
		if (*it == nMsg)
		{
			on_message(nMsg, data, dlen);
			return;
		}
	}

	logger_warn("unknown msg: %d", nMsg);
}
Пример #22
0
bool query::append_key(string& buf, char* key)
{
	acl_lowercase(key);
	std::map<string, query_param*>::iterator it = params_.find(key);
	if (it == params_.end())
	{
		logger_warn("unknown key: %s", key);
		buf.append(key);
		return false;
	}

	char fmt[256];

	query_param* param = it->second;
	switch (param->type)
	{
	case DB_PARAM_CHAR:
		buf.format_append("'%c'", param->v.c);
		break;
	case DB_PARAM_SHORT:
		buf.format_append("%d", param->v.s);
		break;
	case DB_PARAM_INT32:
		buf.format_append("%d", param->v.n);
		break;
	case DB_PARAM_INT64:
		buf.format_append("%lld", param->v.l);
		break;
	case DB_PARAM_STR:
		buf.format_append("'%s'",
			escape(param->v.S, param->dlen, buf_).c_str());
		break;
	case DB_PARAM_FLOAT:
		safe_snprintf(fmt, sizeof(fmt), "%%.%df", param->precision);
		buf.format_append(fmt, param->v.f);
		break;
	case DB_PARAM_DOUBLE:
		safe_snprintf(fmt, sizeof(fmt), "%%.%df", param->precision);
		buf.format_append(fmt, param->v.d);
		break;
	default:
		logger_error("unknown type: %d", param->type);
		break;
	}

	return true;
}
Пример #23
0
bool connect_manager::start_monitor(connect_monitor* monitor)
{
	if (monitor_ != NULL)
	{
		logger_warn("one connect_monitor running!");
		return false;
	}

	monitor_ = monitor;

	// 设置检测线程为非分离模式,以便于主线程可以等待检测线程退出
	monitor_->set_detachable(false);
	// 启动检测线程
	monitor_->start();

	return true;
}
Пример #24
0
bool master_service::thread_on_read(acl::socket_stream* conn)
{
	acl::string buf;

	if (conn->gets(buf) == false)
	{
		logger_warn("gets error from %s, fd %d",
			conn->get_peer(), conn->sock_handle());
		return false;
	}
	else if(conn->format("%s\r\n", buf.c_str()) == -1)
		return false;
	else if (buf == "quit")
		return false;
	else
		return true;
}
Пример #25
0
bool req_callback::read_callback(char* data, int len)
{
	if (res_ == NULL)
	{
		logger_warn("server peer disconnected!");
		return false;
	}

	// 取得服务端连接,并将数据写入
	acl::aio_socket_stream& peer = res_->get_conn();
	peer.write(data, len);

	// 将数据写入本地请求文件
	if (req_fp_)
		req_fp_->write(data, len);

	return true;
}
Пример #26
0
bool master_service::on_accept(acl::aio_socket_stream* client)
{
    if (0)
        logger("connect from %s, fd %d", client->get_peer(true),
               client->sock_handle());

    acl_non_blocking(client->sock_handle(), ACL_BLOCKING);

    IConnection* conn;

    // 根据客户端连接服务端口号的不同来区分不同的服务应用协议
    const char* local = client->get_local(true);
    if (acl_strrncasecmp(local, var_cfg_backend_service,
                         strlen(var_cfg_backend_service)) == 0)
    {
        // 创建服务对象处理来自于后端服务模块的请求
        conn = new ServerConnection(client);
    }
    else if (acl_strrncasecmp(local, var_cfg_status_service,
                              strlen(var_cfg_status_service)) == 0)
    {
        const char* ip = client->get_peer();
        if (ip == NULL || *ip == 0)
        {
            logger_error("can't get peer ip");
            return false;
        }
        if (allow_list::get_instance().allow_manager(ip) == false)
        {
            logger_warn("deny manager ip: %s", ip);
            return false;
        }

        // 创建服务对象处理状态汇报的请求
        conn = new StatusConnection(client);
    }
    else
        // 创建对象处理来自于前端客户端模块的请求
        conn = new ClientConnection(client, var_cfg_conn_expired);

    conn->run();

    return true;
}
Пример #27
0
connect_pool* connect_manager::peek()
{
	connect_pool* pool;
	size_t service_size, n;

	lock_.lock();
	service_size = pools_.size();
	if (service_size == 0)
	{
		lock_.unlock();
		logger_warn("pools's size is 0!");
		return NULL;
	}
	n = service_idx_ % service_size;
	service_idx_++;
	lock_.unlock();
	pool = pools_[n];
	return pool;
}
Пример #28
0
void redis_monitor::status(void)
{
	acl::redis_client client(addr_, conn_timeout_, rw_timeout_);
	acl::redis redis(&client);

	std::vector<acl::redis_node*> nodes;
	redis_util::get_nodes(redis, prefer_master_, nodes);

	if (nodes.empty())
	{
		logger_error("no redis nodes available");
		return;
	}

	std::vector<acl::redis_client*> conns;
	for (std::vector<acl::redis_node*>::const_iterator
		cit = nodes.begin(); cit != nodes.end(); ++cit)
	{
		const char* addr = (*cit)->get_addr();
		if (addr == NULL || *addr == 0)
		{
			logger_warn("addr NULL, skip it");
			continue;
		}

		acl::redis_client* conn = new acl::redis_client(
			addr, conn_timeout_, rw_timeout_);
		conns.push_back(conn);
	}

	while (true)
	{
		show_status(conns);
		sleep(1);
	}

	for (std::vector<acl::redis_client*>::iterator it = conns.begin();
		it != conns.end(); ++it)
	{
		delete *it;
	}
}
Пример #29
0
void ManagerTimer::timer_callback(unsigned int)
{
	ClientConnection* client;

	// 从客户端管理对象弹出所有延迟待处理的客户端连接对象
	// 并传递给服务端,如果传递失败,则再次置入客户端管理
	// 对象,由下次定时器再次尝试处理

	logger("total client: %d, total server: %d",
		(int) ClientManager::get_instance().length(),
		(int) ServerManager::get_instance().length());

	while (true)
	{
		client = ClientManager::get_instance().pop();
		if (client == NULL)
			break;

		if (transfer(client) == true)
		{
			ClientManager::get_instance().del(client);
			delete client;
			continue;
		}

		// 如果在规定的时间内依然没有服务端准备接收连接,
		// 则直接删除该对象
		if (client->expired())
		{
			logger_error("no server side, client(%s) expired!",
				client->get_peer());
			delete client;
		}
		else
		{
			logger_warn("set client(%s) into queue",
				client->get_peer());
			ClientManager::get_instance().set(client);
		}
		break;
	}
}
Пример #30
0
void check_timer::remove_client(const char* addr, check_client* checker)
{
	// 从当前检查服务器地址列表中删除当前的检测地址
	std::map<string, int>::iterator it1 = addrs_.find(addr);
	if (it1 != addrs_.end())
		addrs_.erase(it1);
	else
		logger_warn("not found addr: %s", addr);

	// 从检测连接集群中删除本连接对象
	for (std::vector<check_client*>::iterator it2 = checkers_.begin();
		it2 != checkers_.end(); ++it2)
	{
		if ((*it2) == checker)
		{
			checkers_.erase(it2);
			break;
		}
	}
}