summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9>2005-03-14 12:21:25 +0000
committerjan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9>2005-03-14 12:21:25 +0000
commitdadd10e0ca2f8a23781096e23d525d1d906346eb (patch)
treeb3d0ac05a34d478b77ed47a36e4753bdf04006bb
parent6efe00a439770608fee5e839fa0659059cc1d26d (diff)
downloadlighttpd-dadd10e0ca2f8a23781096e23d525d1d906346eb.tar.gz
added the new file_cache and file_descr handling
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/post-upload-cleanup@130 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--src/response.c346
1 files changed, 180 insertions, 166 deletions
diff --git a/src/response.c b/src/response.c
index dcc77124..27d5d42a 100644
--- a/src/response.c
+++ b/src/response.c
@@ -17,7 +17,7 @@
#include "response.h"
#include "keyvalue.h"
#include "log.h"
-#include "file_cache.h"
+#include "file_cache_funcs.h"
#include "etag.h"
#include "connections.h"
@@ -254,7 +254,6 @@ int http_response_write_header(server *srv, connection *con,
}
static int http_response_parse_range(server *srv, connection *con) {
- struct stat st;
int multipart = 0;
int error;
off_t start, end;
@@ -262,14 +261,15 @@ static int http_response_parse_range(server *srv, connection *con) {
char *boundary = "fkj49sn38dcn3";
const char *content_type = NULL;
data_string *ds;
+ file_cache_entry *fce = NULL;
+
- if (-1 == stat(con->physical.path->ptr, &st)) {
- log_error_write(srv, __FILE__, __LINE__, "ss", "stat failed: ", strerror(errno));
- return -1;
+ if (NULL == (fce = file_cache_get_entry(srv, con->physical.path))) {
+ file_cache_add_entry(srv, con, con->physical.path, &fce);
}
start = 0;
- end = st.st_size - 1;
+ end = fce->st.st_size - 1;
con->response.content_length = 0;
@@ -296,14 +296,14 @@ static int http_response_parse_range(server *srv, connection *con) {
/* end */
s = err;
- end = st.st_size - 1;
- start = st.st_size + le;
+ end = fce->st.st_size - 1;
+ start = fce->st.st_size + le;
} else if (*err == ',') {
multipart = 1;
s = err + 1;
- end = st.st_size - 1;
- start = st.st_size + le;
+ end = fce->st.st_size - 1;
+ start = fce->st.st_size + le;
} else {
error = 1;
}
@@ -319,14 +319,14 @@ static int http_response_parse_range(server *srv, connection *con) {
if (*(err + 1) == '\0') {
s = err + 1;
- end = st.st_size - 1;
+ end = fce->st.st_size - 1;
start = la;
} else if (*(err + 1) == ',') {
multipart = 1;
s = err + 2;
- end = st.st_size - 1;
+ end = fce->st.st_size - 1;
start = la;
} else {
error = 1;
@@ -376,9 +376,9 @@ static int http_response_parse_range(server *srv, connection *con) {
if (start < 0) start = 0;
/* RFC 2616 - 14.35.1 */
- if (end > st.st_size - 1) end = st.st_size - 1;
+ if (end > fce->st.st_size - 1) end = fce->st.st_size - 1;
- if (start > st.st_size - 1) {
+ if (start > fce->st.st_size - 1) {
error = 1;
con->http_status = 416;
@@ -401,7 +401,7 @@ static int http_response_parse_range(server *srv, connection *con) {
buffer_append_string(b, "-");
buffer_append_off_t(b, end);
buffer_append_string(b, "/");
- buffer_append_off_t(b, st.st_size);
+ buffer_append_off_t(b, fce->st.st_size);
buffer_append_string(b, "\r\nContent-Type: ");
buffer_append_string(b, content_type);
@@ -413,7 +413,7 @@ static int http_response_parse_range(server *srv, connection *con) {
}
- chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1);
+ chunkqueue_append_file(con->write_queue, fce, start, end - start + 1);
con->response.content_length += end - start + 1;
}
}
@@ -450,7 +450,7 @@ static int http_response_parse_range(server *srv, connection *con) {
buffer_append_string(srv->range_buf, "-");
buffer_append_off_t(srv->range_buf, end);
buffer_append_string(srv->range_buf, "/");
- buffer_append_off_t(srv->range_buf, st.st_size);
+ buffer_append_off_t(srv->range_buf, fce->st.st_size);
response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(srv->range_buf));
}
@@ -1054,151 +1054,23 @@ handler_t http_response_prepare(server *srv, connection *con) {
char *pathinfo = NULL;
int found = 0;
size_t k;
+ file_cache_entry *fce = NULL;
+ handler_t ret;
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s", "-- handling physical path");
log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
}
-
- switch (file_cache_get_entry(srv, con, con->physical.path, &(con->fce))) {
- case HANDLER_WAIT_FOR_FD:
- return HANDLER_WAIT_FOR_FD;
- case HANDLER_ERROR:
- if (errno == EACCES) {
- con->http_status = 403;
- buffer_reset(con->physical.path);
-
- return HANDLER_FINISHED;
- }
-
- if (errno != ENOENT &&
- errno != ENOTDIR) {
- /* we have no idea what happend. let's tell the user so. */
-
- con->http_status = 500;
- buffer_reset(con->physical.path);
-
- log_error_write(srv, __FILE__, __LINE__, "ssbsb",
- "file not found ... or so: ", strerror(errno),
- con->uri.path,
- "->", con->physical.path);
-
- return HANDLER_FINISHED;
- }
+ if (NULL != (fce = file_cache_get_entry(srv, con->physical.path)) ||
+ HANDLER_GO_ON == (ret = file_cache_add_entry(srv, con, con->physical.path, &fce))) {
+ /* file exists */
- /* not found, perhaps PATHINFO */
-
- if (con->physical.rel_path->ptr[0] == '/') {
- buffer_copy_string_len(srv->tmp_buf, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
- } else {
- buffer_copy_string_buffer(srv->tmp_buf, con->physical.rel_path);
- }
-
- /*
- *
- * FIXME:
- *
- * Check for PATHINFO fall to dir of
- *
- * /a is a dir and
- *
- * /a/b/c is requested
- *
- */
-
- do {
- struct stat st;
-
- buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
- BUFFER_APPEND_SLASH(con->physical.path);
- if (slash) {
- buffer_append_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
- } else {
- buffer_append_string_buffer(con->physical.path, srv->tmp_buf);
- }
-
- if (0 == stat(con->physical.path->ptr, &(st)) &&
- S_ISREG(st.st_mode)) {
- found = 1;
- break;
- }
-
- if (pathinfo != NULL) {
- *pathinfo = '\0';
- }
- slash = strrchr(srv->tmp_buf->ptr, '/');
-
- if (pathinfo != NULL) {
- /* restore '/' */
- *pathinfo = '/';
- }
-
- if (slash) pathinfo = slash;
- } while ((found == 0) && (slash != NULL) && (slash != srv->tmp_buf->ptr));
-
- if (found == 0) {
- /* no it really doesn't exists */
- con->http_status = 404;
-
- if (con->conf.log_file_not_found) {
- log_error_write(srv, __FILE__, __LINE__, "sbsb",
- "file not found:", con->uri.path,
- "->", con->physical.path);
- }
-
- buffer_reset(con->physical.path);
-
- return HANDLER_FINISHED;
- }
-
-
- /* we have a PATHINFO */
- if (pathinfo) {
- buffer_copy_string(con->request.pathinfo, pathinfo);
-
- /*
- * shorten uri.path
- */
-
- con->uri.path->used -= strlen(pathinfo);
- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
- }
-
- if (con->conf.log_request_handling) {
- log_error_write(srv, __FILE__, __LINE__, "s", "-- after pathinfo check");
- log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
- log_error_write(srv, __FILE__, __LINE__, "sb", "URI :", con->uri.path);
- log_error_write(srv, __FILE__, __LINE__, "sb", "Pathinfo :", con->request.pathinfo);
- }
-
- /* setup the right file cache entry (FCE) */
- switch (file_cache_get_entry(srv, con, con->physical.path, &(con->fce))) {
- case HANDLER_ERROR:
- con->http_status = 404;
-
- if (con->conf.log_file_not_found) {
- log_error_write(srv, __FILE__, __LINE__, "sbsb",
- "file not found:", con->uri.path,
- "->", con->physical.path);
- }
-
- return HANDLER_FINISHED;
- case HANDLER_WAIT_FOR_FD:
- return HANDLER_WAIT_FOR_FD;
- case HANDLER_GO_ON:
- break;
- default:
- break;
- }
-
- break;
- case HANDLER_GO_ON:
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s", "-- file found");
log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
}
- if (S_ISDIR(con->fce->st.st_mode)) {
+ if (S_ISDIR(fce->st.st_mode)) {
if (con->physical.path->ptr[con->physical.path->used - 2] != '/') {
/* redirect to .../ */
@@ -1208,21 +1080,27 @@ handler_t http_response_prepare(server *srv, connection *con) {
} else {
found = 0;
/* indexfile */
-
+ WP();
for (k = 0; !found && (k < con->conf.indexfiles->used); k++) {
data_string *ds = (data_string *)con->conf.indexfiles->data[k];
buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
buffer_append_string_buffer(srv->tmp_buf, ds->value);
- switch (file_cache_get_entry(srv, con, srv->tmp_buf, &(con->fce))) {
+ log_error_write(srv, __FILE__, __LINE__, "sbsb",
+ "index-file: ", con->uri.path,
+ "->", con->physical.path);
+ WP();
+ switch (file_cache_add_entry(srv, con, srv->tmp_buf, &(fce))) {
case HANDLER_GO_ON:
/* rewrite uri.path to the real path (/ -> /index.php) */
buffer_append_string_buffer(con->uri.path, ds->value);
+ WP();
found = 1;
break;
case HANDLER_ERROR:
+ WP();
if (errno == EACCES) {
con->http_status = 403;
@@ -1255,7 +1133,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
if (!found &&
(k == con->conf.indexfiles->used)) {
/* directory listing ? */
-
+ WP();
buffer_reset(srv->tmp_buf);
if (con->conf.dir_listing == 0) {
@@ -1270,22 +1148,158 @@ handler_t http_response_prepare(server *srv, connection *con) {
return HANDLER_FINISHED;
}
-
buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
+
+
+ log_error_write(srv, __FILE__, __LINE__, "sbsb",
+ "index-file: ", con->uri.path,
+ "->", con->physical.path);
+
}
}
- break;
- default:
- break;
+ } else {
+ switch (ret) {
+ case HANDLER_WAIT_FOR_FD:
+ return HANDLER_WAIT_FOR_FD;
+ case HANDLER_ERROR:
+ if (errno == EACCES) {
+ con->http_status = 403;
+ buffer_reset(con->physical.path);
+
+ return HANDLER_FINISHED;
+ }
+
+ if (errno != ENOENT &&
+ errno != ENOTDIR) {
+ /* we have no idea what happend. let's tell the user so. */
+
+ con->http_status = 500;
+ buffer_reset(con->physical.path);
+
+ log_error_write(srv, __FILE__, __LINE__, "ssbsb",
+ "file not found ... or so: ", strerror(errno),
+ con->uri.path,
+ "->", con->physical.path);
+
+ return HANDLER_FINISHED;
+ }
+
+ /* not found, perhaps PATHINFO */
+
+ if (con->physical.rel_path->ptr[0] == '/') {
+ buffer_copy_string_len(srv->tmp_buf, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
+ } else {
+ buffer_copy_string_buffer(srv->tmp_buf, con->physical.rel_path);
+ }
+
+ /*
+ *
+ * FIXME:
+ *
+ * Check for PATHINFO fall to dir of
+ *
+ * /a is a dir and
+ *
+ * /a/b/c is requested
+ *
+ */
+
+ do {
+ struct stat st;
+
+ buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
+ BUFFER_APPEND_SLASH(con->physical.path);
+ if (slash) {
+ buffer_append_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
+ } else {
+ buffer_append_string_buffer(con->physical.path, srv->tmp_buf);
+ }
+
+ if (0 == stat(con->physical.path->ptr, &(st)) &&
+ S_ISREG(st.st_mode)) {
+ found = 1;
+ break;
+ }
+
+ if (pathinfo != NULL) {
+ *pathinfo = '\0';
+ }
+ slash = strrchr(srv->tmp_buf->ptr, '/');
+
+ if (pathinfo != NULL) {
+ /* restore '/' */
+ *pathinfo = '/';
+ }
+
+ if (slash) pathinfo = slash;
+ } while ((found == 0) && (slash != NULL) && (slash != srv->tmp_buf->ptr));
+
+ if (found == 0) {
+ /* no it really doesn't exists */
+ con->http_status = 404;
+
+ if (con->conf.log_file_not_found) {
+ log_error_write(srv, __FILE__, __LINE__, "sbsb",
+ "file not found:", con->uri.path,
+ "->", con->physical.path);
+ }
+
+ buffer_reset(con->physical.path);
+
+ return HANDLER_FINISHED;
+ }
+
+
+ /* we have a PATHINFO */
+ if (pathinfo) {
+ buffer_copy_string(con->request.pathinfo, pathinfo);
+
+ /*
+ * shorten uri.path
+ */
+
+ con->uri.path->used -= strlen(pathinfo);
+ con->uri.path->ptr[con->uri.path->used - 1] = '\0';
+ }
+
+ if (con->conf.log_request_handling) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "-- after pathinfo check");
+ log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
+ log_error_write(srv, __FILE__, __LINE__, "sb", "URI :", con->uri.path);
+ log_error_write(srv, __FILE__, __LINE__, "sb", "Pathinfo :", con->request.pathinfo);
+ }
+
+ /* setup the right file cache entry (FCE) */
+ switch (file_cache_add_entry(srv, con, con->physical.path, &(fce))) {
+ case HANDLER_ERROR:
+ con->http_status = 404;
+
+ if (con->conf.log_file_not_found) {
+ log_error_write(srv, __FILE__, __LINE__, "sbsb",
+ "file not found:", con->uri.path,
+ "->", con->physical.path);
+ }
+
+ return HANDLER_FINISHED;
+ case HANDLER_WAIT_FOR_FD:
+ return HANDLER_WAIT_FOR_FD;
+ case HANDLER_GO_ON:
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
}
- if (!S_ISREG(con->fce->st.st_mode)) {
+ if (!S_ISREG(fce->st.st_mode)) {
con->http_status = 404;
if (con->conf.log_file_not_found) {
log_error_write(srv, __FILE__, __LINE__, "sbsb",
"not a regular file:", con->uri.path,
- "->", con->fce->name);
+ "->", fce->name);
}
return HANDLER_FINISHED;
@@ -1310,14 +1324,14 @@ handler_t http_response_prepare(server *srv, connection *con) {
/* set response content-type */
- if (buffer_is_empty(con->fce->content_type)) {
+ if (buffer_is_empty(fce->content_type)) {
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/octet-stream"));
} else {
- response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(con->fce->content_type));
+ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(fce->content_type));
}
/* generate e-tag */
- etag_mutate(con->physical.etag, con->fce->etag);
+ etag_mutate(con->physical.etag, fce->etag);
/*
* 14.26 If-None-Match
@@ -1343,7 +1357,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
size_t used_len;
char *semicolon;
- strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(con->fce->st.st_mtime)));
+ strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(fce->st.st_mtime)));
if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
used_len = strlen(con->request.http_if_modified_since);
@@ -1363,7 +1377,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
if (-1 != (t = mktime(&tm)) &&
- t <= con->fce->st.st_mtime) {
+ t <= fce->st.st_mtime) {
con->http_status = 304;
}
} else {
@@ -1386,7 +1400,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
size_t used_len;
char *semicolon;
- tm = gmtime(&(con->fce->st.st_mtime));
+ tm = gmtime(&(fce->st.st_mtime));
strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", tm);
if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {