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; }
static void render_human_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) { UNUSED (error_num); /* Time */ cherokee_buffer_add_char (output, '['); cherokee_buf_add_bogonow (output, false); cherokee_buffer_add_str (output, "] "); /* Error 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; } /* Source */ cherokee_buffer_add_va (output, " %s:%d - ", filename, line); /* Error */ cherokee_buffer_add_va_list (output, error->title, ap); cherokee_buffer_add_char (output, '\n'); /* Backtrace */ #ifdef BACKTRACES_ENABLED cherokee_buf_add_backtrace (output, 2, "\n", " "); #endif }
static ret_t generate_password (cherokee_buffer_t *buf) { cuint_t i; cuint_t n; for (i=0; i<PASSWORD_LEN; i++) { n = cherokee_random()%(sizeof(ALPHA_NUM)-1); cherokee_buffer_add_char (buf, ALPHA_NUM[n]); } return ret_ok; }
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 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 generate_admin_password (cherokee_buffer_t *buf) { cuint_t i; cuint_t n; srand(getpid()*time(NULL)); for (i=0; i<PASSWORD_LEN; i++) { n = rand()%(sizeof(ALPHA_NUM)-1); cherokee_buffer_add_char (buf, ALPHA_NUM[n]); } return ret_ok; }
ret_t cherokee_url_build_string (cherokee_url_t *url, cherokee_buffer_t *buf) { cherokee_buffer_add_buffer (buf, &url->host); if (((url->protocol == http) && (url->port != 80)) || ((url->protocol == https) && (url->port != 443))) { cherokee_buffer_add_char (buf, ':'); cherokee_buffer_add_ulong10 (buf, (culong_t) url->port); } cherokee_buffer_add_buffer (buf, &url->request); return ret_ok; }
ret_t cherokee_url_build_string (cherokee_url_t *url, cherokee_buffer_t *buf) { cherokee_buffer_add_buffer (buf, &url->host); if (! http_port_is_standard (url->port, (url->protocol == https))) { cherokee_buffer_add_char (buf, ':'); cherokee_buffer_add_ulong10 (buf, (culong_t) url->port); } cherokee_buffer_add_buffer (buf, &url->request); 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_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 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 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; }
static ret_t build_log_string (cherokee_logger_ncsa_t *logger, cherokee_connection_t *cnt, cherokee_buffer_t *buf) { ret_t ret; const char *method; const char *username; const char *version; cuint_t method_len = 0; size_t username_len = 0; cuint_t version_len = 0; cherokee_buffer_t *referer = &logger->referer; cherokee_buffer_t *useragent = &logger->useragent; char ipaddr[CHE_INET_ADDRSTRLEN]; /* Look for the user */ if (cnt->validator && !cherokee_buffer_is_empty (&cnt->validator->user)) { username_len = cnt->validator->user.len; username = cnt->validator->user.buf; } else { username_len = 1; username = "******"; } /* Get the method and version strings */ ret = cherokee_http_method_to_string (cnt->header.method, &method, &method_len); if (unlikely (ret < ret_ok)) { method = ""; method_len = 0; } ret = cherokee_http_version_to_string (cnt->header.version, &version, &version_len); if (unlikely (ret < ret_ok)) { version = ""; version_len = 0; } /* Build the log string * * "%s - %s [%02d/%s/%d:%02d:%02d:%02d %c%02d%02d] \"%s %s %s\" %d " * FMT_OFFSET */ if (cherokee_buffer_is_empty (&cnt->logger_real_ip)) { memset (ipaddr, 0, sizeof(ipaddr)); cherokee_socket_ntop (&cnt->socket, ipaddr, sizeof(ipaddr)-1); cherokee_buffer_add (buf, ipaddr, strlen(ipaddr)); } else { cherokee_buffer_add_buffer (buf, &cnt->logger_real_ip); } cherokee_buffer_add_str (buf, " - "); cherokee_buffer_add (buf, username, username_len); /* " [date time] " */ cherokee_buffer_add_buffer (buf, &now); cherokee_buffer_add (buf, method, method_len); cherokee_buffer_add_char (buf, ' '); if (! cherokee_buffer_is_empty (&cnt->request_original)) { cherokee_buffer_add_buffer (buf, &cnt->request_original); if (! cherokee_buffer_is_empty (&cnt->query_string_original)) { cherokee_buffer_add_char (buf, '?'); cherokee_buffer_add_buffer (buf, &cnt->query_string_original); } } else { cherokee_buffer_add_buffer (buf, &cnt->request); if (! cherokee_buffer_is_empty (&cnt->query_string)) { cherokee_buffer_add_char (buf, '?'); cherokee_buffer_add_buffer (buf, &cnt->query_string); } } cherokee_buffer_add_char (buf, ' '); cherokee_buffer_add (buf, version, version_len); cherokee_buffer_add_str (buf, "\" "); if (unlikely (cnt->error_internal_code != http_unset)) { cherokee_buffer_add_long10 (buf, cnt->error_internal_code); } else { cherokee_buffer_add_long10 (buf, cnt->error_code); } cherokee_buffer_add_char (buf, ' '); cherokee_buffer_add_ullong10 (buf, cnt->tx); /* Look for the "combined" information */ if (!logger->combined) { cherokee_buffer_add_char (buf, '\n'); return ret_ok; } /* "combined" information */ cherokee_buffer_clean (referer); cherokee_buffer_clean (useragent); cherokee_header_copy_known (&cnt->header, header_referer, referer); cherokee_header_copy_known (&cnt->header, header_user_agent, useragent); cherokee_buffer_ensure_addlen (buf, 8 + referer->len + referer->len); if (referer->len > 0) { cherokee_buffer_add_str (buf, " \""); cherokee_buffer_add_buffer (buf, referer); cherokee_buffer_add_str (buf, "\" \""); } else { cherokee_buffer_add_str (buf, " \"-\" \""); } if (useragent->len > 0) { cherokee_buffer_add_buffer (buf, useragent); } cherokee_buffer_add_str (buf, "\"\n"); return ret_ok; }
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; }
static ret_t config_server (cherokee_server_t *srv) { ret_t ret; cherokee_config_node_t conf; cherokee_buffer_t buf = CHEROKEE_BUF_INIT; cherokee_buffer_t rrd_dir = CHEROKEE_BUF_INIT; cherokee_buffer_t rrd_bin = CHEROKEE_BUF_INIT; cherokee_buffer_t fake; /* Generate the password */ if (unsecure == 0) { ret = generate_admin_password (&password); if (ret != ret_ok) return ret; } /* Configure the embedded server */ if (scgi_port > 0) { ret = find_empty_port (scgi_port, &scgi_port); } else { ret = remove_old_socket (DEFAULT_UNIX_SOCKET); } if (ret != ret_ok) { return ret_error; } cherokee_buffer_add_va (&buf, "server!bind!1!port = %d\n", port); cherokee_buffer_add_str (&buf, "server!ipv6 = 1\n"); cherokee_buffer_add_str (&buf, "server!max_connection_reuse = 0\n"); cherokee_buffer_add_va (&buf, "server!iocache = %d\n", iocache); if (bind_to) { cherokee_buffer_add_va (&buf, "server!bind!1!interface = %s\n", bind_to); } if (thread_num != -1) { cherokee_buffer_add_va (&buf, "server!thread_number = %d\n", thread_num); } cherokee_buffer_add_str (&buf, "vserver!1!nick = default\n"); cherokee_buffer_add_va (&buf, "vserver!1!document_root = %s\n", document_root); if (scgi_port <= 0) { cherokee_buffer_add_va (&buf, "source!1!nick = app-logic\n" "source!1!type = interpreter\n" "source!1!timeout = " TIMEOUT "\n" "source!1!host = %s\n" "source!1!interpreter = %s/server.py %s %s %s\n" "source!1!env_inherited = 1\n", DEFAULT_UNIX_SOCKET, document_root, DEFAULT_UNIX_SOCKET, config_file, (debug) ? "-x" : ""); } else { cherokee_buffer_add_va (&buf, "source!1!nick = app-logic\n" "source!1!type = interpreter\n" "source!1!timeout = " TIMEOUT "\n" "source!1!host = localhost:%d\n" "source!1!interpreter = %s/server.py %d %s %s\n" "source!1!env_inherited = 1\n", scgi_port, document_root, scgi_port, config_file, (debug) ? "-x" : ""); } if (debug) { cherokee_buffer_add_str (&buf, "source!1!debug = 1\n"); } cherokee_buffer_add_str (&buf, RULE_PRE "1!match = default\n" RULE_PRE "1!handler = scgi\n" RULE_PRE "1!timeout = " TIMEOUT "\n" RULE_PRE "1!handler!balancer = round_robin\n" RULE_PRE "1!handler!balancer!source!1 = 1\n"); cherokee_buffer_add_str (&buf, RULE_PRE "1!handler!env!CTK_COOKIE = "); generate_admin_password (&buf); cherokee_buffer_add_char (&buf, '\n'); if (! debug) { cherokee_buffer_add_str (&buf, RULE_PRE "1!encoder!gzip = 1\n"); } if ((unsecure == 0) && (!cherokee_buffer_is_empty (&password))) { cherokee_buffer_add_va (&buf, RULE_PRE "1!auth = authlist\n" RULE_PRE "1!auth!methods = digest\n" RULE_PRE "1!auth!realm = Cherokee-admin\n" RULE_PRE "1!auth!list!1!user = admin\n" RULE_PRE "1!auth!list!1!password = %s\n", password.buf); } cherokee_buffer_add_str (&buf, RULE_PRE "2!match = directory\n" RULE_PRE "2!match!directory = /about\n" RULE_PRE "2!handler = server_info\n"); cherokee_buffer_add_str (&buf, RULE_PRE "3!match = directory\n" RULE_PRE "3!match!directory = /static\n" RULE_PRE "3!handler = file\n" RULE_PRE "3!expiration = time\n" RULE_PRE "3!expiration!time = 30d\n"); cherokee_buffer_add_va (&buf, RULE_PRE "4!match = request\n" RULE_PRE "4!match!request = ^/favicon.ico$\n" RULE_PRE "4!document_root = %s/static/images\n" RULE_PRE "4!handler = file\n" RULE_PRE "4!expiration = time\n" RULE_PRE "4!expiration!time = 30d\n", document_root); cherokee_buffer_add_va (&buf, RULE_PRE "5!match = directory\n" RULE_PRE "5!match!directory = /icons_local\n" RULE_PRE "5!handler = file\n" RULE_PRE "5!document_root = %s\n" RULE_PRE "5!expiration = time\n" RULE_PRE "5!expiration!time = 30d\n", CHEROKEE_ICONSDIR); cherokee_buffer_add_va (&buf, RULE_PRE "6!match = directory\n" RULE_PRE "6!match!directory = /CTK\n" RULE_PRE "6!handler = file\n" RULE_PRE "6!document_root = %s/CTK/static\n" RULE_PRE "6!expiration = time\n" RULE_PRE "6!expiration!time = 30d\n", document_root); /* Embedded help */ cherokee_buffer_add_va (&buf, RULE_PRE "7!match = and\n" RULE_PRE "7!match!left = directory\n" RULE_PRE "7!match!left!directory = /help\n" RULE_PRE "7!match!right = not\n" RULE_PRE "7!match!right!right = extensions\n" RULE_PRE "7!match!right!right!extensions = html\n" RULE_PRE "7!handler = file\n"); cherokee_buffer_add_va (&buf, RULE_PRE "8!match = fullpath\n" RULE_PRE "8!match!fullpath!1 = /static/help_404.html\n" RULE_PRE "8!handler = file\n" RULE_PRE "8!document_root = %s\n", document_root); cherokee_buffer_add_va (&buf, RULE_PRE "9!match = and\n" RULE_PRE "9!match!left = directory\n" RULE_PRE "9!match!left!directory = /help\n" RULE_PRE "9!match!right = not\n" RULE_PRE "9!match!right!right = exists\n" RULE_PRE "9!match!right!right!match_any = 1\n" RULE_PRE "9!handler = redir\n" RULE_PRE "9!handler!rewrite!1!show = 1\n" RULE_PRE "9!handler!rewrite!1!substring = /static/help_404.html\n"); cherokee_buffer_add_va (&buf, RULE_PRE "10!match = directory\n" RULE_PRE "10!match!directory = /help\n" RULE_PRE "10!match!final = 0\n" RULE_PRE "10!document_root = %s\n", CHEROKEE_DOCDIR); /* GZip */ if (! debug) { cherokee_buffer_add_va (&buf, RULE_PRE "15!match = extensions\n" RULE_PRE "15!match!extensions = css,js,html\n" RULE_PRE "15!match!final = 0\n" RULE_PRE "15!encoder!gzip = 1\n"); } /* RRDtool graphs */ cherokee_config_node_init (&conf); cherokee_buffer_fake (&fake, config_file, strlen(config_file)); ret = cherokee_config_reader_parse (&conf, &fake); if (ret == ret_ok) { cherokee_config_node_copy (&conf, "server!collector!rrdtool_path", &rrd_bin); cherokee_config_node_copy (&conf, "server!collector!database_dir", &rrd_dir); } if (! cherokee_buffer_is_empty (&rrd_bin)) { cherokee_buffer_add_va (&buf, RULE_PRE "20!handler!rrdtool_path = %s\n", rrd_bin.buf); } if (! cherokee_buffer_is_empty (&rrd_dir)) { cherokee_buffer_add_va (&buf, RULE_PRE "20!handler!database_dir = %s\n", rrd_dir.buf); } cherokee_buffer_add_str (&buf, RULE_PRE "20!match = directory\n" RULE_PRE "20!match!directory = /graphs\n" RULE_PRE "20!handler = render_rrd\n" RULE_PRE "20!expiration = epoch\n" RULE_PRE "20!expiration!caching = no-cache\n" RULE_PRE "20!expiration!caching!no-store = 1\n"); cherokee_buffer_add_str (&buf, RULE_PRE "20!document_root = "); cherokee_tmp_dir_copy (&buf); cherokee_buffer_add_va (&buf, "/cherokee/rrd-cache\n"); /* MIME types */ cherokee_buffer_add_str (&buf, "mime!text/javascript!extensions = js\n" "mime!text/css!extensions = css\n" "mime!image/png!extensions = png\n" "mime!image/jpeg!extensions = jpeg,jpg\n" "mime!image/svg+xml!extensions = svg,svgz\n" "mime!image/gif!extensions = gif\n"); ret = cherokee_server_read_config_string (srv, &buf); if (ret != ret_ok) { PRINT_ERROR_S ("Could not initialize the server\n"); return ret; } cherokee_config_node_mrproper (&conf); cherokee_buffer_mrproper (&rrd_bin); cherokee_buffer_mrproper (&rrd_dir); cherokee_buffer_mrproper (&buf); 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; }
void cherokee_trace_do_trace (const char *entry, const char *file, int line, const char *func, const char *fmt, ...) { ret_t ret; char *p; char *lentry; char *lentry_end; va_list args; cherokee_connection_t *conn; cherokee_buffer_t *trace_modules = &trace.modules; cherokee_boolean_t do_log = false; cherokee_buffer_t entries = CHEROKEE_BUF_INIT; /* Prevents loops */ if (disabled) { return; } disabled = true; /* Return ASAP if nothing is being traced */ if (cherokee_buffer_is_empty (&trace.modules)) { goto out; } /* Check the connection source, if possible */ if (trace.from_filter != NULL) { conn = CONN (CHEROKEE_THREAD_PROP_GET (thread_connection_ptr)); /* No conn, no trace entry */ if (conn == NULL) { goto out; } if (conn->socket.socket < 0) { goto out; } /* Skip the trace if the conn doesn't match */ ret = cherokee_access_ip_match (trace.from_filter, &conn->socket); if (ret != ret_ok) { goto out; } } /* Also, check for 'all' */ p = strstr (trace_modules->buf, "all"); if (p == NULL) { /* Parse the In-code module string */ cherokee_buffer_add (&entries, entry, strlen(entry)); for (lentry = entries.buf;;) { lentry_end = strchr (lentry, ','); if (lentry_end) *lentry_end = '\0'; /* Check the type */ p = strstr (trace_modules->buf, lentry); if (p) { char *tmp = p + strlen(lentry); if ((*tmp == '\0') || (*tmp == ',') || (*tmp == ' ')) do_log = true; } if ((lentry_end == NULL) || (do_log)) break; lentry = lentry_end + 1; } /* Return if trace entry didn't match with the configured list */ if (! do_log) { goto out; } } /* Format the message and log it: * 'entries' is not needed at this stage, reuse it */ cherokee_buffer_clean (&entries); if (trace.print_thread) { int len; char tmp[32+1]; static int longest_len = 0; len = snprintf (tmp, 32+1, "%llX", (unsigned long long) CHEROKEE_THREAD_SELF); longest_len = MAX (longest_len, len); cherokee_buffer_add_str (&entries, "{0x"); cherokee_buffer_add_char_n (&entries, '0', longest_len - len); cherokee_buffer_add (&entries, tmp, len); cherokee_buffer_add_str (&entries, "} "); } if (trace.print_time) { cherokee_buffer_add_char (&entries, '['); cherokee_buf_add_bogonow (&entries, true); cherokee_buffer_add_str (&entries, "] "); } cherokee_buffer_add_va (&entries, "%18s:%04d (%30s): ", file, line, func); va_start (args, fmt); cherokee_buffer_add_va_list (&entries, (char *)fmt, args); va_end (args); if (trace.use_syslog) { cherokee_syslog (LOG_DEBUG, &entries); } else { #ifdef HAVE_FLOCKFILE flockfile (stdout); #endif fprintf (stdout, "%s", entries.buf); #ifdef HAVE_FUNLOCKFILE funlockfile (stdout); #endif } out: cherokee_buffer_mrproper (&entries); disabled = false; }