mod_swift is a technology demo which shows how to write native modules for the Apache Web Server in the Swift 3 programming language. Server Side Swift the right way.
This project/sourcedir contains the actual C-language mod_swift
.
It is a straight Apache module which is then used to load Swift based Apache
modules (mods_xyz).
Also included are Xcode base configurations, module maps for Apache and APR
as well as a few API wrappers that are used to workaround swiftc
crashers
and Swift-C binding limitations.
Before you can load a Swift Apache module, you need to load mod_swift into Apache:
LoadModule swift_module .libs/mod_swift.so
This exposes a new Apache directive called LoadSwiftModule
which is used to
load Swift based Apache modules into the server. Example:
LoadSwiftModule ApacheMain .libs/mods_demo.so
Well, Apache is a highly modular and efficient server framework. The httpd daemon itself is quite tiny and pretty much all webserver functionality is actually implemented in the form of modules. Be it thread handling, access control, mime detection or content negotation - all of that is implemented as modules. And can be replaced by own modules!
The Apache core modules are written in portable C. Some modules are built right into the server, but most are loaded as dynamic libraries. Which ones is specified by the user in the configuration file, e.g.:
LoadModule authz_core_module /usr/libexec/apache2/mod_authz_core.so
LoadModule mime_module /usr/libexec/apache2/mod_mime.so
Now with mod_swift you can write such modules using the Swift programming language. Enter:
LoadSwiftModule ApacheMain /usr/libexec/apache2/mods_demo.so
This is a little different to something like mod_php
which enables Apache
to directly interpret PHP scripts. mod_php
itself is C software and a single
module.
Since Swift compiles down to regular executable binaries,
and because Swift has excellent
C integration,
you can write arbitrary modules with mod_swift which behave just like the
regular C modules.
-
The code is properly formatted, max width 80 chars, 2-space indent.
-
This doesn't use
apxs
because that is badly b0rked on both 10.11 and 10.12. -
It uses a lot of hardcoded load and lookup pathes, remember, it is a demo!
-
It has some leaks and issues, e.g. modules are not properly unloaded.
-
Sure, you can link against arbitrary Swift dylibs, mustache is an example for exactly that.
-
However, you currently cannot use the Swift Package Manager to create dylibs (AFAIK). So while in theory that would work, you need to do the final linking step separately.
-
Yes
mod_swift
itself could be avoided by including the .c in the Swift module. Yes, you can even statically link Swift including its runtime. Let me know if this is interesting, I have a branch which does exactly that. -
There is one big bet in the code: Officially there is no way to invoke a Swift function from C, only the other way around! In other words: it is pure luck that this works and is ABI compatible with C.
-
If you would want to debug the stuff in Xcode -
/usr/sbin/httpd
is under macOS SIP. -
On macOS 10.11 starting Apache with -X crashes a few seconds after the last request was received. Maybe just SIGPIPE or sth. 10.12 looks fine.
-
Unloading is an issue. I think the Apple and GNUstep Objective-C runtimes cannot be properly unloaded (I've heard there is a great runtime that can). No idea what the situation with 'pure Swift' is.
-
Would be cool if Swift 4 would get a proper
extern C {}
. -
Yes, Apache content handlers are not Noze.io like asynchronous but run in a traditional, synchronous thread-setup.
-
Apache varargs funcs are not available since Swift doesn't support such. We provide a wrapper for
ap_log_rerror_
, other funcs would need to be wrapped the same way. -
Apache also uses quite a few
#define
s, e.g.ap_fwrite
-
The Apache C headers are prone to crash
swiftc
. Which is why we wrap the Apacherequest_rec
in an additional struct.(__) / .\/. ______ | /\_| | \ | |___ | | | ---@ |_______| * | | ---- | | \ | |_____ \|________|
Oh, ages ago I did mod_objc for Apache 1.3.
This is a demo. Do not use it for realz. At least not w/o our help ;->
mod_swift is brought to you by The Always Right Institute and ZeeZide. We like feedback, GitHub stars, cool contract work, presumably any form of praise you can think of. We don't like people who are wrong.
There is a #mod_swift
channel on the Noze.io Slack.