Commit Diff


commit - 17b09e3cb7158d3b817b42b3f1498b43dcc41e9f
commit + 05c23a54ea7a2fdfb35d08cdaedea01ab3d5b427
blob - 30ca1cf180c1c16f136ba1e47a2a68f7739a214e
blob + 76dbe3d3223be14a39a0548f58b60449c9682224
--- ChangeLog
+++ ChangeLog
@@ -1,5 +1,7 @@
 2021-01-19  Omar Polo  <op@omarpolo.com>
 
+	* parse.y (servopt): add "lang" server option
+
 	* Dockerfile: add a dockerfile
 
 2021-01-18  Omar Polo  <op@omarpolo.com>
blob - 6905b408d315cd8122623cd6ba8a6faee6f748f6
blob + 7f70c2b55cbb3a80f2ab364659a119508e8572d7
--- gmid.1
+++ gmid.1
@@ -168,6 +168,11 @@ Enable the execution of CGI scripts if
 is a prefix of the user request string.
 An empty path "" will effectively enable the execution of any file
 with the executable bit set inside the root directory.
+.It Ic lang Ar string
+Specify the language tag for the text/gemini content served.
+If not specified, no
+.Dq lang
+parameter will be added in the response.
 .El
 .Sh CGI
 When CGI scripts are enabled for a directory, a request for an
blob - 5d4b5f83d291ca27bf763feffaa69b2fdf0b524c
blob + 892399c18a88cc5f36b94c778b71a63ca9a6fa7d
--- gmid.h
+++ gmid.h
@@ -59,6 +59,7 @@ struct vhost {
 	const char	*key;
 	const char	*dir;
 	const char	*cgi;
+	char		*lang;
 	int		 dirfd;
 };
 
blob - cb6326a081556d03a109761b2a3902d32276a592
blob + 154fa6932bf4775cedc6379b545c2cd4bcae89d3
--- lex.l
+++ lex.l
@@ -58,6 +58,7 @@ protocols	return TPROTOCOLS;
 mime		return TMIME;
 default		return TDEFAULT;
 type		return TTYPE;
+lang		return TLANG;
 server		return TSERVER;
 
 cert		return TCERT;
blob - 286969ac678457a1abdd4c6abff0e4cb382a1ff6
blob + 36c3eac30f4c8165e2dde500514ba5b56878c2ae
--- parse.y
+++ parse.y
@@ -43,7 +43,7 @@ extern void yyerror(const char*);
 }
 
 %token TDAEMON TIPV6 TPORT TPROTOCOLS TMIME TDEFAULT TTYPE TSERVER
-%token TCERT TKEY TROOT TCGI
+%token TCERT TKEY TROOT TCGI TLANG
 %token TERR
 
 %token <str>	TSTRING
@@ -98,6 +98,10 @@ servopt		: TCERT TSTRING		{ host->cert = $2; }
 			/* drop the starting '/', if any */
 			if (*host->cgi == '/')
 				host->cgi++;
-}
+		}
+		| TLANG TSTRING {
+			free(host->lang);
+			host->lang = $2;
+		}
 		;
 
blob - 08d6541f8b98c058eacd154f3d1140fbeeaee7ee
blob + d9bf46fbb00a0a25bea51cbaf4e8403f1302fd9c
--- sample.conf
+++ sample.conf
@@ -14,11 +14,14 @@ server "example.com" {
 	root "/var/gemini/example.com"
 }
 
-# another example server, this time with CGI enabled for scripts in
-# /cgi-bin/
 server "it.example.com" {
 	cert "/path/to/cert.pem"
 	key  "/path/to/key.pem"
 	root "/var/gemini/example.com"
+
+        # enable CGI scripts in /cgi-bin/
 	cgi  "/cgi-bin/"
+
+        # optional
+        lang "it"
 }
blob - 0ce28d7f3af78cf7a3d2b2c4589653de6e6e0975
blob + 49d71f05d9ab582462c0eea5929c35c9691f0f48
--- server.c
+++ server.c
@@ -249,14 +249,21 @@ handle_open_conn(struct pollfd *fds, struct client *c)
 int
 start_reply(struct pollfd *pfd, struct client *client, int code, const char *reason)
 {
-	char buf[1030]; 	/* status + ' ' + max reply len + \r\n\0 */
+	char buf[1030];		/* status + ' ' + max reply len + \r\n\0 */
 	int len;
 
 	client->code = code;
 	client->meta = reason;
 	client->state = S_INITIALIZING;
 
-	len = snprintf(buf, sizeof(buf), "%d %s\r\n", code, reason);
+	snprintf(buf, sizeof(buf), "%d ", code);
+	strlcat(buf, reason, sizeof(buf));
+	if (!strcmp(reason, "text/gemini") && client->host->lang != NULL) {
+		strlcat(buf, "; lang=", sizeof(buf));
+		strlcat(buf, client->host->lang, sizeof(buf));
+	}
+
+	len = strlcat(buf, "\r\n", sizeof(buf));
 	assert(len < (int)sizeof(buf));
 
 	switch (tls_write(client->ctx, buf, len)) {