Browse Source

moved last-modifed handling to response.c and let mod_cml_lua.c use it.

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x@655 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.3
Jan Kneschke 16 years ago
parent
commit
9dd464a72b
  1. 22
      src/mod_cml_lua.c
  2. 84
      src/mod_staticfile.c
  3. 91
      src/response.c
  4. 2
      src/response.h

22
src/mod_cml_lua.c

@ -322,18 +322,32 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
lua_settop(L, curelem - 1);
if (ret == 0) {
data_string *ds;
char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
buffer tbuf;
con->file_finished = 1;
ds = (data_string *)array_get_element(con->response.headers, "Last-Modified");
/* no Last-Modified specified */
if (mtime && NULL == array_get_element(con->response.headers, "Last-Modified")) {
char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
if ((mtime) && (NULL == ds)) {
strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime));
response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), timebuf, sizeof(timebuf) - 1);
tbuf.ptr = timebuf;
tbuf.used = sizeof(timebuf);
tbuf.size = sizeof(timebuf);
} else if (ds) {
tbuf.ptr = ds->value->ptr;
tbuf.used = ds->value->used;
tbuf.size = ds->value->size;
}
if (http_response_handle_cachable(srv, con, mtime)) {
if (http_response_handle_cachable(srv, con, &tbuf)) {
/* ok, the client already has our content,
* no need to send it again */
chunkqueue_reset(con->write_queue);

84
src/mod_staticfile.c

@ -445,87 +445,9 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
} else {
mtime = ds->value;
}
/*
* 14.26 If-None-Match
* [...]
* If none of the entity tags match, then the server MAY perform the
* requested method as if the If-None-Match header field did not exist,
* but MUST also ignore any If-Modified-Since header field(s) in the
* request. That is, if no entity tags match, then the server MUST NOT
* return a 304 (Not Modified) response.
*/
/* last-modified handling */
if (con->request.http_if_none_match) {
if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) {
if (con->request.http_method == HTTP_METHOD_GET ||
con->request.http_method == HTTP_METHOD_HEAD) {
/* check if etag + last-modified */
if (con->request.http_if_modified_since) {
size_t used_len;
char *semicolon;
if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
used_len = strlen(con->request.http_if_modified_since);
} else {
used_len = semicolon - con->request.http_if_modified_since;
}
if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
con->http_status = 304;
return HANDLER_FINISHED;
} else {
char buf[64];
/* convert to timestamp */
if (used_len < sizeof(buf) - 1) {
time_t t;
struct tm tm;
strncpy(buf, con->request.http_if_modified_since, used_len);
buf[used_len] = '\0';
strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
if (-1 != (t = mktime(&tm)) &&
t <= sce->st.st_mtime) {
con->http_status = 304;
return HANDLER_FINISHED;
}
} else {
log_error_write(srv, __FILE__, __LINE__, "ss",
con->request.http_if_modified_since, buf);
con->http_status = 412;
return HANDLER_FINISHED;
}
}
} else {
con->http_status = 304;
return HANDLER_FINISHED;
}
} else {
con->http_status = 412;
return HANDLER_FINISHED;
}
}
} else if (con->request.http_if_modified_since) {
size_t used_len;
char *semicolon;
if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
used_len = strlen(con->request.http_if_modified_since);
} else {
used_len = semicolon - con->request.http_if_modified_since;
}
if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
con->http_status = 304;
return HANDLER_FINISHED;
}
if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
return HANDLER_FINISHED;
} else if (con->request.http_range) {
/* content prepared, I'm done */
con->file_finished = 1;

91
src/response.c

@ -550,3 +550,94 @@ handler_t http_response_prepare(server *srv, connection *con) {
/* can't happen */
return HANDLER_COMEBACK;
}
int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) {
/*
* 14.26 If-None-Match
* [...]
* If none of the entity tags match, then the server MAY perform the
* requested method as if the If-None-Match header field did not exist,
* but MUST also ignore any If-Modified-Since header field(s) in the
* request. That is, if no entity tags match, then the server MUST NOT
* return a 304 (Not Modified) response.
*/
/* last-modified handling */
if (con->request.http_if_none_match) {
if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) {
if (con->request.http_method == HTTP_METHOD_GET ||
con->request.http_method == HTTP_METHOD_HEAD) {
/* check if etag + last-modified */
if (con->request.http_if_modified_since) {
size_t used_len;
char *semicolon;
if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
used_len = strlen(con->request.http_if_modified_since);
} else {
used_len = semicolon - con->request.http_if_modified_since;
}
if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
con->http_status = 304;
return HANDLER_FINISHED;
} else {
char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
/* convert to timestamp */
if (used_len < sizeof(buf) - 1) {
time_t t_header, t_file;
struct tm tm;
strncpy(buf, con->request.http_if_modified_since, used_len);
buf[used_len] = '\0';
strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
t_header = mktime(&tm);
strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
t_file = mktime(&tm);
if (t_file > t_header) {
con->http_status = 304;
return HANDLER_FINISHED;
}
} else {
log_error_write(srv, __FILE__, __LINE__, "ss",
con->request.http_if_modified_since, buf);
con->http_status = 412;
return HANDLER_FINISHED;
}
}
} else {
con->http_status = 304;
return HANDLER_FINISHED;
}
} else {
con->http_status = 412;
return HANDLER_FINISHED;
}
}
} else if (con->request.http_if_modified_since) {
size_t used_len;
char *semicolon;
if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
used_len = strlen(con->request.http_if_modified_since);
} else {
used_len = semicolon - con->request.http_if_modified_since;
}
if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
con->http_status = 304;
return HANDLER_FINISHED;
}
}
return HANDLER_GO_ON;
}

2
src/response.h

@ -13,7 +13,7 @@ int response_header_overwrite(server *srv, connection *con, const char *key, siz
handler_t http_response_prepare(server *srv, connection *con);
int http_response_redirect_to_directory(server *srv, connection *con);
int http_response_handle_cachable(server *srv, connection *con, time_t mtime);
int http_response_handle_cachable(server *srv, connection *con, buffer * mtime);
buffer * strftime_cache_get(server *srv, time_t last_mod);
#endif

Loading…
Cancel
Save