Server provide HTTP technologies integrations under a common interface.

Server implementations are dynamically loaded using gmodule-2.0/GLib.Module. It makes it possible to define its own implementation if necessary.

To load an implementation, use the factory, which can receive GObject-style arguments as well.

var cgi_server = ("cgi");

if (cgi_server == null) {
    assert_not_reached ();

cgi_server.set_application_callback ((req, res) => {
    return res.expand_utf8 ("Hello world!");

Custom implementation

For more flexibility, the ServerModule class allow a more fine-grained control for loading a server implementation. If non-null, the directory property will be used to retrieve the implementation from the given path instead of standard locations.

The computed path of the shared library is available from path property, which can be used for debugging purposes.

The shared library name must conform to vsgi-<name> with the appropriate prefix and extension. For instance, on GNU/Linux, the CGI module is stored in ${prefix}/${libdir}/vsgi-0.3/servers/

var directory  = "/usr/lib64/vsgi-0.3/servers";
var cgi_module = new ServerModule (directory, "cgi");

if (!cgi_module.load ()) {
    error ("could not load 'cgi' from '%s'", cgi_module.path);

var server = (cgi_module.server_type);

Unloading a module is not necessary: once initially loaded, a use count is kept so that it can be loaded on need or unloaded if not used.


Since a ServerModule cannot be disposed (see gobject-2.0/GLib.TypeModule), one must be careful of how its reference is being handled. For instance, keeps track of requested implementations and persist them forever.

Mixing direct usages of ServerModule and Server.@new (and the likes) is not recommended and will result in undefined behaviours if an implementation is loaded more than once.


Each server implementation expose its own set of parameters via GObject properties which are passed using the provided static constructors:

var https_server = ("http", https: true);

More details on available parameters are presented in implementation-specific documents.


Once initialized, a server can be made ready to listen with listen and listen_socket. Implementations typically support listening from an arbitrary number of interfaces.

If the provided parameters are not supported, a gio-2.0/GLib.IOError.NOT_SUPPORTED will be raised.

The listen call is designed to make the server listen on a gio-2.0/GLib.SocketAddress such as gio-2.0/GLib.InetSocketAddress and gio-2.0/GLib.UnixSocketAddress.

server.listen (new InetSocketAddress (new InetAddress.loopback (SocketFamily.IPV4), 3003));

It’s also possible to pass null such that the default interface for the implementation will be used.

server.listen (); // default is 'null'

The listen_socket call make the server listen on an existing socket or file descriptor if passed through GLib.Socket.from_fd.

server.listen_socket (new Socket.from_fd (0));


Once ready, either call or launch a glib-2.0/GLib.MainLoop to start serving incoming requests:

using GLib;
using VSGI;

var server = ("http");

server.listen (new InetSocketAddress (new InetAddress (SocketFamily.IPV4), 3003));

new MainLoop ().run (); // or ();


To achieve optimal performances on a multi-core architecture, VSGI support forking at the server level.


Keep in mind that the fork system call will actually copy the whole process: no resources (e.g. lock, memory) can be shared unless inter-process communication is used.

The Server.fork call is used for that purpose:

using GLib;
using VSGI;

var server = ("http");

server.listen (new InetSocketAddress (new InetAddress.loopback (SocketFamily.IPV4), 3003));

server.fork ();

new MainLoop ().run ();

It is recommended to fork only through that call since implementations such as CGI are not guaranteed to support it and will gently fallback on doing nothing.


The VSGI.Application class provide a nice cushion around Server that deals with pretty logging and CLI argument parsing. The function is a shorthand to create and run an application.

using VSGI;

public int main (string[] args) {
    var server = ("http");
    return new Application (server).run (args);


The following options are made available:

Option Default Description
--forks none number of forks to create
--log-writer none log writer to use
--address none listen on each addresses
--port none listen on each ports, ‘0’ for random
--socket none listen on each UNIX socket paths
--any disabled listen on any address instead of only from the loopback interface
--ipv4-only disabled listen only to IPv4 interfaces
--ipv6-only disabled listen only on IPv6 interfaces
--file-descriptor none listen on each file descriptors

The --log-writer flag allow one to chose among various log writer implementations:

  • standard-streams
  • journald
  • default

If no choice is made, no specific log writer is attached.

If none of --address, --port, --socket nor --file-descriptor flags are provided, it will fallback on the default listening interface for the implementation.

The --address flag uses gio-2.0/GLib.NetworkAddress.parse under the hood, which properly interpret IPv4 and IPv6 addresses. It will also resolve domains and parse ports. If no port is provided, a random one will be used.

The default when --port is provided is to listen on both IPv4 and IPv6 interfaces, or just IPv4 if IPv6 is not supported.

Use the --help flag to obtain more information about available options.