Exemplo n.º 1
0
static void
worker_pool_connect(struct worker *w) {

	int i;
	/* create connections */
	for(i = 0; i < w->pool->count; ++i) {
		pool_connect(w->pool, w->s->cfg->database, 1);
	}

}
Exemplo n.º 2
0
static int
ws_execute(struct http_client *c, const char *frame, size_t frame_len) {

	struct cmd*(*fun_extract)(struct http_client *, const char *, size_t) = NULL;
	formatting_fun fun_reply = NULL;

	if((c->path_sz == 1 && strncmp(c->path, "/", 1) == 0) ||
	   strncmp(c->path, "/.json", 6) == 0) {
		fun_extract = json_ws_extract;
		fun_reply = json_reply;
	} else if(strncmp(c->path, "/.raw", 5) == 0) {
		fun_extract = raw_ws_extract;
		fun_reply = raw_reply;
	}

	if(fun_extract) {

		/* Parse websocket frame into a cmd object. */
		struct cmd *cmd = fun_extract(c, frame, frame_len);

		if(cmd) {
			/* copy client info into cmd. */
			cmd_setup(cmd, c);
			cmd->is_websocket = 1;

			if (c->pub_sub != NULL) {
				/* This client already has its own connection
				 * to Redis due to a subscription; use it from
				 * now on. */
				cmd->ac = c->pub_sub->ac;
			} else if (cmd_is_subscribe(cmd)) {
				/* New subscribe command; make new Redis context
				 * for this client */
				cmd->ac = pool_connect(c->w->pool, cmd->database, 0);
				c->pub_sub = cmd;
				cmd->pub_sub_client = c;
			} else {
				/* get Redis connection from pool */
				cmd->ac = (redisAsyncContext*)pool_get_context(c->w->pool);
			}

			/* send it off */
			cmd_send(cmd, fun_reply);

			return 0;
		}
	}

	return -1;
}
Exemplo n.º 3
0
Arquivo: cmd.c Projeto: 9612jhf/webdis
cmd_response_t
cmd_run(struct worker *w, struct http_client *client,
		const char *uri, size_t uri_len,
		const char *body, size_t body_len) {

	char *qmark = memchr(uri, '?', uri_len);
	char *slash;
	const char *p, *cmd_name = uri;
	int cmd_len;
	int param_count = 0, cur_param = 1;

	struct cmd *cmd;
	formatting_fun f_format;

	/* count arguments */
	if(qmark) {
		uri_len = qmark - uri;
	}
	for(p = uri; p && p < uri + uri_len; param_count++) {
		p = memchr(p+1, '/', uri_len - (p+1-uri));
	}

	if(body && body_len) { /* PUT request */
		param_count++;
	}
	if(param_count == 0) {
		return CMD_PARAM_ERROR;
	}

	cmd = cmd_new(param_count);
	cmd->fd = client->fd;
	cmd->database = w->s->cfg->database;

	/* get output formatting function */
	uri_len = cmd_select_format(client, cmd, uri, uri_len, &f_format);

	/* add HTTP info */
	cmd_setup(cmd, client);

	/* check if we only have one command or more. */
	slash = memchr(uri, '/', uri_len);
	if(slash) {

		/* detect DB number by checking if first arg is only numbers */
		int has_db = 1;
		int db_num = 0;
		for(p = uri; p < slash; ++p) {
			if(*p < '0' || *p > '9') {
				has_db = 0;
				break;
			}
			db_num = db_num * 10 + (*p - '0');
		}

		/* shift to next arg if a db was set up */
		if(has_db) {
			char *next;
			cmd->database = db_num;
			cmd->count--; /* overcounted earlier */
			cmd_name = slash + 1;

			if((next = memchr(cmd_name, '/', uri_len - (slash - uri)))) {
				cmd_len = next - cmd_name;
			} else {
				cmd_len = uri_len - (slash - uri + 1);
			}
		} else {
			cmd_len = slash - uri;
		}
	} else {
		cmd_len = uri_len;
	}

	/* there is always a first parameter, it's the command name */
	cmd->argv[0] = malloc(cmd_len);
	memcpy(cmd->argv[0], cmd_name, cmd_len);
	cmd->argv_len[0] = cmd_len;

	/* check that the client is able to run this command */
	if(!acl_allow_command(cmd, w->s->cfg, client)) {
		cmd_free(cmd);
		return CMD_ACL_FAIL;
	}

	if(cmd_is_subscribe(cmd)) {
		/* create a new connection to Redis */
		cmd->ac = (redisAsyncContext*)pool_connect(w->pool, cmd->database, 0);

		/* register with the client, used upon disconnection */
		client->pub_sub = cmd;
		cmd->pub_sub_client = client;
	} else if(cmd->database != w->s->cfg->database) {
		/* create a new connection to Redis for custom DBs */
		cmd->ac = (redisAsyncContext*)pool_connect(w->pool, cmd->database, 0);
	} else {
		/* get a connection from the pool */
		cmd->ac = (redisAsyncContext*)pool_get_context(w->pool);
	}

	/* no args (e.g. INFO command) */
	if(!slash) {
		if(!cmd->ac) {
			cmd_free(cmd);
			return CMD_REDIS_UNAVAIL;
		}
		redisAsyncCommandArgv(cmd->ac, f_format, cmd, 1,
				(const char **)cmd->argv, cmd->argv_len);
		return CMD_SENT;
	}
	p = cmd_name + cmd_len + 1;
	while(p < uri + uri_len) {

		const char *arg = p;
		int arg_len;
		char *next = memchr(arg, '/', uri_len - (arg-uri));
		if(!next || next > uri + uri_len) { /* last argument */
			p = uri + uri_len;
			arg_len = p - arg;
		} else { /* found a slash */
			arg_len = next - arg;
			p = next + 1;
		}

		/* record argument */
		cmd->argv[cur_param] = decode_uri(arg, arg_len, &cmd->argv_len[cur_param], 1);
		cur_param++;
	}

	if(body && body_len) { /* PUT request */
		cmd->argv[cur_param] = malloc(body_len);
		memcpy(cmd->argv[cur_param], body, body_len);
		cmd->argv_len[cur_param] = body_len;
	}

	/* send it off! */
	if(cmd->ac) {
		cmd_send(cmd, f_format);
		return CMD_SENT;
	}
	/* failed to find a suitable connection to Redis. */
	cmd_free(cmd);
	client->pub_sub = NULL;
	return CMD_REDIS_UNAVAIL;
}
Exemplo n.º 4
0
        boost::system::error_code Connector::connect(
            SocketType & peer1, 
            NetName const & netname, 
            boost::system::error_code & ec)
        {
            typedef typename SocketType::protocol_type::socket socket;
            typedef typename socket::endpoint_type endpoint_type;

            socket & peer(peer1); // we should use the real socket type, not the child type

            if (netname.is_digit()) {
                return connect(peer, netname.endpoint(), ec);
            }
            if (!started_) {
                canceled_ = canceled_forever_;
                stat_.reset();
                connect_started_ = false;
                boost::asio::detail::mutex::scoped_lock lock(mutex_);
                if (canceled_) {
                    ec = boost::asio::error::operation_aborted;
                    canceled_ = false;
                } else {
                    lock.unlock();
                    resolver_iterator_ = resolver_.resolve(netname, ec);
                    lock.lock();
                }
                stat_.resolve_time = stat_.elapse();
                if (ec) {
                    return ec;
                } else if (canceled_) {
                    canceled_ = false;
                    return ec = boost::asio::error::operation_aborted;
                }
                started_ = true;
            }
            ResolverIterator end;
            for (; resolver_iterator_ != end; ++resolver_iterator_) {
                if (!connect_started_) {
                    Endpoint const & e = *resolver_iterator_;
                    {
                        boost::asio::detail::mutex::scoped_lock lock(mutex_);
                        if (canceled_) {
                            ec = boost::asio::error::operation_aborted;
                            canceled_ = false;
                        } else {
                            if (peer.is_open()) {
                                peer.close(ec);
                            }
                            boost::asio::socket_base::non_blocking_io cmd1(non_block_);
#ifndef UNDER_CE
                            boost::asio::socket_base::receive_time_out cmd2(time_out_);
#endif
                            ec || peer.open(endpoint_type(e).protocol(), ec) 
                                || peer.io_control(cmd1, ec) 
#ifndef UNDER_CE
                                || peer.set_option(cmd2, ec)
#endif
                                ;
                        }
                    }
                    if (ec) {
                        break;
                    }
                    LOG_TRACE("[connect] try server, ep: " << e.to_string());
                    start_connect(peer, e, ec);
                } else {
                    ec = boost::asio::error::would_block;
                }
                if (ec == boost::asio::error::would_block) {
                    pool_connect(peer, ec);
                }
                if (ec != boost::asio::error::would_block) {
                    if (!ec) {
                        post_connect(peer, ec);
                    } else {
                        boost::system::error_code ec1;
                        post_connect(peer, ec1);
                    }
                }
                if (!ec || ec == boost::asio::error::would_block || canceled_) {
                    break;
                }
                LOG_DEBUG("[connect] failed, ep: " << 
                    resolver_iterator_->to_string() << ",ec: " << ec.message());
            } // for
            if ((!ec || ec == boost::asio::error::would_block) && canceled_) {
                ec = boost::asio::error::operation_aborted;
            }
            if (ec != boost::asio::error::would_block) {
                stat_.connect_time = stat_.elapse();
                started_ = false;
                canceled_ = false;
            }
            return ec;
        }
