static ret_t match (cherokee_rule_request_t *rule, cherokee_connection_t *conn, cherokee_config_entry_t *ret_conf) { int re; ret_t ret; cherokee_regex_table_t *regexs = CONN_SRV(conn)->regexs; UNUSED(ret_conf); /* Sanity checks */ if (unlikely (regexs == NULL)) { LOG_ERROR_S (CHEROKEE_ERROR_RULE_REQUEST_NO_TABLE); return ret_error; } if (unlikely (rule->pcre == NULL)) { LOG_ERROR_S (CHEROKEE_ERROR_RULE_REQUEST_NO_PCRE_PTR); return ret_error; } /* Build the request string */ if (! cherokee_buffer_is_empty (&conn->query_string)) { cherokee_buffer_add_str (&conn->request, "?"); cherokee_buffer_add_buffer (&conn->request, &conn->query_string); } /* Evaluate the pcre */ re = pcre_exec (rule->pcre, NULL, conn->request.buf, conn->request.len, 0, 0, conn->regex_ovector, OVECTOR_LEN); if (re < 0) { TRACE (ENTRIES, "Request \"%s\" didn't match with \"%s\"\n", conn->request.buf, rule->pattern.buf); ret = ret_not_found; goto restore; } conn->regex_ovecsize = re; TRACE (ENTRIES, "Request \"%s\" matches with \"%s\", ovecsize=%d\n", conn->request.buf, rule->pattern.buf, conn->regex_ovecsize); ret = ret_ok; restore: if (! cherokee_buffer_is_empty (&conn->query_string)) { cherokee_buffer_drop_ending (&conn->request, conn->query_string.len + 1); } return ret; }
ret_t cherokee_validator_digest_response (cherokee_validator_t *validator, char *A1, cherokee_buffer_t *buf, cherokee_connection_t *conn) { ret_t ret; cherokee_buffer_t a2 = CHEROKEE_BUF_INIT; /* A1 has to be in string of length 32: * MD5_digest(user":"******":"passwd) */ /* Sanity checks */ if (A1 == NULL) return ret_deny; if (cherokee_buffer_is_empty (&validator->nonce)) return ret_deny; /* Build A2 */ ret = digest_HA2 (validator, &a2, conn); if (ret != ret_ok) goto error; /* Build the final string */ cherokee_buffer_ensure_size (buf, 32 + a2.len + validator->nonce.len + 4); cherokee_buffer_add (buf, A1, 32); cherokee_buffer_add_str (buf, ":"); cherokee_buffer_add_buffer (buf, &validator->nonce); cherokee_buffer_add_str (buf, ":"); if (!cherokee_buffer_is_empty (&validator->qop)) { if (!cherokee_buffer_is_empty (&validator->nc)) cherokee_buffer_add_buffer (buf, &validator->nc); cherokee_buffer_add_str (buf, ":"); if (!cherokee_buffer_is_empty (&validator->cnonce)) cherokee_buffer_add_buffer (buf, &validator->cnonce); cherokee_buffer_add_str (buf, ":"); cherokee_buffer_add_buffer (buf, &validator->qop); cherokee_buffer_add_str (buf, ":"); } cherokee_buffer_add_buffer (buf, &a2); cherokee_buffer_encode_md5_digest (buf); cherokee_buffer_mrproper (&a2); return ret_ok; error: cherokee_buffer_mrproper (&a2); return ret; }
static ret_t do_send_socket (cherokee_socket_t *sock, cherokee_buffer_t *buffer, cherokee_socket_status_t *blocking) { ret_t ret; size_t written = 0; ret = cherokee_socket_bufwrite (sock, buffer, &written); switch (ret) { case ret_ok: break; case ret_eagain: if (written > 0) { break; } TRACE (ENTRIES, "Post write: EAGAIN, wrote nothing of %d\n", buffer->len); *blocking = socket_writing; return ret_eagain; default: return ret_error; } cherokee_buffer_move_to_begin (buffer, written); TRACE (ENTRIES, "sent=%d, remaining=%d\n", written, buffer->len); if (! cherokee_buffer_is_empty (buffer)) { return ret_eagain; } return ret_ok; }
static ret_t downloader_send_buffer (cherokee_downloader_t *downloader, cherokee_buffer_t *buf) { ret_t ret; size_t written = 0; cherokee_socket_t *sock = &downloader->socket;; ret = cherokee_socket_bufwrite (sock, buf, &written); switch (ret) { case ret_ok: /* Drop the header that has been sent */ cherokee_buffer_drop_ending (buf, written); if (cherokee_buffer_is_empty (buf)) { return ret_ok; } return ret_eagain; case ret_eagain: return ret; default: return ret_error; } }
ret_t cherokee_handler_ssi_init (cherokee_handler_ssi_t *hdl) { ret_t ret; cherokee_connection_t *conn = HANDLER_CONN(hdl); /* Build the local directory */ cherokee_buffer_add_buffer (&hdl->dir, &conn->local_directory); cherokee_buffer_add_buffer (&hdl->dir, &conn->request); while (true) { if (cherokee_buffer_is_empty (&hdl->dir)) return ret_error; if (cherokee_buffer_is_ending (&hdl->dir, '/')) break; cherokee_buffer_drop_ending (&hdl->dir, 1); } /* Real init function */ cherokee_buffer_add_buffer (&conn->local_directory, &conn->request); ret = init (hdl, &conn->local_directory); cherokee_buffer_drop_ending (&conn->local_directory, conn->request.len); return ret; }
int cherokee_post_has_buffered_info (cherokee_post_t *post, cherokee_buffer_t *tmp) { cherokee_buffer_t *buffer = tmp ? tmp : &post->send.buffer; return (! cherokee_buffer_is_empty (buffer)); }
ret_t cherokee_downloader_connect (cherokee_downloader_t *downloader) { ret_t ret; cherokee_boolean_t uses_proxy; cherokee_url_t *url = &downloader->request.url; /* Does it use a proxy? */ uses_proxy = ! cherokee_buffer_is_empty (&downloader->proxy); ret = cherokee_request_header_uses_proxy (&downloader->request, uses_proxy); if (ret != ret_ok) return ret; /* Connect */ if (uses_proxy) { ret = connect_to (downloader, &downloader->proxy, downloader->proxy_port, http); if (ret != ret_ok) return ret; } else { ret = connect_to (downloader, &url->host, url->port, url->protocol); if (ret != ret_ok) return ret; } return ret_ok; }
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; }
static ret_t digest_HA2 (cherokee_validator_t *validator, cherokee_buffer_t *buf, cherokee_connection_t *conn) { ret_t ret; const char *method; cuint_t method_len; /* Sanity check */ if (cherokee_buffer_is_empty (&validator->uri)) return ret_deny; ret = cherokee_http_method_to_string (conn->header.method, &method, &method_len); if (unlikely (ret != ret_ok)) return ret; cherokee_buffer_ensure_size (buf, method_len + 1 + validator->uri.len); cherokee_buffer_add (buf, method, method_len); cherokee_buffer_add_str (buf, ":"); cherokee_buffer_add_buffer (buf, &validator->uri); cherokee_buffer_encode_md5_digest (buf); return ret_ok; }
static ret_t configure (cherokee_rule_header_t *rule, cherokee_config_node_t *conf, cherokee_virtual_server_t *vsrv) { ret_t ret; cherokee_buffer_t *type = NULL; cherokee_buffer_t *header = NULL; cherokee_regex_table_t *regexs = VSERVER_SRV(vsrv)->regexs; /* Read the header */ ret = cherokee_config_node_read (conf, "header", &header); if (ret != ret_ok) { LOG_ERROR (CHEROKEE_ERROR_RULE_NO_PROPERTY, RULE(rule)->priority, "header"); return ret_error; } ret = header_str_to_type (header, &rule->header); if (ret != ret_ok) { return ret; } /* Type */ ret = cherokee_config_node_read (conf, "type", &type); if (ret == ret_ok) { ret = type_str_to_type (type, &rule->type); if (ret != ret_ok) { return ret; } } /* Read the match */ ret = cherokee_config_node_copy (conf, "match", &rule->match); if (ret != ret_ok) { if (equal_buf_str (type, "regex")) { LOG_ERROR (CHEROKEE_ERROR_RULE_NO_PROPERTY, RULE(rule)->priority, "match"); return ret_error; } } /* Compile the regular expression */ if (! cherokee_buffer_is_empty (&rule->match)) { ret = cherokee_regex_table_add (regexs, rule->match.buf); if (ret != ret_ok) return ret; ret = cherokee_regex_table_get (regexs, rule->match.buf, &rule->pcre); if (ret != ret_ok) return ret; } return ret_ok; }
int cherokee_buffer_is_ending (cherokee_buffer_t *buf, char c) { if (cherokee_buffer_is_empty(buf)) return 0; return (buf->buf[buf->len - 1] == c); }
crc_t cherokee_buffer_crc32 (cherokee_buffer_t *buf) { if (cherokee_buffer_is_empty (buf)) return 0; return crc32_sz (buf->buf, buf->len); }
ret_t cherokee_validator_digest_check (cherokee_validator_t *validator, cherokee_buffer_t *passwd, cherokee_connection_t *conn) { ret_t ret; int re = -1; cherokee_buffer_t a1 = CHEROKEE_BUF_INIT; cherokee_buffer_t buf = CHEROKEE_BUF_INIT; /* Sanity check */ if (cherokee_buffer_is_empty (&validator->user) || cherokee_buffer_is_empty (&validator->realm)) return ret_deny; /* Build A1 */ cherokee_buffer_ensure_size (&a1, validator->user.len + 1 + validator->realm.len + 1 + passwd->len); cherokee_buffer_add_buffer (&a1, &validator->user); cherokee_buffer_add_str (&a1, ":"); cherokee_buffer_add_buffer (&a1, &validator->realm); cherokee_buffer_add_str (&a1, ":"); cherokee_buffer_add_buffer (&a1, passwd); cherokee_buffer_encode_md5_digest (&a1); /* Build a possible response */ ret = cherokee_validator_digest_response (validator, a1.buf, &buf, conn); if (unlikely(ret != ret_ok)) goto go_out; /* Compare and return */ re = cherokee_buffer_cmp_buf (&conn->validator->response, &buf); go_out: cherokee_buffer_mrproper (&a1); cherokee_buffer_mrproper (&buf); return (re == 0) ? ret_ok : ret_deny; }
ret_t cherokee_url_parse (cherokee_url_t *url, cherokee_buffer_t *string, cherokee_buffer_t *user_ret, cherokee_buffer_t *password_ret) { if (cherokee_buffer_is_empty (string)) { return ret_error; } return cherokee_url_parse_guts (url, string, user_ret, password_ret); }
static ret_t load_theme (cherokee_buffer_t *theme_path, cherokee_handler_dirlist_props_t *props) { load_theme_load_file (theme_path, "header.html", &props->header); load_theme_load_file (theme_path, "footer.html", &props->footer); load_theme_load_file (theme_path, "entry.html", &props->entry); load_theme_load_file (theme_path, "theme.css", &props->css); /* Check it */ if ((cherokee_buffer_is_empty (&props->header) || cherokee_buffer_is_empty (&props->entry) || cherokee_buffer_is_empty (&props->footer))) return ret_error; /* Parse conditional blocks */ parse_macros_in_buffer (&props->header, props); parse_macros_in_buffer (&props->footer, props); parse_macros_in_buffer (&props->entry, props); return ret_ok; }
static ret_t process_buffer (cherokee_handler_fcgi_t *hdl, cherokee_buffer_t *inbuf, cherokee_buffer_t *outbuf) { ret_t ret; do { ret = process_package (hdl, inbuf, outbuf); } while (ret == ret_eagain); if (ret == ret_ok) { if (cherokee_buffer_is_empty (outbuf)) return (HDL_CGI_BASE(hdl)->got_eof) ? ret_eof : ret_eagain; } return ret; }
ret_t cherokee_validator_htdigest_check (cherokee_validator_htdigest_t *htdigest, cherokee_connection_t *conn) { ret_t ret; cherokee_buffer_t *fpass; cherokee_buffer_t file = CHEROKEE_BUF_INIT; /* Ensure that we have all what we need */ if ((conn->validator == NULL) || cherokee_buffer_is_empty (&conn->validator->user)) return ret_error; /* Get the full path to the file */ ret = cherokee_validator_file_get_full_path (VFILE(htdigest), conn, &fpass, &CONN_THREAD(conn)->tmp_buf1); if (ret != ret_ok) { ret = ret_error; goto out; } /* Read the whole file */ ret = cherokee_buffer_read_file (&file, fpass->buf); if (ret != ret_ok) { ret = ret_error; goto out; } /* Authenticate */ if (conn->req_auth_type & http_auth_basic) { ret = validate_basic (htdigest, conn, &file); } else if (conn->req_auth_type & http_auth_digest) { ret = validate_digest (htdigest, conn, &file); } else { SHOULDNT_HAPPEN; } out: cherokee_buffer_mrproper (&file); return ret; }
static void print_connection_info (void) { printf ("\n"); if (! cherokee_buffer_is_empty (&password)) { printf ("Login:\n" " User: admin\n" " One-time Password: %s\n\n", password.buf); } printf ("Web Interface:\n" " URL: http://%s:%d/\n\n", (bind_to) ? bind_to : "localhost", port); fflush(stdout); }
ret_t cherokee_handler_cgi_init (cherokee_handler_cgi_t *cgi) { ret_t ret; cherokee_handler_cgi_base_t *cgi_base = HDL_CGI_BASE(cgi); cherokee_connection_t *conn = HANDLER_CONN(cgi); switch (cgi_base->init_phase) { case hcgi_phase_build_headers: /* Extracts PATH_INFO and filename from request uri */ if (cherokee_buffer_is_empty (&cgi_base->executable)) { ret = cherokee_handler_cgi_base_extract_path (cgi_base, true); if (unlikely (ret < ret_ok)) { return ret; } } /* It has to update the timeout of the connection, * otherwhise the server will drop it for the CGI * isn't fast enough */ conn->timeout = cherokee_bogonow_now + CGI_TIMEOUT; cgi_base->init_phase = hcgi_phase_connect; case hcgi_phase_connect: /* Launch the CGI */ ret = fork_and_execute_cgi_via_spawner(cgi); if (unlikely (ret != ret_ok)) { ret = fork_and_execute_cgi(cgi); if (unlikely (ret != ret_ok)) { return ret; } } default: break; } TRACE (ENTRIES, "finishing %s\n", "ret_ok"); return ret_ok; }
static ret_t cherokee_bind_v6 (cherokee_socket_t *sock, cuint_t port, cherokee_buffer_t *listen_to) { int re; ret_t ret; SOCKET_ADDR_IPv6(sock)->sin6_port = htons(port); if (cherokee_buffer_is_empty (listen_to)) { SOCKET_ADDR_IPv6(sock)->sin6_addr = in6addr_any; } else{ ret = cherokee_socket_pton (sock, listen_to); if (ret != ret_ok) return ret; } re = bind (SOCKET_FD(sock), (struct sockaddr *)&SOCKET_ADDR(sock), sock->client_addr_len); if (re != 0) return ret_error; 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; }
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; }
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 validate_digest (cherokee_validator_htdigest_t *htdigest, cherokee_connection_t *conn, cherokee_buffer_t *file) { int re; ret_t ret; char *user = NULL; char *realm = NULL; char *passwd = NULL; cherokee_buffer_t buf = CHEROKEE_BUF_INIT; /* Sanity check */ if (cherokee_buffer_is_empty (&conn->validator->response)) return ret_error; /* Extact the right entry information */ ret = extract_user_entry (file, conn->validator->user.buf, &user, &realm, &passwd); if (unlikely(ret != ret_ok)) return ret; /* Build the hash: * In this case passwd is the HA1 hash: md5(user:realm:passwd) */ ret = cherokee_validator_digest_response (VALIDATOR(htdigest), passwd, &buf, conn); if (unlikely(ret != ret_ok)) goto go_out; /* Compare and return */ re = cherokee_buffer_cmp_buf (&conn->validator->response, &buf); go_out: cherokee_buffer_mrproper (&buf); return (re == 0) ? ret_ok : ret_deny; }
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 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 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; }
ret_t cherokee_buffer_add_buffer_slice (cherokee_buffer_t *buf, cherokee_buffer_t *buf2, ssize_t begin, ssize_t end) { ssize_t pos_end; ssize_t pos_begin; /* Ensure there's something to copy */ if (unlikely (cherokee_buffer_is_empty (buf2))) return ret_ok; /* Check the end */ if (end == CHEROKEE_BUF_SLIDE_NONE) { /* [__:] */ pos_end = buf2->len; } else { if (end > 0) { /* [__:x] */ pos_end = end; } else { if ((-end) > buf2->len) { /* [__:-x] */ pos_end = buf2->len - (-end); } else { /* [__:-xxxxx] */ return ret_ok; } } } /* Check the beginning */ if (begin == CHEROKEE_BUF_SLIDE_NONE) { /* [:__] */ pos_begin = 0; } else { if (begin >= 0) { if (begin > buf2->len) { /* [xxxx:__] */ pos_begin = buf2->len; } else { /* [x:__] */ pos_begin = begin; } } else { if ((-begin) < buf2->len) { /* [-x:__] */ pos_begin = buf2->len - begin; } else { /* [-xxxx:__] */ pos_begin = 0; } } } /* Sanity check */ if (unlikely ((pos_begin < 0) || (pos_end < 0) || (pos_end > buf2->len) || (pos_end < pos_begin))) { return ret_ok; } /* Copy the substring */ return cherokee_buffer_add (buf, buf2->buf + pos_begin, pos_end - pos_begin); }
int main (int argc, char **argv) { int re; ret_t ret; cint_t val; cint_t param_num; cint_t long_index; cherokee_downloader_t *downloader; cherokee_buffer_t proxy = CHEROKEE_BUF_INIT; cuint_t proxy_port; struct option long_options[] = { /* Options without arguments */ {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {"quiet", no_argument, NULL, 'q'}, {"save-headers", no_argument, NULL, 's'}, {"header", required_argument, NULL, 0 }, {NULL, 0, NULL, 0} }; /* Parse known parameters */ while ((val = getopt_long (argc, argv, "VshqO:", long_options, &long_index)) != -1) { switch (val) { case 'V': printf ("Cherokee Downloader %s\n" "Written by Alvaro Lopez Ortega <*****@*****.**>\n\n" "Copyright (C) 2001-2014 Alvaro Lopez Ortega.\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", PACKAGE_VERSION); return EXIT_OK; case 'O': if (global_fd != UNSET_FD) { close (global_fd); } if ((strlen(optarg) == 1) && (optarg[0] == '-')) { global_fd = fileno(stdout); } else { global_fd = open (optarg, O_WRONLY | O_CREAT, 0644); } if (global_fd < 0) { PRINT_MSG ("ERROR: Can not open %s\n", optarg); return EXIT_ERROR; } break; case 0: break; case 'q': quiet = true; break; case 's': save_headers = true; break; case 'h': case '?': default: print_help(); return EXIT_OK; } } /* The rest.. */ param_num = argc - optind; if (param_num <= 0) { print_usage(); return EXIT_OK; } /* Tracing and proxy discovering.. */ cherokee_init(); cget_find_proxy (&proxy, &proxy_port); for (val=optind; val<optind+param_num; val++) { cherokee_buffer_t url = CHEROKEE_BUF_INIT; /* Build the url buffer */ ret = cherokee_buffer_add_va (&url, "%s", argv[val]); if (ret != ret_ok) exit (EXIT_ERROR); /* Create the downloader object.. */ ret = cherokee_downloader_new (&downloader); if (ret != ret_ok) exit (EXIT_ERROR); ret = cherokee_downloader_init(downloader); if (ret != ret_ok) exit (EXIT_ERROR); if (! cherokee_buffer_is_empty (&proxy)) { ret = cherokee_downloader_set_proxy (downloader, &proxy, proxy_port); if (ret != ret_ok) exit (EXIT_ERROR); } ret = cherokee_downloader_set_url (downloader, &url); if (ret != ret_ok) exit (EXIT_ERROR); ret = cherokee_downloader_connect (downloader); if (ret != ret_ok) exit (EXIT_ERROR); /* Download it! */ ret = do_download (downloader); if ((ret != ret_ok) && (ret != ret_eof)) { exit (EXIT_ERROR); } /* Free the objects.. */ cherokee_buffer_mrproper (&url); cherokee_downloader_free (downloader); } /* Close the output file */ re = close (output_fd); if (re != 0) exit (EXIT_ERROR); cherokee_mrproper(); return EXIT_OK; }
ret_t cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock) { ret_t ret; cherokee_resolv_cache_t *resolv; /* Short path: it's already connecting */ if (sock->socket >= 0) { return cherokee_socket_connect (sock); } /* Create the new socket and set the target IP info */ if (! cherokee_buffer_is_empty (&src->unix_socket)) { /* Create the socket descriptor */ ret = cherokee_socket_create_fd (sock, AF_UNIX); if (unlikely (ret != ret_ok)) { return ret; } ret = cherokee_socket_gethostbyname (sock, &src->unix_socket); if (unlikely (ret != ret_ok)) { return ret; } } else { cherokee_boolean_t tested_all; const struct addrinfo *addr; const struct addrinfo *addr_info = NULL; /* Query the resolv cache */ ret = cherokee_resolv_cache_get_default (&resolv); if (unlikely (ret!=ret_ok)) { return ret; } ret = cherokee_resolv_cache_get_addrinfo (resolv, &src->host, &addr_info); if ((ret != ret_ok) || (addr_info == NULL)) { return ret_error; } /* Current address */ if (src->addr_current) { tested_all = false; addr = src->addr_current; } else { tested_all = true; addr = addr_info; } /* Create the fd for the address family * * Iterates through the different addresses of the * host and stores a pointer to the first one with * a supported family. */ while (addr != NULL) { ret = cherokee_socket_create_fd (sock, addr->ai_family); #ifdef TRACE_ENABLED if (cherokee_trace_is_tracing()) { ret_t ret2; char ip[46]; ret2 = cherokee_ntop (addr->ai_family, addr->ai_addr, ip, sizeof(ip)); if (ret2 == ret_ok) { TRACE (ENTRIES, "Connecting to %s, ret=%d\n", ip, ret); } } #endif if (ret == ret_ok) { src->addr_current = addr; break; } addr = addr->ai_next; if (addr == NULL) { if (tested_all) { return ret_error; } tested_all = true; src->addr_current = NULL; addr = addr_info; continue; } cherokee_socket_close(sock); } /* Update the new socket with the address info */ switch (src->addr_current->ai_family) { case AF_INET: SOCKET_ADDR_IPv4(sock)->sin_port = htons(src->port); break; case AF_INET6: SOCKET_ADDR_IPv6(sock)->sin6_port = htons(src->port); break; default: SHOULDNT_HAPPEN; return ret_error; } ret = cherokee_socket_update_from_addrinfo (sock, src->addr_current, 0); if (unlikely (ret != ret_ok)) { return ret_error; } } /* Set non-blocking */ ret = cherokee_fd_set_nonblocking (sock->socket, true); if (unlikely (ret != ret_ok)) { LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_SOURCE_NONBLOCK, sock->socket); } /* Set close-on-exec and reuse-address */ cherokee_fd_set_closexec (sock->socket); cherokee_fd_set_reuseaddr (sock->socket); return cherokee_socket_connect (sock); }