Permalink
Fetching contributors…
Cannot retrieve contributors at this time
145 lines (117 sloc) 5.97 KB

mod_swift

Apache 2 Swift3 macOS Travis

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.

How to use the module in Apache

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

What is an Apache module?

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.

Notes of interest

  • 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 #defines, e.g. ap_fwrite

  • The Apache C headers are prone to crash swiftc. Which is why we wrap the Apache request_rec in an additional struct.

            (__)
          /  .\/.     ______
         |  /\_|     |      \
         |  |___     |       |
         |   ---@    |_______|
      *  |  |   ----   |    |
       \ |  |_____
        \|________|
    

    CompuCow Discovers Bug in Compiler

Oh, ages ago I did mod_objc for Apache 1.3.

Status

This is a demo. Do not use it for realz. At least not w/o our help ;->

Who

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.