static ret_t while_print_name (cherokee_buffer_t *key, void *value, void *param) { entry_t *entry = value; cherokee_buffer_t *buffer = param; if (entry->built_in) { cherokee_buffer_add_buffer (buffer, key); cherokee_buffer_add_char (buffer, ' '); } return ret_ok; }
static ret_t set_host (cherokee_source_t *src, cherokee_buffer_t *host) { ret_t ret; cherokee_resolv_cache_t *resolv; if (cherokee_buffer_is_empty (host)) return ret_error; TRACE (ENTRIES, "Configuring source, setting host '%s'\n", host->buf); /* Original */ cherokee_buffer_add_buffer (&src->original, host); /* Unix socket */ if (host->buf[0] == '/' || host->buf[0] == '@') { cherokee_buffer_add_buffer (&src->unix_socket, host); return ret_ok; } /* Host name */ ret = cherokee_parse_host (host, &src->host, (cuint_t *)&src->port); if (unlikely (ret != ret_ok)) { return ret_error; } /* Resolve and cache it */ ret = cherokee_resolv_cache_get_default (&resolv); if (unlikely (ret!=ret_ok)) { return ret_error; } cherokee_resolv_cache_get_ipstr (resolv, &src->host, NULL); return ret_ok; }
ret_t cherokee_handler_error_step (cherokee_handler_error_t *hdl, cherokee_buffer_t *buffer) { ret_t ret; /* Usual content */ ret = cherokee_buffer_add_buffer (buffer, &hdl->content); if (unlikely(ret < ret_ok)) return ret; return ret_eof_have_data; }
/* 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; }
static ret_t configure_rewrite_entry (cherokee_list_t *list, cherokee_config_node_t *conf, cherokee_regex_table_t *regexs) { ret_t ret; cherokee_regex_entry_t *n; cherokee_buffer_t *substring; cherokee_boolean_t hidden = true; pcre *re = NULL; cherokee_buffer_t *regex = NULL; TRACE(ENTRIES, "Converting rewrite rule '%s'\n", conf->key.buf); /* Query conf */ cherokee_config_node_read_bool (conf, "show", &hidden); hidden = !hidden; ret = cherokee_config_node_read (conf, "regex", ®ex); if (ret == ret_ok) { ret = cherokee_regex_table_get (regexs, regex->buf, (void **)&re); if (ret != ret_ok) return ret; } ret = cherokee_config_node_read (conf, "substring", &substring); if (ret != ret_ok) return ret; /* New RegEx */ n = (cherokee_regex_entry_t *) malloc(sizeof(cherokee_regex_entry_t)); if (unlikely (n == NULL)) return ret_nomem; INIT_LIST_HEAD (&n->listed); n->re = re; n->hidden = hidden; cherokee_buffer_init (&n->subs); cherokee_buffer_add_buffer (&n->subs, substring); /* Add the list */ cherokee_list_add_tail (&n->listed, list); 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; }
static ret_t parse_contry_list (cherokee_buffer_t *value, cherokee_avl_t *countries) { char *val; char *tmpp; cherokee_buffer_t tmp = CHEROKEE_BUF_INIT; TRACE(ENTRIES, "Adding geoip countries: '%s'\n", value->buf); cherokee_buffer_add_buffer (&tmp, value); tmpp = tmp.buf; while ((val = strsep(&tmpp, ",")) != NULL) { TRACE(ENTRIES, "Adding country: '%s'\n", val); cherokee_avl_add_ptr (countries, val, (void *)MAGIC); } cherokee_buffer_mrproper (&tmp); return ret_ok; }
static ret_t parse_value (cherokee_buffer_t *value, cherokee_avl_t *extensions) { char *val; char *tmpp; cherokee_buffer_t tmp = CHEROKEE_BUF_INIT; TRACE(ENTRIES, "Adding extensions: '%s'\n", value->buf); cherokee_buffer_add_buffer (&tmp, value); tmpp = tmp.buf; while ((val = strsep(&tmpp, ",")) != NULL) { TRACE(ENTRIES, "Adding extension: '%s'\n", val); cherokee_avl_add_ptr (extensions, val, (void *)MAGIC); } cherokee_buffer_mrproper (&tmp); return ret_ok; }
ret_t cherokee_validator_file_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) { ret_t ret; cherokee_config_node_t *subconf; cherokee_validator_file_props_t *props = PROP_VFILE(*_props); UNUSED (srv); /* Password file */ ret = cherokee_config_node_get (conf, "passwdfile", &subconf); if (ret == ret_ok) { cherokee_buffer_add_buffer (&props->password_file, &subconf->val); } /* Path type */ ret = cherokee_config_node_get (conf, "passwdfile_path", &subconf); if (ret == ret_ok) { if (equal_buf_str (&subconf->val, "full")) { props->password_path_type = val_path_full; } else if (equal_buf_str (&subconf->val, "local_dir")) { props->password_path_type = val_path_local_dir; } else { LOG_ERROR (CHEROKEE_ERROR_VALIDATOR_FILE, subconf->val.buf); return ret_error; } } /* Final checks */ if (cherokee_buffer_is_empty (&props->password_file)) { LOG_CRITICAL_S (CHEROKEE_ERROR_VALIDATOR_FILE_NO_FILE); return ret_error; } return ret_ok; }
ret_t cherokee_handler_ssi_add_headers (cherokee_handler_ssi_t *hdl, cherokee_buffer_t *buffer) { ret_t ret; char *ext; cherokee_buffer_t *mime = NULL; cherokee_server_t *srv = HANDLER_SRV(hdl); cherokee_connection_t *conn = HANDLER_CONN(hdl); /* MIME type */ if (srv->mime != NULL) { ext = strrchr (conn->request.buf, '.'); if (ext == NULL) return ret_ok; ret = cherokee_mime_get_by_suffix (srv->mime, ext+1, &hdl->mime); if (ret == ret_ok) { cherokee_mime_entry_get_type (hdl->mime, &mime); cherokee_buffer_add_str (buffer, "Content-Type: "); cherokee_buffer_add_buffer (buffer, mime); cherokee_buffer_add_str (buffer, CRLF); } } /* Length */ if (cherokee_connection_should_include_length(conn)) { HANDLER(hdl)->support = hsupport_length; cherokee_buffer_add_str (buffer, "Content-Length: "); cherokee_buffer_add_ullong10(buffer, (cullong_t) hdl->render.len); cherokee_buffer_add_str (buffer, CRLF); } 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; }
static ret_t report_error (cherokee_buffer_t *buf) { cherokee_logger_writer_t *writer = NULL; /* 1st Option, the thread variable */ writer = LOGGER_WRITER (CHEROKEE_THREAD_PROP_GET (thread_error_writer_ptr)); /* 2nd, the default error logger */ if (writer == NULL) { writer = default_error_writer; } /* Last resource: Print it to stderr. */ if ((writer == NULL) || (! writer->initialized)) { fprintf (stderr, "%s\n", buf->buf); fflush (stderr); return ret_ok; } /* Do logging */ if (writer->initialized) { cherokee_buffer_t *writer_log = NULL; cherokee_logger_writer_get_buf (writer, &writer_log); cherokee_buffer_add_buffer (writer_log, buf); cherokee_logger_writer_flush (writer, true); cherokee_logger_writer_release_buf (writer); return ret_ok; } return ret_ok; }
static ret_t write_logger (cherokee_buffer_t *buf, cherokee_logger_writer_t *error_writer) { int val; /* No writer */ if (error_writer == NULL) { goto nothing; } switch (error_writer->type) { case cherokee_logger_writer_stderr: val = 6; cherokee_buffer_add (buf, (char *)&val, sizeof(int)); cherokee_buffer_add_str (buf, "stderr"); cherokee_buffer_add_char (buf, '\0'); break; case cherokee_logger_writer_file: val = 5 + error_writer->filename.len; cherokee_buffer_add (buf, (char *)&val, sizeof(int)); cherokee_buffer_add_str (buf, "file,"); cherokee_buffer_add_buffer (buf, &error_writer->filename); cherokee_buffer_add_char (buf, '\0'); break; default: goto nothing; } return ret_ok; nothing: val = 0; cherokee_buffer_add (buf, (char *)&val, sizeof(int)); return ret_ok; }
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_request_header_build_string (cherokee_request_header_t *request, cherokee_buffer_t *buf, cherokee_buffer_t *tmp1, cherokee_buffer_t *tmp2) { ret_t ret; const char *ptr; cuint_t len; cherokee_url_t *url = REQUEST_URL(request); /* 200 bytes should be enough for a small header */ cherokee_buffer_ensure_size (buf, 200); /* Add main request line: * GET /dir/object HTTP/1.1 */ ret = cherokee_http_method_to_string (request->method, &ptr, &len); if (ret != ret_ok) return ret; ret = cherokee_buffer_add (buf, ptr, len); if (ret != ret_ok) return ret; cherokee_buffer_add_str (buf, " "); /* Check if the requests goes through a proxy */ if (request->proxy) { cherokee_buffer_add_str (buf, "http://"); cherokee_buffer_add_buffer (buf, URL_HOST(url)); } cherokee_buffer_add_buffer (buf, URL_REQUEST(url)); switch (REQUEST_VERSION(request)) { case http_version_11: cherokee_buffer_add_str (buf, " HTTP/1.1" CRLF); break; case http_version_10: cherokee_buffer_add_str (buf, " HTTP/1.0" CRLF); break; default: SHOULDNT_HAPPEN; return ret_error; } /* Add "Host:" header - in HTTP/1.1 */ if (REQUEST_VERSION(request) == http_version_11) { cherokee_buffer_add_str (buf, "Host: "); cherokee_buffer_add_buffer (buf, URL_HOST(url)); cherokee_buffer_add_str (buf, CRLF); } /* Post information */ if (request->post_len != 0) { /* "Content-Length: " FMT_OFFSET CRLF, request->post_len; */ cherokee_buffer_add_str (buf, "Content-Length: "); cherokee_buffer_add_ullong10 (buf, (cullong_t) request->post_len); cherokee_buffer_add_str (buf, CRLF); } /* Add "Connection:" header */ if (REQUEST_KEEPALIVE(request)) { cherokee_buffer_add_str (buf, "Connection: Keep-Alive"CRLF); } else { cherokee_buffer_add_str (buf, "Connection: close"CRLF); } /* Authentication */ if (! cherokee_buffer_is_empty (&request->user) || ! cherokee_buffer_is_empty (&request->password)) { cherokee_buffer_clean (tmp1); cherokee_buffer_clean (tmp2); cherokee_buffer_add_buffer (tmp1, &request->user); cherokee_buffer_add_char (tmp1, ':'); cherokee_buffer_add_buffer (tmp1, &request->password); cherokee_buffer_encode_base64 (tmp1, tmp2); cherokee_buffer_add_str (buf, "Authorization: Basic "); cherokee_buffer_add_buffer (buf, tmp2); cherokee_buffer_add_str (buf, CRLF); } /* Extra headers */ if (! cherokee_buffer_is_empty (&request->extra_headers)) { cherokee_buffer_add_buffer (buf, &request->extra_headers); } /* Finish the header */ cherokee_buffer_add_str (buf, CRLF); return ret_ok; }
ret_t cherokee_spawner_spawn (cherokee_buffer_t *binary, cherokee_buffer_t *user, uid_t uid, gid_t gid, int env_inherited, char **envp, cherokee_logger_writer_t *error_writer, pid_t *pid_ret) { #ifdef HAVE_SYSV_SEMAPHORES char **n; int *pid_shm; int pid_prev; int k; int phase; int envs = 0; cherokee_buffer_t tmp = CHEROKEE_BUF_INIT; #define ALIGN4(buf) \ while (buf.len & 0x3) { \ cherokee_buffer_add_char (&buf, '\0'); \ } /* Check it's initialized */ if ((! _active) || (cherokee_spawn_shared.mem == NULL)) { TRACE (ENTRIES, "Spawner is not active. Returning: %s\n", binary->buf); return ret_deny; } /* Lock the monitor mutex */ k = CHEROKEE_MUTEX_TRY_LOCK (&spawning_mutex); if (k) { return ret_eagain; } /* Build the string * The first character of each block is a mark. */ cherokee_buffer_ensure_size (&tmp, SPAWN_SHARED_LEN); /* 1.- Executable */ phase = 0xF0; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); cherokee_buffer_add (&tmp, (char *)&binary->len, sizeof(int)); cherokee_buffer_add_buffer (&tmp, binary); cherokee_buffer_add_char (&tmp, '\0'); ALIGN4 (tmp); /* 2.- UID & GID */ phase = 0xF1; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); cherokee_buffer_add (&tmp, (char *)&user->len, sizeof(int)); cherokee_buffer_add_buffer (&tmp, user); cherokee_buffer_add_char (&tmp, '\0'); ALIGN4(tmp); cherokee_buffer_add (&tmp, (char *)&uid, sizeof(uid_t)); cherokee_buffer_add (&tmp, (char *)&gid, sizeof(gid_t)); /* 3.- Environment */ phase = 0xF2; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); for (n=envp; *n; n++) { envs ++; } cherokee_buffer_add (&tmp, (char *)&env_inherited, sizeof(int)); cherokee_buffer_add (&tmp, (char *)&envs, sizeof(int)); for (n=envp; *n; n++) { int len = strlen(*n); cherokee_buffer_add (&tmp, (char *)&len, sizeof(int)); cherokee_buffer_add (&tmp, *n, len); cherokee_buffer_add_char (&tmp, '\0'); ALIGN4(tmp); } /* 4.- Error log */ phase = 0xF3; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); write_logger (&tmp, error_writer); ALIGN4 (tmp); /* 5.- PID (will be rewritten by the other side) */ phase = 0xF4; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); pid_shm = (int *) (((char *)cherokee_spawn_shared.mem) + tmp.len); k = *pid_ret; pid_prev = *pid_ret; cherokee_buffer_add (&tmp, (char *)&k, sizeof(int)); /* Copy it to the shared memory */ if (unlikely (tmp.len > SPAWN_SHARED_LEN)) { goto error; } memcpy (cherokee_spawn_shared.mem, tmp.buf, tmp.len); cherokee_buffer_mrproper (&tmp); /* Wake up the spawning thread */ sem_unlock (cherokee_spawn_sem, SEM_LAUNCH_START); /* Wait for the PID */ sem_adquire (cherokee_spawn_sem, SEM_LAUNCH_READY); if (*pid_shm == -1) { TRACE(ENTRIES, "Could not get the PID of: '%s'\n", binary->buf); goto error; } if (*pid_shm == pid_prev) { TRACE(ENTRIES, "Could not the new PID, previously it was %d\n", pid_prev); goto error; } TRACE(ENTRIES, "Successfully launched PID=%d\n", *pid_shm); *pid_ret = *pid_shm; CHEROKEE_MUTEX_UNLOCK (&spawning_mutex); return ret_ok; error: CHEROKEE_MUTEX_UNLOCK (&spawning_mutex); return ret_error; #else return ret_not_found; #endif /* HAVE_SYSV_SEMAPHORES */ }
static ret_t entry_fill_up (cherokee_resolv_cache_entry_t *entry, cherokee_buffer_t *domain) { ret_t ret; char tmp[46]; // Max IPv6 length is 45 struct addrinfo *addr; time_t eagain_at = 0; while (true) { ret = cherokee_gethostbyname (domain, &entry->addr); if (ret == ret_ok) { break; } else if (ret == ret_eagain) { if (eagain_at == 0) { eagain_at = cherokee_bogonow_now; } else if (cherokee_bogonow_now > eagain_at + 3) { LOG_WARNING (CHEROKEE_ERROR_RESOLVE_TIMEOUT, domain->buf); return ret_error; } CHEROKEE_THREAD_YIELD; continue; } else { return ret_error; } } if (unlikely (entry->addr == NULL)) { return ret_error; } /* Render the text representation */ ret = cherokee_ntop (entry->addr->ai_family, entry->addr->ai_addr, tmp, sizeof(tmp)); if (ret != ret_ok) { return ret_error; } cherokee_buffer_add (&entry->ip_str, tmp, strlen(tmp)); /* Render the text representation (all the IPs) */ cherokee_buffer_add_buffer (&entry->ip_str_all, &entry->ip_str); addr = entry->addr; while (addr != NULL) { ret = cherokee_ntop (entry->addr->ai_family, addr->ai_addr, tmp, sizeof(tmp)); if (ret != ret_ok) { return ret_error; } cherokee_buffer_add_char (&entry->ip_str_all, ','); cherokee_buffer_add (&entry->ip_str_all, tmp, strlen(tmp)); addr = addr->ai_next; } return ret_ok; }
ret_t cherokee_validator_mysql_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) { cherokee_list_t *i; cherokee_validator_mysql_props_t *props; UNUSED(srv); if(*_props == NULL) { CHEROKEE_NEW_STRUCT (n, validator_mysql_props); cherokee_validator_props_init_base (VALIDATOR_PROPS (n), MODULE_PROPS_FREE(props_free)); cherokee_buffer_init (&n->host); cherokee_buffer_init (&n->unix_socket); cherokee_buffer_init (&n->user); cherokee_buffer_init (&n->passwd); cherokee_buffer_init (&n->database); cherokee_buffer_init (&n->query); n->port = MYSQL_DEFAULT_PORT; n->hash_type = cherokee_mysql_hash_none; *_props = MODULE_PROPS (n); } props = PROP_MYSQL(*_props); cherokee_config_node_foreach (i, conf) { cherokee_config_node_t *subconf = CONFIG_NODE(i); if (equal_buf_str (&subconf->key, "host")) { cherokee_buffer_add_buffer (&props->host, &subconf->val); } else if (equal_buf_str (&subconf->key, "port")) { props->port = atoi (subconf->val.buf); } else if (equal_buf_str (&subconf->key, "unix_socket")) { cherokee_buffer_add_buffer (&props->unix_socket, &subconf->val); } else if (equal_buf_str (&subconf->key, "user")) { cherokee_buffer_add_buffer (&props->user, &subconf->val); } else if (equal_buf_str (&subconf->key, "passwd")) { cherokee_buffer_add_buffer (&props->passwd, &subconf->val); } else if (equal_buf_str (&subconf->key, "database")) { cherokee_buffer_add_buffer (&props->database, &subconf->val); } else if (equal_buf_str (&subconf->key, "query")) { cherokee_buffer_add_buffer (&props->query, &subconf->val); } else if (equal_buf_str (&subconf->key, "hash")) { if (equal_buf_str (&subconf->val, "md5")) { props->hash_type = cherokee_mysql_hash_md5; } else if (equal_buf_str (&subconf->val, "sha1")) { props->hash_type = cherokee_mysql_hash_sha1; } else { LOG_CRITICAL (CHEROKEE_ERROR_VALIDATOR_MYSQL_HASH, subconf->val.buf); return ret_error; } } else if ((equal_buf_str (&subconf->key, "methods") || equal_buf_str (&subconf->key, "realm"))) { /* not handled here */ } else { LOG_CRITICAL (CHEROKEE_ERROR_VALIDATOR_MYSQL_KEY, subconf->key.buf); return ret_error; } }
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 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); } if (! cherokee_buffer_is_empty (&conn->web_directory)) { cherokee_buffer_add (tmp, conn->request.buf + conn->web_directory.len, conn->request.len - conn->web_directory.len); } else { 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); if (ret == ret_ok) { 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; }
static ret_t fork_and_execute_cgi_win32 (cherokee_handler_cgi_t *cgi) { int re; PROCESS_INFORMATION pi; STARTUPINFO si; char *cmd; cherokee_buffer_t cmd_line = CHEROKEE_BUF_INIT; cherokee_buffer_t exec_dir = CHEROKEE_BUF_INIT; cherokee_connection_t *conn = HANDLER_CONN(cgi); SECURITY_ATTRIBUTES saSecAtr; HANDLE hProc; HANDLE hChildStdinRd = INVALID_HANDLE_VALUE; HANDLE hChildStdinWr = INVALID_HANDLE_VALUE; HANDLE hChildStdoutRd = INVALID_HANDLE_VALUE; HANDLE hChildStdoutWr = INVALID_HANDLE_VALUE; /* Create the environment for the process */ add_environment (cgi, conn); cherokee_buffer_add (&cgi->envp, "\0", 1); /* Command line */ cmd = HDL_CGI_BASE(cgi)->executable.buf; cherokee_buffer_add (&cmd_line, cmd, strlen(cmd)); // cherokee_buffer_add_va (&cmd_line, " \"%s\"", HDL_CGI_BASE(cgi)->param.buf); /* Execution directory */ if (! cherokee_buffer_is_empty (&conn->effective_directory)) { cherokee_buffer_add_buffer (&exec_dir, &conn->effective_directory); } else { char *file = strrchr (cmd, '/'); char *end = HDL_CGI_BASE(cgi)->executable.buf + HDL_CGI_BASE(cgi)->executable.len; cherokee_buffer_add (&exec_dir, cmd, HDL_CGI_BASE(cgi)->executable.len - (end - file)); } /* Set the bInheritHandle flag so pipe handles are inherited. */ memset(&saSecAtr, 0, sizeof(SECURITY_ATTRIBUTES)); saSecAtr.nLength = sizeof(SECURITY_ATTRIBUTES); saSecAtr.lpSecurityDescriptor = NULL; saSecAtr.bInheritHandle = TRUE; /* Create the pipes */ hProc = GetCurrentProcess(); re = CreatePipe (&hChildStdoutRd, &hChildStdoutWr, &saSecAtr, 0); if (!re) return ret_error; re = CreatePipe (&hChildStdinRd, &hChildStdinWr, &saSecAtr, 0); if (!re) return ret_error; /* Make them inheritable */ re = DuplicateHandle (hProc, hChildStdoutRd, hProc, &hChildStdoutRd, 0, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); if (!re) return ret_error; re = DuplicateHandle (hProc, hChildStdinWr, hProc, &hChildStdinWr, 0, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); if (!re) return ret_error; /* Starting information */ ZeroMemory (&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.hStdOutput = hChildStdoutWr; si.hStdError = hChildStdoutWr; si.hStdInput = hChildStdinRd; si.dwFlags |= STARTF_USESTDHANDLES; TRACE (ENTRIES, "exec %s dir %s\n", cmd_line.buf, exec_dir.buf); /* Launch the child process */ re = CreateProcess (cmd, /* ApplicationName */ cmd_line.buf, /* Command line */ NULL, /* Process handle not inheritable */ NULL, /* Thread handle not inheritable */ TRUE, /* Handle inheritance */ 0, /* Creation flags */ cgi->envp.buf, /* Use parent's environment block */ exec_dir.buf, /* Use parent's starting directory */ &si, /* Pointer to STARTUPINFO structure */ &pi); /* Pointer to PROCESS_INFORMATION structure */ CloseHandle (hChildStdinRd); CloseHandle (hChildStdoutWr); if (!re) { LOG_ERROR (CHEROKEE_ERROR_HANDLER_CGI_CREATEPROCESS, GetLastError()); CloseHandle (pi.hProcess); CloseHandle (pi.hThread); conn->error_code = http_internal_error; return ret_error; } cherokee_buffer_mrproper (&cmd_line); cherokee_buffer_mrproper (&exec_dir); cgi->thread = pi.hThread; cgi->process = pi.hProcess; /* Wait for the CGI process to be ready */ WaitForInputIdle (pi.hProcess, INFINITE); /* Extract the file descriptors */ cgi->pipeInput = _open_osfhandle((LONG)hChildStdoutRd, O_BINARY|_O_RDONLY); if (! conn->post.len <= 0) { CloseHandle (hChildStdinWr); } else { cgi->pipeOutput = _open_osfhandle((LONG)hChildStdinWr, O_BINARY|_O_WRONLY); } TRACE (ENTRIES, "In fd %d, Out fd %d\n", cgi->pipeInput, cgi->pipeOutput); return ret_ok; }
ret_t cherokee_handler_tmi_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) { ret_t ret; cherokee_list_t *i; cherokee_handler_tmi_props_t *props; cherokee_plugin_info_t *info = NULL; /* Instance a new property object */ if (*_props == NULL) { CHEROKEE_NEW_STRUCT (n, handler_tmi_props); cherokee_handler_props_init_base (HANDLER_PROPS(n), MODULE_PROPS_FREE(props_free)); cherokee_buffer_init (&n->reply); cherokee_buffer_init (&n->subscriberid); cherokee_buffer_init (&n->version); cherokee_buffer_init (&n->dossiername); cherokee_buffer_init (&n->endpoint); n->io_threads = 1; n->validate_xml = false; CHEROKEE_MUTEX_INIT (&n->mutex, CHEROKEE_MUTEX_FAST); *_props = MODULE_PROPS(n); } props = PROP_TMI(*_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, "subscriberid")) { cherokee_buffer_clean (&props->subscriberid); cherokee_buffer_add_buffer (&props->subscriberid, &subconf->val); } else if (equal_buf_str (&subconf->key, "version")) { cherokee_buffer_clean (&props->version); cherokee_buffer_add_buffer (&props->version, &subconf->val); } else if (equal_buf_str (&subconf->key, "dossiername")) { cherokee_buffer_clean (&props->dossiername); cherokee_buffer_add_buffer (&props->dossiername, &subconf->val); } else 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, "validate_xml")) { cherokee_atob (subconf->val.buf, &props->validate_xml); } 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; } }
ret_t cherokee_handler_tmi_read_post (cherokee_handler_tmi_t *hdl) { zmq_msg_t message; int re; ret_t ret; ret_t ret_final; cherokee_buffer_t *post = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_buffer_t *encoded = &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_final = re ? ret_ok : ret_eagain; cherokee_buffer_clean(encoded); if (hdl->encoder != NULL) { if (ret == ret_ok) { cherokee_encoder_flush(hdl->encoder, post, encoded); } else { cherokee_encoder_encode(hdl->encoder, post, encoded); } } else { encoded = post; } cherokee_buffer_add_buffer(&hdl->output, post); if (ret_final == ret_ok) { cherokee_buffer_t *tmp = &HANDLER_THREAD(hdl)->tmp_buf1; cherokee_handler_tmi_props_t *props = HANDLER_TMI_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); #ifdef LIBXML_PUSH_ENABLED if (hdl->validate_xml) { if (hdl->inflated) { hdl->strm.avail_in = hdl->output.len; hdl->strm.next_in = hdl->output.buf; /* run inflate() on input until output buffer not full */ do { #define CHUNK 131072 int have; char out[CHUNK]; hdl->strm.avail_out = CHUNK; hdl->strm.next_out = out; hdl->z_ret = inflate(&(hdl->strm), Z_NO_FLUSH); switch (hdl->z_ret) { case Z_NEED_DICT: hdl->z_ret = Z_DATA_ERROR; /* and fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: case Z_STREAM_ERROR: hdl->z_ret = Z_STREAM_ERROR; return ret_ok; } have = CHUNK - hdl->strm.avail_out; xmlParseChunk(hdl->ctxt, out, have, 0); } while (hdl->strm.avail_out == 0); } else { xmlParseChunk(hdl->ctxt, hdl->output.buf, hdl->output.len, 0); } } #endif } return ret_final; }
ret_t cherokee_logger_writer_configure (cherokee_logger_writer_t *writer, cherokee_config_node_t *config) { ret_t ret; cherokee_buffer_t *tmp = NULL; /* Check the type */ ret = config_read_type (config, &writer->type); if (ret != ret_ok) { return ret; } /* Extra properties */ switch (writer->type) { case cherokee_logger_writer_file: ret = cherokee_config_node_read (config, "filename", &tmp); if (ret != ret_ok) { LOG_ERROR (CHEROKEE_ERROR_LOGGER_WRITER_READ, "file"); return ret_error; } cherokee_buffer_add_buffer (&writer->filename, tmp); break; case cherokee_logger_writer_pipe: ret = cherokee_config_node_read (config, "command", &tmp); if (ret != ret_ok) { LOG_ERROR (CHEROKEE_ERROR_LOGGER_WRITER_READ, "exec"); return ret_error; } cherokee_buffer_add_buffer (&writer->command, tmp); break; default: break; } /* Reside the internal buffer if needed */ ret = cherokee_config_node_read (config, "bufsize", &tmp); if (ret == ret_ok) { int buf_len; ret = cherokee_atoi (tmp->buf, &buf_len); if (ret != ret_ok) { return ret_error; } if (buf_len < LOGGER_MIN_BUFSIZE) buf_len = LOGGER_MIN_BUFSIZE; else if (buf_len > LOGGER_MAX_BUFSIZE) buf_len = LOGGER_MAX_BUFSIZE; cherokee_buffer_mrproper (&writer->buffer); cherokee_buffer_init (&writer->buffer); ret = cherokee_buffer_ensure_size (&writer->buffer, buf_len); if (ret != ret_ok) { LOG_ERROR (CHEROKEE_ERROR_LOGGER_WRITER_ALLOC, writer->max_bufsize); return ret_nomem; } writer->max_bufsize = (size_t)buf_len; } return ret_ok; }
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); }
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; }
ret_t cherokee_mime_entry_set_type (cherokee_mime_entry_t *mentry, cherokee_buffer_t *type) { cherokee_buffer_clean (&mentry->mime_name); return cherokee_buffer_add_buffer (&mentry->mime_name, type); }
ret_t cherokee_validator_ldap_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) { ret_t ret; cherokee_list_t *i; cherokee_validator_ldap_props_t *props; UNUSED(srv); if (*_props == NULL) { CHEROKEE_NEW_STRUCT (n, validator_ldap_props); cherokee_validator_props_init_base (VALIDATOR_PROPS(n), MODULE_PROPS_FREE(props_free)); n->port = LDAP_DEFAULT_PORT; n->tls = false; cherokee_buffer_init (&n->server); cherokee_buffer_init (&n->binddn); cherokee_buffer_init (&n->bindpw); cherokee_buffer_init (&n->basedn); cherokee_buffer_init (&n->filter); cherokee_buffer_init (&n->ca_file); *_props = MODULE_PROPS(n); } props = PROP_LDAP(*_props); cherokee_config_node_foreach (i, conf) { cherokee_config_node_t *subconf = CONFIG_NODE(i); if (equal_buf_str (&subconf->key, "server")) { cherokee_buffer_add_buffer (&props->server, &subconf->val); } else if (equal_buf_str (&subconf->key, "port")) { ret = cherokee_atoi (subconf->val.buf, &props->port); if (ret != ret_ok) return ret_error; } else if (equal_buf_str (&subconf->key, "bind_dn")) { cherokee_buffer_add_buffer (&props->binddn, &subconf->val); } else if (equal_buf_str (&subconf->key, "bind_pw")) { cherokee_buffer_add_buffer (&props->bindpw, &subconf->val); } else if (equal_buf_str (&subconf->key, "base_dn")) { cherokee_buffer_add_buffer (&props->basedn, &subconf->val); } else if (equal_buf_str (&subconf->key, "filter")) { cherokee_buffer_add_buffer (&props->filter, &subconf->val); } else if (equal_buf_str (&subconf->key, "tls")) { ret = cherokee_atob (subconf->val.buf, &props->tls); if (ret != ret_ok) return ret_error; } else if (equal_buf_str (&subconf->key, "ca_file")) { cherokee_buffer_add_buffer (&props->ca_file, &subconf->val); } else if (equal_buf_str (&subconf->key, "methods") || equal_buf_str (&subconf->key, "realm") || equal_buf_str (&subconf->key, "users")) { /* Handled in validator.c */ } else { LOG_WARNING (CHEROKEE_ERROR_VALIDATOR_LDAP_KEY, subconf->key.buf); } }
ret_t cherokee_handler_admin_step (cherokee_handler_admin_t *hdl, cherokee_buffer_t *buffer) { cherokee_buffer_add_buffer (buffer, &hdl->reply); return ret_eof_have_data; }