示例#1
0
ret_t
cherokee_handler_tmi_init (cherokee_handler_tmi_t *hdl)
{
    ret_t ret;
    cherokee_connection_t *conn = HANDLER_CONN(hdl);
    cherokee_buffer_t	 *tmp  = &HANDLER_THREAD(hdl)->tmp_buf1;
    cherokee_handler_tmi_props_t *props = HANDLER_TMI_PROPS(hdl);

    /* We are going to look for gzipped encoding */
    cherokee_buffer_clean (tmp);
    ret = cherokee_header_copy_known (&conn->header, header_content_encoding, tmp);
    if (ret == ret_ok && cherokee_buffer_cmp_str(tmp, "gzip") == 0) {
        TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf);
        hdl->inflated = true;
    } else {
        cherokee_buffer_clean (tmp);
        ret = cherokee_header_copy_known (&conn->header, header_content_type, tmp);
        if (ret == ret_ok && (cherokee_buffer_cmp_str(tmp, "application/gzip") == 0 || cherokee_buffer_cmp_str(tmp, "application/zip") == 0)) {
            TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf);
            hdl->inflated = true;
        } else {
            hdl->inflated = false;
        }
    }

#ifdef LIBXML_PUSH_ENABLED
    if (props->validate_xml) {
        hdl->validate_xml = true;
        hdl->ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
        xmlCtxtUseOptions(hdl->ctxt, XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NONET | XML_PARSE_COMPACT);

        if (hdl->inflated) {
            /* allocate inflate state */
            hdl->strm.zalloc = Z_NULL;
            hdl->strm.zfree = Z_NULL;
            hdl->strm.opaque = Z_NULL;
            hdl->strm.avail_in = 0;
            hdl->strm.next_in = Z_NULL;
            hdl->z_ret = inflateInit2(&(hdl->strm), 16+MAX_WBITS);
            if (hdl->z_ret != Z_OK)
                hdl->validate_xml = false;
        }
    }
#endif

    if (!hdl->inflated) {
        /* If we end up here that means content is plain, lets set up an encoder */
        ret = props->encoder_props->instance_func((void **)&hdl->encoder, props->encoder_props);
        if (unlikely (ret != ret_ok)) {
            return ret_error;
        }

        ret = cherokee_encoder_init (hdl->encoder, conn);
        if (unlikely (ret != ret_ok)) {
            return ret_error;
        }
    }

    return ret_ok;
}
ret_t
cherokee_handler_dbslayer_configure (cherokee_config_node_t  *conf,
				     cherokee_server_t       *srv,
				     cherokee_module_props_t **_props)
{
	ret_t                              ret;
	cherokee_list_t                   *i;
	cherokee_handler_dbslayer_props_t *props;

	/* Instance a new property object
	 */
	if (*_props == NULL) {
		CHEROKEE_NEW_STRUCT (n, handler_dbslayer_props);

		cherokee_handler_props_init_base (HANDLER_PROPS(n),
						  MODULE_PROPS_FREE(props_free));
		n->balancer = NULL;
		cherokee_buffer_init (&n->user);
		cherokee_buffer_init (&n->password);
		cherokee_buffer_init (&n->db);

		*_props = MODULE_PROPS(n);
	}

	props = PROP_DBSLAYER(*_props);

	/* Parse the configuration tree
	 */
	cherokee_config_node_foreach (i, conf) {
		cherokee_config_node_t *subconf = CONFIG_NODE(i);

		if (equal_buf_str (&subconf->key, "balancer")) {
			ret = cherokee_balancer_instance (&subconf->val, subconf, srv, &props->balancer);
			if (ret != ret_ok)
				return ret;

		} else  if (equal_buf_str (&subconf->key, "user")) {
			cherokee_buffer_clean (&props->user);
			cherokee_buffer_add_buffer (&props->user, &subconf->val);

		} else  if (equal_buf_str (&subconf->key, "password")) {
			cherokee_buffer_clean (&props->password);
			cherokee_buffer_add_buffer (&props->password, &subconf->val);

		} else  if (equal_buf_str (&subconf->key, "db")) {
			cherokee_buffer_clean (&props->db);
			cherokee_buffer_add_buffer (&props->db, &subconf->val);

		} else  if (equal_buf_str (&subconf->key, "lang")) {

			ret = cherokee_dwriter_lang_to_type (&subconf->val, &props->lang);
			if (ret != ret_ok) {
				LOG_CRITICAL (CHEROKEE_ERROR_HANDLER_DBSLAYER_LANG, subconf->val.buf);
				return ret_error;
			}
		}
	}
示例#3
0
ret_t
cherokee_url_clean (cherokee_url_t *url)
{
	url->port = 80;

	cherokee_buffer_clean (&url->host);
	cherokee_buffer_clean (&url->request);

	return ret_ok;
}
示例#4
0
static ret_t
add_environment (cherokee_handler_cgi_t *cgi,
		 cherokee_connection_t  *conn)
{
	ret_t                        ret;
	cherokee_handler_cgi_base_t *cgi_base = HDL_CGI_BASE(cgi);
	cherokee_buffer_t           *tmp      = THREAD_TMP_BUF2(CONN_THREAD(conn));

	ret = cherokee_handler_cgi_base_build_envp (HDL_CGI_BASE(cgi), conn);
	if (unlikely (ret != ret_ok))
		return ret;

	/* CONTENT_LENGTH
	 */
	if (http_method_with_input (conn->header.method)) {
		cherokee_buffer_clean (tmp);
		cherokee_buffer_add_ullong10 (tmp, conn->post.len);
		set_env (cgi_base, "CONTENT_LENGTH", tmp->buf, tmp->len);
	}

	/* SCRIPT_FILENAME
	 */
	if (cgi_base->executable.len <= 0)
		return ret_error;

	set_env (cgi_base, "SCRIPT_FILENAME",
		 cgi_base->executable.buf,
		 cgi_base->executable.len);

	return ret_ok;
}
示例#5
0
ret_t
cherokee_shm_map (cherokee_shm_t    *shm,
                  cherokee_buffer_t *name)
{
    int         re;
    int         fd;
    struct stat info;

    fd = shm_open (name->buf, O_RDWR, 0600);
    if (fd < 0) {
        return ret_error;
    }

    re = fstat (fd, &info);
    if (re != 0) {
        return ret_error;
    }

    shm->mem = mmap (0, info.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (shm->mem == MAP_FAILED) {
        cherokee_fd_close (fd);
        shm->mem = NULL;
        return ret_error;
    }

    cherokee_fd_close (fd);

    cherokee_buffer_clean      (&shm->name);
    cherokee_buffer_add_buffer (&shm->name, name);

    return ret_ok;
}
示例#6
0
ret_t
cherokee_validator_file_get_full_path (cherokee_validator_file_t  *validator,
				       cherokee_connection_t      *conn,
				       cherokee_buffer_t         **ret_buf,
				       cherokee_buffer_t          *tmp)
{
	cherokee_validator_file_props_t *props = VAL_VFILE_PROP(validator);

	switch (props->password_path_type) {
	case val_path_full:
		*ret_buf = &props->password_file;
		return ret_ok;

	case val_path_local_dir:
		cherokee_buffer_clean (tmp);
		cherokee_buffer_add_buffer (tmp, &conn->local_directory);
		cherokee_buffer_add_char   (tmp, '/');
		cherokee_buffer_add_buffer (tmp, &props->password_file);

		*ret_buf = tmp;
		return ret_ok;

	default:
		SHOULDNT_HAPPEN;
	}

	return ret_error;
}
示例#7
0
ret_t
cherokee_request_header_set_auth (cherokee_request_header_t *request,
				  cherokee_http_auth_t       auth,
				  cherokee_buffer_t         *user,
				  cherokee_buffer_t         *password)
{
	request->auth = auth;

	cherokee_buffer_clean (&request->user);
	cherokee_buffer_clean (&request->password);

	cherokee_buffer_add_buffer (&request->user, user);
	cherokee_buffer_add_buffer (&request->password, password);

	return ret_ok;
}
示例#8
0
static void
bogotime_callback (void *param)
{
	struct tm              *pnow_tm;
	cherokee_logger_ncsa_t *logger   = LOG_NCSA(param);

	/* Choose between local and universal time
	 */
	if (LOGGER(logger)->utc_time) {
		pnow_tm = &cherokee_bogonow_tmgmt;
	} else {
		pnow_tm = &cherokee_bogonow_tmloc;
	}

	/* Render the string
	 */
	cherokee_buffer_clean  (&now);
	cherokee_buffer_add_va (&now,
				" [%02d/%s/%d:%02d:%02d:%02d %c%02d%02d] \"",
				pnow_tm->tm_mday,
				month[pnow_tm->tm_mon],
				1900 + pnow_tm->tm_year,
				pnow_tm->tm_hour,
				pnow_tm->tm_min,
				pnow_tm->tm_sec,
				(cherokee_bogonow_tzloc < 0) ? '-' : '+',
				(int) (abs(cherokee_bogonow_tzloc) / 60),
				(int) (abs(cherokee_bogonow_tzloc) % 60));
}
static ret_t
send_query (cherokee_handler_dbslayer_t *hdl)
{
	int                    re;
	cuint_t                len;
	cherokee_connection_t *conn = HANDLER_CONN(hdl);
	cherokee_buffer_t     *tmp  = &HANDLER_THREAD(hdl)->tmp_buf1;

	/* Extract the SQL query
	 */
	if ((cherokee_buffer_is_empty (&conn->web_directory)) ||
	    (cherokee_buffer_is_ending (&conn->web_directory, '/')))
	{
		len = conn->web_directory.len;
	} else {
		len = conn->web_directory.len + 1;
	}

	cherokee_buffer_clean (tmp);
	cherokee_buffer_add   (tmp,
			       conn->request.buf + len,
			       conn->request.len - len);

	cherokee_buffer_unescape_uri (tmp);

	/* Send the query
	 */
	re = mysql_real_query (hdl->conn, tmp->buf, tmp->len);
	if (re != 0)
		return ret_error;

	return ret_ok;
}
示例#10
0
ret_t
cherokee_plugin_loader_set_directory  (cherokee_plugin_loader_t *loader, cherokee_buffer_t *dir)
{
	cherokee_buffer_clean (&loader->module_dir);
	cherokee_buffer_add_buffer (&loader->module_dir, dir);

	return ret_ok;
}
static ret_t
poll_release (cherokee_handler_proxy_poll_t *poll,
	      cherokee_handler_proxy_conn_t *pconn)
{
	/* Not longer an active connection */
	cherokee_list_del (&pconn->listed);

	/* Don't reuse connection w/o keep-alive
	 */
	if (! pconn->keepalive_in) {
		cherokee_handler_proxy_conn_free (pconn);
		return ret_ok;
	}

	/* If the reuse-list is full, dispose the oldest obj
	 */
	if (poll->reuse_len > poll->reuse_max) {
		cherokee_handler_proxy_conn_t *oldest;

		oldest = PROXY_CONN(poll->reuse.prev);
		cherokee_list_del (&oldest->listed);
		poll->reuse_len -= 1;

		cherokee_handler_proxy_conn_free (oldest);
	}

	/* Clean up
	 */
	pconn->keepalive_in = false;
	pconn->size_in      = 0;
	pconn->sent_out     = 0;
	pconn->enc          = pconn_enc_none;

	pconn->post.do_buf_sent = true;
	pconn->post.sent        = 0;

	cherokee_buffer_clean (&pconn->post.buf_temp);
	cherokee_buffer_clean (&pconn->header_in_raw);

	/* Store it to be reused
	 */
	poll->reuse_len += 1;
	cherokee_list_add (&pconn->listed, &poll->reuse);

	return ret_ok;
}
示例#12
0
ret_t
cherokee_plugin_loader_set_deps_dir (cherokee_plugin_loader_t *loader, cherokee_buffer_t *dir)
{
	cherokee_buffer_clean (&loader->deps_dir);
	cherokee_buffer_add_buffer (&loader->deps_dir, dir);

	return ret_ok;
}
示例#13
0
文件: trace.c 项目: BeQ/webserver
ret_t
cherokee_trace_set_modules (cherokee_buffer_t *modules)
{
	ret_t              ret;
	char              *p;
	char              *end;
	cherokee_buffer_t  tmp = CHEROKEE_BUF_INIT;

	/* Store a copy of the modules
	 */
	cherokee_buffer_clean (&trace.modules);

	if (trace.from_filter != NULL) {
		cherokee_access_free (trace.from_filter);
	}
	trace.from_filter = NULL;

	if (cherokee_buffer_case_cmp_str (modules, "none") != 0) {
		cherokee_buffer_add_buffer (&trace.modules, modules);
	}

	/* Check the special properties
	 */
	trace.use_syslog   = (strstr (modules->buf, "syslog") != NULL);
	trace.print_time   = (strstr (modules->buf, "time") != NULL);
	trace.print_thread = (strstr (modules->buf, "thread") != NULL);

	/* Even a more special 'from' property
	 */
	p = strstr (modules->buf, "from=");
	if (p != NULL) {
		p += 5;

		end = strchr(p, ',');
		if (end == NULL) {
			end = p + strlen(p);
		}

		if (end > p) {
			ret = cherokee_access_new (&trace.from_filter);
			if (ret != ret_ok) return ret_error;

			cherokee_buffer_add (&tmp, p, end-p);

			ret = cherokee_access_add (trace.from_filter, tmp.buf);
			if (ret != ret_ok) {
				ret = ret_error;
				goto out;
			}
		}
	}

	ret = ret_ok;

out:
	cherokee_buffer_mrproper (&tmp);
	return ret;
}
示例#14
0
ret_t 
cherokee_handler_zeromq_configure (cherokee_config_node_t *conf,
								   cherokee_server_t *srv,
								   cherokee_module_props_t **_props)
{
	ret_t							ret;
	cherokee_list_t				 *i;
	cherokee_handler_zeromq_props_t *props;
	cherokee_plugin_info_t		  *info = NULL;
	
	/* Instance a new property object
	 */
	if (*_props == NULL) {
		CHEROKEE_NEW_STRUCT (n, handler_zeromq_props);

		cherokee_handler_props_init_base (HANDLER_PROPS(n), 
						  MODULE_PROPS_FREE(props_free));
		cherokee_buffer_init (&n->endpoint);
		n->io_threads = 1;
		CHEROKEE_MUTEX_INIT (&n->mutex, CHEROKEE_MUTEX_FAST);

		*_props = MODULE_PROPS(n);
	}

	props = PROP_ZEROMQ(*_props);
	
	/* Voodoo to get our own backend gzipper
	 */
	ret = cherokee_plugin_loader_get (&srv->loader, "gzip", &info);
	if (ret != ret_ok) {
		return ret;
	}

	/* Parse the configuration tree
	 */
	cherokee_config_node_foreach (i, conf) {
		cherokee_config_node_t *subconf = CONFIG_NODE(i);

		if (equal_buf_str (&subconf->key, "endpoint")) {
			cherokee_buffer_clean (&props->endpoint);
			cherokee_buffer_add_buffer (&props->endpoint, &subconf->val);
		} else if (equal_buf_str (&subconf->key, "io_threads")) {
			props->io_threads = atoi(subconf->val.buf);
		} else if (equal_buf_str (&subconf->key, "encoder") && info->configure) {
			encoder_func_configure_t configure = info->configure;
			props->encoder_props = NULL;

			ret = configure (subconf, srv, (cherokee_module_props_t **)&props->encoder_props);
			if (ret != ret_ok) {
				return ret;
			}

			props->encoder_props->instance_func = PLUGIN_INFO(info)->instance;
		}

	}
示例#15
0
static ret_t
local_file_exists (cherokee_rule_extensions_t *rule,
		   cherokee_connection_t      *conn,
		   cherokee_config_entry_t    *ret_conf)
{
	ret_t                     ret;
	struct stat              *info;
	struct stat               nocache_info;
	cherokee_boolean_t        is_file;
	cherokee_iocache_entry_t *io_entry      = NULL;
	cherokee_server_t        *srv           = CONN_SRV(conn);
	cherokee_buffer_t        *tmp           = THREAD_TMP_BUF1(CONN_THREAD(conn));

	UNUSED(rule);

	/* Build the full path
	 */
	cherokee_buffer_clean (tmp);

	if (ret_conf->document_root != NULL) {
		/* A previous non-final rule set a custom document root */
		cherokee_buffer_add_buffer (tmp, ret_conf->document_root);
	} else {
		cherokee_buffer_add_buffer (tmp, &conn->local_directory);
	}

	cherokee_buffer_add_str    (tmp, "/");
	cherokee_buffer_add_buffer (tmp, &conn->request);

	/* Check the local file
	 */
	ret = cherokee_io_stat (srv->iocache, tmp, rule->use_iocache,
				&nocache_info, &io_entry, &info);

	is_file = S_ISREG(info->st_mode);

	if (io_entry) {
		cherokee_iocache_entry_unref (&io_entry);
	}

	/* Report and return
	 */
	if (ret != ret_ok) {
		TRACE(ENTRIES, "Rule extensions: almost matched '%s', but file does not exist\n", tmp->buf);
		return ret_not_found;
	}

	if (! is_file) {
		TRACE(ENTRIES, "Rule extensions: almost matched '%s', but it is not a file\n", tmp->buf);
		return ret_not_found;
	}

	return ret_ok;
}
示例#16
0
ret_t
cherokee_downloader_reuse (cherokee_downloader_t *downloader)
{
	TRACE(ENTRIES, "%p\n", downloader);

	downloader->phase = downloader_phase_init;

	downloader->info.request_sent = 0;
	downloader->info.headers_recv = 0;
	downloader->info.post_sent    = 0;
	downloader->info.body_recv    = 0;

	cherokee_buffer_clean (&downloader->request_header);
	cherokee_buffer_clean (&downloader->reply_header);
	cherokee_buffer_clean (&downloader->body);
	cherokee_buffer_clean (&downloader->post);

	cherokee_request_header_clean (&downloader->request);
	return ret_ok;
}
示例#17
0
/* Methods implementation
 */
static ret_t
load_theme_load_file (cherokee_buffer_t *theme_path, const char *file, cherokee_buffer_t *output)
{
    cherokee_buffer_t path = CHEROKEE_BUF_INIT;

    cherokee_buffer_add_buffer (&path, theme_path);
    cherokee_buffer_add (&path, file, strlen(file));

    cherokee_buffer_clean (output);
    cherokee_buffer_read_file (output, path.buf);

    cherokee_buffer_mrproper (&path);
    return ret_ok;
}
示例#18
0
ret_t
cherokee_handler_zeromq_init (cherokee_handler_zeromq_t *hdl)
{
	ret_t							 ret;
	cherokee_buffer_t				*tmp   = &HANDLER_THREAD(hdl)->tmp_buf1;
	cherokee_connection_t			*conn  = HANDLER_CONN(hdl);
	cherokee_handler_zeromq_props_t *props = HANDLER_ZEROMQ_PROPS(hdl);

	/* We are going to look for gzipped encoding */
	cherokee_buffer_clean (tmp);
	ret = cherokee_header_copy_known (&conn->header, header_content_encoding, tmp);
	if (ret == ret_ok && cherokee_buffer_cmp_str(tmp, "gzip") == 0) {
		TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf);
		return ret_ok;
	} else {
		cherokee_buffer_clean (tmp);
		ret = cherokee_header_copy_known (&conn->header, header_content_type, tmp);
		if (ret == ret_ok && cherokee_buffer_cmp_str(tmp, "application/gzip") == 0) {
			TRACE(ENTRIES, "ZeroMQ: incomming header '%s'\n", tmp->buf);
			return ret_ok;
		}
	}

	/* If we end up here that means content is plain, lets set up an encoder */
	ret = props->encoder_props->instance_func((void **)&hdl->encoder, props->encoder_props);
	if (unlikely (ret != ret_ok)) {
		return ret_error;
	}

	ret = cherokee_encoder_init (hdl->encoder, conn);
	/* TODO: this is a great idea for KV78turbo, but being able to configure
	 * the reply (KV6, 15, 17) sounds like a good idea too.
	 */
	conn->error_code = http_no_content;
	return ret_error;
}
示例#19
0
ret_t
cherokee_buffer_move_to_begin (cherokee_buffer_t *buf, cuint_t pos)
{
	if (pos >= buf->len) {
		cherokee_buffer_clean(buf);
		return ret_ok;
	}

	/* At this point: 0 < pos < buf->len
	 */
	memmove (buf->buf, buf->buf+pos, (buf->len - pos) + 1);
	buf->len -= pos;

	return ret_ok;
}
ret_t
cherokee_handler_proxy_hosts_get (cherokee_handler_proxy_hosts_t  *hosts,
				  cherokee_source_t               *src,
				  cherokee_handler_proxy_poll_t  **poll,
				  cuint_t                          reuse_max)
{
	ret_t ret;

	CHEROKEE_MUTEX_LOCK (&hosts->hosts_mutex);

	/* Build the index name */
	cherokee_buffer_clean       (&hosts->tmp);
	cherokee_buffer_add_buffer  (&hosts->tmp, &src->host);
	cherokee_buffer_add_char    (&hosts->tmp, ':');
	cherokee_buffer_add_ulong10 (&hosts->tmp, src->port);

	/* Check the hosts tree */
	ret = cherokee_avl_get (&hosts->hosts, &hosts->tmp, (void **)poll);
	switch (ret) {
	case ret_ok:
		break;
	case ret_not_found: {
		cherokee_handler_proxy_poll_t *n;

		ret = cherokee_handler_proxy_poll_new (&n, reuse_max);
		if (ret != ret_ok)
			return ret;

		cherokee_avl_add (&hosts->hosts, &hosts->tmp, n);
		*poll = n;
		break;
	}
	default:
		goto error;
	}

	/* Got it */
	CHEROKEE_MUTEX_UNLOCK (&hosts->hosts_mutex);
	return ret_ok;

error:
	CHEROKEE_MUTEX_LOCK (&hosts->hosts_mutex);
	return ret_error;
}
示例#21
0
ret_t
cherokee_buffer_remove_chunk (cherokee_buffer_t *buf, cuint_t from, cuint_t len)
{
	char *end;
	char *begin;

	if (len == buf->len) {
		cherokee_buffer_clean (buf);
		return ret_ok;
	}

	begin = buf->buf + from;
	end   = begin + len;

	memmove (begin, end, ((buf->buf + buf->len) - end) + 1);
	buf->len -= len;

	return ret_ok;
}
ret_t
cherokee_handler_proxy_conn_send (cherokee_handler_proxy_conn_t *pconn,
				  cherokee_buffer_t             *buf)
{
	ret_t  ret;
	size_t sent = 0;

	ret = cherokee_socket_bufwrite (&pconn->socket, buf, &sent);
	if (unlikely(ret != ret_ok)) {
		return ret;
	}

	if (sent >= buf->len) {
		cherokee_buffer_clean (buf);
		return ret_ok;
	}

	cherokee_buffer_move_to_begin (buf, sent);
	return ret_eagain;
}
示例#23
0
ret_t
cherokee_buffer_remove_chunk (cherokee_buffer_t *buf, cuint_t from, cuint_t len)
{
	char *end;
	char *begin;

	if (from >= buf->len)
		return ret_ok;

	if ((from == 0) && (len >= buf->len)) {
		cherokee_buffer_clean (buf);
		return ret_ok;
	}

	begin = buf->buf + from;
	end   = MIN ((begin + len), (buf->buf + buf->len));

	memmove (begin, end, ((buf->buf + buf->len) - end) + 1);
	buf->len -= len;

	return ret_ok;
}
示例#24
0
文件: post.c 项目: Daniel15/webserver
static ret_t
do_read_plain (cherokee_post_t   *post,
	       cherokee_socket_t *sock_in,
	       cherokee_buffer_t *buffer,
	       off_t              to_read)
{
	ret_t  ret;
	size_t len;

	/* Surplus from header read
	 */
	if (! cherokee_buffer_is_empty (&post->header_surplus)) {
		TRACE (ENTRIES, "Post appending %d surplus bytes\n", post->header_surplus.len);
		post->send.read += post->header_surplus.len;

		cherokee_buffer_add_buffer (buffer, &post->header_surplus);
		cherokee_buffer_clean (&post->header_surplus);

		return ret_ok;
	}

	/* Read
	 */
	if (to_read <= 0) {
		return ret_ok;
	}

	TRACE (ENTRIES, "Post reading from client (to_read=%d)\n", to_read);
	ret = cherokee_socket_bufread (sock_in, buffer, to_read, &len);
	TRACE (ENTRIES, "Post read from client: ret=%d len=%d\n", ret, len);

	if (ret != ret_ok) {
		return ret;
	}

	post->send.read += len;
	return ret_ok;
}
示例#25
0
ret_t
cherokee_downloader_set_proxy (cherokee_downloader_t *downloader,
                               cherokee_buffer_t     *proxy,
                               cuint_t                port)
{
	char *tmp;

	/* Skip 'http(s)://'
	 */
	tmp = strchr (proxy->buf, '/');
	if (tmp == NULL)
		tmp = proxy->buf;
	else
		tmp += 2;

	/* Copy the values
	 */
	cherokee_buffer_clean (&downloader->proxy);
	cherokee_buffer_add (&downloader->proxy, tmp, strlen(tmp));

	downloader->proxy_port = port;
	return ret_ok;
}
示例#26
0
static ret_t
parse (cherokee_handler_ssi_t *hdl,
       cherokee_buffer_t      *in,
       cherokee_buffer_t      *out)
{
	ret_t              ret;
	char              *p, *q;
	char              *begin;
	int                re;
	cuint_t            len;
	operations_t       op;
	path_type_t        path;
	struct stat        info;
	cherokee_boolean_t ignore;
	cherokee_buffer_t  key     = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  val     = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  pair    = CHEROKEE_BUF_INIT;
	cherokee_buffer_t  fpath   = CHEROKEE_BUF_INIT;

	q = in->buf;

	while (true) {
		begin = q;

		/* Check the end
		 */
		if (q >= in->buf + in->len)
			break;

		/* Find next SSI tag
		 */
		p = strstr (q, "<!--#");
		if (p == NULL) {
			cherokee_buffer_add (out, begin, (in->buf + in->len) - begin);
			ret = ret_ok;
			goto out;
		}

		q = strstr (p + 5, "-->");
		if (q == NULL) {
			ret = ret_error;
			goto out;
		}

		len = q - p;
		len -= 5;

		cherokee_buffer_clean (&key);
		cherokee_buffer_add (&key, p+5, len);
		cherokee_buffer_trim (&key);

		q += 3;
		TRACE(ENTRIES, "Found key '%s'\n", key.buf);

		/* Add the previous chunk
		 */
		cherokee_buffer_add (out, begin, p - begin);

		/* Check element
		 */
		op     = op_none;
		ignore = false;

		if (strncmp (key.buf, "include", 7) == 0) {
			op  = op_include;
			len = 7;
		} else if (strncmp (key.buf, "fsize", 5) == 0) {
			op  = op_size;
			len = 5;
		} else if (strncmp (key.buf, "flastmod", 8) == 0) {
			op  = op_lastmod;
			len = 8;
		} else {
			LOG_ERROR (CHEROKEE_ERROR_HANDLER_SSI_PROPERTY, key.buf);
		}

		/* Deeper parsing
		 */
		path = path_none;

		switch (op) {
		case op_size:
		case op_include:
		case op_lastmod:
			/* Read a property key
			 */
			cherokee_buffer_move_to_begin (&key, len);
			cherokee_buffer_trim (&key);

			cherokee_buffer_clean (&pair);
			get_pair (&key, &pair);

			cherokee_buffer_drop_ending (&key, pair.len);
			cherokee_buffer_trim (&key);

			/* Parse the property
			 */
			if (strncmp (pair.buf, "file=", 5) == 0) {
				path = path_file;
				len  = 5;
			} else if (strncmp (pair.buf, "virtual=", 8) == 0) {
				path = path_virtual;
				len  = 8;
			}

			cherokee_buffer_clean (&val);
			get_val (pair.buf + len, &val);

			cherokee_buffer_clean (&fpath);

			switch (path) {
			case path_file:
				cherokee_buffer_add_buffer (&fpath, &hdl->dir);
				cherokee_buffer_add_char   (&fpath, '/');
				cherokee_buffer_add_buffer (&fpath, &val);

				TRACE(ENTRIES, "Path: file '%s'\n", fpath.buf);
				break;
			case path_virtual:
				cherokee_buffer_add_buffer (&fpath, &HANDLER_VSRV(hdl)->root);
				cherokee_buffer_add_char   (&fpath, '/');
				cherokee_buffer_add_buffer (&fpath, &val);

				TRACE(ENTRIES, "Path: virtual '%s'\n", fpath.buf);
				break;
			default:
				ignore = true;
				SHOULDNT_HAPPEN;
			}

			/* Path security check: ensure that the file
			 * to include is inside the document root.
			 */
			if (! cherokee_buffer_is_empty (&fpath)) {
				cherokee_path_short (&fpath);

				if (fpath.len < HANDLER_VSRV(hdl)->root.len) {
					ignore = true;

				}  else {
					re = strncmp (fpath.buf,
					              HANDLER_VSRV(hdl)->root.buf,
					              HANDLER_VSRV(hdl)->root.len);
					if (re != 0) {
						ignore = true;
					}
				}
			}

			/* Perform the operation
			 */
			if (! ignore) {
				switch (op) {
				case op_include: {
					cherokee_buffer_t file_content = CHEROKEE_BUF_INIT;

					ret = cherokee_buffer_read_file (&file_content, fpath.buf);
					if (unlikely (ret != ret_ok)) {
						cherokee_buffer_mrproper (&file_content);
						ret = ret_error;
						goto out;
					}

					TRACE(ENTRIES, "Including file '%s'\n", fpath.buf);

					ret = parse (hdl, &file_content, out);
					if (unlikely (ret != ret_ok)) {
						cherokee_buffer_mrproper (&file_content);
						ret = ret_error;
						goto out;
					}

					cherokee_buffer_mrproper (&file_content);
					break;
				}

				case op_size:
					TRACE(ENTRIES, "Including file size '%s'\n", fpath.buf);
					re = cherokee_stat (fpath.buf, &info);
					if (re >=0) {
						cherokee_buffer_add_ullong10 (out, info.st_size);
					}
					break;

				case op_lastmod:
					TRACE(ENTRIES, "Including file modification date '%s'\n", fpath.buf);
					re = cherokee_stat (fpath.buf, &info);
					if (re >= 0) {
						struct tm *ltime;
						struct tm  ltime_buf;
						char       tmp[50];

						ltime = cherokee_localtime (&info.st_mtime, &ltime_buf);
						if (ltime != NULL) {
							strftime (tmp, sizeof(tmp), "%d-%b-%Y %H:%M", ltime);
							cherokee_buffer_add (out, tmp, strlen(tmp));
						}
					}
					break;
				default:
					SHOULDNT_HAPPEN;
				}
			} /* !ignore */

			break;
		default:
			SHOULDNT_HAPPEN;
		} /* switch(op) */
	} /* while */

	ret = ret_ok;

out:
	cherokee_buffer_mrproper (&key);
	cherokee_buffer_mrproper (&val);
	cherokee_buffer_mrproper (&pair);
	cherokee_buffer_mrproper (&fpath);

	return ret;
}
示例#27
0
static ret_t
match (cherokee_rule_directory_t *rule,
       cherokee_connection_t     *conn,
       cherokee_config_entry_t   *ret_conf)
{
	UNUSED(ret_conf);

	/* Not the same lenght
	 */
	if (conn->request.len < rule->directory.len) {
		TRACE(ENTRIES, "Match directory: rule=%s req=%s: (shorter) ret_not_found\n",
		      rule->directory.buf, conn->request.buf);
		return ret_not_found;
	}

	/* Does not match
	 */
	if (strncmp (rule->directory.buf, conn->request.buf, rule->directory.len) != 0) {
		TRACE(ENTRIES, "Match directory: rule=%s req=%s: (str) ret_not_found\n",
		      rule->directory.buf, conn->request.buf);
		return ret_not_found;
	}

	/* Does not match: same begining, but a longer name
	 */
	if ((conn->request.len > rule->directory.len) &&
	    (conn->request.buf[rule->directory.len] != '/'))
	{
		TRACE(ENTRIES, "Match directory: rule=%s req=%s: (str) ret_not_found\n",
		      rule->directory.buf, conn->request.buf);
		return ret_not_found;
	}

	/* If the request is exactly the directory entry, and it
	 * doesn't end with a slash, it must be redirected. Eg:
	 *
	 * web_directory = "/blog"
	 * request       = "/blog"
	 *
	 * It must be redirected to "/blog/"
	 */
	if ((conn->request.len > 1) &&
	    (cherokee_buffer_end_char (&conn->request) != '/') &&
	    (cherokee_buffer_cmp_buf (&conn->request, &rule->directory) == 0))
	{
		cherokee_buffer_add_str (&conn->request, "/");
		cherokee_connection_set_redirect (conn, &conn->request);
		cherokee_buffer_drop_ending (&conn->request, 1);

		TRACE(ENTRIES, "Had to redirect to: %s\n", conn->redirect.buf);
		conn->error_code = http_moved_permanently;
		return ret_error;
	}

	/* Copy the web directory property
	 */
	if ((RULE(rule)->config.handler_new_func != NULL) ||
	    (RULE(rule)->config.document_root != NULL))
	{
		cherokee_buffer_clean      (&conn->web_directory);
		cherokee_buffer_add_buffer (&conn->web_directory, &rule->directory);
	}

	TRACE(ENTRIES, "Match! rule=%s req=%s web_directory=%s: ret_ok\n",
	      rule->directory.buf, conn->request.buf, conn->web_directory.buf);

	return ret_ok;
}
示例#28
0
ret_t
cherokee_handler_dirlist_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props)
{
    ret_t                             ret;
    cherokee_list_t                  *i;
    cherokee_handler_dirlist_props_t *props;
    const char                       *theme      = NULL;
    cherokee_buffer_t                 theme_path = CHEROKEE_BUF_INIT;

    UNUSED(srv);

    if (*_props == NULL) {
        CHEROKEE_NEW_STRUCT (n, handler_dirlist_props);

        cherokee_handler_props_init_base (HANDLER_PROPS(n),
                                          MODULE_PROPS_FREE(cherokee_handler_dirlist_props_free));

        n->show_size      = true;
        n->show_date      = true;
        n->show_user      = false;
        n->show_group     = false;
        n->show_icons     = true;
        n->show_symlinks  = true;
        n->redir_symlinks = false;

        n->show_hidden    = false;
        n->show_backup    = false;

        cherokee_buffer_init (&n->header);
        cherokee_buffer_init (&n->footer);
        cherokee_buffer_init (&n->entry);
        cherokee_buffer_init (&n->css);

        cherokee_buffer_init (&n->icon_web_dir);
        cherokee_buffer_add_str (&n->icon_web_dir, ICON_WEB_DIR_DEFAULT);

        INIT_LIST_HEAD (&n->notice_files);
        INIT_LIST_HEAD (&n->hidden_files);

        *_props = MODULE_PROPS(n);
    }

    props = PROP_DIRLIST(*_props);

    cherokee_config_node_foreach (i, conf) {
        cherokee_config_node_t *subconf = CONFIG_NODE(i);

        /* Convert the properties
         */
        if (equal_buf_str (&subconf->key, "size")) {
            props->show_size  = !! atoi (subconf->val.buf);
        } else if (equal_buf_str (&subconf->key, "date")) {
            props->show_date  = !! atoi (subconf->val.buf);
        } else if (equal_buf_str (&subconf->key, "user")) {
            props->show_user  = !! atoi (subconf->val.buf);
        } else if (equal_buf_str (&subconf->key, "group")) {
            props->show_group = !! atoi (subconf->val.buf);
        } else if (equal_buf_str (&subconf->key, "symlinks")) {
            props->show_symlinks = !! atoi (subconf->val.buf);
        } else if (equal_buf_str (&subconf->key, "redir_symlinks")) {
            props->redir_symlinks = !! atoi (subconf->val.buf);
        } else if (equal_buf_str (&subconf->key, "hidden")) {
            props->show_hidden = !! atoi (subconf->val.buf);
        } else if (equal_buf_str (&subconf->key, "backup")) {
            props->show_backup = !! atoi (subconf->val.buf);

        } else if (equal_buf_str (&subconf->key, "theme")) {
            theme = subconf->val.buf;

        } else if (equal_buf_str (&subconf->key, "icon_dir")) {
            cherokee_buffer_clean (&props->icon_web_dir);
            cherokee_buffer_add_buffer (&props->icon_web_dir, &subconf->val);

        } else if (equal_buf_str (&subconf->key, "notice_files")) {
            ret = cherokee_config_node_read_list (subconf, NULL, file_match_add_cb, &props->notice_files);
            if (unlikely (ret != ret_ok))
                return ret;

        } else if (equal_buf_str (&subconf->key, "hidden_files")) {
            ret = cherokee_config_node_read_list (subconf, NULL, file_match_add_cb, &props->hidden_files);
            if (unlikely (ret != ret_ok))
                return ret;
        }
    }
示例#29
0
ret_t
cherokee_handler_zeromq_read_post (cherokee_handler_zeromq_t *hdl)
{
	zmq_msg_t				message;
	int						re;
	ret_t					ret;
	cherokee_buffer_t	   *post = &HANDLER_THREAD(hdl)->tmp_buf1;
	cherokee_buffer_t	   *out  = &HANDLER_THREAD(hdl)->tmp_buf2;
	cherokee_connection_t  *conn = HANDLER_CONN(hdl);

	/* Check for the post info
	 */
	if (! conn->post.has_info) {
		conn->error_code = http_bad_request;
		return ret_error;
	}

	cherokee_buffer_clean (post);
	ret = cherokee_post_read (&conn->post, &conn->socket, post);
	switch (ret) {
	case ret_ok:
		cherokee_connection_update_timeout (conn);
		break;
	case ret_eagain:
		ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(hdl),
												   HANDLER_CONN(hdl),
												   conn->socket.socket,
												   FDPOLL_MODE_READ, false);
		if (ret != ret_ok) {
			return ret_error;
		} else {
			return ret_eagain;
		}
	default:
		conn->error_code = http_bad_request;
		return ret_error;
	}

	TRACE (ENTRIES, "Post contains: '%s'\n", post->buf);

	re = cherokee_post_read_finished (&conn->post);
	ret = re ? ret_ok : ret_eagain;

	if (hdl->encoder != NULL) {
		cherokee_buffer_clean(out);
		if (ret == ret_ok) {
			cherokee_encoder_flush(hdl->encoder, post, out);
		} else {
			cherokee_encoder_encode(hdl->encoder, post, out);
		}

		post = out;
	}
	
	cherokee_buffer_add_buffer(&hdl->output, post);
	
	if (ret == ret_ok) {
		cherokee_buffer_t	 			*tmp   = &HANDLER_THREAD(hdl)->tmp_buf1;
		cherokee_handler_zeromq_props_t *props = HANDLER_ZEROMQ_PROPS(hdl);
		zmq_msg_t envelope;
		zmq_msg_t message;
		cuint_t len;

		if ((cherokee_buffer_is_empty (&conn->web_directory)) ||
			(cherokee_buffer_is_ending (&conn->web_directory, '/'))) {
			len = conn->web_directory.len;
		} else {
			len = conn->web_directory.len + 1;
		}

		cherokee_buffer_clean (tmp);
		cherokee_buffer_add   (tmp, conn->request.buf + len,
									conn->request.len - len);

		TRACE(ENTRIES, "ZeroMQ: incomming path '%s'\n", tmp->buf);

		zmq_msg_init_size (&envelope, tmp->len);
		memcpy (zmq_msg_data (&envelope), tmp->buf, tmp->len);
		zmq_msg_init_size (&message, hdl->output.len);
		memcpy (zmq_msg_data (&message), hdl->output.buf, hdl->output.len);

		/* Atomic Section */
		CHEROKEE_MUTEX_LOCK (&props->mutex);
		zmq_msg_send (&envelope, props->socket, ZMQ_DONTWAIT | ZMQ_SNDMORE);
		zmq_msg_send (&message, props->socket, ZMQ_DONTWAIT);
		CHEROKEE_MUTEX_UNLOCK (&props->mutex);

		zmq_msg_close (&envelope);
		zmq_msg_close (&message);
	}

	return ret;
}
示例#30
0
static void
render_python_error (cherokee_error_type_t   type,
		     const char             *filename,
		     int                     line,
		     int                     error_num,
		     const cherokee_error_t *error,
		     cherokee_buffer_t      *output,
		     va_list                 ap)
{
	cherokee_buffer_t tmp = CHEROKEE_BUF_INIT;

	/* Dict: open */
	cherokee_buffer_add_char (output, '{');

	/* Error type */
	cherokee_buffer_add_str (output, "'type': \"");

	switch (type) {
	case cherokee_err_warning:
		cherokee_buffer_add_str (output, "warning");
		break;
	case cherokee_err_error:
		cherokee_buffer_add_str (output, "error");
		break;
	case cherokee_err_critical:
		cherokee_buffer_add_str (output, "critical");
		break;
	default:
		SHOULDNT_HAPPEN;
	}
	cherokee_buffer_add_str (output, "\", ");

	/* Time */
	cherokee_buffer_add_str  (output, "'time': \"");
	cherokee_buf_add_bogonow (output, false);
	cherokee_buffer_add_str  (output, "\", ");

	/* Render the title */
	cherokee_buffer_add_str     (output, "'title': \"");
	cherokee_buffer_add_va_list (output, error->title, ap);
	cherokee_buffer_add_str     (output, "\", ");
	skip_args (ap, error->title);

	/* File and line*/
	cherokee_buffer_add_str (output, "'code': \"");
	cherokee_buffer_add_va  (output, "%s:%d", filename, line);
	cherokee_buffer_add_str (output, "\", ");

	/* Error number */
	cherokee_buffer_add_str (output, "'error': \"");
	cherokee_buffer_add_va  (output, "%d", error_num);
	cherokee_buffer_add_str (output, "\", ");

	/* Description */
	if (error->description) {
		cherokee_buffer_add_str     (output, "'description': \"");
		cherokee_buffer_clean       (&tmp);
		cherokee_buffer_add_va_list (&tmp, error->description, ap);
		cherokee_buffer_add_escape_html (output, &tmp);
		cherokee_buffer_add_str     (output, "\", ");
		skip_args (ap, error->description);
	}

	/* Admin URL */
	if (error->admin_url) {
		cherokee_buffer_add_str     (output, "'admin_url': \"");
		cherokee_buffer_add_va_list (output, error->admin_url, ap);
		cherokee_buffer_add_str     (output, "\", ");

		/* ARGS: Skip 'admin_url' */
		skip_args (ap, error->admin_url);
	}

	/* Debug information */
	if (error->debug) {
		cherokee_buffer_add_str     (output, "'debug': \"");
		cherokee_buffer_add_va_list (output, error->debug, ap);
		cherokee_buffer_add_str     (output, "\", ");

		/* ARGS: Skip 'debug' */
		skip_args (ap, error->debug);
	}

	/* Version */
	cherokee_buffer_add_str (output, "'version': \"");
	cherokee_buffer_add_str (output, PACKAGE_VERSION);
	cherokee_buffer_add_str (output, "\", ");

	cherokee_buffer_add_str (output, "'compilation_date': \"");
	cherokee_buffer_add_str (output, __DATE__ " " __TIME__);
	cherokee_buffer_add_str (output, "\", ");

	cherokee_buffer_add_str (output, "'configure_args': \"");
	cherokee_buffer_clean   (&tmp);
	cherokee_buffer_add_str (&tmp, CHEROKEE_CONFIG_ARGS);
	cherokee_buffer_add_escape_html (output, &tmp);
	cherokee_buffer_add_buffer (output, &tmp);
	cherokee_buffer_add_str (output, "\", ");

	/* Backtrace */
	cherokee_buffer_add_str (output, "'backtrace': \"");
#ifdef BACKTRACES_ENABLED
	cherokee_buffer_clean (&tmp);
	cherokee_buf_add_backtrace (&tmp, 2, "\\n", "");
	cherokee_buffer_add_escape_html (output, &tmp);
#endif
	cherokee_buffer_add_str (output, "\", ");

	/* Let's finish here.. */
	if (strcmp (output->buf + output->len - 2, ", ") == 0) {
		cherokee_buffer_drop_ending (output, 2);
	}
	cherokee_buffer_add_str (output, "}\n");

	/* Clean up */
	cherokee_buffer_mrproper (&tmp);
}