Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/disconnect/apache-websocket

Apache WebSocket module
https://github.com/disconnect/apache-websocket

Last synced: 16 days ago
JSON representation

Apache WebSocket module

Awesome Lists containing this project

README

        

# apache-websocket

The apache-websocket module is an Apache 2.x server module that may be used to
process requests using the WebSocket protocol (RFC 6455) by an Apache 2.x
server. The module consists of a plugin architecture for handling WebSocket
messaging. Doing so does _not_ require any knowledge of internal Apache
structures.

This implementation supports protocol versions 7, 8, and 13, along with the
older draft-76 of the WebSocket protocol. Support for draft-75 is disabled by
default, but it may be enabled through the draft-76 module configuration.

Due to the extensive differences between the newer drafts and draft-76
implementations, and because of the Apache module architecture, two separate
modules are used to support the different protocols.

Although draft-76 is technically obsolete, it is the protocol version that is
currently implemented by most of the web browsers. When all of the browsers
finally move to support the latest protocol, simply remove the draft-76 module
and configuration to drop support.

## Download

$ git clone git://github.com/disconnect/apache-websocket.git

## Building and Installation

SCons may be used to build the module.

$ scons
$ sudo scons install

For Windows, do not include the word `sudo` when installing the module. Also,
the `SConstruct` file is hard-coded to look for the Apache headers and
libraries in `C:\Program Files\Apache Software Foundation\Apache2.2`. You
will need to install the headers and libraries when installing Apache. The
`Build Headers and Libraries` option is disabled by default, so you will have
to perform a `Custom` installation of Apache. Refer to the Apache document
entitled _Using Apache HTTP Server on Microsoft Windows_ for more information.

Alternatively, you may use `apxs` to build and install the module. Under Linux
(at least under Ubuntu), use:

$ sudo apxs2 -i -a -c mod_websocket.c
$ sudo apxs2 -i -a -c mod_websocket_draft76.c

You probably only want to use the `-a` option the first time you issue the
command, as it may overwrite your configuration each time you execute it (see
below).

You may use `apxs` under Mac OS X if you do not want to use SCons. In that
case, use:

$ sudo apxs -i -a -c mod_websocket.c
$ sudo apxs -i -a -c mod_websocket_draft76.c

## Plugins

While the module is used to handle the WebSocket protocol, plugins are used to
implement the application-specific handling of WebSocket messages.

A plugin need only have one function exported that returns a pointer to an
initialized `WebSocketPlugin` structure. The `WebSocketPlugin` structure
consists of the structure size, structure version, and several function
pointers. The size should be set to the `sizeof` the `WebSocketPlugin`
structure, the version should be set to 0, and the function pointers should be
set to point to the various functions that will service the requests. The only
required function is the `on_message` function for handling incoming messages.

See `examples/mod_websocket_echo.c` for a simple example implementation of an
"echo" plugin. A sample `client.html` is included as well. If you try it and
you get a message that says Connection Closed, you are likely using a client
that does not support these versions of the protocol.

A more extensive example may be found in
`examples/mod_websocket_dumb_increment.c`. That plugin implements the
dumb-increment-protocol (see libwebsockets by Andy Green for more information
on the protocol). There is a test client for testing the module in
`increment.html`. It uses the WebSocket client API which supports passing
supported protocols in the WebSocket constructor. If your browser does not
support this, either upgrade your browser or modify the plugin so that it
doesn't verify the protocol.

If you provide an `on_connect` function, return a non-null value to accept the
connection, and null if you wish to decline the connection. The return value
will be passed to your other methods for that connection. During your
`on_connect` function, you may access the Apache `request_rec` structure if you
wish. You will have to include the appropriate Apache include files. If you do
not wish to do that, you may also access the headers (both input and output)
using the provided functions. There are also protocol-specific handling
functions for selecting the desired protocol for the WebSocket session. You may
only safely access the `send` or `close` functions in your `on_connect`
function from a separate thread, as the connection will not be completed until
you return from the function.

You may use `apxs`, SCons, or some other build system to be build and install
the plugins. Also, it does not need to be placed in the same directory as the
WebSocket module.

