fix cgi support for PATH_INFO
looks for files immediately after the cgidir, and anything after that file if there are '/'s becomes PATH_INFO. also adds a function strip_trailing_slash which may be useful in other parts too.
This commit is contained in:
parent
8efcdb7512
commit
aa1affb6c2
47
main.c
47
main.c
|
@ -20,7 +20,7 @@
|
||||||
#include "opts.h"
|
#include "opts.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
/* lenght of "gemini://" */
|
/* length of "gemini://" */
|
||||||
#define GEMINI_PART 9
|
#define GEMINI_PART 9
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -38,6 +38,7 @@ void echdir (const char *);
|
||||||
void status (const int, const char *);
|
void status (const int, const char *);
|
||||||
void status_redirect(const int, const char *);
|
void status_redirect(const int, const char *);
|
||||||
void status_error(const int, const char *);
|
void status_error(const int, const char *);
|
||||||
|
void strip_trailing_slash(char *path);
|
||||||
int uridecode (char *);
|
int uridecode (char *);
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,6 +305,17 @@ cgi(const char *cgicmd)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
strip_trailing_slash(char *path)
|
||||||
|
{
|
||||||
|
size_t end = strlen(path);
|
||||||
|
if (end == 0)
|
||||||
|
return;
|
||||||
|
end--;
|
||||||
|
while (path[end] == '/')
|
||||||
|
path[end--] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -454,7 +466,25 @@ main(int argc, char **argv)
|
||||||
* found, then requested file is actually a directory
|
* found, then requested file is actually a directory
|
||||||
*/
|
*/
|
||||||
if (strlen(dir) > 0) {
|
if (strlen(dir) > 0) {
|
||||||
pos = strrchr(dir, '/');
|
/*
|
||||||
|
* if in cgidir, only the first file after cgidir/FILE is to be executed
|
||||||
|
* the rest is PATH_INFO
|
||||||
|
*/
|
||||||
|
/* find the string of cgidir without chroot_dir prefix */
|
||||||
|
char tmp [PATH_MAX] = {'\0'};
|
||||||
|
char *cgipp;
|
||||||
|
strip_trailing_slash(chroot_dir);
|
||||||
|
strip_trailing_slash(cgidir);
|
||||||
|
estrlcpy(tmp, cgidir + strlen(chroot_dir), sizeof(tmp));
|
||||||
|
cgipp = tmp;
|
||||||
|
if (tmp[0] == '/')
|
||||||
|
cgipp++;
|
||||||
|
|
||||||
|
if (docgi && strncmp(dir, cgipp, strlen(cgipp)) == 0) {
|
||||||
|
pos = strchr(dir+strlen(cgipp), '/');
|
||||||
|
} else {
|
||||||
|
pos = strrchr(dir, '/');
|
||||||
|
}
|
||||||
if (pos != NULL) {
|
if (pos != NULL) {
|
||||||
estrlcpy(file, pos + 1, sizeof(file)); /* +1 : no leading '/' */
|
estrlcpy(file, pos + 1, sizeof(file)); /* +1 : no leading '/' */
|
||||||
pos[0] = '\0';
|
pos[0] = '\0';
|
||||||
|
@ -491,15 +521,12 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
if (*query)
|
if (*query)
|
||||||
esetenv("QUERY_STRING", query, 1);
|
esetenv("QUERY_STRING", query, 1);
|
||||||
/* look for an extension to find PATH_INFO */
|
|
||||||
pos = strrchr(file, '.');
|
/* if we've got here and file contains a '/', it should be interpreted as PATH_INFO */
|
||||||
|
pos = strchr(file, '/');
|
||||||
if (pos != NULL) {
|
if (pos != NULL) {
|
||||||
/* found a dot */
|
setenv("PATH_INFO", pos, 1);
|
||||||
pos = strchr(pos, '/');
|
pos[0] = '\0'; /* keep only script name */
|
||||||
if (pos != NULL) {
|
|
||||||
setenv("PATH_INFO", pos, 1);
|
|
||||||
pos[0] = '\0'; /* keep only script name */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
esetenv("SCRIPT_NAME", file, 1);
|
esetenv("SCRIPT_NAME", file, 1);
|
||||||
esetenv("SERVER_NAME", hostname, 1);
|
esetenv("SERVER_NAME", hostname, 1);
|
||||||
|
|
|
@ -91,6 +91,10 @@ if ! [ $OUT = "fa065a67d1f7c973501d4a9e3ca2ea57" ] ; then echo "error" ; exit 1
|
||||||
OUT=$(printf "gemini://host.name/cgi-bin/nope\r\n" | ../vger -d var/gemini/ -c var/gemini/cgi-bin | tee /dev/stderr | MD5)
|
OUT=$(printf "gemini://host.name/cgi-bin/nope\r\n" | ../vger -d var/gemini/ -c var/gemini/cgi-bin | tee /dev/stderr | MD5)
|
||||||
if ! [ $OUT = "74ba4b36dcebec9ce9dae33033f3378a" ] ; then echo "error" ; exit 1 ; fi
|
if ! [ $OUT = "74ba4b36dcebec9ce9dae33033f3378a" ] ; then echo "error" ; exit 1 ; fi
|
||||||
|
|
||||||
|
# cgi with PATH_INFO
|
||||||
|
OUT=$(printf "gemini://host.name/cgi-bin/test.cgi/path/info\r\n" | ../vger -d var/gemini -c var/gemini/cgi-bin | tee /dev/stderr | MD5)
|
||||||
|
if ! [ $OUT = "ec64da76dc578ffb479fbfb23e3a7a5b" ] ; then echo "error" ; exit 1 ; fi
|
||||||
|
|
||||||
# virtualhost + cgi
|
# virtualhost + cgi
|
||||||
OUT=$(printf "gemini://perso.pw/cgi-bin/test.cgi\r\n" | ../vger -v -d var/gemini/ -c var/gemini/perso.pw/cgi-bin | tee /dev/stderr | MD5)
|
OUT=$(printf "gemini://perso.pw/cgi-bin/test.cgi\r\n" | ../vger -v -d var/gemini/ -c var/gemini/perso.pw/cgi-bin | tee /dev/stderr | MD5)
|
||||||
if ! [ $OUT = "666e48200f90018b5e96c2cf974882dc" ] ; then echo "error" ; exit 1 ; fi
|
if ! [ $OUT = "666e48200f90018b5e96c2cf974882dc" ] ; then echo "error" ; exit 1 ; fi
|
||||||
|
|
Loading…
Reference in New Issue