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:
+
-
+
- aisl_new +
- aisl_free +
- aisl_run_cycle +
- aisl_sleep +
+
+ - Methods:
+
- Class AislServer
+
-
+
- Methods: + + +
+ - Class AislClient
+
-
+
- Methods: + + +
+ - Class AislStream
+
-
+
- Properties access methods: + + +
- Response methods:
+
-
+
- aisl_response +
- aisl_header +
- aisl_header_printf +
- aisl_header_vprintf +
- aisl_printf +
- aisl_vprintf +
- aisl_write +
- aisl_puts +
- aisl_flush +
- aisl_reject +
+
+ - 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
+ + +