diff --git a/include/lighttpd/condition.h b/include/lighttpd/condition.h index cc1b5ac..da08ef1 100644 --- a/include/lighttpd/condition.h +++ b/include/lighttpd/condition.h @@ -45,7 +45,7 @@ typedef enum { LI_COMP_REQUEST_METHOD, LI_COMP_REQUEST_CONTENT_LENGTH, LI_COMP_PHYSICAL_PATH, - LI_COMP_PHYSICAL_PATH_EXISTS, + LI_COMP_PHYSICAL_EXISTS, LI_COMP_PHYSICAL_SIZE, LI_COMP_PHYSICAL_ISDIR, LI_COMP_PHYSICAL_ISFILE, diff --git a/include/lighttpd/request.h b/include/lighttpd/request.h index c6a398d..7c37d4f 100644 --- a/include/lighttpd/request.h +++ b/include/lighttpd/request.h @@ -19,17 +19,8 @@ struct liRequestUri { struct liPhysical { GString *path; - GString *basedir; - GString *doc_root; - GString *rel_path; - GString *pathinfo; - - gboolean have_stat; - gboolean have_errno; - guint stat_errno; - struct stat stat; /* contains valid data only if have_stat is true */ }; struct liRequest { diff --git a/include/lighttpd/virtualrequest.h b/include/lighttpd/virtualrequest.h index 0bd350e..e72fa51 100644 --- a/include/lighttpd/virtualrequest.h +++ b/include/lighttpd/virtualrequest.h @@ -140,8 +140,6 @@ LI_API void li_vrequest_state_machine(liVRequest *vr); LI_API void li_vrequest_joblist_append(liVRequest *vr); LI_API void li_vrequest_joblist_append_async(liVRequest *vr); -LI_API gboolean li_vrequest_stat(liVRequest *vr); - LI_API gboolean li_vrequest_redirect(liVRequest *vr, GString *uri); #endif diff --git a/src/main/condition.c b/src/main/condition.c index bf1a415..b1f5cdf 100644 --- a/src/main/condition.c +++ b/src/main/condition.c @@ -254,7 +254,7 @@ const char* li_cond_lvalue_to_string(liCondLValue t) { case LI_COMP_REQUEST_METHOD: return "request.method"; case LI_COMP_REQUEST_CONTENT_LENGTH: return "request.length"; case LI_COMP_PHYSICAL_PATH: return "physical.path"; - case LI_COMP_PHYSICAL_PATH_EXISTS: return "physical.exist"; + case LI_COMP_PHYSICAL_EXISTS: return "physical.exist"; case LI_COMP_PHYSICAL_SIZE: return "physical.size"; case LI_COMP_PHYSICAL_ISDIR: return "physical.is_dir"; case LI_COMP_PHYSICAL_ISFILE: return "physical.is_file"; @@ -297,7 +297,7 @@ liCondLValue li_cond_lvalue_from_string(const gchar *str, guint len) { if (strncmp(c, "path", len) == 0) return LI_COMP_PHYSICAL_PATH; else if (strncmp(c, "exists", len) == 0) - return LI_COMP_PHYSICAL_PATH_EXISTS; + return LI_COMP_PHYSICAL_EXISTS; else if (strncmp(c, "size", len) == 0) return LI_COMP_PHYSICAL_SIZE; else if (strncmp(c, "is_file", len) == 0) @@ -310,40 +310,47 @@ liCondLValue li_cond_lvalue_from_string(const gchar *str, guint len) { } static liHandlerResult li_condition_check_eval_bool(liVRequest *vr, liCondition *cond, gboolean *res) { - *res = FALSE; + liHandlerResult r; + struct stat st; + int err; + + *res = !cond->rvalue.b; /* "FALSE" is "not (expected result)" */ - if (cond->lvalue->type == LI_COMP_PHYSICAL_ISDIR || - cond->lvalue->type == LI_COMP_PHYSICAL_ISFILE) { - if (!vr->physical.have_stat) { - if (vr->physical.have_errno || !li_vrequest_stat(vr)) { - switch (vr->physical.stat_errno) { - case EACCES: vr->response.http_status = 403; break; - case EBADF: vr->response.http_status = 500; break; - case EFAULT: vr->response.http_status = 500; break; - case ELOOP: vr->response.http_status = 500; break; - case ENAMETOOLONG: vr->response.http_status = 500; break; - case ENOENT: vr->response.http_status = 404; break; - case ENOMEM: vr->response.http_status = 500; break; - case ENOTDIR: vr->response.http_status = 404; break; - default: vr->response.http_status = 500; - } - li_vrequest_handle_direct(vr); - return LI_HANDLER_GO_ON; - } + switch (cond->lvalue->type) { + case LI_COMP_PHYSICAL_ISDIR: + case LI_COMP_PHYSICAL_ISFILE: + case LI_COMP_PHYSICAL_EXISTS: + if (vr->physical.path->len == 0) { + /* no file, return FALSE */ + return LI_HANDLER_GO_ON; } + + r = li_stat_cache_get(vr, vr->physical.path, &st, &err, NULL); + if (r == LI_HANDLER_WAIT_FOR_EVENT) return r; + + /* not found, return FALSE */ + if (r != LI_HANDLER_GO_ON) return LI_HANDLER_GO_ON; + break; + default: + memset(&st, 0, sizeof(st)); + break; } switch (cond->lvalue->type) { case LI_COMP_PHYSICAL_ISDIR: - *res = S_ISDIR(vr->physical.stat.st_mode); + *res = S_ISDIR(st.st_mode); break; case LI_COMP_PHYSICAL_ISFILE: - *res = S_ISREG(vr->physical.stat.st_mode); + *res = S_ISREG(st.st_mode); + break; + case LI_COMP_PHYSICAL_EXISTS: + *res = TRUE; break; default: VR_ERROR(vr, "invalid lvalue \"%s\" for boolean comparison", li_cond_lvalue_to_string(cond->lvalue->type)); return LI_HANDLER_ERROR; } + if (!cond->rvalue.b) *res = !*res; return LI_HANDLER_GO_ON; } @@ -380,9 +387,6 @@ static liHandlerResult li_condition_check_eval_string(liVRequest *vr, liConditio case LI_COMP_PHYSICAL_PATH: val = vr->physical.path->str; break; - case LI_COMP_PHYSICAL_PATH_EXISTS: - /* TODO: physical path exists */ - break; case LI_COMP_REQUEST_HEADER: li_http_header_get_all(con->wrk->tmp_str, vr->request.headers, GSTR_LEN(cond->lvalue->key)); val = con->wrk->tmp_str->str; @@ -392,6 +396,7 @@ static liHandlerResult li_condition_check_eval_string(liVRequest *vr, liConditio val = con->wrk->tmp_str->str; break; default: + VR_ERROR(vr, "couldn't get string value for '%s'", li_cond_lvalue_to_string(cond->lvalue->type)); return LI_HANDLER_ERROR; } @@ -439,6 +444,9 @@ static liHandlerResult li_condition_check_eval_string(liVRequest *vr, liConditio static liHandlerResult li_condition_check_eval_int(liVRequest *vr, liCondition *cond, gboolean *res) { + liHandlerResult r; + struct stat st; + int err; gint64 val; *res = FALSE; @@ -447,24 +455,19 @@ static liHandlerResult li_condition_check_eval_int(liVRequest *vr, liCondition * val = vr->request.content_length; break; case LI_COMP_PHYSICAL_SIZE: - if (!vr->physical.have_stat) { - if (vr->physical.have_errno || !li_vrequest_stat(vr)) { - switch (vr->physical.stat_errno) { - case EACCES: vr->response.http_status = 403; break; - case EBADF: vr->response.http_status = 500; break; - case EFAULT: vr->response.http_status = 500; break; - case ELOOP: vr->response.http_status = 500; break; - case ENAMETOOLONG: vr->response.http_status = 500; break; - case ENOENT: vr->response.http_status = 404; break; - case ENOMEM: vr->response.http_status = 500; break; - case ENOTDIR: vr->response.http_status = 404; break; - default: vr->response.http_status = 500; - } - li_vrequest_handle_direct(vr); - return LI_HANDLER_GO_ON; - } + if (vr->physical.path->len == 0) { + val = -1; + break; + } + + r = li_stat_cache_get(vr, vr->physical.path, &st, &err, NULL); + if (r == LI_HANDLER_WAIT_FOR_EVENT) return r; + + if (r != LI_HANDLER_GO_ON) { + val = -1; /* not found -> size "-1" */ + } else { + val = (gint64)st.st_size; } - val = (gint64)vr->physical.stat.st_size; break; default: VR_ERROR(vr, "couldn't get int value for '%s'", li_cond_lvalue_to_string(cond->lvalue->type)); @@ -555,9 +558,8 @@ static liHandlerResult li_condition_check_eval_ip(liVRequest *vr, liCondition *c case LI_COMP_REQUEST_METHOD: VR_ERROR(vr, "%s", "Cannot parse request.method as ip"); return LI_HANDLER_ERROR; - break; case LI_COMP_PHYSICAL_PATH: - case LI_COMP_PHYSICAL_PATH_EXISTS: + case LI_COMP_PHYSICAL_EXISTS: VR_ERROR(vr, "%s", "Cannot parse physical.path(-exists) as ip"); return LI_HANDLER_ERROR; break; @@ -586,8 +588,10 @@ static liHandlerResult li_condition_check_eval_ip(liVRequest *vr, liCondition *c switch (cond->op) { case LI_CONFIG_COND_IP: *res = ip_in_net(&ipval, &cond->rvalue); + break; case LI_CONFIG_COND_NOTIP: *res = !ip_in_net(&ipval, &cond->rvalue); + break; case LI_CONFIG_COND_PREFIX: case LI_CONFIG_COND_NOPREFIX: case LI_CONFIG_COND_SUFFIX: diff --git a/src/main/config_parser.rl b/src/main/config_parser.rl index 85c5d6d..372b8ae 100644 --- a/src/main/config_parser.rl +++ b/src/main/config_parser.rl @@ -877,7 +877,7 @@ if (g_str_equal(str, "path")) lvalue = li_condition_lvalue_new(LI_COMP_PHYSICAL_PATH, NULL); else if (g_str_equal(str, "exists")) - lvalue = li_condition_lvalue_new(LI_COMP_PHYSICAL_PATH_EXISTS, NULL); + lvalue = li_condition_lvalue_new(LI_COMP_PHYSICAL_EXISTS, NULL); else if (g_str_equal(str, "size")) lvalue = li_condition_lvalue_new(LI_COMP_PHYSICAL_SIZE, NULL); else if (g_str_equal(str, "is_dir")) diff --git a/src/main/request.c b/src/main/request.c index 93b024d..b0b581d 100644 --- a/src/main/request.c +++ b/src/main/request.c @@ -257,30 +257,18 @@ gboolean li_request_validate_header(liConnection *con) { void li_physical_init(liPhysical *phys) { phys->path = g_string_sized_new(127); - phys->basedir = g_string_sized_new(63); phys->doc_root = g_string_sized_new(63); - phys->rel_path = g_string_sized_new(63); phys->pathinfo = g_string_sized_new(63); - phys->have_stat = FALSE; - phys->have_errno = FALSE; } void li_physical_reset(liPhysical *phys) { g_string_truncate(phys->path, 0); - g_string_truncate(phys->basedir, 0); g_string_truncate(phys->doc_root, 0); - g_string_truncate(phys->rel_path, 0); g_string_truncate(phys->pathinfo, 0); - phys->have_stat = FALSE; - phys->have_errno = FALSE; } void li_physical_clear(liPhysical *phys) { g_string_free(phys->path, TRUE); - g_string_free(phys->basedir, TRUE); g_string_free(phys->doc_root, TRUE); - g_string_free(phys->rel_path, TRUE); g_string_free(phys->pathinfo, TRUE); - phys->have_stat = FALSE; - phys->have_errno = FALSE; } diff --git a/src/main/virtualrequest.c b/src/main/virtualrequest.c index 43cbb9e..7222847 100644 --- a/src/main/virtualrequest.c +++ b/src/main/virtualrequest.c @@ -484,29 +484,6 @@ void li_vrequest_joblist_append_async(liVRequest *vr) { ev_async_send(wrk->loop, &wrk->job_async_queue_watcher); } -gboolean li_vrequest_stat(liVRequest *vr) { - /* Do not stat again */ - if (vr->physical.have_stat || vr->physical.have_errno) return vr->physical.have_stat; - - if (-1 == stat(vr->physical.path->str, &vr->physical.stat)) { - vr->physical.have_stat = FALSE; - vr->physical.have_errno = TRUE; - vr->physical.stat_errno = errno; - switch (errno) { - case EACCES: - case ENOENT: - case ENOTDIR: - break; - default: - VR_DEBUG(vr, "stat(%s) failed: %s (%d)", vr->physical.path->str, g_strerror(vr->physical.stat_errno), vr->physical.stat_errno); - } - return FALSE; - } - - vr->physical.have_stat = TRUE; - return TRUE; -} - gboolean li_vrequest_redirect(liVRequest *vr, GString *uri) { if (!li_vrequest_handle_direct(vr)) return FALSE; diff --git a/src/modules/mod_vhost.c b/src/modules/mod_vhost.c index 80d31ab..947c706 100644 --- a/src/modules/mod_vhost.c +++ b/src/modules/mod_vhost.c @@ -143,7 +143,6 @@ static liHandlerResult vhost_simple(liVRequest *vr, gpointer param, gpointer *co } /* check if directory exists. if not, fall back to default host */ - vr->physical.have_stat = FALSE; vr->physical.have_errno = FALSE; switch (li_stat_cache_get(vr, vr->physical.path, &st, &err, NULL)) { case LI_HANDLER_GO_ON: break;