VSGI is a middleware that interfaces different Web server technologies under a common and simple set of abstractions.
As of Valum 0.4, VSGI is distributed in its own repository and can be used as-is. Efforts are put toward making it portable (i.e. work on Windows) and more efficient.
.. toctree:: authentication connection request response cookies converters server/index
VSGI produces process-based applications that are able to communicate with various HTTP servers using standardized protocols.
The entry point of any VSGI application implement the :valadoc:`vsgi-0.3/VSGI.Handler` abstract class. It provides a function of two arguments: a :doc:`request` and a :doc:`response` that return a boolean indicating if the request has been or will be processed. It may also raise an error.
using VSGI; public class App : Handler { public override bool handle (Request req, Response res) throws Error { // process the request and produce the response... return true; } } Server.new ("http", handler: new App ()).run ();
If a handler indicate that the request has not been processed, it's up to the server implementation to decide what will happen.
.. versionadded:: 0.4
To go asynchronous, one can override the :valadoc:`vsgi-0.3/VSGI.Handler.handle_async` symbol instead.
using VSGI; public class App : Handler { public override async bool handle_async (Request req, Response res) throws Error { // process the request and produce the response... return true; } } Server.new ("http", handler: new App ()).run ();
From now on, examples will consist of :valadoc:`vsgi-0.3/VSGI.Handler.handle` content to remain more concise.
.. versionadded:: 0.3
At any moment, an error can be raised and handled by the server implementation which will in turn teardown the connection appropriately.
throw new IOError.FAILED ("some I/O failed");
.. versionadded:: 0.3
It could be handy to dynamically load handlers the same way :doc:`server/index` are.
Fortunately, this can be performed with the HandlerModule
by providing
a directory and name for the shared library containing a dynamically loadable
application.
var module = var new HandlerModule ("<directory>", "<name>"); Server.new ("http", handler: Object.new (module.handler_type)).run ();
The only required definition is a handler_init
symbol that return the type
of some Handler
. In this case, the library should be located in <directory>/lib<name>.so
,
although the actual name is system-dependant.
[ModuleInit] public Type handler_init (TypeModule type_module) { return typeof (App); } public class App : Handler { public bool handle (Request req, Response res) { return res.expand_utf8 ("Hello world!"); } }
.. versionadded:: 0.4
VSGI provide the vsgi-loader
utility designed to serve handlers written as
:valadoc:`gmodule-2.0/GLib.Module` from any supported implementation, no
recompilation needed.
Furthermore, it also provide a live-reloader based on :valadoc:`gio-2.0/GLib.FileMonitor` to remove the necessity of restarting the server if the application code changes.
The vsgi-loader
program can be used as follow:
vsgi-loader [--directory=<directory>] [--server=<server>] [--live-reload] <module_name> -- <server_arguments>
- the
directory
where the shared library is located or default system path - the
server
implementation which is eitherhttp
,fastcgi
orscgi
and defaults tohttp
- if
--live-reload
is set, the server will automatically reload the shared library on change - the name of the library without the
lib
prefix and.so
extension - arguments for the server implementation specified by the
--server
flag and delimited by--
Warning
Arguments for the server implementation must be separated by a --
indicator, otherwise they will be interpreted by vsgi-loader
.
vsgi-loader --directory=build/examples/loader loader -- --port=3005
Additional arguments are described in vsgi-loader --help
.
vsgi-loader --help
For details about server-specific options, the --help
flag can be passed
beyond.
vsgi-loader --server=fastcgi app -- --help
To perform initialization, one can implement the :valadoc:`gio-2.0/GLib.Initable` interface, it will automatically be called by the loader.
[ModuleInit] public Type handler_init (TypeModule type_module) { return typeof (App); } public class App : Handler, Initable { public Gda.Connection database { get; construct; } public bool init (Cancellable? cancellable = null) throws Error { database.open (); } public bool handle (Request req, Response res) { return res.expand_utf8 ("Hello world!"); } }