commit e872053b20d763005a398200c638c923aebd04e1 from: Omar Polo date: Fri Aug 18 12:40:10 2023 UTC send all the params as per RFC3875 (CGI) and sync documentation commit - f5dc7eddd7ac6cf06d7092e9526691b566850b50 commit + e872053b20d763005a398200c638c923aebd04e1 blob - e681e1b5bb39bf3e023e0ca22acdf7218c249daa blob + 2219ecb5114fbc8afc04b620a93f808831b3b029 --- fcgi.c +++ fcgi.c @@ -371,12 +371,37 @@ fcgi_error(struct bufferevent *bev, short err, void *d c->type = REQUEST_DONE; } +static void +path_translate(const char *path, struct location *loc, struct location *rloc, + char *buf, size_t len) +{ + const char *root, *sufx; + + buf[0] = '\0'; + + if (*loc->dir != '\0') + root = loc->dir; + else if (*rloc->dir != '\0') + root = rloc->dir; + else + return; + + sufx = ""; + if (*root != '\0') + sufx = root[strlen(root) - 1] == '/' ? "" : "/"; + + while (*path == '/') + path++; + + snprintf(buf, len, "%s%s%s", root, sufx, path); +} + void fcgi_req(struct client *c, struct location *loc) { - char buf[22], path[GEMINI_URL_LEN]; + char buf[22], path[GEMINI_URL_LEN], path_tr[PATH_MAX]; char *scriptname, *qs; - const char *stripped; + const char *stripped, *port; size_t l; time_t tim; struct tm tminfo; @@ -384,6 +409,16 @@ fcgi_req(struct client *c, struct location *loc) fcgi_begin_request(c->cgibev); + stripped = strip_path(c->iri.path, loc->fcgi_strip); + if (*stripped != '/') + snprintf(path, sizeof(path), "/%s", stripped); + else + strlcpy(path, stripped, sizeof(path)); + + port = c->iri.host; + if (port == NULL || *port == '\0') + port = "1965"; + scriptname = ""; TAILQ_FOREACH(p, &loc->params, envs) { if (!strcmp(p->name, "SCRIPT_NAME")) { @@ -392,35 +427,36 @@ fcgi_req(struct client *c, struct location *loc) } } - stripped = strip_path(c->iri.path, loc->fcgi_strip); - if (*stripped != '/') - snprintf(path, sizeof(path), "/%s", stripped); - else - strlcpy(path, stripped, sizeof(path)); - l = strlen(scriptname); while (l > 0 && scriptname[l - 1] == '/') l--; if (!strncmp(scriptname, path, l) && (path[l] == '/' || path[l] == '\0')) { fcgi_send_param(c->cgibev, "PATH_INFO", &path[l]); + path_translate(&path[l], loc, TAILQ_FIRST(&c->host->locations), + path_tr, sizeof(path_tr)); path[l] = '\0'; fcgi_send_param(c->cgibev, "SCRIPT_NAME", path); } else { + path_translate(stripped, loc, TAILQ_FIRST(&c->host->locations), + path_tr, sizeof(path_tr)); fcgi_send_param(c->cgibev, "PATH_INFO", stripped); fcgi_send_param(c->cgibev, "SCRIPT_NAME", scriptname); } fcgi_send_param(c->cgibev, "GATEWAY_INTERFACE", "CGI/1.1"); - fcgi_send_param(c->cgibev, "GEMINI_URL_PATH", c->iri.path); + fcgi_send_param(c->cgibev, "PATH_TRANSLATED", path_tr); fcgi_send_param(c->cgibev, "QUERY_STRING", c->iri.query); fcgi_send_param(c->cgibev, "REMOTE_ADDR", c->rhost); fcgi_send_param(c->cgibev, "REMOTE_HOST", c->rhost); - fcgi_send_param(c->cgibev, "REQUEST_METHOD", ""); + fcgi_send_param(c->cgibev, "REQUEST_METHOD", "GET"); fcgi_send_param(c->cgibev, "SERVER_NAME", c->iri.host); + fcgi_send_param(c->cgibev, "SERVER_PORT", port); fcgi_send_param(c->cgibev, "SERVER_PROTOCOL", "GEMINI"); fcgi_send_param(c->cgibev, "SERVER_SOFTWARE", GMID_VERSION); + fcgi_send_param(c->cgibev, "GEMINI_URL_PATH", c->iri.path); + if (*c->iri.query != '\0' && strchr(c->iri.query, '=') == NULL && (qs = strdup(c->iri.query)) != NULL) { blob - 5738e72613a9504aec57e8694007461b164bdeb5 blob + fc7845222690e79ccee09f573e33cfa8eebab720 --- gmid.conf.5 +++ gmid.conf.5 @@ -11,7 +11,7 @@ .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.Dd July 24, 2023 +.Dd August 18, 2023 .Dt GMID.CONF 5 .Os .Sh NAME @@ -326,25 +326,25 @@ leading path components from the .Pp The FastCGI handler will be given the following variables by default: .Bl -tag -width 24m -.It Ev GATEWAY_INTERFACE -.Dq CGI/1.1 -.It Ev GEMINI_DOCUMENT_ROOT -The root directory of the virtual host. -.It Ev GEMINI_SCRIPT_FILENAME -Full path to the FastCGI script being executed. -.It Ev GEMINI_URL -The full IRI of the request. +.\" .It Ev GEMINI_DOCUMENT_ROOT +.\" The root directory of the virtual host. .It Ev GEMINI_URL_PATH -The path of the request. +Full path of the request. .It Ev GEMINI_SEARCH_STRING The decoded .Ev QUERY_STRING if defined in the request and if it doesn't contain any unencoded .Sq = characters, otherwise unset. +.It Ev GATEWAY_INTERFACE +.Dq CGI/1.1 +.It Ev AUTH_TYPE +The string "Certificate" if the client used a certificate, otherwise +unset. .It Ev PATH_INFO The portion of the requested path that is derived from the the IRI -path hierarchy following the part that identifies the script itself. +path hierarchy following +.Ev SCRIPT_NAME . Can be unset. .It Ev PATH_TRANSLATED Present if and only if @@ -362,9 +362,17 @@ The URL-encoded search or parameter string. Textual representation of the client IP. .It Ev REQUEST_METHOD This is present only for RFC3875 (CGI) compliance. -It's always set to the empty string. +It's always set to +.Dq GET . .It Ev SCRIPT_NAME The virtual URI path to the script. +Since it's impossible to determine in all cases the correct +.Ev SCRIPT_NAME +programmatically +.Nm gmid +assumes it's the empty string. +It is recommended to manually specify this parameter when serving a +sub-tree of a virtual host via FastCGI. .It Ev SERVER_NAME The name of the server .It Ev SERVER_PORT @@ -374,9 +382,6 @@ The port the server is listening on. .It Ev SERVER_SOFTWARE The name and version of the server, i.e. .Dq gmid/1.8.4 -.It Ev AUTH_TYPE -The string "Certificate" if the client used a certificate, otherwise -unset. .It Ev REMOTE_USER The subject of the client certificate if provided, otherwise unset. .It Ev TLS_CLIENT_ISSUER