General points

  • Swiftfire is a GUI-less server application for OS-X that can service HTTP(S) v1.0 and v1.1 requests.

  • Swiftfire can handle the following server side technologies:
    • HTML/CSS (static)
    • HTML/CSS + Swiftfire (pseudo-static)
    • HTML/CSS + PHP (dynamic)
    • HTML/CSS + PHP + Swiftfire (dynamic).
  • Once compiled, it does not need any additional tools or services. It is fully self-contained, only when PHP is required must a PHP interpreter be present.

  • Swiftfire can be monitored and controlled via an administration account which is created during initial setup.

  • Currently Swiftfire can only be installed by downloading the sourcecode and compiling it. OpenSSL should also be downloaded and compiled. It is possible to use the openSSL binaries included in the Swiftfire git repository. However you owe it to your visitors to install openSSL directly from the source. Note that the directions included in SecureSockets for OpenSSL must be followed, a standard install of openSSL cannot be used.

  • At a minimum the user must configure the service port number and 1 domain. This is described in Quick Setup

Starting with Swiftfire development

There are three hooks into Swiftfire that are of interest when starting out:

  • Custom.swift
    • Contains the “customSetup” that is called by Swiftfire after the Swiftfire setup is complete, but before the servers (HTTP and HTTPS) are started.
  • Service.Registration.swift
  • Function.Registration.swift

Specific notes

Logging

Logging has 8 levels in Swiftfire:

DEBUG     = 0
INFO      = 1
NOTICE    = 2
WARNING   = 3
ERROR     = 4
CRITICAL  = 5
ALERT     = 6
EMERGENCY = 7
NONE      = 8

When configuring loglevels an integer is used. The value 8 means that no logging is done, a value of 0 means that all possible logging is done. Logging levels DEBUG and INFO are intended for use during debugging only.

Accepting HTTP(S) requests

Swiftfire uses a connection-object pool to handle incoming requests. When all connection objects are in-use new connection requests will have to wait. There is parameter that controls how many connection-objects are created. Another parameter controls how many connection requests will be kept waiting. When all connection objects are in use and the number of waiting requests is reached, new requests will be rejected immediately.

Client requests are handled in a couple of ways:

  1. They are accepted and complete nominally. The user notices nothing.
  2. They have to wait, but are accepted before the time-out and terminate nominally. The user experiences a delay.
  3. They have to wait and are not accepted before the time-out expires. These requests are rejected after the time-out. The user experiences a “server busy” after a delay.
  4. They are rejected immediately. The user immediately experiences a “server busy”.

No 1 should be normal case, no 2 is acceptable if it does not happen too often. No 3 & 4 should be avoided except for rare circumstances.

The number of connection objects is equal to the number of parallel client requests that can be handled. The more parallel client requests are handled, the more sluggishness the end user experiences. Hence there is a trade-off point where adding more connection-objects no longer improves user experience. Unfortunately there is no easy way to calculate this number. It depends on the system (hardware) the type of website, as well as the way the typical user chooses to interact with the site.

The only way to achieve the “correct” number of objects is to keep track of end-user complaints concerning the system performance and to balance “sluggish” complaints with “server busy message” complaints such that the minimum number of complaints is received.

A very simple, completely static, website running on a system with an SSD drive should be able to handle roughly as many requests per second as there are connection objects (if the keep-alive-inactivity is set to 1 second)

Performance

A difficult subject. Running on a mac mini with SSD (Late 2014, MacOS 10.12.5, 2.8 GHz i5), we often see round trip times of about 2 mS per request for static pages (i.e. no functions) with full logging enabled (which is quite a lot). This includes blacklisting and session (cookie based) processing.

Returning the server admin ‘Domains - edit’ page -which is completely created by Swift code- takes 8mS.

Obviously the more functions a page contains, the more the raw processing power of the server will drive the performance.