aboutsummaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2021-04-30 17:16:34 +0000
committerOmar Polo <op@omarpolo.com>2021-04-30 17:16:34 +0000
commitfdea6aa0bca24f6f947e2126ce101fd59caa7a31 (patch)
treec167f225e73250eb8cc82347a23ce7a86cfbf027 /server.c
parentadbe6a6493c0e91fcfc918db8f4b5839a2867b1c (diff)
allow ``root'' rule to be specified per-location block
Diffstat (limited to 'server.c')
-rw-r--r--server.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/server.c b/server.c
index 86c8d08..60d1da8 100644
--- a/server.c
+++ b/server.c
@@ -203,6 +203,25 @@ vhost_block_return(struct vhost *v, const char *path, int *code, const char **fm
}
int
+vhost_dirfd(struct vhost *v, const char *path)
+{
+ struct location *loc;
+
+ if (v == NULL || path == NULL)
+ return -1;
+
+ loc = TAILQ_FIRST(&v->locations);
+ while ((loc = TAILQ_NEXT(loc, locations)) != NULL) {
+ if (loc->dirfd != -1)
+ if (matches(loc->match, path))
+ return loc->dirfd;
+ }
+
+ loc = TAILQ_FIRST(&v->locations);
+ return loc->dirfd;
+}
+
+int
vhost_strip(struct vhost *v, const char *path)
{
struct location *loc;
@@ -265,22 +284,30 @@ check_path(struct client *c, const char *path, int *fd)
{
struct stat sb;
const char *p;
- int flags;
+ int flags, dirfd, strip;
assert(path != NULL);
- if (*path == '\0')
+ /*
+ * in send_dir we add an initial / (to be redirect-friendly),
+ * but here we want to skip it
+ */
+ if (*path == '/')
+ path++;
+
+ strip = vhost_strip(c->host, path);
+ p = strip_path(path, strip);
+
+ if (*p == '/')
+ p = p+1;
+ if (*p == '\0')
p = ".";
- else if (*path == '/')
- /* in send_dir we add an initial / (to be
- * redirect-friendly), but here we want to skip it */
- p = path+1;
- else
- p = path;
+ dirfd = vhost_dirfd(c->host, path);
+ log_debug(c, "check_path: strip=%d path=%s original=%s",
+ strip, p, path);
flags = O_RDONLY | O_NOFOLLOW;
-
- if (*fd == -1 && (*fd = openat(c->host->dirfd, p, flags)) == -1)
+ if (*fd == -1 && (*fd = openat(dirfd, p, flags)) == -1)
return FILE_MISSING;
if (fstat(*fd, &sb) == -1) {