aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-08-08 12:05:43 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-08-08 12:05:43 +0100
commit4a11cb6875e196297d44553c3f640d7bbb25256c (patch)
tree2fbb34d94f9c8e861f006a4cb9a7aa067ec41bc7 /server
parenta42d3883f110831440f2d85977e9251c4a22541a (diff)
downloadspacebeans-4a11cb6875e196297d44553c3f640d7bbb25256c.tar.gz
spacebeans-4a11cb6875e196297d44553c3f640d7bbb25256c.zip
Formattting
Diffstat (limited to 'server')
-rw-r--r--server/src/net/usebox/gemini/server/Response.scala44
-rw-r--r--server/src/net/usebox/gemini/server/Server.scala18
-rw-r--r--server/src/net/usebox/gemini/server/ServiceConf.scala25
-rw-r--r--server/src/net/usebox/gemini/server/TLSUtils.scala41
-rw-r--r--server/src/net/usebox/gemini/server/URIUtils.scala4
-rw-r--r--server/src/net/usebox/gemini/server/handlers/GeminiHandler.scala6
-rw-r--r--server/src/net/usebox/gemini/server/handlers/ProtocolHandler.scala11
-rw-r--r--server/test/src/ServerSpec.scala2
-rw-r--r--server/test/src/URIUtilsSpec.scala4
-rw-r--r--server/test/src/handlers/GeminiHandlerSpec.scala12
-rw-r--r--server/test/src/handlers/ProtocolHandlerSpec.scala8
11 files changed, 82 insertions, 93 deletions
diff --git a/server/src/net/usebox/gemini/server/Response.scala b/server/src/net/usebox/gemini/server/Response.scala
index 82fa95d..9675262 100644
--- a/server/src/net/usebox/gemini/server/Response.scala
+++ b/server/src/net/usebox/gemini/server/Response.scala
@@ -5,13 +5,12 @@ import java.nio.file.Path
import scala.sys.process._
import scala.util.Try
-import org.log4s._
+import net.usebox.gemini.server.URIUtils._
+import akka.stream.scaladsl.{FileIO, Source}
import akka.stream.ActorAttributes
-import akka.stream.scaladsl.{Source, FileIO}
import akka.util.ByteString
-
-import URIUtils._
+import org.log4s._
sealed trait Response {
def req: String
@@ -58,21 +57,21 @@ case class DirListing(
(List(s"# Index of ${uriPath}\n") ++
(if (uriPath != "/") List(s"=> ../ ..") else Nil)
++
- path
- .toFile()
- .listFiles()
- .toList
- .sortBy {
- case f if f.isDirectory() => 0
- case f if f.isFile() => 1
- case _ => 2
- }
- .flatMap {
- case f if !f.canRead() || f.getName().startsWith(".") => None
- case f if f.isDirectory() =>
- Some(s"=> ${f.getName().encode()}/ ${f.getName()}/")
- case f => Some(s"=> ${f.getName().encode()} ${f.getName()}")
- }).mkString("\n") + "\n"
+ path
+ .toFile()
+ .listFiles()
+ .toList
+ .sortBy {
+ case f if f.isDirectory() => 0
+ case f if f.isFile() => 1
+ case _ => 2
+ }
+ .flatMap {
+ case f if !f.canRead() || f.getName().startsWith(".") => None
+ case f if f.isDirectory() =>
+ Some(s"=> ${f.getName().encode()}/ ${f.getName()}/")
+ case f => Some(s"=> ${f.getName().encode()} ${f.getName()}")
+ }).mkString("\n") + "\n"
}
def bodySize: Long = body.size
@@ -122,7 +121,9 @@ case class Cgi(
Try {
val jpb = new java.lang.ProcessBuilder(filename)
jpb.environment.clear()
- env.foreach { case (k, v) => jpb.environment.put(k, v) }
+ env.foreach {
+ case (k, v) => jpb.environment.put(k, v)
+ }
val exit = (Process(jpb) #> output).!
output.close()
@@ -132,8 +133,7 @@ case class Cgi(
case Right(0) =>
val body = output.toString("UTF-8")
body.split("\r\n").headOption match {
- case Some(req @ responseRe(status, meta))
- if req.length <= Server.maxReqLen =>
+ case Some(req @ responseRe(status, meta)) if req.length <= Server.maxReqLen =>
(status.toInt, meta, body)
case _ =>
logger.warn(s"$scriptName: invalid CGI response")
diff --git a/server/src/net/usebox/gemini/server/Server.scala b/server/src/net/usebox/gemini/server/Server.scala
index 96cf5ef..3925f12 100644
--- a/server/src/net/usebox/gemini/server/Server.scala
+++ b/server/src/net/usebox/gemini/server/Server.scala
@@ -1,24 +1,24 @@
package net.usebox.gemini.server
+import java.net.URI
import java.nio.charset.Charset
import javax.net.ssl.SSLEngine
-import java.net.URI
-import scala.util.{Try, Success => TrySuccess}
+import scala.concurrent.ExecutionContextExecutor
+import scala.util.{Success => TrySuccess, Try}
-import org.log4s._
+import net.usebox.gemini.server.handlers.GeminiHandler
+import akka.actor.ActorSystem
import akka.stream._
import akka.stream.scaladsl._
-import akka.actor.ActorSystem
import akka.util.ByteString
-
-import net.usebox.gemini.server.handlers.GeminiHandler
+import org.log4s._
case class Server(conf: ServiceConf) {
- implicit val system = ActorSystem("space-beans")
- implicit val ec = system.dispatcher
+ implicit val system: ActorSystem = ActorSystem("space-beans")
+ implicit val ec: ExecutionContextExecutor = system.dispatcher
private[this] val logger = getLogger
@@ -89,7 +89,7 @@ case class Server(conf: ServiceConf) {
certs.foreach {
case (host, (cert, _)) =>
logger.info(s"Certificate for ${host} - serial-no: ${cert
- .getSerialNumber()}, final-date: ${cert.getNotAfter()}")
+ .getSerialNumber()}, final-date: ${cert.getNotAfter()}")
}
def createSSLEngine: SSLEngine = {
diff --git a/server/src/net/usebox/gemini/server/ServiceConf.scala b/server/src/net/usebox/gemini/server/ServiceConf.scala
index ec082cf..c6b5d9a 100644
--- a/server/src/net/usebox/gemini/server/ServiceConf.scala
+++ b/server/src/net/usebox/gemini/server/ServiceConf.scala
@@ -1,14 +1,13 @@
package net.usebox.gemini.server
-import java.nio.file.{Path, FileSystems}
+import java.nio.file.{FileSystems, Path}
import scala.concurrent.duration.FiniteDuration
+import org.log4s._
import pureconfig._
import pureconfig.generic.semiauto._
-import org.log4s._
-
case class KeyStore(path: String, alias: String, password: String)
case class Directory(
@@ -46,7 +45,8 @@ object VirtualHost {
vhost.directories
.filter(_.allowCgi == Some(true))
.sortWith {
- case (d1, d2) => d1.path.length() > d2.path.length()
+ case (d1, d2) =>
+ d1.path.length() > d2.path.length()
}
.find(d =>
path.startsWith(
@@ -64,12 +64,10 @@ object VirtualHost {
def getRoot(path: String): (String, String) =
path match {
- case userRe(user, null)
- if vhost.userDirectories && vhost.userDirectoryPath.nonEmpty =>
+ 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 =>
+ case userRe(user, userPath) if vhost.userDirectories && vhost.userDirectoryPath.nonEmpty =>
(vhost.userDirectoryPath.get.replace(userTag, user), userPath)
case _ => (vhost.root, path)
}
@@ -92,10 +90,13 @@ object ServiceConf {
private[this] val logger = getLogger
- implicit val keyStoreReader = deriveReader[KeyStore]
- implicit val directoryHostReader = deriveReader[Directory]
- implicit val virtualHostReader = deriveReader[VirtualHost]
- implicit val serviceConfReader = deriveReader[ServiceConf]
+ implicit val keyStoreReader: ConfigReader[KeyStore] = deriveReader[KeyStore]
+ implicit val directoryHostReader: ConfigReader[Directory] =
+ deriveReader[Directory]
+ implicit val virtualHostReader: ConfigReader[VirtualHost] =
+ deriveReader[VirtualHost]
+ implicit val serviceConfReader: ConfigReader[ServiceConf] =
+ deriveReader[ServiceConf]
import VirtualHost.userTag
diff --git a/server/src/net/usebox/gemini/server/TLSUtils.scala b/server/src/net/usebox/gemini/server/TLSUtils.scala
index 03e2216..012da2f 100644
--- a/server/src/net/usebox/gemini/server/TLSUtils.scala
+++ b/server/src/net/usebox/gemini/server/TLSUtils.scala
@@ -1,29 +1,22 @@
package net.usebox.gemini.server
import java.io.FileInputStream
-import java.time.Instant
import java.math.BigInteger
-import java.util.Date
+import java.net.Socket
+import java.security.{KeyPairGenerator, KeyStore, Principal, PrivateKey, SecureRandom, Security}
import java.security.cert.X509Certificate
-import java.security.{
- Security,
- KeyStore,
- SecureRandom,
- PrivateKey,
- KeyPairGenerator,
- Principal
-}
import java.security.KeyStore.PrivateKeyEntry
-import java.net.Socket
+import java.time.Instant
+import java.util.Date
import javax.net.ssl.{
- SSLContext,
- TrustManagerFactory,
+ ExtendedSSLSession,
KeyManagerFactory,
- X509ExtendedKeyManager,
+ SNIHostName,
+ SSLContext,
SSLEngine,
- ExtendedSSLSession,
StandardConstants,
- SNIHostName
+ TrustManagerFactory,
+ X509ExtendedKeyManager
}
import scala.concurrent.duration.FiniteDuration
@@ -31,9 +24,8 @@ import scala.jdk.CollectionConverters._
import scala.util.Try
import org.bouncycastle.jce.provider.BouncyCastleProvider
-import org.bouncycastle.x509.X509V3CertificateGenerator
import org.bouncycastle.jce.X509Principal
-
+import org.bouncycastle.x509.X509V3CertificateGenerator
import org.log4s._
object TLSUtils {
@@ -43,8 +35,7 @@ object TLSUtils {
Security.addProvider(new BouncyCastleProvider())
// https://github.com/grahamedgecombe/netty-sni-example/
- class SniKeyManager(keyManager: X509ExtendedKeyManager, defaultAlias: String)
- extends X509ExtendedKeyManager {
+ class SniKeyManager(keyManager: X509ExtendedKeyManager, defaultAlias: String) extends X509ExtendedKeyManager {
override def getClientAliases(
keyType: String,
issuers: Array[Principal]
@@ -84,8 +75,7 @@ object TLSUtils {
.getRequestedServerNames()
.asScala
.collectFirst {
- case n: SNIHostName
- if n.getType() == StandardConstants.SNI_HOST_NAME =>
+ case n: SNIHostName if n.getType() == StandardConstants.SNI_HOST_NAME =>
n.getAsciiName()
} match {
case Some(hostname)
@@ -136,10 +126,9 @@ object TLSUtils {
(
ks.getCertificate(alias).asInstanceOf[X509Certificate],
ks.getEntry(
- alias,
- new KeyStore.PasswordProtection(password.toCharArray())
- )
- .asInstanceOf[PrivateKeyEntry]
+ alias,
+ new KeyStore.PasswordProtection(password.toCharArray())
+ ).asInstanceOf[PrivateKeyEntry]
.getPrivateKey()
)
}.toEither
diff --git a/server/src/net/usebox/gemini/server/URIUtils.scala b/server/src/net/usebox/gemini/server/URIUtils.scala
index 76e2adf..5100a65 100644
--- a/server/src/net/usebox/gemini/server/URIUtils.scala
+++ b/server/src/net/usebox/gemini/server/URIUtils.scala
@@ -1,8 +1,8 @@
package net.usebox.gemini.server
-import java.nio.charset.StandardCharsets
-import java.net.{URLEncoder, URLDecoder}
+import java.net.{URLDecoder, URLEncoder}
import java.net.URI
+import java.nio.charset.StandardCharsets
import scala.util.Try
diff --git a/server/src/net/usebox/gemini/server/handlers/GeminiHandler.scala b/server/src/net/usebox/gemini/server/handlers/GeminiHandler.scala
index ad5272c..377d213 100644
--- a/server/src/net/usebox/gemini/server/handlers/GeminiHandler.scala
+++ b/server/src/net/usebox/gemini/server/handlers/GeminiHandler.scala
@@ -3,10 +3,10 @@ package net.usebox.gemini.server.handlers
import java.net.URI
import java.nio.file.FileSystems
-import org.log4s._
-
import net.usebox.gemini.server._
-import URIUtils._
+import net.usebox.gemini.server.URIUtils._
+
+import org.log4s._
class GeminiHandler(conf: ServiceConf) extends ProtocolHandler(conf) {
diff --git a/server/src/net/usebox/gemini/server/handlers/ProtocolHandler.scala b/server/src/net/usebox/gemini/server/handlers/ProtocolHandler.scala
index 7c85850..b89d040 100644
--- a/server/src/net/usebox/gemini/server/handlers/ProtocolHandler.scala
+++ b/server/src/net/usebox/gemini/server/handlers/ProtocolHandler.scala
@@ -1,11 +1,11 @@
package net.usebox.gemini.server.handlers
import java.net.URI
-import java.nio.file.{Path, Files}
+import java.nio.file.{Files, Path}
import scala.util.Try
-import net.usebox.gemini.server.{ServiceConf, Response}
+import net.usebox.gemini.server.{Response, ServiceConf}
abstract class ProtocolHandler(conf: ServiceConf) {
@@ -25,9 +25,12 @@ abstract class ProtocolHandler(conf: ServiceConf) {
} { types =>
types
.find {
- case (t, exts) => exts.exists(path.toString().endsWith(_))
+ case (t, exts) =>
+ exts.exists(path.toString().endsWith(_))
+ }
+ .fold(defaultMimeType) {
+ case (t, _) => t
}
- .fold(defaultMimeType) { case (t, _) => t }
} match {
case mime @ "text/gemini" =>
params.fold(mime)(p => s"$mime; ${p.stripMargin(';').trim()}")
diff --git a/server/test/src/ServerSpec.scala b/server/test/src/ServerSpec.scala
index cfb613a..800230a 100644
--- a/server/test/src/ServerSpec.scala
+++ b/server/test/src/ServerSpec.scala
@@ -1,8 +1,8 @@
package net.usebox.gemini.server
+import akka.util.ByteString
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
-import akka.util.ByteString
class ServerSpec extends AnyFlatSpec with Matchers {
diff --git a/server/test/src/URIUtilsSpec.scala b/server/test/src/URIUtilsSpec.scala
index ab00c86..e471e8c 100644
--- a/server/test/src/URIUtilsSpec.scala
+++ b/server/test/src/URIUtilsSpec.scala
@@ -1,10 +1,10 @@
package net.usebox.gemini.server
+import net.usebox.gemini.server.URIUtils._
+
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
-import URIUtils._
-
class URIUtilsSpec extends AnyFlatSpec with Matchers {
behavior of "validPath"
diff --git a/server/test/src/handlers/GeminiHandlerSpec.scala b/server/test/src/handlers/GeminiHandlerSpec.scala
index 158042c..8704db1 100644
--- a/server/test/src/handlers/GeminiHandlerSpec.scala
+++ b/server/test/src/handlers/GeminiHandlerSpec.scala
@@ -2,11 +2,11 @@ package net.usebox.gemini.server.handlers
import java.net.URI
+import net.usebox.gemini.server._
+
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
-import net.usebox.gemini.server._
-
class GeminiHandlerSpec extends AnyFlatSpec with Matchers {
val handler = new GeminiHandler(TestData.conf)
@@ -87,9 +87,7 @@ class GeminiHandlerSpec extends AnyFlatSpec with Matchers {
it should "include gemini params for gemini MIME type" in {
handleWith(
new GeminiHandler(
- TestData.conf.copy(virtualHosts =
- List(TestData.conf.virtualHosts(0).copy(geminiParams = Some("test")))
- )
+ TestData.conf.copy(virtualHosts = List(TestData.conf.virtualHosts(0).copy(geminiParams = Some("test"))))
),
"gemini://localhost/index.gmi"
) should matchPattern {
@@ -188,9 +186,7 @@ class GeminiHandlerSpec extends AnyFlatSpec with Matchers {
it should "return not found if directory listing is not enabled and no index" in {
handleWith(
new GeminiHandler(
- TestData.conf.copy(virtualHosts =
- List(TestData.conf.virtualHosts(0).copy(directoryListing = false))
- )
+ TestData.conf.copy(virtualHosts = List(TestData.conf.virtualHosts(0).copy(directoryListing = false)))
),
"gemini://localhost/dir/"
) should be(a[NotFound])
diff --git a/server/test/src/handlers/ProtocolHandlerSpec.scala b/server/test/src/handlers/ProtocolHandlerSpec.scala
index d35c9f2..31b0700 100644
--- a/server/test/src/handlers/ProtocolHandlerSpec.scala
+++ b/server/test/src/handlers/ProtocolHandlerSpec.scala
@@ -1,14 +1,14 @@
package net.usebox.gemini.server.handlers
-import java.nio.file.FileSystems
import java.net.URI
+import java.nio.file.FileSystems
+
+import net.usebox.gemini.server.{Response, ServiceConf}
+import net.usebox.gemini.server.TestData
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
-import net.usebox.gemini.server.{ServiceConf, Response}
-import net.usebox.gemini.server.TestData
-
class ProtocolHandlerSpec extends AnyFlatSpec with Matchers {
def getPath(value: String) = FileSystems.getDefault().getPath(value)