commit 05c23a54ea7a2fdfb35d08cdaedea01ab3d5b427 from: Omar Polo date: Tue Jan 19 10:58:29 2021 UTC add "lang" server option commit - 17b09e3cb7158d3b817b42b3f1498b43dcc41e9f commit + 05c23a54ea7a2fdfb35d08cdaedea01ab3d5b427 blob - 30ca1cf180c1c16f136ba1e47a2a68f7739a214e blob + 76dbe3d3223be14a39a0548f58b60449c9682224 --- ChangeLog +++ ChangeLog @@ -1,5 +1,7 @@ 2021-01-19 Omar Polo + * parse.y (servopt): add "lang" server option + * Dockerfile: add a dockerfile 2021-01-18 Omar Polo 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 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)) {