make docroot a function action instead of setting, add stat member to vr.physical and enable physical.size conditional
This commit is contained in:
parent
2489fbfbfe
commit
01068d7f1d
|
@ -17,8 +17,6 @@ enum core_options_t {
|
|||
|
||||
CORE_OPTION_MIME_TYPES,
|
||||
|
||||
CORE_OPTION_DOCROOT,
|
||||
|
||||
CORE_OPTION_THROTTLE
|
||||
};
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ struct physical {
|
|||
|
||||
GString *pathinfo;
|
||||
|
||||
gint64 size;
|
||||
gboolean have_stat;
|
||||
struct stat stat; /* contains valid data only if have_stat is true */
|
||||
};
|
||||
|
||||
struct request {
|
||||
|
|
|
@ -121,4 +121,6 @@ LI_API gboolean vrequest_handle_indirect(vrequest *vr, plugin *p);
|
|||
LI_API void vrequest_state_machine(vrequest *vr);
|
||||
LI_API void vrequest_joblist_append(vrequest *vr);
|
||||
|
||||
LI_API gboolean vrequest_stat(vrequest *vr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -348,8 +348,24 @@ static handler_t condition_check_eval_int(vrequest *vr, condition *cond, gboolea
|
|||
case COMP_REQUEST_CONTENT_LENGTH:
|
||||
val = vr->request.content_length;
|
||||
case COMP_PHYSICAL_SIZE:
|
||||
/* TODO: stat file */
|
||||
val = vr->physical.size;
|
||||
if (!vr->physical.have_stat) {
|
||||
if (!vrequest_stat(vr)) {
|
||||
switch (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;
|
||||
}
|
||||
vrequest_handle_direct(vr);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
}
|
||||
val = (gint64)vr->physical.stat.st_size;
|
||||
break;
|
||||
default:
|
||||
VR_ERROR(vr, "couldn't get int value for '%s'", cond_lvalue_to_string(cond->lvalue->type));
|
||||
|
|
|
@ -139,18 +139,44 @@ static gboolean core_setup_set(server *srv, plugin* p, value *val) {
|
|||
return plugin_set_default_option(srv, val_name->data.string->str, val_val);
|
||||
}
|
||||
|
||||
static handler_t core_handle_docroot(vrequest *vr, gpointer param, gpointer *context) {
|
||||
UNUSED(context);
|
||||
|
||||
g_string_truncate(vr->physical.doc_root, 0);
|
||||
g_string_append_len(vr->physical.doc_root, GSTR_LEN((GString*) param));
|
||||
/* reset stat info because path has changed */
|
||||
vr->physical.have_stat = FALSE;
|
||||
|
||||
/* build physical path: docroot + uri.path */
|
||||
g_string_truncate(vr->physical.path, 0);
|
||||
g_string_append_len(vr->physical.path, GSTR_LEN((GString*) param));
|
||||
g_string_append_len(vr->physical.path, GSTR_LEN(vr->request.uri.path));
|
||||
|
||||
VR_DEBUG(vr, "physical path: %s", vr->physical.path->str);
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
static void core_docroot_free(server *srv, gpointer param) {
|
||||
UNUSED(srv);
|
||||
g_string_free(param, TRUE);
|
||||
}
|
||||
|
||||
static action* core_docroot(server *srv, plugin* p, value *val) {
|
||||
UNUSED(p);
|
||||
if (!val || val->type != VALUE_STRING) {
|
||||
ERROR(srv, "%s", "docroot action expects a string parameter");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return action_new_function(core_handle_docroot, NULL, core_docroot_free, value_extract(val).string);
|
||||
}
|
||||
|
||||
static handler_t core_handle_static(vrequest *vr, gpointer param, gpointer *context) {
|
||||
int fd;
|
||||
UNUSED(param);
|
||||
UNUSED(context);
|
||||
|
||||
/* build physical path: docroot + uri.path */
|
||||
g_string_truncate(vr->physical.path, 0);
|
||||
g_string_append_len(vr->physical.path, GSTR_LEN(CORE_OPTION(CORE_OPTION_DOCROOT).string));
|
||||
g_string_append_len(vr->physical.path, GSTR_LEN(vr->request.uri.path));
|
||||
|
||||
VR_DEBUG(vr, "physical path: %s", vr->physical.path->str);
|
||||
|
||||
if (vr->physical.path->len == 0) return HANDLER_GO_ON;
|
||||
|
||||
if (!vrequest_handle_direct(vr)) return HANDLER_GO_ON;
|
||||
|
@ -750,8 +776,6 @@ static const plugin_option options[] = {
|
|||
|
||||
{ "mime_types", VALUE_LIST, NULL, core_option_mime_types_parse, core_option_mime_types_free },
|
||||
|
||||
{ "docroot", VALUE_STRING, NULL, NULL, NULL },
|
||||
|
||||
{ "throttle", VALUE_NUMBER, GINT_TO_POINTER(0), NULL, NULL },
|
||||
|
||||
{ NULL, 0, NULL, NULL, NULL }
|
||||
|
@ -762,6 +786,7 @@ static const plugin_action actions[] = {
|
|||
{ "when", core_when },
|
||||
{ "set", core_set },
|
||||
|
||||
{ "docroot", core_docroot },
|
||||
{ "static", core_static },
|
||||
|
||||
{ "test", core_test },
|
||||
|
|
|
@ -242,7 +242,7 @@ void physical_init(physical *phys) {
|
|||
phys->doc_root = g_string_sized_new(256);
|
||||
phys->rel_path = g_string_sized_new(256);
|
||||
phys->pathinfo = g_string_sized_new(256);
|
||||
phys->size = -1;
|
||||
phys->have_stat = FALSE;
|
||||
}
|
||||
|
||||
void physical_reset(physical *phys) {
|
||||
|
@ -251,7 +251,7 @@ void physical_reset(physical *phys) {
|
|||
g_string_truncate(phys->doc_root, 0);
|
||||
g_string_truncate(phys->rel_path, 0);
|
||||
g_string_truncate(phys->pathinfo, 0);
|
||||
phys->size = -1;
|
||||
phys->have_stat = FALSE;
|
||||
}
|
||||
|
||||
void physical_clear(physical *phys) {
|
||||
|
@ -260,5 +260,5 @@ void physical_clear(physical *phys) {
|
|||
g_string_free(phys->doc_root, TRUE);
|
||||
g_string_free(phys->rel_path, TRUE);
|
||||
g_string_free(phys->pathinfo, TRUE);
|
||||
phys->size = -1;
|
||||
phys->have_stat = FALSE;
|
||||
}
|
||||
|
|
|
@ -350,3 +350,13 @@ void vrequest_joblist_append(vrequest *vr) {
|
|||
vr->job_queue_link = g_queue_peek_tail_link(q);
|
||||
ev_timer_start(wrk->loop, &wrk->job_queue_watcher);
|
||||
}
|
||||
|
||||
gboolean vrequest_stat(vrequest *vr) {
|
||||
if (-1 == stat(vr->physical.path->str, &vr->physical.stat)) {
|
||||
VR_DEBUG(vr, "stat(%s) failed: %s (%d)", vr->physical.path->str, g_strerror(errno), errno);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
vr->physical.have_stat = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue