Exemple #1
0
bool db_mysql::begin_transaction(void)
{
	const char* sql = "start transaction";
	if (sql_update(sql) == false)
	{
		logger_error("%s error: %s", sql, get_error());
		return false;
	}
	return true;
}
Exemple #2
0
int db_mysql::affect_count(void) const
{
	if (!is_opened())
	{
		logger_error("mysql not opened yet");
		return -1;
	}

	return (int) __mysql_affected_rows(conn_);
}
Exemple #3
0
bool session::set(const char* name, const void* value, size_t len,
	bool delay /* = false */)
{
	if (delay)
	{
		std::map<string, VBUF*>::iterator it = attrs_cache_.find(name);
		if (it == attrs_cache_.end())
			attrs_cache_[name] = vbuf_new(value, len, TODO_SET);
		else
			attrs_cache_[name] = vbuf_set(it->second, value, len, TODO_SET);
		dirty_ = true;
		return true;
	}

	// 直接操作后端 cache 服务器,设置(添加/修改) 属性字段

	string buf(256);

	// 调用纯虚接口,获得原来的 sid 数据
	if (get_data(sid_->buf, buf) == false)
	{
		// 如果没有则创建新的 sid 数据
		serialize(name, value, len, buf);
	}

	// 如果存在对应 sid 的数据,则将新数据添加在原来数据中
	else
	{
		if (!sid_saved_)
			sid_saved_ = true;

		// 反序列化
		deserialize(buf, attrs_);

		// 如果该属性已存在,则需要先释放原来的属性值后再添加新值

		std::map<string, VBUF*>::iterator it = attrs_.find(name);
		if (it == attrs_.end())
			attrs_[name] = vbuf_new(value, len, TODO_SET);
		else
			attrs_[name] = vbuf_set(it->second, value, len, TODO_SET);
		serialize(attrs_, buf);  // 序列化数据
		attrs_clear(attrs_);
	}

	// 调用纯虚接口,向 memcached 或类似缓存中添加数据
	if (set_data(sid_->buf, buf.c_str(), buf.length(), ttl_) == false)
	{
		logger_error("set cache error, sid(%s)", sid_->buf);
		return false;
	}
	if (!sid_saved_)
		sid_saved_ = true;
	return true;
}
Exemple #4
0
bool http_client::read_request_head(void)
{
	// 以防万一,先清除可能的上次请求的残留的中间数据对象
	reset();

	if (stream_ == NULL)
	{
		logger_error("client stream not open yet");
		disconnected_ = true;
		return false;
	}
	ACL_VSTREAM* vstream = stream_->get_vstream();
	if (vstream == NULL)
	{
		logger_error("client stream null");
		disconnected_ = true;
		return false;
	}

	hdr_req_ = http_hdr_req_new();
	int   ret = http_hdr_req_get_sync(hdr_req_, vstream, rw_timeout_);
	if (ret == -1)
	{
		http_hdr_req_free(hdr_req_);
		hdr_req_ = NULL;
		disconnected_ = true;
		return false;
	}

	if (http_hdr_req_parse(hdr_req_) < 0)
	{
		logger_error("parse request header error");
		http_hdr_req_free(hdr_req_);
		hdr_req_ = NULL;
		disconnected_ = true;
		return false;
	}

	if (hdr_req_->hdr.content_length <= 0)
		body_finish_ = true;
	return true;
}
Exemple #5
0
bool ssl_aio_stream::ssl_client_init()
{
#ifdef HAS_POLARSSL
	ACL_VSTREAM* stream = get_vstream();
	acl_assert(stream);

	// 0. Initialize the RNG and the session data
	havege_init((havege_state*) hs_);

	int   ret;
	if ((ret = ssl_init((ssl_context*) ssl_)) != 0)
	{
		logger_error("failed, ssl_init returned %d", ret);
		return false;
	}

	ssl_set_endpoint((ssl_context*) ssl_, SSL_IS_CLIENT);
	ssl_set_authmode((ssl_context*) ssl_, SSL_VERIFY_NONE);

	ssl_set_rng((ssl_context*) ssl_, ::havege_random, hs_);
	//ssl_set_dbg((ssl_context*) ssl_, my_debug, stdout);
	ssl_set_bio((ssl_context*) ssl_, __sock_read, this, __sock_send, this);

	const int* cipher_suites = ssl_list_ciphersuites();
	if (cipher_suites == NULL)
	{
		logger_error("ssl_list_ciphersuites null");
		return false;
	}

	ssl_set_ciphersuites((ssl_context*) ssl_, cipher_suites);
	ssl_set_session((ssl_context*) ssl_, (ssl_session*) ssn_);

	acl_vstream_ctl(stream,
		ACL_VSTREAM_CTL_READ_FN, __ssl_read,
		ACL_VSTREAM_CTL_WRITE_FN, __ssl_send,
		ACL_VSTREAM_CTL_CTX, this,
		ACL_VSTREAM_CTL_END);
	acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(stream));
#endif
	return true;
}
Exemple #6
0
bool hsclient::del(const char* values[], int num,
	const char* cond /* = "=" */, int nlimit /* = 1 */, int noffset /* = 0 */)
{
	if (tbl_curr_ == NULL)
	{
		error_ = HS_ERR_NOT_OPEN;
		logger_error("tbl not opened yet!");
		return (false);
	}
	else if (values == NULL || values[0] == NULL)
	{
		error_ = HS_ERR_PARAMS;
		logger_error("values null");
		return (false);
	}
	else if (num <= 0 || num > tbl_curr_->nfld_)
	{
		error_ = HS_ERR_PARAMS;
		logger_error("num(%d) invalid, nfld(%d)",
			num, tbl_curr_->nfld_);
		return (false);
	}
	else if (cond == NULL || *cond == 0)
	{
		error_ = HS_ERR_PARAMS;
		logger_error("cond null");
		return (false);
	}

	if (nlimit <= 0)
		nlimit = 1;
	if (noffset < 0)
		noffset = 0;
	char buf[32], *limit_offset = NULL;
	if (nlimit > 1)
	{
		safe_snprintf(buf, sizeof(buf), "%d\t%d", nlimit, noffset);
		limit_offset = buf;
	}

	return (query(cond, values, num, limit_offset, 'D', 0, 0));
}
Exemple #7
0
unsigned beanstalk::beanstalk_watch(const char* tube)
{
	if (conn_.format("watch %s\r\n", tube) == -1)
	{
		logger_error("'watch %s' failed: %s", tube, last_serror());
		errbuf_ = "watch";
		return 0;
	}
	string line(128);
	if (conn_.gets(line) == false)
	{
		logger_error("'watch %s' error(%s): reply ailed",
			last_serror(), tube);
		errbuf_ = "watch";
		return 0;
	}

	ACL_ARGV* tokens = acl_argv_split(line.c_str(), "\t ");
	if (tokens->argc < 2 || strcasecmp(tokens->argv[0], "WATCHING"))
	{
		logger_error("'watch %s' error: %s", tube, line.c_str());
		errbuf_ = tokens->argv[0];
		acl_argv_free(tokens);
		close();
		return 0;
	}

	unsigned n = (unsigned) atoi(tokens->argv[1]);
	acl_argv_free(tokens);

	// 如果服务器返回所关注的队列数为 0,肯定是出错了,因为至少还有一个
	// 缺省队列:default,所以此时需要关闭连接,以尽量消除与本连接相关
	// 的错误,下一个命令会自动进行重连操作以恢复操作过程
	if (n == 0)
	{
		logger_error("'watch %s' error(%s), tube watched is 0",
			line.c_str(), tube);
		errbuf_ = line.c_str();
		close();
	}
	return n;
}
Exemple #8
0
bool mime_builder::add_body(acl::ofstream& fp)
{
	acl::string buf;
	const char* ptr;
	size_t len;
	if (body_html_)
		ptr = body_html_;
	else
		ptr = body_text_;
	if (ptr == NULL)
	{
		logger_error("no body!");
		return false;
	}

	int ret = fp.format("Content-Type: text/%s; charset=\"utf-8\"\r\n"
		"Content-Transfer-Encoding: base64\r\n\r\n",
		body_html_ ? "html" : "plain");
	if (ret == -1)
	{
		logger_error("write body header to %s error %s",
			fp.file_path(), acl::last_serror());
		return false;
	}

	len = strlen(ptr);
	acl::mime_base64::encode(ptr, (int) len, &buf);
	if (fp.write(buf) == -1)
	{
		logger_error("write body to %s error %s",
			fp.file_path(), acl::last_serror());
		return false;
	}
	else if (fp.format("\r\n") == -1)
	{
		logger_error("write body endline to %s error %s",
			fp.file_path(), acl::last_serror());
		return false;
	}
	else
		return true;
}
Exemple #9
0
bool socket_stream::get_tcp_nodelay()
{
	ACL_SOCKET sock = sock_handle();
	if (sock == ACL_SOCKET_INVALID)
	{
		logger_error("invalid socket handle");
		return false;
	}

	return acl_get_tcp_nodelay(sock) == 0 ? false : true;
}
Exemple #10
0
bool socket_stream::set_local(const char* addr)
{
	if (stream_ == NULL)
	{
		logger_error("stream not opened yet!");
		return false;
	}

	acl_vstream_set_local(stream_, addr);
	return true;
}
Exemple #11
0
const char* db_row::field_value(size_t ifield) const
{
	if (ifield >= values_.size())
	{
		logger_error("ifield(%d) invalid, values_.size: %d",
			(int) ifield, (int) values_.size());
		return (NULL);
	}

	return (values_[ifield]);
}
Exemple #12
0
static int plist_report_if_too_nested_and_continue( int res, char *path )
{
	if (res == PLIST_TOO_NESTED)
	{
		logger_error(player_log, 0,
				_("Unable to add '%s' because nesting level is too high. "
				  "It is likely to be a recursive playlist"), path);
		return 0;
	}
	return res;
}
Exemple #13
0
static int
executable(clib_package_t *pkg) {
  int rc;
  char *url = NULL;
  char *file = NULL;
  char *tarball = NULL;
  char *command = NULL;
  char *dir = NULL;
  char *deps = NULL;
  char *tmp = NULL;

  tmp = gettempdir();
  if (NULL == tmp) {
    logger_error("error", "gettempdir() out of memory");
    return -1;
  }

  E_FORMAT(&url
    , "https://github.com/%s/%s/archive/%s.tar.gz"
    , pkg->author
    , pkg->name
    , pkg->version);
  E_FORMAT(&file, "%s-%s.tar.gz", pkg->name, pkg->version);
  E_FORMAT(&tarball, "%s/%s", tmp, file);
  rc = http_get_file(url, tarball);
  E_FORMAT(&command, "cd %s && tar -xf %s", tmp, file);

  // cheap untar
  rc = system(command);
  if (0 != rc) goto cleanup;

  E_FORMAT(&dir, "%s/%s-%s", tmp, pkg->name, pkg->version);

  if (pkg->dependencies) {
    E_FORMAT(&deps, "%s/deps", dir);
    rc = clib_package_install_dependencies(pkg, deps, opts.verbose);
    if (-1 == rc) goto cleanup;
  }

  free(command);
  command = NULL;

  E_FORMAT(&command, "cd %s && %s", dir, pkg->install);
  rc = system(command);

cleanup:
  free(tmp);
  free(dir);
  free(command);
  free(tarball);
  free(file);
  free(url);
  return rc;
}
Exemple #14
0
	// 处理 text/plain 类型数据
	bool do_plain(acl::http_request& req)
	{
		acl::string body;
		if (req.get_body(body, to_charset_) == false)
		{
			logger_error("get http body error");
			return false;
		}
		printf("body:\r\n(%s)\r\n", body.c_str());
		return true;
	}