## Configuration

The `http.conf` file is used to configure WebSocket plugins to handle requests
for particular locations. Inside each `Location` block, set the handler, using
the `SetHandler` keyword, to `websocket-handler`. Next, add a
`WebSocketHandler` entry that contains two parameters. The first is the name of
the dynamic plugin library that will service the requests for the specified
location, and the second is the name of the function in the dynamic library
that will initialize the plugin. For the draft-76 implementation only, you may
optionally include a flag for supporting the draft-75 version of the WebSocket
protocol (it will default to "off" if you do not include it). It is enabled
using the `SupportDraft75` keyword, along with a value of `On`.

Here is an example of the configuration changes to `http.conf` that are used to
handle the WebSocket plugin requests directed at `/echo` under Mac OS X. The
server will initialize the module by calling the `echo_init` function in
`mod_websocket_echo.so`:

LoadModule websocket_module libexec/apache2/mod_websocket.so
LoadModule websocket_draft76_module libexec/apache2/mod_websocket_draft76.so



SetHandler websocket-handler
WebSocketHandler libexec/apache2/mod_websocket_echo.so echo_init


SetHandler websocket-handler
WebSocketHandler libexec/apache2/mod_websocket_dumb_increment.so dumb_increment_init



SetHandler websocket-handler
WebSocketHandler libexec/apache2/mod_websocket_echo.so echo_init
SupportDraft75 On


SetHandler websocket-handler
WebSocketHandler libexec/apache2/mod_websocket_dumb_increment.so dumb_increment_init
SupportDraft75 On

If your settings are the same between the two modules, you may try to remove
the `` section of the configuration (you will
still need the `LoadModule` line if you want to support draft-76).

Since we are dealing with messages, not streams, we need to specify a maximum
message size. The default size is 32 megabytes. You may override this value by
specifying a `MaxMessageSize` configuration setting. This option is not
available for the draft-76 implementation. Here is an example of how to set
the maximum message size is set to 64 megabytes:



SetHandler websocket-handler
WebSocketHandler /usr/lib/apache2/modules/mod_websocket_echo.so echo_init
MaxMessageSize 67108864

Under Linux, the module-specific configuration may be contained in a single
file called `/etc/apache2/mods-available/websocket.load` (your version of Linux
may vary). If you did not use `apxs2` with the `-a` option to initially
create the module, you will have to make a link between
`/etc/apache2/mods-enabled/websocket.load` and
`/etc/apache2/mods-available/websocket.load`. Take a look at the already enabled
modules to see how it should look. Since the directory containing the module is
different from Mac OS X, the configuration will look more like this:

LoadModule websocket_module /usr/lib/apache2/modules/mod_websocket.so
LoadModule websocket_draft76_module /usr/lib/apache2/modules/mod_websocket_draft76.so



SetHandler websocket-handler
WebSocketHandler /usr/lib/apache2/modules/mod_websocket_echo.so echo_init



SetHandler websocket-handler
WebSocketHandler /usr/lib/apache2/modules/mod_websocket_echo.so echo_init
SupportDraft75 On

This is the configuration that may be overwritten when the `-a` option is
included using `axps2`, so be careful.

Under Windows, the initialization function is of the form `_echo_init@0`, as it
is using the `__stdcall` calling convention:

LoadModule websocket_module modules/mod_websocket.so
LoadModule websocket_draft76_module modules/mod_websocket_draft76.so



SetHandler websocket-handler
WebSocketHandler modules/mod_websocket_echo.so _echo_init@0



SetHandler websocket-handler
WebSocketHandler modules/mod_websocket_echo.so _echo_init@0
SupportDraft75 On

For all architectures, to drop draft-76 support, remove the loading of the
draft-76 module along with the module configuration block. Here is how the
example configuration could look under Mac OS X after removing the the
`websocket_draft76_module` references:

LoadModule websocket_module libexec/apache2/mod_websocket.so



SetHandler websocket-handler
WebSocketHandler libexec/apache2/mod_websocket_echo.so echo_init

## Authors

* The original code was written by `self.disconnect`.

## License

Please see the file called LICENSE.