CGI: Use path wildcards with `bin_root` executables; look for "index.gmi" files
This commit is contained in:
parent
a9923d43fc
commit
8ff7ab3d17
13
README.md
13
README.md
|
@ -47,6 +47,14 @@ The log can be viewed via journalctl (or syslog):
|
|||
|
||||
## Change log
|
||||
|
||||
### v0.7
|
||||
|
||||
* CGI: Fixed contents of `PATH_INFO`: it is now URL-decoded and the script path is removed so only the part following the script path is included in the environment variable (RFC 3875, section 4.1.5).
|
||||
* CGI: `bin_root` applies a wildcard to all found CGI executables so `PATH_INFO` can be used.
|
||||
* CGI: `bin_root` looks for executable "index.gmi" files in requested directories to provide the directory index.
|
||||
* Skip the TLS SNI check when request hostname has a literal IP address. (SNI is not supposed to be used with literal addresses.)
|
||||
* Respond with status 53 if an unknown hostname is requested. This helps reveal configuration errors where the correct hostnames are not specified.
|
||||
|
||||
### v0.6
|
||||
|
||||
* Added `stream` to the `[cgi.*]` section to enable streaming output mode where the output of the CGI child process is immediately sent to the client without any buffering. Streaming is not supported if the server is using multiple processes.
|
||||
|
@ -57,11 +65,6 @@ v0.6.1:
|
|||
* Static: Fixed unquoting URL paths when looking up files.
|
||||
* Added example of printing Gemini meta line in CGI documentation.
|
||||
|
||||
v0.6.2:
|
||||
|
||||
* Skip the TLS SNI check when request hostname has a literal IP address. (SNI is not supposed to be used with literal addresses.)
|
||||
* Respond with status 53 if an unknown hostname is requested. This helps reveal configuration errors where the correct hostnames are not specified.
|
||||
|
||||
### v0.5
|
||||
|
||||
* Added `processes` to the `[server]` section to configure how many request handler processes are started.
|
||||
|
|
|
@ -17,8 +17,8 @@ class CgiContext:
|
|||
self.port = port
|
||||
self.args = args
|
||||
self.base_path = url_path
|
||||
if self.base_path.endswith('/*'):
|
||||
self.base_path = self.base_path[:-2]
|
||||
if self.base_path.endswith('*'):
|
||||
self.base_path = self.base_path[:-1]
|
||||
self.work_dir = work_dir
|
||||
self.is_streaming = is_streaming
|
||||
|
||||
|
@ -31,7 +31,11 @@ class CgiContext:
|
|||
env_vars['REMOTE_ADDR'] = '%s:%d' % req.remote_address
|
||||
if req.query != None:
|
||||
env_vars['QUERY_STRING'] = req.query
|
||||
env_vars['PATH_INFO'] = req.path
|
||||
# PATH_INFO contains any additional subdirectories deeper than the script location.
|
||||
path_info = urllib.parse.unquote(req.path)
|
||||
if path_info.startswith(self.base_path):
|
||||
path_info = path_info[len(self.base_path):]
|
||||
env_vars['PATH_INFO'] = path_info
|
||||
env_vars['SCRIPT_NAME'] = self.base_path
|
||||
env_vars['SERVER_SOFTWARE'] = 'GmCapsule/' + gmcapsule.__version__
|
||||
env_vars['SERVER_PROTOCOL'] = req.scheme.upper()
|
||||
|
@ -110,13 +114,25 @@ class CgiTreeMapper:
|
|||
def __call__(self, url_path):
|
||||
# Check if url_path is a valid CGI entrypoint and return
|
||||
# a CgiContext for it.
|
||||
fn = str(self.root_dir) + url_path
|
||||
root_dir = str(self.root_dir)
|
||||
fn = root_dir + url_path
|
||||
if self.protocol == 'titan':
|
||||
fn += ',titan'
|
||||
if os.path.isdir(fn):
|
||||
return None
|
||||
if os.access(fn, os.X_OK):
|
||||
return CgiContext(self.port, url_path, [fn], work_dir=os.path.dirname(fn))
|
||||
# Look for an executable up the path.
|
||||
par_path = fn
|
||||
par_url = url_path
|
||||
while len(par_path) > len(root_dir):
|
||||
# An executable 'index.gmi' is used for generating the index page.
|
||||
if os.path.isdir(par_path):
|
||||
if os.access(os.path.join(par_path, 'index.gmi'), os.X_OK):
|
||||
return CgiContext(self.port, par_url + '*', [os.path.join(par_path, 'index.gmi')],
|
||||
work_dir=par_path)
|
||||
else:
|
||||
return None
|
||||
if os.access(par_path, os.X_OK):
|
||||
return CgiContext(self.port, par_url + '*', [par_path], work_dir=os.path.dirname(par_path))
|
||||
par_path = os.path.dirname(par_path)
|
||||
par_url = os.path.dirname(par_url)
|
||||
return None
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue