"GOT", but the "O" is a cute, smiling sun Index | Thread

From:
Omar Polo <op@omarpolo.com>
Subject:
Re: gotwebd: use SCRIPT_NAME to derive URLs
To:
Stefan Sperling <stsp@stsp.name>
Cc:
gameoftrees@openbsd.org
Date:
Tue, 30 Aug 2022 17:42:06 +0200

Download raw body.

On 2022/08/30 17:07:23 +0200, Stefan Sperling <stsp@stsp.name> wrote:
> On Tue, Aug 30, 2022 at 05:04:26PM +0200, Stefan Sperling wrote:
> > On Tue, Aug 30, 2022 at 02:55:41PM +0200, Omar Polo wrote:
> > > gotwebd uses DOCUMENT_ROOT as a base for the URLs, but i think this is
> > > a bit counter-intuitive.
> > > 
> > > DOCUMENT_ROOT is meant to be a *physical* path, while to generate URLs
> > > we need to look at how things are exposed.  In short, I think it
> > > should use SCRIPT_NAME (which httpd.conf(5) documents as "the virtual
> > > URI path to the script") as base for the URLs generation.
> > > 
> > > This allows to remove the extra `root "/"' that we currently need in
> > > the gotwebd location and, as a bonus, allows to have gotwebd served on
> > > a path different from "/" too!
> > 
> > Great, thanks a lot for figuring this out! ok stsp
> 
> Hmm, on a closer look this probably still needs some adjustments.
> I noticed some links in the generated pages are incorrect.
> 
> For example, if I view a repository under a link like this:
> http://localhost/gotwebd-unix/?index_page=&path=diff.git&action=summary
> the links in the "Repos / diff.git / summary" bar at the top lack
> the "gotwebd-unix" part and lead into 404:
> http://localhost/?index_page=0&path=diff.git&action=summary

good catch! yes, they were incorrectly generated.

here's an improved diff, now all the URLs except the CSS and the logo
are all relative (i.e. they're all href="?...")

I've clicked around for a bit and all the pages seem to work.

> Just to confirm, this still works fine in your setup which
> runs in location "/", correct?

I tried it on localhost and it works.  The httpd configuration can
also be shortened a bit:

server "localhost" {
	listen on * port 80
	root "/htdocs/gotwebd"
	location "/" {
		fastcgi socket tcp localhost 9001 # or whatever
	}
}


diff /home/op/w/got
commit - b1328b3e37580e44e7c53530bfc32374b74514fc
path + /home/op/w/got
blob - ae872cfb0d22ad79db91ef2e1032bae6db071f17
file + gotwebd/fcgi.c
--- gotwebd/fcgi.c
+++ gotwebd/fcgi.c
@@ -274,19 +274,13 @@ fcgi_parse_params(uint8_t *buf, uint16_t n, struct req
 			bcopy(buf, c->http_host, val_len);
 			c->http_host[val_len] = '\0';
 		}
-		if (val_len < MAX_DOCUMENT_ROOT && strcmp(env_entry->val,
-		    "DOCUMENT_ROOT") == 0 && c->document_root[0] == '\0') {
-
-			/* drop first char, as it's always / */
-			dr_buf = &buf[1];
-
-			bcopy(dr_buf, c->document_root, val_len - 1);
-			c->document_root[val_len] = '\0';
+		if (val_len < MAX_SCRIPT_NAME && strcmp(env_entry->val,
+		    "SCRIPT_NAME") == 0 && c->script_name[0] == '\0') {
+			bcopy(dr_buf, c->script_name, val_len);
+			c->script_name[val_len] = '\0';
 		}
 		if (val_len < MAX_SERVER_NAME && strcmp(env_entry->val,
 		    "SERVER_NAME") == 0 && c->server_name[0] == '\0') {
-			/* drop first char, as it's always / */
-
 			bcopy(buf, c->server_name, val_len);
 			c->server_name[val_len] = '\0';
 		}
blob - 363270dc22f396c6ba871d5448b712f226c3a791
file + gotwebd/gotweb.c
--- gotwebd/gotweb.c
+++ gotwebd/gotweb.c
@@ -108,7 +108,7 @@ static const struct got_error *gotweb_render_branches(
 static void gotweb_free_querystring(struct querystring *);
 static void gotweb_free_repo_dir(struct repo_dir *);
 
-struct server *gotweb_get_server(uint8_t *, uint8_t *, uint8_t *);
+struct server *gotweb_get_server(uint8_t *, uint8_t *);
 
 void
 gotweb_process_request(struct request *c)
@@ -130,7 +130,7 @@ gotweb_process_request(struct request *c)
 	if (c->sock->client_status == CLIENT_DISCONNECT)
 		return;
 	/* get the gotwebd server */
-	srv = gotweb_get_server(c->server_name, c->document_root, c->http_host);
+	srv = gotweb_get_server(c->server_name, c->http_host);
 	if (srv == NULL) {
 		log_warnx("%s: error server is NULL", __func__);
 		goto err;
@@ -299,24 +299,17 @@ done:
 }
 
 struct server *
-gotweb_get_server(uint8_t *server_name, uint8_t *document_root,
-    uint8_t *subdomain)
+gotweb_get_server(uint8_t *server_name, uint8_t *subdomain)
 {
 	struct server *srv = NULL;
 
-	/* check against document_root first */
+	/* check against the server name first */
 	if (strlen(server_name) > 0)
 		TAILQ_FOREACH(srv, &gotwebd_env->servers, entry)
 			if (strcmp(srv->name, server_name) == 0)
 				goto done;
 
-	/* check against document_root second */
-	if (strlen(document_root) > 0)
-		TAILQ_FOREACH(srv, &gotwebd_env->servers, entry)
-			if (strcmp(srv->name, document_root) == 0)
-				goto done;
-
-	/* check against subdomain third */
+	/* check against subdomain second */
 	if (strlen(subdomain) > 0)
 		TAILQ_FOREACH(srv, &gotwebd_env->servers, entry)
 			if (strcmp(srv->name, subdomain) == 0)
@@ -650,16 +643,8 @@ gotweb_render_header(struct request *c)
 {
 	struct server *srv = c->srv;
 	struct querystring *qs = c->t->qs;
-	char droot[PATH_MAX];
 	int r;
 
-	if (strlen(c->document_root) > 0) {
-		r = snprintf(droot, sizeof(droot), "/%s/", c->document_root);
-		if (r < 0 || (size_t)r >= sizeof(droot))
-			return got_error(GOT_ERR_NO_SPACE);
-	} else
-		strlcpy(droot, "/", sizeof(droot));
-
 	r = fcgi_printf(c, "<!doctype html>\n"
 	    "<html>\n"
 	    "<head>\n"
@@ -689,22 +674,21 @@ gotweb_render_header(struct request *c)
 	    "</div>\n"		/* #header */
 	    "<div id='site_path'>\n"
 	    "<div id='site_link'>\n"
-	    "<a href='/%s?index_page=%d'>%s</a>",
+	    "<a href='?index_page=%d'>%s</a>",
 	    srv->site_name,
-	    droot, srv->custom_css,
+	    c->script_name, srv->custom_css,
 	    srv->logo_url,
-	    droot, srv->logo,
-	    c->document_root, qs->index_page, srv->site_link);
+	    c->script_name, srv->logo,
+	    qs->index_page, srv->site_link);
 	if (r == -1)
 		goto done;
 
 	if (qs != NULL) {
 		if (qs->path != NULL) {
 			r = fcgi_printf(c, " / "
-			    "<a href='/%s?index_page=%d&path=%s&action=summary'>"
+			    "<a href='?index_page=%d&path=%s&action=summary'>"
 			    "%s</a>",
-			    c->document_root, qs->index_page, qs->path,
-			    qs->path);
+			    qs->index_page, qs->path, qs->path);
 			if (r == -1)
 				goto done;
 		}
blob - 0e4e5d563e08acd3a08ee2114c3cb043cb55d2bd
file + gotwebd/gotwebd.h
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -49,7 +49,7 @@
 
 /* GOTWEB DEFAULTS */
 #define MAX_QUERYSTRING		 2048
-#define MAX_DOCUMENT_ROOT	 255
+#define MAX_SCRIPT_NAME		 255
 #define MAX_SERVER_NAME		 255
 
 #define GOTWEB_GOT_DIR		 ".got"
@@ -219,7 +219,7 @@ struct request {
 
 	char				 querystring[MAX_QUERYSTRING];
 	char				 http_host[GOTWEBD_MAXTEXT];
-	char				 document_root[MAX_DOCUMENT_ROOT];
+	char				 script_name[MAX_SCRIPT_NAME];
 	char				 server_name[MAX_SERVER_NAME];
 
 	struct env_head			 env;