Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Expiration headers returned by Front-Line Cache can now be overwritten.

git-svn-id: svn://cherokee-project.com/cherokee/trunk@6620 5dc97367-97f1-0310-9951-d761b3857238
  • Loading branch information...
commit d7c81afc2684dec80da16d55f389b7a6f624ce9b 1 parent 8e0652c
@alobbs alobbs authored
View
82 cherokee/connection.c
@@ -616,16 +616,29 @@ build_response_header_authentication (cherokee_connection_t *conn, cherokee_buff
}
+ret_t
+cherokee_connection_read_post (cherokee_connection_t *conn)
+{
+ /* Shortcut
+ */
+ if (conn->handler->read_post == NULL) {
+ return ret_ok;
+ }
+
+ return cherokee_handler_read_post (conn->handler);
+}
+
+
void
cherokee_connection_add_expiration_header (cherokee_connection_t *conn,
cherokee_buffer_t *buffer,
cherokee_boolean_t use_maxage)
{
- time_t exp_time;
- struct tm exp_tm;
- char bufstr[DTM_SIZE_GMTTM_STR + 2];
- size_t szlen = 0;
- cherokee_boolean_t first_prop = true;
+ time_t exp_time;
+ struct tm exp_tm;
+ char bufstr[DTM_SIZE_GMTTM_STR + 2];
+ size_t szlen = 0;
+ cherokee_boolean_t first_prop = true;
/* Expires, and Cache-Control: max-age
*/
@@ -801,22 +814,6 @@ build_response_header (cherokee_connection_t *conn,
}
}
- /* Expiration
- */
- if (conn->expiration != cherokee_expiration_none) {
- /* Front-line Cache (in) */
- if (conn->flcache.mode == flcache_mode_in) {
- cherokee_buffer_clean (tmp1);
- cherokee_connection_add_expiration_header (conn, tmp1, false);
- cherokee_buffer_add_buffer (buffer, tmp1);
- cherokee_buffer_add_buffer (&conn->flcache.header, tmp1);
- }
- /* Straight */
- else {
- cherokee_connection_add_expiration_header (conn, buffer, true);
- }
- }
-
/* Redirected connections
*/
if (conn->redirect.len >= 1) {
@@ -840,25 +837,36 @@ build_response_header (cherokee_connection_t *conn,
cherokee_encoder_add_headers (conn->encoder, buffer);
}
}
-
- /* Headers ops
- */
- if (conn->header_ops) {
- cherokee_header_op_render (conn->header_ops, buffer);
- }
}
-ret_t
-cherokee_connection_read_post (cherokee_connection_t *conn)
+static void
+build_response_header_final (cherokee_connection_t *conn,
+ cherokee_buffer_t *buffer)
{
- /* Shortcut
+ cherokee_buffer_t *tmp1 = THREAD_TMP_BUF1(CONN_THREAD(conn));
+
+ /* Expiration
*/
- if (conn->handler->read_post == NULL) {
- return ret_ok;
+ if (conn->expiration != cherokee_expiration_none) {
+ /* Add expiration headers if Front-Line Cache is not
+ * enabled. If it were, the header was already stored
+ * in the response file.
+ */
+ if (conn->flcache.mode == flcache_mode_undef) {
+ cherokee_connection_add_expiration_header (conn, buffer, true);
+ } else if (conn->flcache.mode == flcache_mode_in) {
+ cherokee_header_del_entry (buffer, "Cache-Control", 13);
+ cherokee_connection_add_expiration_header (conn, buffer, true);
+ }
}
- return cherokee_handler_read_post (conn->handler);
+ /* Headers ops:
+ * This must be the last operation
+ */
+ if (conn->header_ops) {
+ cherokee_header_op_render (conn->header_ops, &conn->buffer);
+ }
}
@@ -944,7 +952,7 @@ cherokee_connection_build_header (cherokee_connection_t *conn)
}
out:
- /* Add the server headers
+ /* Add the server headers (phase 1)
*/
build_response_header (conn, &conn->buffer);
@@ -952,11 +960,9 @@ cherokee_connection_build_header (cherokee_connection_t *conn)
*/
cherokee_buffer_add_buffer (&conn->buffer, &conn->header_buffer);
- /* Headers ops
+ /* Add the server headers (phase 2)
*/
- if (conn->header_ops) {
- cherokee_header_op_render (conn->header_ops, &conn->buffer);
- }
+ build_response_header_final (conn, &conn->buffer);
/* EOH
*/
View
58 cherokee/flcache.c
@@ -340,7 +340,7 @@ cherokee_flcache_conn_init (cherokee_flcache_conn_t *flcache_conn)
flcache_conn->header_sent = 0;
flcache_conn->response_sent = 0;
flcache_conn->avl_node_ref = NULL;
- flcache_conn->mode = flcache_mdoe_undef;
+ flcache_conn->mode = flcache_mode_undef;
flcache_conn->fd = -1;
cherokee_buffer_init (&flcache_conn->header);
@@ -407,14 +407,17 @@ inspect_header (cherokee_flcache_conn_t *flcache_conn,
const char *header_end;
char chr_end;
char *p, *q;
- cherokee_avl_flcache_node_t *node = flcache_conn->avl_node_ref;
- cherokee_boolean_t via_found = false;
- cherokee_buffer_t *tmp = THREAD_TMP_BUF2(CONN_THREAD(conn));
- cherokee_boolean_t do_cache = false;
+ cherokee_boolean_t overwrite_control;
+ cherokee_avl_flcache_node_t *node = flcache_conn->avl_node_ref;
+ cherokee_boolean_t via_found = false;
+ cherokee_buffer_t *tmp = THREAD_TMP_BUF2(CONN_THREAD(conn));
+ cherokee_boolean_t do_cache = false;
begin = header->buf;
header_end = header->buf + header->len;
+ overwrite_control = (conn->expiration != cherokee_expiration_none);
+
while ((begin < header_end)) {
end = cherokee_header_get_next_line (begin);
if (end == NULL) {
@@ -427,10 +430,16 @@ inspect_header (cherokee_flcache_conn_t *flcache_conn,
/* Expire
*/
if (strncasecmp (begin, "Expires:", 8) == 0) {
+ /* Cache control overridden */
+ if (overwrite_control) {
+ goto remove_line;
+ }
+
+ /* Regular Cache control */
value = begin + 8;
while ((*value == ' ') && (value < end)) value++;
- node->valid_until = 0;
+ node->valid_until = 0;
cherokee_dtm_str2time (value, end - value, &node->valid_until);
if (node->valid_until > cherokee_bogonow_now + 1) {
@@ -441,20 +450,19 @@ inspect_header (cherokee_flcache_conn_t *flcache_conn,
/* Content-length
*/
else if (strncasecmp (begin, "Content-Length:", 15) == 0) {
- *end = chr_end;
-
- while ((*end == CHR_CR) || (*end == CHR_LF))
- end++;
-
- cherokee_buffer_remove_chunk (header, begin - header->buf, end - begin);
-
- end = begin;
- continue;
+ goto remove_line;
}
/* Cache-Control
*/
else if (strncasecmp (begin, "Cache-Control:", 14) == 0) {
+
+ /* Cache control overridden */
+ if (overwrite_control) {
+ goto remove_line;
+ }
+
+ /* Regular Cache control */
value = begin + 8;
while ((*value == ' ') && (value < end)) value++;
@@ -560,6 +568,18 @@ inspect_header (cherokee_flcache_conn_t *flcache_conn,
while ((*end == CHR_CR) || (*end == CHR_LF))
end++;
begin = end;
+ continue;
+
+ remove_line:
+ *end = chr_end;
+
+ while ((*end == CHR_CR) || (*end == CHR_LF))
+ end++;
+
+ cherokee_buffer_remove_chunk (header, begin - header->buf, end - begin);
+
+ end = begin;
+ continue;
}
/* Check the caching policy
@@ -578,6 +598,12 @@ inspect_header (cherokee_flcache_conn_t *flcache_conn,
cherokee_buffer_add_str (header, " (Cherokee/"PACKAGE_VERSION")" CRLF);
}
+ /* Overwritten Cache-Control / Expiration
+ */
+ if (overwrite_control) {
+ cherokee_connection_add_expiration_header (conn, header, false);
+ }
+
return ret_ok;
}
@@ -858,7 +884,7 @@ cherokee_flcache_conn_clean (cherokee_flcache_conn_t *flcache_conn)
*/
flcache_conn->header_sent = 0;
flcache_conn->response_sent = 0;
- flcache_conn->mode = flcache_mdoe_undef;
+ flcache_conn->mode = flcache_mode_undef;
if (flcache_conn->fd != -1) {
cherokee_fd_close (flcache_conn->fd);
View
2  cherokee/flcache.h
@@ -46,7 +46,7 @@ typedef struct cherokee_flcache_conn cherokee_flcache_conn_t;
*/
typedef enum {
- flcache_mdoe_undef,
+ flcache_mode_undef,
flcache_mode_in,
flcache_mode_out,
flcache_mode_error
View
4 cherokee/handler_file.c
@@ -484,7 +484,7 @@ cherokee_handler_file_custom_init (cherokee_handler_file_t *fhdl,
(conn->encoder_new_func == NULL) &&
(HDL_FILE_PROP(fhdl)->use_cache) &&
(conn->socket.is_tls == non_TLS) &&
- (conn->flcache.mode == flcache_mdoe_undef) &&
+ (conn->flcache.mode == flcache_mode_undef) &&
(http_method_with_body (conn->header.method)) &&
(fhdl->info->st_size <= srv->iocache->max_file_size) &&
(fhdl->info->st_size >= srv->iocache->min_file_size));
@@ -624,7 +624,7 @@ cherokee_handler_file_custom_init (cherokee_handler_file_t *fhdl,
(conn->encoder == NULL) &&
(conn->encoder_new_func == NULL) &&
(conn->socket.is_tls == non_TLS) &&
- (conn->flcache.mode == flcache_mdoe_undef) &&
+ (conn->flcache.mode == flcache_mode_undef) &&
(fhdl->info->st_size >= srv->sendfile.min) &&
(fhdl->info->st_size < srv->sendfile.max));
View
36 cherokee/util.c
@@ -2033,6 +2033,42 @@ cherokee_header_get_next_line (char *string)
return end1;
}
+ret_t
+cherokee_header_del_entry (cherokee_buffer_t *header,
+ const char *header_name,
+ int header_name_len)
+{
+ char *end;
+ char *begin;
+ const char *header_end;
+
+ begin = header->buf;
+ header_end = header->buf + header->len;
+
+ while ((begin < header_end)) {
+ end = cherokee_header_get_next_line (begin);
+ if (end == NULL) {
+ break;
+ }
+
+ /* Is it the header? */
+ if (strncasecmp (begin, header_name, header_name_len) == 0) {
+ while ((*end == CHR_CR) || (*end == CHR_LF))
+ end++;
+
+ cherokee_buffer_remove_chunk (header, begin - header->buf, end - begin);
+ return ret_ok;
+ }
+
+ /* Next line */
+ while ((*end == CHR_CR) || (*end == CHR_LF))
+ end++;
+ begin = end;
+ }
+
+ return ret_not_found;
+}
+
#ifndef HAVE_STRNSTR
char *
View
6 cherokee/util.h
@@ -227,7 +227,11 @@ ret_t cherokee_split_arguments (cherokee_buffer_t *request,
ret_t cherokee_parse_query_string (cherokee_buffer_t *qstring,
cherokee_avl_t *arguments);
-char *cherokee_header_get_next_line (char *line);
+char *cherokee_header_get_next_line (char *line);
+ret_t cherokee_header_del_entry (cherokee_buffer_t *header,
+ const char *header_name,
+ int header_name_len);
+
CHEROKEE_END_DECLS
View
56 qa/285-Flcache-overwrite.py
@@ -0,0 +1,56 @@
+from base import *
+
+DIR = "flcache-replace1"
+FILE = "file.txt"
+CONTENT = "Front-line cache boosts Cherokee performance"
+
+CONF = """
+vserver!1!rule!2850!match = directory
+vserver!1!rule!2850!match!directory = /%(DIR)s
+vserver!1!rule!2850!flcache = allow
+vserver!1!rule!2850!flcache!policy = all_but_forbidden
+vserver!1!rule!2850!expiration = time
+vserver!1!rule!2850!expiration!caching = public
+vserver!1!rule!2850!expiration!time = 300
+vserver!1!rule!2850!handler = cgi
+""" %(globals())
+
+CGI_CODE = """#!/bin/sh
+
+echo "Content-Type: text/plain"
+echo "Cache-Control: no-store, no-cache"
+echo
+
+echo "%(CONTENT)s"
+""" %(globals())
+
+
+class TestEntry (TestBase):
+ def __init__ (self):
+ TestBase.__init__ (self, __file__)
+ self.request = "GET /%s/%s HTTP/1.0\r\n" %(DIR, FILE) +\
+ "Connection: close\r\n"
+ self.expected_error = 200
+
+
+class Test (TestCollection):
+ def __init__ (self):
+ TestCollection.__init__ (self, __file__)
+
+ self.name = "Front-line: Overwrite Cache-Control"
+ self.conf = CONF
+ self.proxy_suitable = True
+
+ def Prepare (self, www):
+ d = self.Mkdir (www, DIR)
+ self.WriteFile (d, FILE, 0755, CGI_CODE)
+
+ # First request
+ obj = self.Add (TestEntry())
+ obj.expected_content = ['X-Cache: MISS', CONTENT, "public"]
+ obj.forbidden_content = ['no-store', 'no-cache']
+
+ # Second request
+ obj = self.Add (TestEntry())
+ obj.expected_content = ['X-Cache: HIT', CONTENT, "public"]
+ obj.forbidden_content = ['no-store', 'no-cache']
View
3  qa/Makefile.am
@@ -305,7 +305,8 @@ run-tests.py \
281-Flcache-expired1.py \
282-Flcache-expired2.py \
283-Flcache-expired3.py \
-284-SSI-include-recursive.py
+284-SSI-include-recursive.py \
+285-Flcache-overwrite.py
test:
python -m compileall .
Please sign in to comment.
Something went wrong with that request. Please try again.