Build websites in Swift.
Swiftfire is a webserver that allows the injection of HTML code from a routine written in 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.
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.
Linux compatibility is envisaged, but not yet actively supported.
Visit the Swiftfire homepage at http://swiftfire.nl.
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 de 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 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 exists only of:
.buildLandingPage(). And of course you have to implement the function that is registered under the name
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 may 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...
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, any access to the port that has as its URL: '/serveradmin' will end up on the login page of 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.
- 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
- Sessions are supported
- Accounts are supported
- 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
Download the project using git clone:
$ git clone https://github.com/Balancingrock/Swiftfire.git
Then switch to the directory containg the project:
$ cd Swiftfire
The build the project, but first make the build script executable:
$ chmod +x sf-build.sh $ ./sf-build
This should build the project without errors.
However... the project needs openSSL. And while a compiled version of openSSL is provided with the project, you should not trust this. 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. Note that you cannot use an existing installation of openSSL due to some necessary glue code.
You will likely enounter some issues with the target release when you have not compiled openSSL for MacOS 10.12, these are easily fixed by setting the corresponding build options.
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:
- SecureSockets, Core: Add to the build setting
Search Paths -> Header Search Pathsthe value
- SecureSockets, Core & Swiftfire: Add to the build setting
Search Paths -> Library Search Pathsthe value
Of course if you have a different paths for the openSSL include and lib paths then modify accordingly.
When Swiftfire is started for the first time, some configuration must be done. You may want to prepare for this by moving the
sfadmin directory included in the repository to a different location, though it can remain inside the project too.
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
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 location after it was first started. 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.
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
Services targets. Though you should leave their current contents unaffected since the correct functioning of the admin server account depends on them.
| Name | Purpose | Github | Reference |---|---|:-:|:-:| | Ascii | Ascii character definitions | link | link | BRBON | In-memory storage manager, fast access and load/store | link | link | BRUtils | General purpose definitions | link | link | Html | Makes creating HTML code easier | link | link | Http | An API for HTTP messages | link | link | KeyedCache | General purpose dictionary like cache | link | link | SecureSockets | Networking utilities that implement SSL (includes COpenSSL) | link | link | SwifterLog | General purpose logging utility | link | link | SwifterSockets | POSIX based networking interface | link | link | VJson | JSON interpreter/generator | link | link | Custom | Common definitions within Swiftfire | link | link | Admin | Administrator code within Swiftfire | link | link | Core | Core code within Swiftfire | link | link | Functions | Predefined functions in Swiftfire | link | link | Services | Predefined services in Swiftfire | link | link | Swiftfire | Swiftfire main operation | link | link
Note: Planned releases are for information only and almost always change.
- Add URL redirection list
- Documentation changes
- Visibility of keys (not needed yet but will be eventually)
- Removed name definitions for functions and replaced with strings in the place where the vars were used
- Upped to 1.0.0
Removed older history entries
Help us keep the lights on
1.0.0 - Aug 18, 2019
Swiftfire -and all its supporting packages- have been issued in their release 1.0.0
Swiftfire has gained some functionality since the previous releases, most notably the capability to serve PHP based websites and the preparation of the split in server and domain responsibilities. I.e. server admin and domain admin. This last part is visible in the partly redesigned admin interface.
In addition it is now easier to build the project as all the necessary sources are located on github, including the compiled version of OpenSSL.
While this is very convenient to gain some quick appreciation of Swiftfire, it should be warned against using any precompiled OpenSSL binary. When you go operational using Swiftfire, you should compile your own version of OpenSSL from the original sources (be aware that some glue code is necessary)
0.11.1 - Apr 10, 2018
The app compiles and runs again, but has not been tested. Also note that the feature set is changing. The last stable release is 0.10.11
0.11.0 - Apr 9, 2018
This release is for internal purposes only, do not use this code base, use release 0.10.11 or wait until the next release.
0.10.11 - Jul 3, 2017
Fixed a bug on processing a URL with a '&' in it (caused a 'hanger') Fixed missing header logging
Upgraded (rename) SwifterJSON to VJson
0.10.10 - Jun 8, 2017
In this release the serveradmin interface was improved on the code generation side of things. A.o. an HTML subproject was introduced to do the HTML code generation.
As of this release, Swiftfire now supports very large HTTP request bodies. Previously this was limited to about 32KB, now the size is nearly unlimited. A new service was introduced to enforce completeness of HTTP requests for the traditional 'static websites'. If websites want to make use of very large HTTP bodies, they will need to implement a service specifically for that purpose.