From 961d42e3e27772e1522e3827639b6effcb053314 Mon Sep 17 00:00:00 2001 From: Michael Lazar Date: Thu, 4 Jun 2020 13:36:57 -0400 Subject: [PATCH] Clarify support for virtual hosting --- README.md | 16 ++++++++++++++ examples/vhost.py | 53 ++++++++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 04e7f11..1961df9 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,22 @@ a directory is requested, jetforce will look for a file named **index.gmi** in t directory to return. Otherwise, a directory file listing will be automatically generated. +### Virtual Hosting + +For the sake of keeping the command line arguments straightforward and easy +to understand, configuring virtual hosting is not supported via the command +line. However, it is readily available using only a few lines of python and a +custom launch script. Check out [examples/vhost.py](examples/vhost.py) for more +information. + +Jetforce does not (yet) support virtual hosting at the TLS-layer using SNI. +This means that you cannot return different server TLS certificates for +different domains. The suggested workaround is to use a single certificate with +multiple ``subjectAltName`` attributes. There is also an +[sni_callback()](https://github.com/michael-lazar/jetforce/blob/9ac80a986c6ed8a62951c857315ca04b6d127c32/jetforce/tls.py#L140) +hook in the server codebase that can be subclassed to implement custom TLS +behavior. + ### CGI Jetforce supports a simplified version of CGI scripting. It doesn't diff --git a/examples/vhost.py b/examples/vhost.py index 985a7bb..ebf4ec2 100644 --- a/examples/vhost.py +++ b/examples/vhost.py @@ -1,36 +1,41 @@ """ -A server that implements virtual hosting for multiple subdomains. +A server that implements virtual hosting for subdomains. -This is a basic example of you how can run multiple apps from the same server -by creating a composite application. +This is a basic example of you how can run multiple apps from the same server. +You can use different static directories for different domains, or even combine +static applications with your own custom JetforceApplication classes. -> jetforce-client gemini://apple.localhost --host localhost -> jetforce-client gemini://banana.localhost --host localhost +> jetforce-client gemini://app-a.example.com --host localhost +> jetforce-client gemini://app-b.example.com --host localhost + +This is how gemini://astrobotany.mozz.us is served alongside gemini://mozz.us: + +``` +app = jetforce.CompositeApplication( + { + "astrobotany.mozz.us": astrobotany_application, + None: StaticDirectoryApplication(), + } +) +``` """ -from jetforce import GeminiServer, JetforceApplication, Response, Status +from jetforce import GeminiServer, StaticDirectoryApplication from jetforce.app.composite import CompositeApplication -apple = JetforceApplication() +app_a = StaticDirectoryApplication(root_directory="/var/custom_directory_a/") +app_b = StaticDirectoryApplication(root_directory="/var/custom_directory_b/") +app_default = StaticDirectoryApplication(root_directory="/var/gemini/") - -@apple.route() -def index(request): - return Response(Status.SUCCESS, "text/plain", "apple!") - - -banana = JetforceApplication() - - -@banana.route() -def index(request): - return Response(Status.SUCCESS, "text/plain", "banana!") - - -composite_app = CompositeApplication( - {"apple.localhost": apple, "banana.localhost": banana} +app = CompositeApplication( + { + "app-a.example.com": app_a, + "app-b.example.com": app_b, + # Use a default static file server for all other domains + None: app_default, + } ) if __name__ == "__main__": - server = GeminiServer(composite_app) + server = GeminiServer(app) server.run()