Exemple #15
0
bool socket_stream::get_tcp_non_blocking()
{
	ACL_SOCKET sock = sock_handle();
	if (sock == ACL_SOCKET_INVALID)
	{
		logger_error("invalid socket handle");
		return false;
	}

	return acl_is_blocking(sock) == 0 ? true : false;
}
Exemple #16
0
bool master_proc::run_alone(const char* addrs, const char* path /* = NULL */,
	int   count /* = 1 */)
{
	// 每个进程只能有一个实例在运行
	acl_assert(has_called == false);
	has_called = true;
	daemon_mode_ = false;
	__count_limit = count;
	acl_assert(addrs && *addrs);

#ifdef ACL_WINDOWS
	acl_cpp_init();
#endif
	ACL_EVENT* eventp = acl_event_new_select(1, 0);
	set_event(eventp);  // 调用基类方法设置事件引擎句柄

	std::vector<ACL_VSTREAM*> sstreams;
	ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t");
	ACL_ITER iter;

	acl_foreach(iter, tokens)
	{
		const char* addr = (const char*) iter.data;
		ACL_VSTREAM* sstream = acl_vstream_listen(addr, 128);
		if (sstream == NULL)
		{
			logger_error("listen %s error %s",
				addr, last_serror());
			close_all_listener(sstreams);
			acl_argv_free(tokens);
			return false;
		}

		service_on_listen(sstream);
		acl_event_enable_listen(eventp, sstream, 0,
			listen_callback, sstream);
		sstreams.push_back(sstream);
	}
	acl_argv_free(tokens);

	// 初始化配置参数
	conf_.load(path);

	service_pre_jail(NULL, NULL);
	service_init(NULL, NULL);

	while (!__stop)
		acl_event_loop(eventp);

	close_all_listener(sstreams);
	acl_event_free(eventp);
	service_exit(NULL, NULL);
	return true;
}
Exemple #17
0
int socket_stream::get_tcp_recvbuf()
{
	ACL_SOCKET sock = sock_handle();
	if (sock == ACL_SOCKET_INVALID)
	{
		logger_error("invalid socket handle");
		return -1;
	}

	return acl_tcp_get_rcvbuf(sock);
}
Exemple #18
0
aio_timer_callback::~aio_timer_callback(void)
{
	// 如果正在触发定时器的回调过程中析构过程被调用则会发生严重问题
	if (locked())
	{
		logger_error("In trigger proccess, you delete me now!");
		acl_assert(0);
	}

	clear();
}
Exemple #19
0
bool hsclient::chat()
{
	if (stream_.write(buf_) == false)
	{
		error_ = HS_ERR_WRITE;
		logger_error("send(%s) error(%s)",
			buf_.c_str(), acl_last_serror());
		return (false);
	}

	if (stream_.gets(buf_) == false)
	{
		error_ = HS_ERR_READ;
		logger_error("gets error(%s)", acl_last_serror());
		return (false);
	}

	error_ = HS_ERR_OK;
	return (true);
}
Exemple #20
0
static unsigned int
open_max(void)
{
    long z;

    if ((z = (long) sysconf(_SC_OPEN_MAX)) < 0L) {
        logger_error(NULL, "_SC_OPEN_MAX");
        return 2U;
    }
    return (unsigned int) z;
}
Exemple #21
0
bool mail_body::save_text(const char* text, size_t len, string& out) const
{
	if (!text || !len)
	{
		logger_error("invalid input!");
		return false;
	}

	const_cast<mail_body*>(this)->set_content_type("text/plain");
	return build(text, len, out);
}
Exemple #22
0
bool mail_body::save_html(const char* html, size_t len, string& out) const
{
	if (!html || !len)
	{
		logger_error("invalid input!");
		return false;
	}

	const_cast<mail_body*>(this)->set_content_type("text/html");
	return build(html, len, out);
}
Exemple #23
0
stream_hook* stream::setup_hook(stream_hook* hook)
{
	if (stream_ == NULL)
	{
		logger_error("stream_ null");
		return NULL;
	}

	stream_hook* old_hook = hook_;

	if (stream_->type == ACL_VSTREAM_TYPE_FILE)
	{
		ACL_FSTREAM_RD_FN read_fn = stream_->fread_fn;
		ACL_FSTREAM_WR_FN write_fn = stream_->fwrite_fn;

		stream_->fread_fn = fread_hook;
		stream_->fwrite_fn = fsend_hook;
		acl_vstream_add_object(stream_, HOOK_KEY, this);

		if (hook->open(stream_) == false)
		{
			// 如果打开失败,则恢复

			stream_->fread_fn = read_fn;
			stream_->fwrite_fn = write_fn;
			acl_vstream_del_object(stream_, HOOK_KEY);
			return hook;
		}
	}
	else
	{
		ACL_VSTREAM_RD_FN read_fn = stream_->read_fn;
		ACL_VSTREAM_WR_FN write_fn = stream_->write_fn;

		stream_->read_fn = read_hook;
		stream_->write_fn = send_hook;
		acl_vstream_add_object(stream_, HOOK_KEY, this);

		acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(stream_));

		if (hook->open(stream_) == false)
		{
			// 如果打开失败,则恢复

			stream_->read_fn = read_fn;
			stream_->write_fn = write_fn;
			acl_vstream_del_object(stream_, HOOK_KEY);
			return hook;
		}
	}

	hook_ = hook;
	return old_hook;
}
Exemple #24
0
bool db_store::db_update(const http_thread& http)
{
	// 获取数据库连接
	acl::db_handle* db = var_dbpool->peek();
	if (db == NULL)
	{
		logger_error("peek db connect failed!");
		return false;
	}

	// 首先打开数据库
	if (db->open(var_cfg_dbcharset) == false)
	{
		logger_error("open db error, charset: %s",
			var_cfg_dbcharset);
		var_dbpool->put(db);
		return false;
	}

	// 计算下载速度
	double speed = (http.length_ * 1000) / http.spent_http_;

	acl::string sql;
	sql.format("insert into http_tbl(addr, url, total_spent,"
		" dns_spent, connect_spent, http_spent, length, speed,"
		" success, currtime) values('%s', '%s', %.2f, %.2f, %.2f,"
		" %.2f, %d, %.2f, '%s', CURRENT_TIMESTAMP)",
		http.addr_, http.url_.c_str(), http.spent_total_,
		http.spent_dns_, http.spent_connect_, http.spent_http_,
		http.length_, speed, http.success_ ? "ok" : "error");

	// 更新数据库表字段
	if (db->sql_update(sql.c_str()) == false)
		logger_error("sql(%s) error", sql.c_str());
	else
		logger("sql: %s ok", sql.c_str());

	// 归还数据库连接
	var_dbpool->put(db);
	return true;
}
bool WebsocketServlet_impl::doPost(acl::HttpServletRequest& req,
	acl::HttpServletResponse& res)
{
	res.setContentType("text/html; charset=utf-8")	// 设置响应字符集
		.setContentEncoding(false)		// 设置是否压缩数据
		.setChunkedTransferEncoding(true);	// 采用 chunk 传输方式

	const char* ip = req.getLocalAddr();
	if (ip == NULL || *ip == 0)
	{
		logger_error("getLocalAddr error");
		return false;
	}
	unsigned short port = req.getLocalPort();
	if (port == 0)
	{
		logger_error("getLocalPort error");
		return false;
	}

	acl::string local_addr;
	local_addr << ip << ":" << port;

	printf("getLocalAddr: %s\r\n", local_addr.c_str());

	acl::string html_file;
	html_file << "www/upload.html";
	acl::string buf;
	if (acl::ifstream::load(html_file, &buf) == false)
	{
		logger_error("load %s error %s",
			html_file.c_str(), acl::last_serror());
		return doError(req, res);
	}

	buf << "<script>g_url='ws://" << local_addr << "/'</script>";

	// 发送 http 响应体,因为设置了 chunk 传输模式,所以需要多调用一次
	// res.write 且两个参数均为 0 以表示 chunk 传输数据结束
	return res.write(buf) && res.write(NULL, 0);
}
Exemple #26
0
/* Create a new connection descriptor */
server_conn_desc_t *server_conn_desc_new( int sock )
{
	server_conn_desc_t *conn_desc =
		(server_conn_desc_t *)malloc(sizeof(server_conn_desc_t));
	if (!conn_desc)
	{
		logger_error(player_log, 0, _("No enough memory!"));
		return NULL;
	}

	conn_desc->m_socket = sock;
	conn_desc->m_buf[0] = 0;
	conn_desc->m_cur_cmd = str_new("");
	if (!conn_desc->m_cur_cmd)
	{
		free(conn_desc);
		logger_error(player_log, 0, _("No enough memory!"));
		return NULL;
	}

	conn_desc->m_rdwn = rd_with_notify_new(sock);
	if (!conn_desc->m_rdwn)
	{
		logger_error(player_log, 0,
				_("Connection notification pipe create failed: %s"),
				strerror(errno));
		str_free(conn_desc->m_cur_cmd);
		free(conn_desc);
		return NULL;
	}

	/* List management */
	pthread_mutex_lock(&server_mutex);
	conn_desc->m_prev = NULL;
	conn_desc->m_next = server_conns;
	if (server_conns)
		server_conns->m_prev = conn_desc;
	server_conns = conn_desc;
	pthread_mutex_unlock(&server_mutex);
	return conn_desc;
} /* End of 'server_conn_desc_new' function */
Exemple #27
0
bool http_download::save_total(const char* body, size_t len)
{
	// 发送不带 range 字段的下载请求

	http_method_t method = body && len > 0
		? HTTP_METHOD_POST : HTTP_METHOD_GET;

	// 设置 HTTP 请求头信息
	req_->request_header().set_method(method);

	// 发送 HTTP 请求数据
	if (req_->request(body, len) == false)
	{
		logger_error("send request error, url: %s", url_);
		return false;
	}

	http_client* conn = req_->get_client();
	if (conn == NULL)
		logger_fatal("no connect to server");

	// 回调子类虚接口实现
	if (on_response(conn) == false)
	{
		logger_error("deny url(%s)'s download", url_);
		return false;
	}

	// 获得文件长度
	acl_int64 length = conn->body_length();

	// 回调子类虚接口实现
	if (on_length(length) == false)
	{
		logger_error("deny url(%s)'s download", url_);
		return false;
	}

	// 开始下载数据体过程
	return save(req_);
}
Exemple #28
0
bool redis_client::open()
{
	if (conn_.opened())
		return true;
	if (conn_.open(addr_, conn_timeout_, rw_timeout_) == false)
	{
		logger_error("connect redis %s error: %s",
			addr_, last_serror());
		return false;
	}
	return true;
}
Exemple #29
0
bool zlib_stream::zip_begin(zlib_level_t level /* = zlib_default */)
{
	is_compress_ = true;
	int   ret = __deflateInit(zstream_, level,
		ZLIB_VERSION, sizeof(z_stream));
	if (ret != Z_OK)
	{
		logger_error("deflateInit error");
		return (false);
	}
	return (true);
}
Exemple #30
0
db_handle* db_pool::peek_open(const char* charset /* = NULL */)
{
    db_handle* conn = (db_handle*) peek();

    if (conn == NULL)
        return NULL;
    if (conn->dbopen(charset) == true)
        return conn;
    logger_error("open db failed");
    put(conn, false);
    return NULL;
}