Swiftfire is a webserver that allows the injection of HTML code from routines written with Swift.
The Swiftfire webserver can be extended with functions and services written in Swift. The services are used to process a HTTP request, and the functions are used to prepare a response by processing the requested page or file. This makes it possible to create entire websites written in nothing else but HTML, CSS and Swift. No other languages, frameworks or external services necessary, with a minor exception for openSSL for HTTPS.
To use Swiftfire as an end-user you need a MacOS computer capable of running at least MacOS 10.12.
To develop Swiftfire extensions you need Xcode as well.
Also builds and runs on Linux (Mint 19.3) with the Swift Ubuntu 18.04 download from swift.org.
Visit the Swiftfire homepage at http://swiftfire.nl for all available documentation.
Beware: In the current version 1.x Swiftfire is still experimental. It works, but as this way of building websites is still new, it has to be expected that significant changes will need to be made as we gain experience. Hence if you are following along, you should expect that new releases will necessitate some recoding, including any websites that you might be creating. Version 2.0 will be released when we are relatively certain that major recodings will no longer be needed.
How it works
This is a very high level overview of how Swiftfire can use Swift code to create websites.
Every domain that is hosted under Swiftfire implements a stack of services. By default that stack implements a static website.
For each (valid and accepted) request that arrives at the server, Swiftfire finds the stack of services to execute and does so one service after the other.
You can add your own services to modify or extend the default behaviour.
However it is much more likely that you will want to create your own functions.
Functions can be used to inject HTML code into otherwise “static” web pages. Giving them dynamic qualities.
One of the services in the stack retrieves the requested page from disk and verifies if it must be parsed. If it must be parsed it scans the page for ‘functions’. Any function that is found is executed, and the result of the execution is injected into the page at the exact spot of the function. The function itself is removed.
An example for the function “.nofPageHits()”.
In the HTML code we would call the function as follows:
<p>This page has been accessed .nofPageHits() times</p>
which would then be translated by Swiftfire to:
<p>This page has been accessed 59440 times</p>
or any other number of course.
The best part is, you can define and write the functions yourself.
It is even possible to create loops and use conditinal expressions:
<p>Your name is: .if($account, equal, nil) unknown .else() .show($account.name) .end()</p>
It is up to you to determine how much you want to do in Swift. For example, you could decide to have the entire landing page to be created by a function. To do that let index.sf.html exist only of: .buildLandingPage(). And of course you have to implement the function that is registered under the name buildLandingPage.
It is fast. Depending of course on the amount and complexity of the services and functions, Swiftfire as presented here is very fast. On our server (a mac mini) the static pages are usually served in less than 2mS. Adding functions and services will increase this number of course. Still since the function calls and services refer to compiled code instead of interpreted code the speed of Swiftfire can be expected to be higher than interpreter solutions.
Oh, and it does PHP as well…
GUI
Swiftfire is a faceless webserver application. However it comes with a website that can be used for administration purposes. On initial start of the server, any request on the port on which the server listens will result in a landing page that asks the user to create an admin account and the directory in which the administration site is installed.
Once set up, access any hosted domain and append: ‘/serveradmin’ to the url. This will return the server administrator website. Note that the login is only as secure as the protocol. Use HTTP only when accessing from within a private LAN.
When a domain is created the domain setup page can be accessed at ‘domain-url/setup’.
Features
Builds and runs on MacOS and Linux
Allows code injection (HTML and CSS) from functions written in Swift
Allows website services to be implemented in Swift
Out of the box support for static websites
Handles multiple domains
Integrated comment system for local storage
Sessions are supported
Accounts are supported
End-user registration and lost-password supported (needs postfix)
Integrated comment system
Client forwarding (to other hosts or a different port on the same host)
Integrated usage statistics (page visits)
Blacklisting (refusal of service) on IP basis for Server and per domain
Supports HTTP1.0 and HTTP1.1
Supports HTTPS
Web based interface for Swiftfire Administrator
Custom pages for errors (for example the infamous 404 page not found)
Logging of received headers possible
Logging of missing pages (404)
Supports PHP
Multiple server administrators
Multiple domain administrators
Integrated with the Jekyll theme: Swifterfire-Jekyll-Theme
Then switch to the directory containg the project:
$ cd Swiftfire
The build the project, but first make the build script executable:
$ chmod +x *.sh
$ ./sf-build.sh
This should build the project without errors.
If the target macOS is before 10.14.4 then it is also necessary to install the Swift 5 Runtime Support for Command Line Tools. This will install a set of libraries into /usr/lib/swift among which libswiftCoreFoundation.dyLib. When you get an error message -when starting Swiftfire- complaining that this library is missing, install the Swift 5 runtime.
We could stop here, but… the project needs openSSL. And while pre-compiled versions of openSSL are provided for convenience, you should not trust this for operational use. Make sure to download and install openSSL from the original sources at openSSL.org
Directions for the installation of openSSL are in the subproject SecureSockets.
Though it is still possible to deploy Swiftfire on MacOS 10.12, this is no longer recommended due to the patches that have to be made on the openSSL source code. If the hardware is incapable of running any macOS higher than 10.12, consider switching to Linux Mint 19.3.
Using Xcode
First follow the steps as per directions above. Perform exactly the same steps, but this time there is no need to build the project. Instead generate the xcode project:
$ swift package generate-xcodeproj
Opening the generated Xcode project update the build settings Search Paths for the targets:
CopensslGlue, SecureSockets, Core: Add to the build setting Search Paths -> Header Search Paths the value $(SRCROOT)/openssl/<<openssl-to-be-used>>/include.
CopensslGlue: Add to the build setting Search Paths -> Library Search Paths the value $(SRCROOT)/openssl/<<openssl-to-be-used>>/lib.
CopensslGlue: Add to the build setting Linking -> Other Linker Flags the value -lssl and -lcrypto
Swiftfire: Remove the build setting -lssl -lcrypto from Linking -> Other Linker Flags
<<openssl-to-be-used>> must of course be replaced by the openSSL version/compilate of your choice. See the README file in the openssl directory.
Configuring
When Swiftfire is started for the first time, some configuration must be done. You may want to prepare for this by copying the sfadmin and demo directories included in the repository to a different location. Though they can remain inside the project, it is less error prone to have these two websites in a different location so that potential changes will not affect an operational scenario.
In the default configuration Swiftfire will listen on port 6678 for incoming connections. Any connection attempt without domains being present will result in the return of a primitive page where the administrator ID and password must be set in addition to the location of the sfadmin directory.
Once that is done, Swiftfire can be customized by logging in as admin and using the admin pages.
Note that Swiftfire will store and expect information in the ~/Library/Application Support/Swiftfire/<<instance-root>> location after it was first started. Changes to the settings are immediately stored. The <<instance-root>> can be used to allow multiple instances of Swiftfire to run in parallel.
Some of the logs are in *.txt format, settings are in *.json format (for which we recommend our proJSON app) and the visitor statistics are in the *.brbon format. For which there is currently no app available. The BRBON spec however can be found on github including a BRBON API. How to make the visitor statistics available is a subject of discussion.
Making changes
You can of course change whatever you want, but the current source code layout was choosen for a reason. While this layout is rather new (and thus may need to change) we hope that you will only need to add to the Custom, Functions and Services modules. Though you should leave their current contents unaffected since the correct functioning of the admin server account depends on them.
Jekyll
The sources for the server admin site are generated using Jekyll. If changes must be made, you will need to install Jekyll and the theme Classic-Jekyll-Theme. For more information on Jekyll see jekyllrb.com/ for more information on Classic-Jekyll-Theme see balancingrock.github.io/classic-jekyll-theme
Theme
There is a Swiftfire-Jekyll-Theme to quickly setup a (blogging) website that includes handling of user comments. Swiftfire 1.3.2 is matched by Swiftfire-Jekyll-Theme 0.2.0.
Build websites with Swift.
Swiftfire is a webserver that allows the injection of HTML code from routines written with Swift.
The Swiftfire webserver can be extended with functions and services written in Swift. The services are used to process a HTTP request, and the functions are used to prepare a response by processing the requested page or file. This makes it possible to create entire websites written in nothing else but HTML, CSS and Swift. No other languages, frameworks or external services necessary, with a minor exception for openSSL for HTTPS.
To use Swiftfire as an end-user you need a MacOS computer capable of running at least MacOS 10.12.
To develop Swiftfire extensions you need Xcode as well.
Also builds and runs on Linux (Mint 19.3) with the Swift Ubuntu 18.04 download from swift.org.
Visit the Swiftfire homepage at http://swiftfire.nl for all available documentation.
Beware: In the current version 1.x Swiftfire is still experimental. It works, but as this way of building websites is still new, it has to be expected that significant changes will need to be made as we gain experience. Hence if you are following along, you should expect that new releases will necessitate some recoding, including any websites that you might be creating. Version 2.0 will be released when we are relatively certain that major recodings will no longer be needed.
How it works
This is a very high level overview of how Swiftfire can use Swift code to create websites.
Every domain that is hosted under Swiftfire implements a stack of services. By default that stack implements a static website.
For each (valid and accepted) request that arrives at the server, Swiftfire finds the stack of services to execute and does so one service after the other.
You can add your own services to modify or extend the default behaviour.
However it is much more likely that you will want to create your own functions.
Functions can be used to inject HTML code into otherwise “static” web pages. Giving them dynamic qualities.
One of the services in the stack retrieves the requested page from disk and verifies if it must be parsed. If it must be parsed it scans the page for ‘functions’. Any function that is found is executed, and the result of the execution is injected into the page at the exact spot of the function. The function itself is removed.
An example for the function “.nofPageHits()”.
In the HTML code we would call the function as follows:
which would then be translated by Swiftfire to:
or any other number of course.
The best part is, you can define and write the functions yourself.
It is even possible to create loops and use conditinal expressions:
It is up to you to determine how much you want to do in Swift. For example, you could decide to have the entire landing page to be created by a function. To do that let index.sf.html exist only of:
.buildLandingPage()
. And of course you have to implement the function that is registered under the namebuildLandingPage
.It is fast. Depending of course on the amount and complexity of the services and functions, Swiftfire as presented here is very fast. On our server (a mac mini) the static pages are usually served in less than 2mS. Adding functions and services will increase this number of course. Still since the function calls and services refer to compiled code instead of interpreted code the speed of Swiftfire can be expected to be higher than interpreter solutions.
Oh, and it does PHP as well…
GUI
Swiftfire is a faceless webserver application. However it comes with a website that can be used for administration purposes. On initial start of the server, any request on the port on which the server listens will result in a landing page that asks the user to create an admin account and the directory in which the administration site is installed.
Once set up, access any hosted domain and append: ‘/serveradmin’ to the url. This will return the server administrator website. Note that the login is only as secure as the protocol. Use HTTP only when accessing from within a private LAN.
When a domain is created the domain setup page can be accessed at ‘domain-url/setup’.
Features
Installation
Using SPM
Download the project using git clone:
Then switch to the directory containg the project:
The build the project, but first make the build script executable:
This should build the project without errors.
If the target macOS is before 10.14.4 then it is also necessary to install the Swift 5 Runtime Support for Command Line Tools. This will install a set of libraries into
/usr/lib/swift
among whichlibswiftCoreFoundation.dyLib
. When you get an error message -when starting Swiftfire- complaining that this library is missing, install the Swift 5 runtime.We could stop here, but… the project needs openSSL. And while pre-compiled versions of openSSL are provided for convenience, you should not trust this for operational use. Make sure to download and install openSSL from the original sources at openSSL.org
Directions for the installation of openSSL are in the subproject SecureSockets.
Though it is still possible to deploy Swiftfire on MacOS 10.12, this is no longer recommended due to the patches that have to be made on the openSSL source code. If the hardware is incapable of running any macOS higher than 10.12, consider switching to Linux Mint 19.3.
Using Xcode
First follow the steps as per directions above. Perform exactly the same steps, but this time there is no need to build the project. Instead generate the xcode project:
Opening the generated Xcode project update the build settings
Search Paths
for the targets:Search Paths -> Header Search Paths
the value$(SRCROOT)/openssl/<<openssl-to-be-used>>/include
.Search Paths -> Library Search Paths
the value$(SRCROOT)/openssl/<<openssl-to-be-used>>/lib
.Linking -> Other Linker Flags
the value-lssl
and-lcrypto
-lssl -lcrypto
fromLinking -> Other Linker Flags
<<openssl-to-be-used>>
must of course be replaced by the openSSL version/compilate of your choice. See the README file in the openssl directory.Configuring
When Swiftfire is started for the first time, some configuration must be done. You may want to prepare for this by copying the
sfadmin
anddemo
directories included in the repository to a different location. Though they can remain inside the project, it is less error prone to have these two websites in a different location so that potential changes will not affect an operational scenario.In the default configuration Swiftfire will listen on port 6678 for incoming connections. Any connection attempt without domains being present will result in the return of a primitive page where the administrator ID and password must be set in addition to the location of the
sfadmin
directory.Once that is done, Swiftfire can be customized by logging in as admin and using the admin pages.
Note that Swiftfire will store and expect information in the
~/Library/Application Support/Swiftfire/<<instance-root>>
location after it was first started. Changes to the settings are immediately stored. The<<instance-root>>
can be used to allow multiple instances of Swiftfire to run in parallel.Some of the logs are in *.txt format, settings are in *.json format (for which we recommend our proJSON app) and the visitor statistics are in the *.brbon format. For which there is currently no app available. The BRBON spec however can be found on github including a BRBON API. How to make the visitor statistics available is a subject of discussion.
Making changes
You can of course change whatever you want, but the current source code layout was choosen for a reason. While this layout is rather new (and thus may need to change) we hope that you will only need to add to the
Custom
,Functions
andServices
modules. Though you should leave their current contents unaffected since the correct functioning of the admin server account depends on them.Jekyll
The sources for the server admin site are generated using Jekyll. If changes must be made, you will need to install Jekyll and the theme Classic-Jekyll-Theme. For more information on Jekyll see jekyllrb.com/ for more information on Classic-Jekyll-Theme see balancingrock.github.io/classic-jekyll-theme
Theme
There is a Swiftfire-Jekyll-Theme to quickly setup a (blogging) website that includes handling of user comments. Swiftfire 1.3.2 is matched by Swiftfire-Jekyll-Theme 0.2.0.
Useful links
Swiftfire projects Overview
Version history
HEAD
1.3.3
1.3.2
1.3.1
1.3.0
demo
site to showcase features and serve as a user website template1.2.1
1.2.0
1.1.0
1.0.1
1.0.0
Removed older history entries