aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2021-08-31 22:57:23 +0100
committerJuan J. Martinez <jjm@usebox.net>2021-08-31 23:04:09 +0100
commita6bd4cba833bd576c20ca05badc3aa26ce7f0f91 (patch)
treefe66763fbc353a8ab435b5dfdb4fedad12a42ce2
parentc09ffd688c1edd43c545aaf442a1cb582d5ad20d (diff)
downloadspacebeans-a6bd4cba833bd576c20ca05badc3aa26ce7f0f91.tar.gz
spacebeans-a6bd4cba833bd576c20ca05badc3aa26ce7f0f91.zip
Support to pass env variables to CGIs
Env variables are configured per virtual host.
-rw-r--r--CHANGES.md12
-rw-r--r--server/src/net/usebox/gemini/server/Response.scala5
-rw-r--r--server/src/net/usebox/gemini/server/Server.scala3
-rw-r--r--server/src/net/usebox/gemini/server/ServiceConf.scala3
-rw-r--r--server/test/src/ServerSpec.scala65
-rw-r--r--spacebeans.conf.example3
6 files changed, 87 insertions, 4 deletions
diff --git a/CHANGES.md b/CHANGES.md
index 9ebcb9e..0d0c53e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,17 @@
# What's new?
+## Release 1.3.0 - 2021-??-??
+
+ - Support to provide extra environment variables to CGIs:
+
+```
+// in virtual host
+environment = { "VARIABLE": "VALUE" }
+```
+ When executing a CGI, SapaceBeans provides a clean environment (other than
+ the CGI variables). Any required environment variable must be specified
+ using this configuration token.
+
## Release 1.2.0 - 2021-07-20
- Classic CGI support:
diff --git a/server/src/net/usebox/gemini/server/Response.scala b/server/src/net/usebox/gemini/server/Response.scala
index a6993c4..edb6cdc 100644
--- a/server/src/net/usebox/gemini/server/Response.scala
+++ b/server/src/net/usebox/gemini/server/Response.scala
@@ -91,7 +91,8 @@ case class Cgi(
scriptName: String,
host: String,
port: String,
- remoteAddr: String
+ remoteAddr: String,
+ vhEnv: Map[String, String]
) extends Response {
private[this] val logger = getLogger
@@ -100,7 +101,7 @@ case class Cgi(
val responseRe = "([0-9]{2}) (.*)".r
- val env = Map(
+ val env = vhEnv ++ Map(
"GATEWAY_INTERFACE" -> "CGI/1.1",
"SERVER_SOFTWARE" -> s"${BuildInfo.name}/${BuildInfo.version}",
"SERVER_PROTOCOL" -> "GEMINI",
diff --git a/server/src/net/usebox/gemini/server/Server.scala b/server/src/net/usebox/gemini/server/Server.scala
index 3c78721..f402191 100644
--- a/server/src/net/usebox/gemini/server/Server.scala
+++ b/server/src/net/usebox/gemini/server/Server.scala
@@ -137,7 +137,8 @@ case class Server(conf: ServiceConf) {
scriptName = cgiFile.getFileName().toString(),
host = vhost.host,
port = conf.port.toString(),
- remoteAddr = remoteAddr
+ remoteAddr = remoteAddr,
+ vhEnv = vhost.environment.getOrElse(Map())
)
case path if !path.exists() =>
logger.debug("no resource")
diff --git a/server/src/net/usebox/gemini/server/ServiceConf.scala b/server/src/net/usebox/gemini/server/ServiceConf.scala
index dc28650..43786af 100644
--- a/server/src/net/usebox/gemini/server/ServiceConf.scala
+++ b/server/src/net/usebox/gemini/server/ServiceConf.scala
@@ -26,7 +26,8 @@ case class VirtualHost(
geminiParams: Option[String] = None,
directories: List[Directory] = Nil,
userDirectories: Boolean = false,
- userDirectoryPath: Option[String] = None
+ userDirectoryPath: Option[String] = None,
+ environment: Option[Map[String, String]] = None
)
object VirtualHost {
diff --git a/server/test/src/ServerSpec.scala b/server/test/src/ServerSpec.scala
index 7a2b501..bd909ca 100644
--- a/server/test/src/ServerSpec.scala
+++ b/server/test/src/ServerSpec.scala
@@ -455,6 +455,7 @@ class ServerSpec extends AnyFlatSpec with Matchers {
"cgi",
TestData.host,
TestData.portStr,
+ _,
_
) =>
}
@@ -473,6 +474,7 @@ class ServerSpec extends AnyFlatSpec with Matchers {
"cgi",
TestData.host,
TestData.portStr,
+ _,
_
) =>
}
@@ -491,6 +493,7 @@ class ServerSpec extends AnyFlatSpec with Matchers {
"cgi",
TestData.host,
TestData.portStr,
+ _,
_
) =>
}
@@ -509,6 +512,7 @@ class ServerSpec extends AnyFlatSpec with Matchers {
"cgi",
TestData.host,
TestData.portStr,
+ _,
_
) =>
}
@@ -566,6 +570,57 @@ class ServerSpec extends AnyFlatSpec with Matchers {
bad.body should include(meta)
}
+ it should "enviroment variables are optional" in {
+ Server(TestData.cgiConf).handleReq(
+ "gemini://localhost/dir/cgi/",
+ "127.0.0.1"
+ ) should matchPattern {
+ case Cgi(
+ _,
+ _,
+ _,
+ _,
+ "cgi",
+ TestData.host,
+ TestData.portStr,
+ _,
+ m
+ ) if m == Map() =>
+ }
+ }
+
+ it should "pass enviroment variables to the CGI" in {
+ Server(TestData.cgiEnvConf).handleReq(
+ "gemini://localhost/dir/cgi/",
+ "127.0.0.1"
+ ) should matchPattern {
+ case Cgi(
+ _,
+ _,
+ _,
+ _,
+ "cgi",
+ TestData.host,
+ TestData.portStr,
+ _,
+ m
+ ) if m == Map("env1" -> "value") =>
+ }
+ }
+
+ it should "execute a CGI with the environment variables" in {
+ val cgi = Server(TestData.cgiEnvConf)
+ .handleReq(
+ "gemini://localhost/dir/cgi",
+ "127.0.0.1"
+ )
+ .asInstanceOf[Cgi]
+
+ cgi.status should be(20)
+ cgi.meta should be("text/gemini")
+ cgi.body should include("env1=value")
+ }
+
object TestData {
val host = "localhost"
@@ -607,6 +662,16 @@ class ServerSpec extends AnyFlatSpec with Matchers {
)
)
+ val cgiEnvConf = cgiConf.copy(virtualHosts =
+ List(
+ cgiConf
+ .virtualHosts(0)
+ .copy(
+ environment = Some(Map("env1" -> "value"))
+ )
+ )
+ )
+
val confUserDir = conf.copy(virtualHosts =
List(
conf
diff --git a/spacebeans.conf.example b/spacebeans.conf.example
index 9e92d45..8e24325 100644
--- a/spacebeans.conf.example
+++ b/spacebeans.conf.example
@@ -29,6 +29,9 @@ virtual-hosts = [
// optional parameters for text/gemini
// gemini-params = "charset=utf-8; lang=en"
+ // optional environment variables to pass to CGIs
+ // environment = { "VAR1": "VALUE1", "VAR2": "VALUE2" }
+
// override defaults, set properties per directory
// important: directory's path is relative to the root
//