Exemplo n.º 5
0
        boost::system::error_code Connector::connect(
            SocketType & peer1, 
            Endpoint const & endpoint, 
            boost::system::error_code & ec)
        {
            typedef typename SocketType::protocol_type::socket socket;
            typedef typename socket::endpoint_type endpoint_type;

            socket & peer(peer1); // we should use the real socket type, not the child type

            if (!started_) {
                canceled_ = canceled_forever_;
                stat_.reset();
                stat_.resolve_time = 0;
                if (ec) {
                    return ec;
                }
                {
                    boost::asio::detail::mutex::scoped_lock lock(mutex_);
                    if (canceled_) {
                        ec = boost::asio::error::operation_aborted;
                        canceled_ = false;
                    } else if (peer.is_open()) {
                        peer.close(ec);
                    }
                    boost::asio::socket_base::non_blocking_io cmd1(non_block_);
#ifndef UNDER_CE
                    boost::asio::socket_base::receive_time_out cmd2(time_out_);
#endif
                    ec || peer.open(endpoint_type(endpoint).protocol(), ec) 
                        || peer.io_control(cmd1, ec)
#ifndef UNDER_CE
                        || peer.set_option(cmd2, ec)
#endif
                        ;
                    started_ = true;
                }
                connect_started_ = false;
                if (ec)
                    return ec;
                start_connect(peer, endpoint, ec);
            } else {
                ec = boost::asio::error::would_block;
            }
            if (ec == boost::asio::error::would_block) {
                pool_connect(peer, ec);
            }
            if (ec == boost::asio::error::would_block) {
                if (time_out_ && stat_.elapse() > time_out_) {
                    ec = boost::asio::error::timed_out;
                }
            }
            if (ec != boost::asio::error::would_block) {
                if (!ec) {
                    post_connect(peer, ec);
                } else {
                    boost::system::error_code ec1;
                    post_connect(peer, ec1);
                }
                stat_.connect_time = stat_.elapse();
                started_ = false;
                canceled_ = false;
            } 
            return ec;
        }