diff --git a/README.md b/README.md

index 6c04597..fbccb70 100644

--- a/README.md

+++ b/README.md

@@ -7,7 +7,7 @@ This is a simple Python script that listens for Titan requests and then adds, up

The configuration file ~/.booster/config.json must exist:



-{ 

+{

 "python": "/usr/bin/python3",

 "git": {

     "exec": "/usr/bin/git",

@@ -18,8 +18,15 @@ The configuration file ~/.booster/config.json must exist:

 "cert": "/absolute-path/titan.crt",

 "key": "/absolute-path/titan.key",

 "authorized": "/absolute-path/titan-clients.pem",

- "file_root": "/absolute-path-where-files-are-kept/",

 "site_url": "gemini://skyjake.fi",

- "root": "/gemlog"

+ "files": {

+ "root": "/absolute-path/capsule-files/",

+ "Gemlog": {

+ "subdir": "gemlog/"

+ },

+ "Title prefix for Git": {

+ "file": "relative-path-of-single-file.gmi"

+ }

+ }

}

diff --git a/booster.py b/booster.py

index d4e9d09..a2636da 100755

--- a/booster.py

+++ b/booster.py

@@ -30,11 +30,15 @@

ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

POSSIBILITY OF SUCH DAMAGE.



-import os, sys, json, subprocess

+import os, sys, json, subprocess, time

import socket, ssl, OpenSSL.crypto, hashlib

from urllib.parse import urlparse

pjoin = os.path.join



+def append_slash(p):

+ if not p.endswith('/'): return p + '/'

+ return p

+

#----------------------------------------------------------------------------#

CONFIGURATION #

#----------------------------------------------------------------------------#

@@ -45,9 +49,8 @@ if not os.path.exists(CFG_PATH):

 print(f'ERROR: Configuration file {CFG_PATH} not found.')

 sys.exit(1)

CONFIG = json.loads(open(CFG_PATH, 'rt').read())

-if not CONFIG['root'].endswith('/'):

- CONFIG['root'] = CONFIG['root'] + '/'

print(json.dumps(CONFIG, indent=2))

+FILES_ROOT = append_slash(CONFIG['files']['root'])



#----------------------------------------------------------------------------#

REQUEST HANDLING #

@@ -75,6 +78,7 @@ def urlenc(q):

 return q



def handle_client(stream):

+ print(time.strftime('%Y-%m-%d %H:%M:%S'))

 data = bytes()

 incoming = stream.recv(1024)

 expected_size = -1

@@ -105,54 +109,81 @@ def handle_client(stream):

     if len(data) >= expected_size:

         break

     incoming = stream.recv(1024)

- # process the request

+

 print(f'URL   : {req_url}')

 print(f'Token : {req_token}')

 print(f'MIME  : {req_mime}')

 print(f'Data  : {len(data)} bytes')

+

 parts = urlparse(req_url)

 path = parts.path

- if not path.startswith(CONFIG['root']):

- report_error(stream, 51, "invalid path")

- return

- path = path[len(CONFIG['root']):]

- if path.startswith('.'):

+ file_path = None

+ msg_path = None

+ if (path.startswith('.') or

+ os.path.basename(path).startswith('.') or

+ '..' in path):

     report_error(stream, 61, "access is not authorized")

     return

- file_path = pjoin(CONFIG['file_root'], path)

- view_url = '%s/%s%s' % (CONFIG['site_url'], CONFIG['root'], path)

+

+ # Are we allowed to edit this path?

+ msg_prefix = ''

+ for file_group in CONFIG['files']:

+ group = CONFIG['files'][file_group]

+ if type(group) != dict: continue

+ if 'subdir' in group:

+ auth_prefix = append_slash(group['subdir'])

+ msg_path = path[len(auth_prefix):]

+ elif 'file' in group:

+ auth_prefix = '/' + group['file']

+ msg_path = os.path.basename(path)

+ if path.startswith(auth_prefix):

+ file_path = os.path.normpath(FILES_ROOT + path)

+ if not file_path.startswith(FILES_ROOT) or \

+ os.path.isdir(file_path):

+ report_error(stream, 61, "access is not authorized")

+ return

+ msg_prefix = f'{file_group}: '

+ break

+ if not file_path:

+ report_error(stream, 61, "unauthorized location")

+ return

+

+ # Process the request.

+ is_new = not os.path.exists(file_path)

+ view_url = '%s%s' % (CONFIG['site_url'], path)

 response = '# Booster log\n'

- is_new = not os.path.exists(file_path)

- GIT = CONFIG['git']

 if not is_new and req_token == 'DELETE':

     response += f'* deleting file: {file_path}\n'

     os.remove(file_path)

- git_msg = GIT['message_prefix'] + 'Removed ' + path

+ git_msg = msg_prefix + 'Removed ' + msg_path

 else:

     if is_new:

         response += f'* creating a new file: {file_path}\n'

- git_msg = GIT['message_prefix'] + 'Added ' + path

+ git_msg = msg_prefix + 'Added ' + msg_path

     else:

         response += f'* updating file: {file_path}\n'

- git_msg = GIT['message_prefix'] + 'Updated ' + path

+ git_msg = msg_prefix + 'Updated ' + msg_path

     # write the data

     response += f'* writing %d bytes\n' % len(data)

     dst = open(file_path, 'wb')

     dst.write(data)

     dst.close()

- # update indices

- os.chdir(CONFIG['file_root'])

+

+ # Update Gemlog indices.

+ GEMLOG_SUBDIR = CONFIG['files']['Gemlog']['subdir']

+ os.chdir(pjoin(FILES_ROOT, GEMLOG_SUBDIR))

 response += f'* updating indices\n'

 response += run_command([CONFIG['python'], ".makeindex.py"])

 response += '* committing changes to Git repository\n'

 if is_new:

- response += run_command([GIT['exec'], 'add', file_path])

- response += run_command([GIT['exec'], 'commit', '-a', '-m', git_msg])

+ response += run_command([CONFIG['git'], 'add', file_path])

+ response += run_command([CONFIG['git'], 'commit', '-a', '-m', git_msg])

 response += "\n"

 response += f"=> {view_url} View the page\n"

 response += f"=> gemini://warmedal.se/~antenna/submit?%s Notify Antenna" %\

- urlenc('%s%s' % (CONFIG['site_url'], CONFIG['root']))

- # compose a response

+ urlenc('%s%s' % (CONFIG['site_url'], GEMLOG_SUBDIR))

+

+ # Send the response.

 stream.sendall(('20 text/gemini; charset=utf-8\r\n%s' %

                  response).encode('utf-8'))



Proxy Information
Original URL
gemini://git.skyjake.fi/booster/main/pcdiff/1e13c94ae4967b6676007027a922d7e88874a20c
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
258.85993 milliseconds
Gemini-to-HTML Time
2.803267 milliseconds

This content has been proxied by September (ba2dc).