Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

339 lines (273 sloc) 7.827 kb
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* Cherokee
*
* Authors:
* Alvaro Lopez Ortega <alvaro@alobbs.com>
*
* Copyright (C) 2001-2011 Alvaro Lopez Ortega
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "common-internal.h"
#include "gen_evhost.h"
#include "plugin_loader.h"
#include "connection-protected.h"
#include "server-protected.h"
#include "util.h"
#define ENTRIES "evhost"
PLUGIN_INFO_EASY_INIT (cherokee_generic, evhost);
PLUGIN_EMPTY_INIT_FUNCTION(evhost);
static ret_t
_free (cherokee_generic_evhost_t *evhost)
{
cherokee_template_mrproper (&evhost->tpl_document_root);
free (evhost);
return ret_ok;
}
static ret_t
_check_document_root (cherokee_connection_t *conn)
{
ret_t ret;
struct stat stat_mem;
struct stat *info;
cherokee_iocache_entry_t *io_entry = NULL;
ret = cherokee_io_stat (CONN_SRV(conn)->iocache,
&conn->local_directory,
(CONN_SRV(conn)->iocache != NULL),
&stat_mem, &io_entry, &info);
if (ret != ret_ok) {
ret = ret_not_found;
goto out;
}
if (! S_ISDIR(info->st_mode)) {
ret = ret_not_found;
goto out;
}
ret = ret_ok;
out:
if (io_entry) {
cherokee_iocache_entry_unref (&io_entry);
}
return ret;
}
static ret_t
_render_document_root (cherokee_generic_evhost_t *evhost,
cherokee_connection_t *conn)
{
ret_t ret;
/* Render the document root
*/
ret = cherokee_template_render (&evhost->tpl_document_root,
&conn->local_directory, conn);
if (unlikely (ret != ret_ok))
return ret_error;
if (! evhost->check_document_root)
return ret_ok;
/* Check the Document Root
*/
ret = _check_document_root (conn);
if (ret != ret_ok) {
TRACE(ENTRIES, "Dynamic Document Root '%s' doesn't exist\n", conn->local_directory.buf);
return ret_not_found;
}
TRACE(ENTRIES, "Dynamic Document Root '%s' exists\n", conn->local_directory.buf);
return ret_ok;
}
ret_t
cherokee_generic_evhost_configure (cherokee_generic_evhost_t *evhost,
cherokee_config_node_t *config)
{
ret_t ret;
cherokee_buffer_t *tmp;
cherokee_config_node_read_bool (config, "check_document_root",
&evhost->check_document_root);
ret = cherokee_config_node_read (config, "tpl_document_root", &tmp);
if (ret != ret_ok) {
LOG_CRITICAL_S (CHEROKEE_ERROR_GEN_EVHOST_TPL_DROOT);
return ret;
}
ret = cherokee_template_parse (&evhost->tpl_document_root, tmp);
if (ret != ret_ok) {
LOG_CRITICAL (CHEROKEE_ERROR_GEN_EVHOST_PARSE, tmp->buf);
return ret_error;
}
return ret_ok;
}
static ret_t
add_domain (cherokee_template_t *template,
cherokee_template_token_t *token,
cherokee_buffer_t *output,
void *param)
{
cherokee_connection_t *conn = CONN(param);
UNUSED(template);
UNUSED(token);
return cherokee_buffer_add_buffer (output, &conn->host);
}
static ret_t
add_tld (cherokee_template_t *template,
cherokee_template_token_t *token,
cherokee_buffer_t *output,
void *param)
{
const char *p;
const char *end;
cherokee_connection_t *conn = CONN(param);
UNUSED(template);
UNUSED(token);
end = conn->host.buf + conn->host.len;
p = end - 1;
if (unlikely (*p == '.')) {
/* Host: example.com. */
return ret_deny;
}
while (p > conn->host.buf) {
if (*p != '.') {
p--;
continue;
}
p += 1;
cherokee_buffer_add (output, p, end-p);
return ret_ok;
}
/* Host: example */
return ret_not_found;
}
static ret_t
add_domain_no_tld (cherokee_template_t *template,
cherokee_template_token_t *token,
cherokee_buffer_t *output,
void *param)
{
const char *p;
const char *end;
cherokee_connection_t *conn = CONN(param);
UNUSED(template);
UNUSED(token);
end = conn->host.buf + conn->host.len;
p = end - 1;
if (unlikely (*p == '.')) {
/* Host: example.com. */
return ret_deny;
}
while (p > conn->host.buf) {
if (*p != '.') {
p--;
continue;
}
cherokee_buffer_add (output, conn->host.buf, p - conn->host.buf);
return ret_ok;
}
/* Host: example */
return ret_not_found;
}
static ret_t
_add_subdomain (cherokee_buffer_t *output,
cherokee_connection_t *conn,
int starting_dot)
{
const char *p;
const char *end;
const char *dom_end = NULL;
end = conn->host.buf + conn->host.len;
p = end - 1;
if (unlikely (*p == '.')) {
/* Host: example.com. */
return ret_deny;
}
while (p > conn->host.buf) {
if (*p != '.') {
p--;
continue;
}
if (dom_end != NULL) {
p++;
break;
}
starting_dot--;
if (starting_dot == 0) {
dom_end = p;
}
p--;
}
if (dom_end != NULL) {
cherokee_buffer_add (output, p, dom_end - p);
return ret_ok;
}
/* Host: example */
return ret_not_found;
}
static ret_t
add_root_domain (cherokee_template_t *template,
cherokee_template_token_t *token,
cherokee_buffer_t *output,
void *param)
{
UNUSED(template);
UNUSED(token);
return _add_subdomain (output, CONN(param), 1);
}
static ret_t
add_subdomain1 (cherokee_template_t *template,
cherokee_template_token_t *token,
cherokee_buffer_t *output,
void *param)
{
UNUSED(template);
UNUSED(token);
return _add_subdomain (output, CONN(param), 2);
}
static ret_t
add_subdomain2 (cherokee_template_t *template,
cherokee_template_token_t *token,
cherokee_buffer_t *output,
void *param)
{
UNUSED(template);
UNUSED(token);
return _add_subdomain (output, CONN(param), 3);
}
ret_t
cherokee_generic_evhost_new (cherokee_generic_evhost_t **evhost)
{
ret_t ret;
CHEROKEE_NEW_STRUCT(n,generic_evhost);
/* Methods
*/
cherokee_module_init_base (MODULE(n), NULL, PLUGIN_INFO_PTR(evhost));
MODULE(n)->free = (module_func_free_t) _free;
n->func_document_root = (evhost_func_droot_t) _render_document_root;
n->check_document_root = true;
/* Properties
*/
ret = cherokee_template_init (&n->tpl_document_root);
if (ret != ret_ok) {
return ret_error;
}
cherokee_template_set_token (&n->tpl_document_root, "domain",
TEMPLATE_FUNC(add_domain), n, NULL);
cherokee_template_set_token (&n->tpl_document_root, "tld",
TEMPLATE_FUNC(add_tld), n, NULL);
cherokee_template_set_token (&n->tpl_document_root, "domain_no_tld",
TEMPLATE_FUNC(add_domain_no_tld), n, NULL);
cherokee_template_set_token (&n->tpl_document_root, "root_domain",
TEMPLATE_FUNC(add_root_domain), n, NULL);
cherokee_template_set_token (&n->tpl_document_root, "subdomain1",
TEMPLATE_FUNC(add_subdomain1), n, NULL);
cherokee_template_set_token (&n->tpl_document_root, "subdomain2",
TEMPLATE_FUNC(add_subdomain2), n, NULL);
*evhost = n;
return ret_ok;
}
Jump to Line
Something went wrong with that request. Please try again.