AISL Handbook
This document describes main concepts and API of AISL library v.1.0.x.
Last update: 2019-06-16
Table of Contents
- AISL Overview
- Features
- Installation
- Getting started — Hello World
- Getting advanced
- API Reference
- Class AislInstance
- Methods:
- Class AislServer
- Class AislClient
- Class AislStream
- Properties access methods:
- Response methods:
- Enumeration AislStatus
- Functions:
- Enumeration AislEvent — AISL event model
- Values:
- Callback:
- AislCallback — AISL event callback prototype
- Payloads:
- struct aisl_evt — Common event payload
- struct aisl_evt_open — Event specific payload
- struct aisl_evt_header — Event specific payload
- struct aisl_evt_input — Event specific payload
- Functions:
- Enumeration AislHttpVersion
- Functions:
- Enumeration AislHttpMethod
- Functions:
- Enumeration AislHttpResponse
- Functions:
- Configuration Structures
- struct aisl_cfg — Engine configuration
- struct aisl_cfg_ssl — SSL configuration
- struct aisl_cfg_srv — HTTP Server configuration
- Class AislInstance
AISL Overview
If you are reading this, either you are somehow already familiar with web applications and web servers and you probably used to count them as an independent entities. Indeed, most of the existing web technologies are based on standalone web server and HTTP parser that together provide some programming interface to work with cached in memory and on a hard disk HTTP request. It is not that efficient and sometimes even vulnerable in sence of DDoS attacks.
AISL works differently. Using AISL you can create web application that is a web server. It means that developer can keep under control all the workflow of an HTTP stream, by appropriate reactoin on triggered by AISL programmable events, which is a great performance and security advantage. For example, application may want to already start some routines to prepare response, when just first line of the HTTP request like GET /index.html HTTP/1.1 was received. Or it may also want to ignore some of the HTTP headers or even full body content to preserve resources and CPU time, if they are unnecessary or even unwelcome.
Features
- Asynchronous event-based engine
- Lightweight solution: size of the shared C library is just about 38 Kbytes.
- HTTP 1.x support (support of HTTP 2.0 is planned).
- HTTPS support (using openssl).
- Free software with open source code.
- CC BY-ND 4.0 License.
Installation
One can get AISL sources from GitHub at any time. Master branch is always stable. To get the Library follow these steps:
- Clone GIT repositroy
$ git clone https://github.com/lowenware/aisl.git
- Navigate to cloned folder
$ cd aisl
- Compile the library
$ make PREFIX=/usr/local LIB_DIR=lib
SetPREFIX
to preffered installation path andLIB_DIR
to your system related name of library directory (lib, lib32 or lib64). - Install the library
$ sudo make install
- Optionaly advanced users may want to build library with one or more
options:
AISL_WITH_SSL=0
- disable HTTPS support,AISL_WITH_STRINGIFIERS=0
- disable several optional *_to_string functions to preserve library sizea,AISL_WITH_DEBUG=1
- enable library debug output. - You may also want to edit (if you have changed
PREFIX
orLIB_DIR
) and copy libaisl.pc.example file to /usr/lib/pkgconfig, so pkgconfig could be used to simplify future linking.
Getting started - Hello World
If you have AISL installed, it is time to try it out with simple `Hello World!` application. Full source code could be found on a GitHub and the most important steps are highlighted bellow.
Include AISL meta-header file to add necessary declarations to you code file. You should never include other AISL header files in to your projects.
#include
In this example we create one HTTP server without encryption, that will listen to port 8080 on all available network interfaces.
struct aisl_cfg_srv[] srv = {{
.host = "0.0.0.0",
.port = 8080,
.secure = false
}};
To initialize configuration structure we use default values.
struct aisl_cfg cfg = AISL_CFG_DEFAULT;
An address of the defined servers configuration and their number must be also stored in the structure.
cfg.srv = srv;
cfg.srv_cnt = sizeof (srv) / sizeof (srv[0]);
Event handler is a core function of the web application. It should match AislCallback prototype and its address also must be stored in the configuration structure before library initialization.
cfg.callback = hello_world;
When configuration is ready, it is time to allocate and initialize our AislInstance and start application loop.
AislInstance aisl;
AislStatus status;
...
if ( (aisl = aisl_new(&cfg)) != NULL ) {
/* launch application loop */
fprintf(stdout, "Entering main loop\n" );
for(;;) {
status = aisl_run_cycle(aisl);
if ( status != AISL_SUCCESS )
aisl_sleep(aisl, 500);
}
aisl_free(aisl);
} else {
fprintf(stderr, "Failed to initialize AISL\n");
}
Function aisl_run_cycle being called within a loop does all the core routines of our HTTP server and triggers event callback defined in configuration structure. To avoid unnecessary CPU loading we also execute aisl_sleep on idle cycles. To release allocated by AISL resources on a runtime we are using aisl_sleep.
And finally it is time to define the event handler matching AislCallback prototype.
static void
hello_world(const struct aisl_evt *evt, void *p_ctx)
{
AislStream s;
const char html[] =
"<html>"
"<head>"
"<title>Hello World</title>"
"</head>"
"<body>"
"<h1>Hello World</h1>"
"<p>Powered by AISL</p>"
"</body>"
"</html>";
if (evt->code != AISL_EVENT_STREAM_REQUEST)
return;
s = evt->source;
if (aisl_response(s, AISL_HTTP_OK, sizeof (html)-1) == AISL_SUCCESS) {
if (aisl_write(s, html, sizeof (html)-1) != -1) {
aisl_flush(s);
return;
}
}
aisl_reject(s);
(void) p_ctx;
}
The function is being called by AISL engine on every event, but proceeds
only if AISL_EVENT_STREAM_REQUEST
is received. It starts an HTML response stored in html
constant. Make sure you use sizeof (htmk)-1
for
content length, to avoid unwanted write of last NULL terminating character
of html
string constant.
To compile the example using GCC and pkgconfig run:
$ gcc `pkgconf --libs --cflags libaisl` hello-world.c -o hello-world
Or specify paths to installed header files and library manualy:
$ -I/usr/local/include -L/usr/local/lib -laisl hello-world.c -o hello-world
Now execute compiled hello_world binary and open http://localhost:8080 in
your browser. If you get any symbol lookup error
on execution attempt,
try to specify the path to the library in the environment variable:
$ LD_LIBRARY_PATH="/usr/local/lib" ./hello-world
The result should look like this:
Getting advanced
Right after this chapter you will find full AISL API Reference that guides through all the types and functions. The most significant of them you may already know from the Hello World example. To become an advanced AISL developer, you will need to understand events model and stream concept. The rest of library components carry more auxiliary function.
API Reference
AISL library API has object oriented model. Although C has no objects, it still allows to use transparent data structures to represent classes and functions as methods.
Each AISL component has a library specific prefix:
- Aisl* - for data types (typedefs)
- aisl_* - for functions and structures names
- AISL_* - for constants and macro definitions
Functions, related to some data type (methods), include name of the type in
their names, i.e. AislServer - aisl_server_get_address()
.
There are two exceptions from this rule though introduced for simplicity and
shorter names for the functions being used most often: AislInstance
and AislStream.
Class AislInstance
This class represents library engine, that could be dynamically allocated in memory. It means that you can have several library instances in one application, though you may never meet a real use case for this.
Every instance may handle several independent HTTP servers running on different network sockets and manages SSL certificates and communication with clients.
Each instance must be configured with proper parameters stored in aisl_cfg data structure with at least one HTTP server and event handler matching AislCallback prototype.
Methods
aisl_new
AislInstance
aisl_new(const struct aisl_cfg *cfg);
DESCRIPTION
A constructor of AislInstance class.
PARAMETERS
- cfg — a pointer to an aisl_cfg configuration structure
RETURN VALUE
Pointer to an AislInstance or NULL if out of memory.
aisl_free
void
aisl_free(AislInstance instance);
DESCRIPTION
Frees previously allocated pointer of AISL instance.
PARAMETERS
- instance — a pointer to an AislInstance.
RETURN VALUE
Returns no value.
aisl_run_cycle
AislStatus
aisl_run_cycle(AislInstance instance);
DESCRIPTION
PARAMETERS
- instance — a pointer to an AislInstance.
RETURN VALUE
- AISL_SUCCESS — if some event was triggered
- AISL_IDLE — if no event was triggered
- AISL_MALLOC_ERROR — if system run out of memory
- AISL_SYSCALL_ERROR — if some system call failed
Return value handling should be soft. It is completely safe to continue program execution even if error value was returned.
To preserve CPU time it is recommended to add a delay between aisl_run_cycle calls, at least if anything but AISL_SUCCESS has been returned. You may want to use aisl_sleep for this.
aisl_sleep
DESCRIPTION
PARAMETERS
RETURN VALUE
Class AislServer
Class AislClient
Class AislStream
Enumeration AislStatus
Enumeration AislEvent
Enumeration AislHttpVersion
Enumeration AislHttpMethod
Enumeration AislHttpResponse
Data Structures
struct aisl_cfg
struct aisl_cfg_ssl
struct aisl_cfg_srv
struct aisl_evt
struct aisl_evt_open
struct aisl_evt_header
struct aisl_evt_input
Events
AISL_EVENT_SERVER_READY
AISL_EVENT_SERVER_ERROR
AISL_EVENT_CLIENT_CONNECT
AISL_EVENT_CLIENT_DISCONNECT
AISL_EVENT_STREAM_OPEN
AISL_EVENT_STREAM_HEADER
AISL_EVENT_STREAM_INPUT
AISL_EVENT_STREAM_REQUEST
AISL_EVENT_STREAM_OUTPUT
AISL_EVENT_STREAM_CLOSE
AISL_EVENT_STREAM_ERROR
Functions
aisl_get_server
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_get_client
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_stream_get_instance
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_is_secure
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_get_http_version
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_set_context
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_get_context
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_set_output_event
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_get_output_event
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_response
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_header
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_header_printf
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_header_vprintf
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_printf
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_vprintf
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_write
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_puts
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_flush
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_reject
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_server_get_instance
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_server_get_address
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_server_get_ssl
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_client_get_server
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_client_get_address
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_client_get_http_version
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_client_disconnect
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_client_is_secure
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_client_is_online
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_status_to_string
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_event_to_string
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_http_version_to_string
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_http_method_to_string
DESCRIPTION
PARAMETERS
RETURN VALUE
aisl_http_response_to_string
DESCRIPTION
PARAMETERS
RETURN VALUE