From dfd878753475a8c8100be15d740eaacc78ed76f9 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Sun, 28 Feb 2021 15:16:46 +0000 Subject: User directories support --- server/src/net/usebox/gemini/server/Server.scala | 6 +++-- .../src/net/usebox/gemini/server/ServiceConf.scala | 30 +++++++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'server/src') diff --git a/server/src/net/usebox/gemini/server/Server.scala b/server/src/net/usebox/gemini/server/Server.scala index 2e9bb6b..d6bcb8a 100644 --- a/server/src/net/usebox/gemini/server/Server.scala +++ b/server/src/net/usebox/gemini/server/Server.scala @@ -100,10 +100,12 @@ case class Server(conf: ServiceConf) { case ("gemini", _, _, _) if uri.normalize() != uri => logger.debug("redirect to normalize uri") PermanentRedirect(req, uri.normalize().toString()) - case ("gemini", host, path, Some(vhost)) => + case ("gemini", host, rawPath, Some(vhost)) => + val (root, path) = vhost.getRoot(rawPath) + val resource = FileSystems .getDefault() - .getPath(vhost.root, path) + .getPath(root, path) .normalize() logger.debug(s"requesting: '$resource'") diff --git a/server/src/net/usebox/gemini/server/ServiceConf.scala b/server/src/net/usebox/gemini/server/ServiceConf.scala index e90d6a8..74ed548 100644 --- a/server/src/net/usebox/gemini/server/ServiceConf.scala +++ b/server/src/net/usebox/gemini/server/ServiceConf.scala @@ -20,10 +20,16 @@ case class VirtualHost( indexFile: String = "index.gmi", directoryListing: Boolean = true, geminiParams: Option[String] = None, - directories: List[Directory] = Nil + directories: List[Directory] = Nil, + userDirectories: Boolean = false, + userDirectoryPath: Option[String] = None ) object VirtualHost { + + val userTag = "{user}" + val userRe = raw"/~([a-z_][a-z0-9_-]*)(/{1}.*)?".r + implicit class VirtualHostOps(vhost: VirtualHost) { def getDirectoryListing(path: Path): Boolean = vhost.directories @@ -31,6 +37,18 @@ object VirtualHost { .fold(vhost.directoryListing)(loc => loc.directoryListing.getOrElse(vhost.directoryListing) ) + + def getRoot(path: String): (String, String) = + path match { + case userRe(user, null) + if vhost.userDirectories && vhost.userDirectoryPath.nonEmpty => + // username with no end slash, force redirect + (vhost.userDirectoryPath.get.replace(userTag, user), ".") + case userRe(user, userPath) + if vhost.userDirectories && vhost.userDirectoryPath.nonEmpty => + (vhost.userDirectoryPath.get.replace(userTag, user), userPath) + case _ => (vhost.root, path) + } } } @@ -55,9 +73,19 @@ object ServiceConf { implicit val virtualHostReader = deriveReader[VirtualHost] implicit val serviceConfReader = deriveReader[ServiceConf] + import VirtualHost.userTag + def load(confFile: String) = ConfigSource.file(confFile).load[ServiceConf].map { conf => conf.copy(virtualHosts = conf.virtualHosts.map { vhost => + if ( + vhost.userDirectories && !vhost.userDirectoryPath + .fold(false)(dir => dir.contains(userTag)) + ) + logger.warn( + s"In virtual host '${vhost.host}': user-directories is enabled but $userTag not found in user-directory-path" + ) + vhost.copy(directories = vhost.directories.map { dir => val path = FileSystems -- cgit v1.2.3