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; } } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; } }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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, <ime_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; }
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; }
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; } }
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; }
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); }