summaryrefslogtreecommitdiff
path: root/server/src/net/usebox/gemini
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2021-02-28 15:16:46 +0000
committerJuan J. Martinez <jjm@usebox.net>2021-07-22 19:49:51 +0100
commitdfd878753475a8c8100be15d740eaacc78ed76f9 (patch)
treecd1dbeb75ba8f5f522465961cdac3ca27832581c /server/src/net/usebox/gemini
parent5777f650c69609fecd3e7696432bad256c778856 (diff)
downloadspacebeans-dfd878753475a8c8100be15d740eaacc78ed76f9.tar.gz
spacebeans-dfd878753475a8c8100be15d740eaacc78ed76f9.zip
User directories support
Diffstat (limited to 'server/src/net/usebox/gemini')
-rw-r--r--server/src/net/usebox/gemini/server/Server.scala6
-rw-r--r--server/src/net/usebox/gemini/server/ServiceConf.scala30
2 files changed, 33 insertions, 3 deletions
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