website/aisl/handbook.html

1539 lines
67 KiB
HTML

<!DOCTYPE html>
<html lang="en" data-view="home" class="no-js">
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="google" content="notranslate" />
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="Löwenware s.r.o">
<title>AISL Handbook</title>
<link href="/static/style.css" rel="stylesheet" />
<script type="text/javascript">document.documentElement.className='';</script>
</head>
<body>
<div class="main-wrapper">
<div class="overlay">
<svg class="logo"><use xlink:href="/static/sprite.svg#logo"/></svg>
<a href="javascript:;" id="menu__switch" class="menu__switch" title="Switch menu">
<svg class="icon svg-menu-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<g class="svg-menu-group">
<path class="svg-menu-lines" d="m0 4v2h24v-2zm0 7v2h24v-2zm0 7v2h24v-2z"/>
<path class="svg-menu-cross" d="m4.22 2.81-1.42 1.42 7.78 7.78-7.78 7.78 1.42 1.42 7.78-7.78 7.78 7.78 1.42-1.42-7.78-7.78 7.78-7.78-1.42-1.42-7.78 7.78z">
</g>
</svg>
</a>
<div class="logo__text">Löwenware</div>
</div>
<nav id="menu" class="menu">
<ul class="menu__list">
<li><a href="/">Home</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/aisl/" class="active">AISL</a></li>
<li><a href="/dotrix/">Dotrix</a></li>
<li><a href="/blog/">Blog</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
<main class="content text-content">
<h1>AISL Handbook</h1>
<p>This document describes main concepts and API of AISL library
v.1.0.x.</p>
<p>Last update: 2019-06-18</p>
<h2>Table of Contents</h2>
<ul class="table-of-contents">
<li><a href="#overview">AISL Overview</a>
<ul>
<li><a href="#features">Features</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#getting-started">Getting started</a> — Hello World</li>
<li><a href="#getting-advanced">Getting advanced</a></li>
</ul>
</li>
<li><a href="#api-reference">API Reference</a>
<ul>
<li>Type <a href="#AislInstance">AislInstance</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_new">aisl_new</a></li>
<li><a href="#aisl_free">aisl_free</a></li>
<li><a href="#aisl_run_cycle">aisl_run_cycle</a></li>
<li><a href="#aisl_sleep">aisl_sleep</a></li>
</ul>
</li>
</ul>
</li>
<li>Type <a href="#AislServer">AislServer</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_server_get_instance">aisl_server_get_instance</a></li>
<li><a href="#aisl_server_get_address">aisl_server_get_address</a></li>
<li><a href="#aisl_server_get_ssl">aisl_server_get_ssl</a></li>
</ul>
</li>
</ul>
</li>
<li>Type <a href="#AislClient">AislClient</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_client_get_server">aisl_client_get_server</a></li>
<li><a href="#aisl_client_get_address">aisl_client_get_address</a></li>
<li><a href="#aisl_client_get_http_version">aisl_client_get_http_version</a></li>
<li><a href="#aisl_client_disconnect">aisl_client_disconnect</a></li>
<li><a href="#aisl_client_is_secure">aisl_client_is_secure</a></li>
<li><a href="#aisl_client_is_online">aisl_client_is_online</a></li>
</ul>
</li>
</ul>
</li>
<li>Type <a href="#AislStream">AislStream</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_get_secure">aisl_is_secure</a></li>
<li><a href="#aisl_get_server">aisl_get_server</a></li>
<li><a href="#aisl_get_client">aisl_get_client</a></li>
<li><a href="#aisl_get_instance">aisl_get_instance</a></li>
<li><a href="#aisl_get_http_version">aisl_get_http_version</a></li>
<li><a href="#aisl_set_context">aisl_set_context</a></li>
<li><a href="#aisl_get_context">aisl_get_context</a></li>
<li><a href="#aisl_set_output_event">aisl_set_output_event</a></li>
<li><a href="#aisl_get_output_event">aisl_get_output_event</a></li>
</ul>
</li>
<li>Response Functions:
<ul>
<li><a href="#aisl_response">aisl_response</a></li>
<li><a href="#aisl_header">aisl_header</a></li>
<li><a href="#aisl_header_printf">aisl_header_printf</a></li>
<li><a href="#aisl_header_vprintf">aisl_header_vprintf</a></li>
<li><a href="#aisl_printf">aisl_printf</a></li>
<li><a href="#aisl_vprintf">aisl_vprintf</a></li>
<li><a href="#aisl_write">aisl_write</a></li>
<li><a href="#aisl_puts">aisl_puts</a></li>
<li><a href="#aisl_flush">aisl_flush</a></li>
<li><a href="#aisl_reject">aisl_reject</a></li>
</ul>
</li>
</ul>
</li>
<li>Enumeration <a href="#AislStatus">AislStatus</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_status_to_string">aisl_status_to_string</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#events">Events</a>
<ul>
<li>Enumeration <a href="#AislEvent">AislEvent</a>
<ul>
<li><a href="#AISL_EVENT_SERVER_READY">AISL_EVENT_SERVER_READY</a></li>
<li><a href="#AISL_EVENT_SERVER_ERROR">AISL_EVENT_SERVER_ERROR</a></li>
<li><a href="#AISL_EVENT_CLIENT_CONNECT">AISL_EVENT_CLIENT_CONNECT</a></li>
<li><a href="#AISL_EVENT_CLIENT_DISCONNECT">AISL_EVENT_CLIENT_DISCONNECT</a></li>
<li><a href="#AISL_EVENT_STREAM_OPEN">AISL_EVENT_STREAM_OPEN</a></li>
<li><a href="#AISL_EVENT_STREAM_HEADER">AISL_EVENT_STREAM_HEADER</a></li>
<li><a href="#AISL_EVENT_STREAM_INPUT">AISL_EVENT_STREAM_INPUT</a></li>
<li><a href="#AISL_EVENT_STREAM_REQUEST">AISL_EVENT_STREAM_REQUEST</a></li>
<li><a href="#AISL_EVENT_STREAM_OUTPUT">AISL_EVENT_STREAM_OUTPUT</a></li>
<li><a href="#AISL_EVENT_STREAM_CLOSE">AISL_EVENT_STREAM_CLOSE</a></li>
<li><a href="#AISL_EVENT_STREAM_ERROR">AISL_EVENT_STREAM_ERROR</a></li>
</ul>
</li>
<li>Callback:
<ul>
<li><a href="#AislCallback">AislCallback</a> — AISL event callback prototype</li>
</ul>
</li>
<li>Payloads:
<ul>
<li><a href="#aisl_evt">struct aisl_evt</a> — Common event payload</li>
<li><a href="#aisl_evt_open">struct aisl_evt_open</a> — Event specific payload</li>
<li><a href="#aisl_evt_header">struct aisl_evt_header</a> — Event specific payload</li>
<li><a href="#aisl_evt_input">struct aisl_evt_input</a> — Event specific payload</li>
</ul>
</li>
<li>Functions:
<ul>
<li><a href="#aisl_event_to_string">aisl_event_to_string</a></li>
</ul>
</li>
</ul>
</li>
<li>Enumeration <a href="#AislHttpVersion">AislHttpVersion</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_http_version_to_string">aisl_http_version_to_string</a></li>
</ul>
</li>
</ul>
</li>
<li>Enumeration <a href="#AislHttpMethod">AislHttpMethod</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_http_method_to_string">aisl_http_method_to_string</a></li>
</ul>
</li>
</ul>
</li>
<li>Enumeration <a href="#AislHttpResponse">AislHttpResponse</a>
<ul>
<li>Functions:
<ul>
<li><a href="#aisl_http_response_to_string">aisl_http_response_to_string</a></li>
</ul>
</li>
</ul>
</li>
<li>Configuration structures</li>
<ul>
<li>struct <a href="#aisl_cfg">aisl_cfg</a></li>
<li>struct <a href="#aisl_cfg_ssl">aisl_cfg_ssl</a></li>
<li>struct <a href="#aisl_cfg_srv">aisl_cfg_srv</a></li>
</ul>
</li>
<li>Preprocessor definitions</li>
<ul>
<li><a href="#aisl_cfg">struct aisl_cfg</a></li>
<li><a href="#AISL_AUTO_LENGTH">AISL_AUTO_LENGTH</a></li>
<li><a href="#AISL_CALLBACK">AISL_CALLBACK</a></li>
</ul>
</ul>
</li>
</ul>
<hr />
<h2 id="overview">AISL Overview</h2>
<p>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.</p>
<p>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
<span class="inline-code">GET /index.html HTTP/1.1</span> 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.</p>
<h3 id="features">Features</h3>
<ul>
<li>Asynchronous event-based engine</li>
<li>Lightweight solution: size of the shared C library is just about 38
Kbytes.</li>
<li>HTTP 1.x support (support of HTTP 2.0 is planned).</li>
<li>HTTPS support (using openssl).</li>
<li>Free software with open source code.</li>
<li><a href="https://creativecommons.org/licenses/by-nd/4.0/" rel="license">CC BY-ND 4.0</a> License.</p>
</ul>
<h3 id="installation">Installation</h3>
<p>One can get AISL sources from GitHub at any time. Master branch is always
stable. To get the Library follow these steps:</p>
<ol>
<li>Clone GIT repositroy<code>$ git clone https://github.com/lowenware/aisl.git</code></li>
<li>Navigate to cloned folder<code>$ cd aisl</code></li>
<li>Compile the library<code>$ make PREFIX=/usr/local LIB_DIR=lib</code>
Set <code class="inline">PREFIX</code> to preffered installation path
and <code class="inline">LIB_DIR</code> to your system related name of
library directory (lib, lib32 or lib64).</li>
<li>Install the library<code>$ sudo make install</code></li>
<li>Optionaly advanced users may want to build library with one or more
options:
<code class="inline">AISL_WITH_SSL=0</code> - disable
HTTPS support, <code class="inline">AISL_WITH_STRINGIFIERS=0</code> -
disable several optional *_to_string functions to preserve library sizea,
<code class="inline">AISL_WITH_DEBUG=1</code> - enable library debug
output.</li>
<li>You may also want to edit (if you have changed
<code class="inline">PREFIX</code> or <code class="inline">LIB_DIR</code>)
and copy <i>libaisl.pc.example</i> file to <i>/usr/lib/pkgconfig</i>, so
<i>pkgconfig</i> could be used to simplify future linking.</li>
</ol>
<h3 id="getting-started">Getting started - Hello World</h3>
<p>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
<a href="https://github.com/lowenware/aisl/blob/master/examples/hello-world.c">GitHub</a>
and the most important steps are highlighted bellow.</p>
<p>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.</p>
<code>#include &lt;aisl/aisl.h&gt;</code>
<p>In this example we create one HTTP server without encryption, that will
listen to port 8080 on all available network interfaces.</p>
<code>
<span class="keyword">static const struct</span> <a href="#aisl_cfg_srv">aisl_cfg_srv</a> m_srv[] = {{
.host = <span class="string">"0.0.0.0"</span>,
.port = <span class="string">80</span>,
.secure = <span class="keyword">false</span>
}};</code>
<p>Now we initialize configuration structure</p>
<code>
<span class="keyword">static const struct</span> <a href="#aisl_cfg">aisl_cfg</a> m_cfg = {
<a href="#AISL_CFG_DEFAULTS">AISL_CFG_DEFAULTS</a>
, .srv = m_srv
, .srv_cnt = <span class="keyword">sizeof</span> (m_srv) / <span class="keyword">sizeof</span> (m_srv[0])
, .ssl = <span class="keyword">NULL</span>
, .ssl_cnt = 0
, .callback = hello_world
, .p_ctx = <span class="keyword">NULL</span>
}; </code>
<p>Event handler callback called <code class="inline">hello_world</code> in
our example is a core function of the web application. It should match
<a href="#AislCallback">AislCallback</a> prototype.</p>
<p>The simpliest <code class="inline">main</code> function should allocate
and initialize our <a href="#AislInstance">AislInstance</a> and start
application loop.</p>
<code><span class="keyword">int</span>
main(<span class="keyword">int</span> argc, <span class="keyword">char</span> **argv)
{
<a href="#AislInstance">AislInstance</a> aisl;
<a href="#AislStatus">AislStatus</a> status;
<span class="keyword">if</span> ( (aisl = <a href="#aisl_new">aisl_new</a>(&amp;cfg)) != <span class="keyword">NULL</span> ) {
<span class="string">/* launch application loop */</span>
fprintf(stdout, <span class="string">"Entering main loop\n"</span> );
<span class="keyword">for</span>(;;) {
status = <a href="#aisl_run_cycle">aisl_run_cycle</a>(aisl);
<span class="keyword">if</span> ( status != <a href="#AISL_SUCCESS">AISL_SUCCESS</a> )
<a href="#aisl_sleep">aisl_sleep</a>(aisl, 500);
}
<a href="#aisl_free">aisl_free</a>(aisl);
} <span class="keyword">else</span> {
fprintf(<span class="keyword">stderr</span>, <span class="string">"Failed to initialize AISL\n"</span>);
<span class="keyword">return</span> -1;
}
<span class="keyword">return</span> 0;
}</code>
<p>Function <a href="#aisl_run_cycle">aisl_run_cycle</a> 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 <a href="#aisl_sleep">aisl_sleep</a> on idle cycles. To
release allocated by AISL resources on a runtime we are using
<a href="#aisl_sleep">aisl_sleep</a>.</p>
<p>And finally it is time to define the event handler matching
<a href="#AislCallback">AislCallback</a> prototype.</p>
<code><span class="keyword">static void</span>
hello_world(<span class="keyword">const struct</span> <a href="#aisl_evt">aisl_evt</a> *evt, <span class="keyword">void</span> *p_ctx)
{
<a href="#AislStream">AislStream</a> s;
<span class="keyword">const char</span> html[] = <span class="string;">
"&lt;html&gt;"
"&lt;head&gt;"
"&lt;title&gt;Hello World&lt;/title&gt;"
"&lt;/head&gt;"
"&lt;body&gt;"
"&lt;h1&gt;Hello World&lt;/h1&gt;"
"&lt;p&gt;Powered by AISL&lt;/p&gt;"
"&lt;/body&gt;"
"&lt;/html&gt;"</span>;
<span class="keyword">if</span> (evt-&gt;code != <a href="#AISL_EVENT_STREAM_REQUEST">AISL_EVENT_STREAM_REQUEST</a>)
<span class="keyword">return</span>;
s = evt-&gt;source;
<span class="keyword">if</span> (<a href="#aisl_response">aisl_response</a>(s, <a href="#AislHttpResponse">AISL_HTTP_OK</a>, <span class="keyword">sizeof</span> (html)-1) == <a href="#AISL_SUCCESS">AISL_SUCCESS</a>) {
<span class="keyword">if</span> (<a href="#aisl_write">aisl_write</a>(s, html, <span class="keyword">sizeof</span> (html)-1) != -1) {
<a href="#aisl_flush">aisl_flush</a>(s);
<span class="keyword">return</span>;
}
}
<a href="#aisl_reject">aisl_reject</a>(s);
(<span class="keyword">void</span>) p_ctx;
}</code>
<p>The function is being called by AISL engine on every event, but proceeds
only if <a href="#AISL_EVENT_STREAM_REQUEST">AISL_EVENT_STREAM_REQUEST</a>
is received. It starts an HTML response stored in <code class="inline">html</code>
constant. Make sure you use <code class="inline">sizeof (htmk)-1</code> for
content length, to avoid unwanted write of last NULL terminating character
of <code class="inline">html</code> string constant.</p>
<p>To compile the example using GCC and pkgconfig run:</p>
<code>$ gcc `pkgconf --libs --cflags libaisl` hello-world.c -o hello-world</code>
<p>Or specify paths to installed header files and library manualy:</p>
<code>$ -I/usr/local/include -L/usr/local/lib -laisl hello-world.c -o hello-world</code>
<p>Now execute compiled hello_world binary and open <a href="http://localhost:8080">http://localhost:8080</a> in
your browser. If you get any <code class="inline">symbol lookup error</code> on execution attempt,
try to specify the path to the library in the environment variable:</p>
<code>$ LD_LIBRARY_PATH="/usr/local/lib" ./hello-world</code>
<p>The result should look like this:</p>
<img src="/aisl/hello-world.jpg" class="shrink-picture" />
<h3 id="getting-advanced">Getting advanced</h3>
<p>Right after this chapter you will find full AISL
<a href="#api-reference">API Reference</a> that guides through all the types
and functions. The most significant of them you may already know from the
<a href="#getting-started">Hello World</a> example. To become an advanced
AISL developer, you will need to understand <a href="#AislEvent">events model</a>
and <a href="#AislStream">stream concept</a>. The rest of library
components carry more auxiliary function.</p>
<h2 id="api-reference">API Reference</h2>
<p>AISL library API defines several types (pointers on transparent
data structures), functions to work with them, enumerations, data
structures and preprocessor definitions.</p>
<p>Each AISL component has a library specific prefix:</p>
<ul>
<li><b>Aisl*</b> - for data types (typedefs)</li>
<li><b>aisl_*</b> - for functions and structures names</li>
<li><b>AISL_*</b> - for constants and macro definitions</li>
</ul>
<p>Functions, related to some data type, include name of the type in
their names, i.e. <code class="inline">AislServer -&gt; aisl_server_get_address()</code>.
There are two exceptions from this rule though introduced for simplicity and
shorter names for the functions being used most often: <a href="#AislInstance">AislInstance</a>
and <a href="#AislStream">AislStream</a>.</p>
<h3 id="AislInstance">Type AislInstance</h3>
<p>Pointer of this type 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.</p>
<p>Every instance may handle several independent HTTP servers running on
different network sockets and manages SSL certificates and communication with
clients.</p>
<p>Each instance must be configured with proper parameters stored in
<a href="#aisl_cfg">aisl_cfg</a> data structure with at least one HTTP
server and event handler matching <a href="#AislCallback">AislCallback</a>
prototype.
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_new"><a href="#AislInstance">AislInstance</a>
aisl_new(<span class="keyword">const struct</span> <a href="#aisl_cfg">aisl_cfg</a> *cfg);</code>
<div class="h5-like">DESCRIPTION</div>
<p>A constructor of <a href="#AislInstance">AislInstance</a> class.</p>
<div class="h5-like">PARAMETERS</div>
<ul>
<li><b>cfg</b> — a pointer to an <a href="#aisl_cfg">aisl_cfg</a> configuration
structure</li>
</ul>
<div class="h5-like">RETURN VALUE</div>
<p>Pointer to an <a href="#AislInstance">AislInstance</a> or NULL if
out of memory.</p>
</div>
<div class="code-doc">
<code id="aisl_free"><span class="keyword">void</span>
aisl_free(<a href="#AislInstance">AislInstance</a> instance);</code>
<div class="h5-like">Description</div>
<p>A destructor of <a href="#AislInstance">AislInstance</a> object.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>instance</b> — a pointer to an <a href="#AislInstance">AislInstance</a>.</li>
</ul>
<div class="h5-like">Return value</div>
<p>Returns no value.</p>
</div>
<div class="code-doc">
<code id="aisl_run_cycle"><a href="#AislStatus">AislStatus</a>
aisl_run_cycle(<a href="#AislInstance">AislInstance</a> instance);</code>
<div class="h5-like">Description</div>
<p>Performs an engine work cycle including all queued read and write
sockets operations, accepts new clients and triggers engine events.
Should be called periodically in a main loop of the application.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>instance</b> — a pointer to an <a href="#AislInstance">AislInstance</a>.</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><a href="#AISL_SUCCESS">AISL_SUCCESS</a> — if some event was triggered</li>
<li><a href="#AISL_IDLE">AISL_IDLE</a> — if no event was triggered</li>
<li><a href="#AISL_MALLOC_ERROR">AISL_MALLOC_ERROR</a> — if system run out
of memory</li>
<li><a href="#AISL_SYSCALL_ERROR">AISL_SYSCALL_ERROR</a> — if some system
call failed</li>
</ul>
<p>Return value handling should be soft. It is completely safe to continue
program execution even if error value was returned.</p>
<p>To preserve CPU time it is recommended to add a delay between
<a href="#aisl_run_cycle">aisl_run_cycle</a> calls, at least if anything but
<a href="#AISL_SUCCESS">AISL_SUCCESS</a> has been returned. You may want to
use <a href="#aisl_sleep">aisl_sleep</a> for this.</p>
</div>
<div class="code-doc">
<code id="aisl_sleep"><a href="#AislStatus">AislStatus</a>
aisl_sleep(<a href="#AislInstance">AislInstance</a> instance, <span class="keyword">uint32_t</span> usec);</code>
<div class="h5-like">Description</div>
<p>This function runs select system call inside on all opened sockets for
read or write depending on a stream state for user defined timeout.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>instance</b> — a pointer to an <a href="#AislInstance">AislInstance</a>.</li>
<li><b>usec</b> — a maximum possible timeout in microseconds for execution
blocking</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><a href="#AISL_SUCCESS">AISL_SUCCESS</a> — if some socket is ready for an operation</li>
<li><a href="#AISL_IDLE">AISL_IDLE</a> — if timed out without any activity on sockets</li>
<li><a href="#AISL_SYSCALL_ERROR">AISL_SYSCALL_ERROR</a> — if select() system call failed</li>
</ul>
</div>
<h3 id="AislServer">Type AislServer</h3>
<p>Pointer of this type represents an HTTP server constructed using configuration from
<code class="inline">srv</code> and <code class="inline">srv_cnt</code> members of
an <a href="#aisl_cfg"></a> structure used for <a href="#AislInstance">AislInstance</a>
construction.</p>
<p>AislServer can be a source of the following events:</p>
<ul>
<li><a href="#AISL_EVENT_SERVER_READY">AISL_EVENT_SERVER_READY</a></li>
<li><a href="#AISL_EVENT_SERVER_ERROR">AISL_EVENT_SERVER_ERROR</a></li>
</ul>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_server_get_instance"><a href="#AislInstance">AislInstance</a>
aisl_server_get_instance(<a href="#AislServer">AislServer</a> server);</code>
<div class="h5-like">Description</div>
<p>Gets an <a href="#AislInstance">AislInstance</a> associated with a valid <a href="#AislServer">AislServer</a></p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>server</b> — an <a href="#AislServer">AislServer</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Associated <a href="#AislInstance">AislInstance</a></p>
</div>
<div class="code-doc">
<code id="aisl_server_get_address"><span class="keyword">void</span>
aisl_server_get_address(<a href="#AislServer">AislServer</a> server, <span class="keyword">struct</span> sockaddr_in *address);</code>
<div class="h5-like">Description</div>
<p>Copies server's address and port to provided sockaddr_in structure</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>server</b> — an <a href="#AislServer">AislServer</a> pointer</li>
<li><b>address</b> — a pointer to an output structure</li>
</ul>
<div class="h5-like">Return value</div>
<p>Returns no value.</p>
</div>
<div class="code-doc">
<code id="aisl_server_get_ssl"><span class="keyword">bool</span>
aisl_server_get_ssl(<a href="#AislServer">AislServer</a> server);</code>
<div class="h5-like">Description</div>
<p>Checks if server works on HTTPS (secure) or HTTP (unsecure) protocol</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>server</b> — an <a href="#AislServer">AislServer</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><b>true</b> — if server is secure</li>
<li><b>false</b> — if server is unsecure</li>
</ul>
</div>
<h3 id="AislClient">Type AislClient</h3>
<p>Pointer of this type represents HTTP client connected to an <a href="#AislServer">AislServer</a>.</p>
<p>AislClient can be a source of the following events:</p>
<ul>
<li><a href="#AISL_EVENT_CLIENT_CONNECT">AISL_EVENT_CLIENT_CONNECT</a></li>
<li><a href="#AISL_EVENT_CLIENT_DISCONNECT">AISL_EVENT_CLIENT_DISCONNECT</a></li>
</ul>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_client_get_server"><a href="#AislServer">AislServer</a>
aisl_client_get_server(<a href="#AislClient">AislClient</a> client);</code>
<div class="h5-like">Description</div>
<p>Gets an <a href="#AislServer">AislServer</a> associated with a valid <a href="#AislClient">AislClient</a></p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>client</b> — an <a href="#AislClient">AislClient</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Associated <a href="#AislServer">AislServer</a></p>
</div>
<div class="code-doc">
<code id="aisl_client_get_address"><span class="keyword">void</span>
aisl_client_get_address(<a href="#AislClient">AislClient</a> client, <span class="keyword">struct</span> sockaddr_in *address);</code>
<div class="h5-like">Description</div>
<p>Copies client's address and port to provided sockaddr_in structure</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>client</b> — an <a href="#AislClient">AislClient</a> pointer</li>
<li><b>address</b> — a pointer to an output structure</li>
</ul>
<div class="h5-like">Return value</div>
<p>Returns no value.</p>
</div>
<div class="code-doc">
<code id="aisl_client_get_http_version"><a href="#AislHttpVersion">AislHttpVersion</a>
aisl_client_get_http_version(<a href="#AislClient">AislClient</a> client);</code>
<div class="h5-like">Description</div>
<p>Gets the HTTP version of the communication with <a href="#AislClient">AislClient</a>.
For just connected clients version is set to default <a href="#AislHttpVersion">AISL_HTTP_1_0</a>.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>client</b> — an <a href="#AislClient">AislClient</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>A constant from <a href="#AislHttpVersion">AislHttpVersion</a> enumeration</p>
</div>
<div class="code-doc">
<code id="aisl_client_disconnect"><span class="keyword">void</span>
aisl_client_disconnect(<a href="#AislClient">AislClient</a> client);</code>
<div class="h5-like">Description</div>
<p>Closes client's socket immediately. Resources will be cleaned up
automatically by <a href="#aisl_run_cycle">aisl_run_cycle</a> call.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>client</b> — an <a href="#AislClient">AislClient</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Returns no value.</p>
</div>
<div class="code-doc">
<code id="aisl_client_is_secure"><span class="keyword">bool</span>
aisl_client_is_secure(<a href="#AislClient">AislClient</a> client);</code>
<div class="h5-like">Description</div>
<p>Checks if client works on HTTPS (secure) or HTTP (unsecure) protocol.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>client</b> — an <a href="#AislClient">AislClient</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><b>true</b> — if communication is secure</li>
<li><b>false</b> — if communication is unsecure</li>
</ul>
</div>
<div class="code-doc">
<code id="aisl_client_is_online"><span class="keyword">bool</span>
aisl_client_is_online(<a href="#AislClient">AislClient</a> client);</code>
<div class="h5-like">Description</div>
<p>Checks if connection with client is still up.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>client</b> — an <a href="#AislClient">AislClient</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><b>true</b> — if client is connected</li>
<li><b>false</b> — if client is not connected</li>
</ul>
</div>
<h3 id="AislStream">Type AislStream</h3>
<p>A pointer of this type represents a sequence of a request from <a href="#AislClient">AislClient</a>
and a response from the application. First by handling events you can get
any or all the data from the HTTP request being parsed, and then write the
response to the stream.</p>
<p>Each stream has own extandable internal buffer that is used to store the
response. When you write to the stream using one of the appropriate
functions, the date is being written to this buffer first.</p>
<p>Application must respect the order of write calls to keep response
structure: response code, headers, body. For more information refer
description of related <a href="#response-functions">functions</a>.</p>
<p>AislStream can be a source of the following events:</p>
<ul>
<li><a href="#AISL_EVENT_STREAM_OPEN">AISL_EVENT_STREAM_OPEN</a></li>
<li><a href="#AISL_EVENT_STREAM_HEADER">AISL_EVENT_STREAM_HEADER</a></li>
<li><a href="#AISL_EVENT_STREAM_INPUT">AISL_EVENT_STREAM_INPUT</a></li>
<li><a href="#AISL_EVENT_STREAM_REQUEST">AISL_EVENT_STREAM_REQUEST</a></li>
<li><a href="#AISL_EVENT_STREAM_OUTPUT">AISL_EVENT_STREAM_OUTPUT</a></li>
<li><a href="#AISL_EVENT_STREAM_CLOSE">AISL_EVENT_STREAM_CLOSE</a></li>
<li><a href="#AISL_EVENT_STREAM_ERROR">AISL_EVENT_STREAM_ERROR</a></li>
</ul>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_get_server"><a href="#AislServer">AislServer</a>
aisl_get_server(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Gets an <a href="#AislServer">AislServer</a> associated with a valid <a href="#AislStream">AislStream</a></p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Associated <a href="#AislServer">AislServer</a></p>
</div>
<div class="code-doc">
<code id="aisl_get_client"><a href="#AislClient">AislClient</a>
aisl_get_client(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Gets an <a href="#AislClient">AislClient</a> associated with a valid <a href="#AislStream">AislStream</a></p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Associated <a href="#AislClient">AislClient</a></p>
</div>
<div class="code-doc">
<code id="aisl_get_instance"><a href="#AislInstance">AislInstance</a>
aisl_get_instance(<a href="#AislStream">AislStream</a> stream);</code>
<p>Gets an <a href="#AislInstance">AislInstance</a> associated with a valid <a href="#AislStream">AislStream</a></p>
<div class="h5-like">Description</div>
<p>Gets an <a href="#AislInstance">AislInstance</a> associated with a valid <a href="#AislStream">AislStream</a></p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Associated <a href="#AislInstance">AislInstance</a></p>
</div>
<div class="code-doc">
<code id="aisl_is_secure"><span class="keyword">bool</span>
aisl_is_secure(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Checks if stream is secured with HTTPS</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><b>true</b> — when stream is secure</li>
<li><b>false</b> — when stream is unsecure</li>
</ul>
</div>
<div class="code-doc">
<code id="aisl_get_http_version"><a href="#AislHttpVersion">AislHttpVersion</a>
aisl_get_http_version(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Gets an HTTP version requested by client</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>A constant from <a href="#AislHttpVersion">AislHttpVersion</a> enumeration</p>
</div>
<div class="code-doc">
<code id="aisl_set_context"><span class="keyword">void</span>
aisl_set_context(<a href="#AislStream">AislStream</a> stream, <span class="keyword">void</span> *context);</code>
<div class="h5-like">Description</div>
<p>Store a context pointer into the stream. It could be a pointer to any data
of the application. In general it is designed to store a pointer to a page
constructor while handling HTTP request.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>context</b> — an application data pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Returns no value.</p>
</div>
<div class="code-doc">
<code id="aisl_get_context"><span class="keyword">void</span> *
aisl_get_context(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Gets previously stored with <a href="#aisl_set_context">aisl_set_context</a>
application data pointer.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Previously stored application data pointer</li>
</div>
<div class="code-doc">
<code id="aisl_set_output_event"><span class="keyword">void</span>
aisl_set_output_event(<a href="#AislStream">AislStream</a> stream, <span class="keyword">bool</span> value);</code>
<div class="h5-like">Description</div>
<p>Switches triggering of <a href="#AISL_EVENT_STREAM_OUTPUT">AISL_EVENT_STREAM_OUTPUT</a>,
default value is <b>false</b>.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>value</b> — true to enable and false to disable event triggering</li>
</ul>
<div class="h5-like">Return value</div>
<p>Returns no value.</p>
</div>
<div class="code-doc">
<code id="aisl_get_output_event"><span class="keyword">bool</span>
aisl_get_output_event(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Gets current state of <a href="#AISL_EVENT_STREAM_OUTPUT">AISL_EVENT_STREAM_OUTPUT</a> switch.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<li><b>true</b> — when event triggering is enabled</li>
<li><b>false</b> — when event triggering is disabled</li>
</div>
<h4 id="response-functions">Response functions</h4>
<div class="code-doc">
<code id="aisl_response"><a href="#AislStatus">AislStatus</a>
aisl_response(<a href="#AislStream">AislStream</a> stream, <a href="#AislHttpResponse">AislHttpResponse</a> status_code, <span class="keyword">uint64_t</span> content_length);</code>
<div class="h5-like">Description</div>
<p>Starts an HTTP response with user defined status code and content length.
If content length is unknown at this stage, it could be calculated
automatically during response output, otherwise it is the best practice to
provide content length in a very begining with this call, for example when
transmitting a file.</p>
<p>Function must be called just once for a stream before any other
response function.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>status_code</b> — a constant from <a href="#AislHttpResponse">AislHttpResponse</a> enumeration</li>
<li><b>content_length</b> — content length in bytes or <a href="#AISL_AUTO_LENGTH">AISL_AUTO_LENGTH</a> to
calculate on the fly</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><a href="#AISL_SUCCESS">AISL_SUCCESS</a> — when data was written to the buffer sucessfully</li>
<li><a href="#AISL_IDLE">AISL_IDLE</a> — when response was already started</li>
<li><a href="#AISL_MALLOC_ERROR">AISL_MALLOC_ERROR</a> — when buffer reallocation failed</li>
</ul>
</div>
<div class="code-doc">
<code id="aisl_header"><span class="keyword">int</span>
aisl_header(<a href="#AislStream">AislStream</a> stream, <span class="keyword">const char</span> *key, <span class="keyword">const char</span> *value);</code>
<div class="h5-like">Description</div>
<p>Writes an HTTP header at the end of a stream buffer.</p>
<p>This function could be called only before any data was written to a
response body.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>key</b> — an HTTP header key</li>
<li><b>value</b> — an HTTP header value</li>
</ul>
<div class="h5-like">Return value</div>
<p>Length of data written to the stream buffer, or -1 if memory allocation
or stream workflow error occured</p>
</div>
<div class="code-doc">
<code id="aisl_header_printf"><span class="keyword">int</span>
aisl_header_printf(<a href="#AislStream">AislStream</a> stream, <span class="keyword">const char</span> *key, <span class="keyword">const char</span> *format, ...);</code>
<div class="h5-like">Description</div>
<p>Writes an HTTP header with a formatted value at the end of a stream buffer.</p>
<p>This function could be called only before any data was written to a
response body.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>key</b> — an HTTP header key</li>
<li><b>format</b> — a value <code class="inline">printf</code>-like format string of an HTTP header value</li>
<li><b>...</b> — comma separated variable number of arguments</li>
</ul>
<div class="h5-like">Return value</div>
<p>Length of data written to the stream buffer, or -1 if memory allocation
or stream workflow error occured</p>
</div>
<div class="code-doc">
<code id="aisl_header_vprintf"><span class="keyword">int</span>
aisl_header_vprintf(<a href="#AislStream">AislStream</a> stream, <span class="keyword">const char</span> *key, <span class="keyword">const char</span> *format, <span class="keyword">va_list</span> args);</code>
<div class="h5-like">Description</div>
<p>Writes an HTTP header with a formatted value at the end of a stream buffer, just
like <a href="#aisl_header_printf">aisl_header_printf</a>, except that it
uses <code class="inline">va_list</code> instead of a variable number of
arguments.</p>
<p>This function could be called only before any data was written to a
response body.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>key</b> — an HTTP header key</li>
<li><b>format</b> — a value <code class="inline">printf</code>-like format string of an HTTP header value</li>
<li><b>args</b> — va_list arguments macro</li>
</ul>
<div class="h5-like">Return value</div>
<p>Length of data written to the stream buffer, or -1 if memory allocation
or stream workflow error occured</p>
</div>
<div class="code-doc">
<code id="aisl_printf"><span class="keyword">int</span>
aisl_printf(<a href="#AislStream">AislStream</a> stream, <span class="keyword">const char</span> *format, ...);</code>
<div class="h5-like">Description</div>
<p>Writes a formatted body (content) of an HTTP response at the end of a stream buffer.</p>
<p>After a call of this function, you may not use header output calls anymore.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>format</b> — a value <code class="inline">printf</code>-like format string for response content</li>
<li><b>...</b> — comma separated variable number of arguments</li>
</ul>
<div class="h5-like">Return value</div>
<p>Length of data written to the stream buffer, or -1 if memory allocation
or stream workflow error occured</p>
</div>
<div class="code-doc">
<code id="aisl_vprintf"><span class="keyword">int</span>
aisl_vprintf(<a href="#AislStream">AislStream</a> stream, <span class="keyword">const char</span> *format, <span class="keyword">va_list</span> args);</code>
<div class="h5-like">Description</div>
<p>Writes a formatted body (content) of an HTTP response at the end of a
stream buffer, just like <a href="#aisl_printf">aisl_printf</a>, except
that it uses <code class="inline">va_list</code> instead of a variable
number of arguments.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>format</b> — a value <code class="inline">printf</code>-like format string for response content</li>
<li><b>args</b> — va_list arguments macro</li>
</ul>
<div class="h5-like">Return value</div>
<p>Length of data written to the stream buffer, or -1 if memory allocation
or stream workflow error occured</p>
</div>
<div class="code-doc">
<code id="aisl_write"><span class="keyword">int</span>
aisl_write(<a href="#AislStream">AislStream</a> stream, <span class="keyword">const char</span> *data, <span class="keyword">int</span> d_len);</code>
<div class="h5-like">Description</div>
<p>Writes a part of an HTTP response content of the given length at the
end of a stream buffer.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
<li><b>data</b> — a pointer to a data array</li>
<li><b>d_len</b> — a length of the data to be written</li>
</ul>
<div class="h5-like">Return value</div>
<p>Length of data written to the stream buffer, or -1 if memory allocation
or stream workflow error occured</p>
</div>
<div class="code-doc">
<code id="aisl_puts"><span class="keyword">int</span>
aisl_puts(<span class="keyword">const char</span> *str_data, <a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Writes a NULL-terminated string as a part of an HTTP response content
at the end of a stream buffer.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>str_data</b> — a pointer to a NULL-terminated string</li>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Length of data written to the stream buffer, or -1 if memory allocation
or stream workflow error occured</p>
</div>
<div class="code-doc">
<code id="aisl_flush"><a href="#AislStatus">AislStatus</a>
aisl_flush(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Initiates flushing of a stream buffer. At this stage
<code class="inline">Content-Type</code>,
<code class="inline">Content-Length</code>,
<code class="inline">Connection</code> and
<code class="inline">Server</code> headers will be added to a response if
they were not added manualy before. If <a href="#AISL_AUTO_LENGTH">AISL_AUTO_LENGTH</a>
were given as a <code class="inline">content_length</code> to an
<a href="#aisl_response">aisl_response</a>, it will be automatically
calculated from a stream buffer size.</p>
<p>After this call all other response functions will return -1.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<ul>
<li><a href="#AISL_SUCCESS">AISL_SUCCESS</a> — when operation was successful</li>
<li><a href="#AISL_MALLOC_ERROR">AISL_MALLOC_ERROR</a> — when system run out
of memory</li>
</ul>
</div>
<div class="code-doc">
<code id="aisl_reject"><span class="keyword">void</span>
aisl_reject(<a href="#AislStream">AislStream</a> stream);</code>
<div class="h5-like">Description</div>
<p>Rejects the stream. For HTTP &gt; 2.0 it also closes client's connection.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>stream</b> — an <a href="#AislStream">AislStream</a> pointer</li>
</ul>
<div class="h5-like">Return value</div>
<p>Returns no value.</p>
</div>
<h3 id="AislStatus">Enumeration AislStatus</h3>
<div class="code-doc">
<code id="AISL_SUCCESS">AISL_SUCCESS = 0</code>
<p>Represents successfully executed operation.</p>
</div>
<div class="code-doc">
<code id="AISL_IDLE">AISL_IDLE = 1</code>
<p>Represents situation when traget operation was not executed or nothing
significant was done. It is not an error state.</p>
</div>
<div class="code-doc">
<code id="AISL_INPUT_ERROR">AISL_INPUT_ERROR = -4</code>
<p>Represents error, when some input data provided for an operation
is incorrect.</p>
</div>
<div class="code-doc">
<code id="AISL_EXTCALL_ERROR">AISL_EXTCALL_ERROR = -3</code>
<p>Represents error, when some external library call (i.e. openssl) has
failed.</p>
</div>
<div class="code-doc">
<code id="AISL_SYSCALL_ERROR">AISL_SYSCALL_ERROR = -2</code>
<p>Represents error, when some system call has failed.</p>
</div>
<div class="code-doc">
<code id="AISL_MALLOC_ERROR">AISL_MALLOC_ERROR = -1</code>
<p>Represents error, when memory allocation has failed.</p>
</div>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_status_to_string"><span class="keyword">const char</span> *
aisl_status_to_string(<a href="#AislStatus">AislStatus</a> status);</code>
<div class="h5-like">Description</div>
<p>Converts <a href="#AislStatus">AislStatus</a> enumeration to a NULL-terminated string.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>status</b> — a constant from <a href="#AislStatus">AislStatus</a> enumeration</li>
</ul>
<div class="h5-like">Return value</div>
<p>A NULL-terminated string representation of <a href="#AislStatus">AislStatus</a></p>
</div>
<h3 id="events">Events</h3>
<p>Events triggered by AISL inform application about HTTP server and client
activity, communication state, provide parsed results of HTTP request.</p>
<p>To recieve events notification application have to define an event
handler function, matching <a href="#AislCallback">AislCallback</a>
prototype and assign its pointer to a member named
<code class="inline">callback</code> of an <a href="#aisl_cfg">aisl_cfg</a>
structure, given as a parameter to <a href="#aisl_new">aisl_new</a> call.</p>
<p>Also <code class="inline">p_ctx</code> member of the
<a href="#aisl_cfg">aisl_cfg</a> could be set, so its value will be passed
as a second argument of the event handler function.</p>
<p>Different events may have different payload passed as a first argument to
the event handler function and different source types. In this case you can
access event specific data using type casting. Refer event description of
this document for detailed infromation.</p>
<code><span class="keyword">void</span>
on_aisl_evt(<span class="keyword">const struct</span> <a href="#aisl_evt">aisl_evt</a> *evt, <span class="keyword">void</span> *ctx)
{
<span class="keyword">switch</span> (evt-&gt;code)
{
...
<span class="keyword">case</span> <a href="#AISL_EVENT_STREAM_HEADER">AISL_EVENT_STREAM_HEADER</a>: {
<span class="keyword">struct</span> <a href="#aisl_evt_header">aisl_evt_header</a> *evt_header = (<span class="keyword">struct</span> <a href="#aisl_evt_header">aisl_evt_header</a>aisl_evt_header *) evt;
<a href="#AislStream">AislStream</a> s = (AislStream) evt-&gt;source;
printf("Stream (HTTP%s): header received %s = %s\n", <a href="#aisl_is_secure">aisl_is_secure</a>(s) ? "S" : "",
evt_header-&gt;key, evt_header-&gt;value);
} <span class="keyword">break</span>;
...
}
(void) ctx;
}</code>
<h4>Callback</h4>
<div class="code-doc">
<code id="AislCallback"><span class="keyword">typedef void</span>
(* AislCallback) (<span class="keyword">const struct</span> <a href="#aisl_evt">aisl_evt</a> *evt, <span class="keyword">void</span> *ctx);</code>
<div class="h5-like">Description</div>
<p>A prototype for event handler function to be defined by application.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>evt</b> — an <a href="#AislEvent">AislEvent</a> payload</li>
<li><b>ctx</b> — a user defined context passed in
<a href="#aisl_cfg">aisl_cfg</a> on <a href="#AislInstance">AislInstance</a> initialization</li>
</ul>
<div class="h5-like">Return value</div>
<p>Should not return any value.</p>
</div>
<h4 id="AislEvent">Enumeration AislEvent</h4>
<div class="code-doc">
<code id="AISL_EVENT_SERVER_READY">AISL_EVENT_SERVER_READY</code>
<div class="h5-like">Description</div>
<p>HTTP server has started and is ready to accept clients.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislServer">AislServer</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_SERVER_ERROR">AISL_EVENT_SERVER_ERROR</code>
<div class="h5-like">Description</div>
<p>HTTP server has not started due to an error.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislServer">AislServer</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_CLIENT_CONNECT">AISL_EVENT_CLIENT_CONNECT</code>
<div class="h5-like">Description</div>
<p>HTTP client has connected to the server.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislClient">AislClient</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_CLIENT_DISCONNECT">AISL_EVENT_CLIENT_DISCONNECT</code>
<div class="h5-like">Description</div>
<p>HTTP client has disconnected from the server.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislClient">AislClient</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_STREAM_OPEN">AISL_EVENT_STREAM_OPEN</code>
<div class="h5-like">Description</div>
<p>First line of the HTTP request has been received and parsed.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt_open</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislStream">AislStream</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_STREAM_HEADER">AISL_EVENT_STREAM_HEADER</code>
<div class="h5-like">Description</div>
<p>HTTP header has been received and parsed.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt_header</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislStream">AislStream</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_STREAM_INPUT">AISL_EVENT_STREAM_INPUT</code>
<div class="h5-like">Description</div>
<p>A part of HTTP request content has been received. To know if it is a
last part of the data or not, application shall calculate a sum of lengths
of received parts and compare it with the value of
<code class="inline">Content-Length</code> header or rely on
<a href="#AISL_EVENT_STREAM_REQUEST">AISL_EVENT_STREAM_REQUEST</a>
occurence.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt_input</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislStream">AislStream</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_STREAM_REQUEST">AISL_EVENT_STREAM_REQUEST</code>
<div class="h5-like">Description</div>
<p>Full HTTP request has been received. It is a good time for application
to start response to the client.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislStream">AislStream</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_STREAM_OUTPUT">AISL_EVENT_STREAM_OUTPUT</code>
<div class="h5-like">Description</div>
<p>An optional event disabled by default. Could be enabled by
<a href="#aisl_set_output_event">aisl_set_output_event</a> call.</p>
<p>Being triggered when AISL is ready to buffer a chunk of data,
could be very useful for transmission of big files without need to read
them all to the memory first.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislStream">AislStream</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_STREAM_CLOSE">AISL_EVENT_STREAM_CLOSE</code>
<div class="h5-like">Description</div>
<p>Stream is about to be destroyed. It is a good time to release all
previously allocated resources, for example a context set by
<a href="#aisl_set_context">aisl_set_context</a>.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislStream">AislStream</a></p>
</div>
<div class="code-doc">
<code id="AISL_EVENT_STREAM_ERROR">AISL_EVENT_STREAM_ERROR</code>
<div class="h5-like">Description</div>
<p>Triggered on invalid client's behavior and misformatted HTTP request.</p>
<div class="h5-like">Payload</div>
<p><a href="#aisl_evt">aisl_evt</a></p>
<div class="h5-like">Source</div>
<p><a href="#AislStream">AislStream</a></p>
</div>
<h4>Payload</h4>
<div class="code-doc">
<code id="aisl_evt"><span class="keyword">struct</span> aisl_evt {
<span class="keyword">void</span> *source;
<a href="#AislEvent">AislEvent</a> code;
<a href="#AislStatus">AislStatus</a> status;
};</code>
<ul>
<li><b>source</b><a href="#AislServer">AislServer</a>,
<a href="#AislClient">AislClient</a> or
<a href="#AislStream">AislStream</a>, depends on value of
<code class="inline">code</code> member.</li>
<li><b>code</b> — a constant of <a href="#AislEvent">AislEvent</a> enumeration</li>
<li><b>status</b> — a constant of <a href="#AislStatus">AislStatus</a> specifies the reason of the event.</li>
</ul>
</div>
<div class="code-doc">
<code id="aisl_evt_open"><span class="keyword">struct</span> aisl_evt_open {
<span class="keyword">struct</span> <a href="#aisl_evt">aisl_evt</a> evt;
<span class="keyword">const char</span> *path;
<span class="keyword">const char</span> *query;
<a href="#AislHttpMethod">AislHttpMethod</a> http_method;
};</code>
<ul>
<li><b>evt</b> — parent <a href="#aisl_evt">aisl_evt</a> structure</li>
<li><b>path</b> — HTTP requested page or file</li>
<li><b>query</b> — HTTP query also known as GET parameters</li>
<li><b>http_method</b> — method of the HTTP request</li>
</ul>
</div>
<div class="code-doc">
<code id="aisl_evt_header"><span class="keyword">struct</span> aisl_evt_header {
<span class="keyword">struct</span> <a href="#aisl_evt">aisl_evt</a> evt;
<span class="keyword">const char</span> *key;
<span class="keyword">const char</span> *value;
};</code>
<ul>
<li><b>evt</b> — parent <a href="#aisl_evt">aisl_evt</a> structure</li>
<li><b>key</b> — HTTP header key string (all characters are in lowercase)</li>
<li><b>value</b> — HTTP header value string</li>
</ul>
</div>
<div class="code-doc">
<code id="aisl_evt_input"><span class="keyword">struct</span> aisl_evt_input {
<span class="keyword">struct</span> <a href="#aisl_evt">aisl_evt</a> evt;
<span class="keyword">const char</span> *data;
<span class="keyword">int32_t</span> size;
};</code>
<ul>
<li><b>evt</b> — parent <a href="#aisl_evt">aisl_evt</a> structure</li>
<li><b>data</b> — a pointer to received data array</li>
<li><b>size</b> — a size of received data</li>
</ul>
</div>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_event_to_string"><span class="keyword">const char</span> *
aisl_event_to_string(<a href="#AislEvent">AislEvent</a> evt);
</code>
<div class="h5-like">Description</div>
<p>Converts <a href="#AislEvent">AislEvent</a> enumeration to a NULL-terminated string.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>evt</b> — a constant from <a href="#AislStatus">AislEvent</a> enumeration</li>
</ul>
<div class="h5-like">Return value</div>
<p>A NULL-terminated string representation of <a href="#AislEvent">AislEvent</a></p>
</div>
<h3 id="AislHttpVersion">Enumeration AislHttpVersion</h3>
<code><span class="keyword">typedef enum</span> {
AISL_HTTP_0_9 = 0x0009
, AISL_HTTP_1_0 = 0x0100
, AISL_HTTP_1_1 = 0x0101
, AISL_HTTP_2_0 = 0x0200
} AislHttpVersion;</code>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_http_version_to_string"><span class="keyword">const char</span> *
aisl_http_version_to_string(<a href="#AislHttpVersion">AislHttpVersion</a> version);</code>
<div class="h5-like">Description</div>
<p>Converts <a href="#AislHttpVersion">AislHttpVersion</a> enumeration to a NULL-terminated string.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>version</b> — a constant from <a href="#AislHttpVersion">AislHttpVersion</a> enumeration</li>
</ul>
<div class="h5-like">Return value</div>
<p>A NULL-terminated string representation of <a href="#AislHttpVersion">AislHttpVersion</a></p>
</div>
<h3 id="AislHttpMethod">Enumeration AislHttpMethod</h3>
<code><span class="keyword">typedef enum</span> {
AISL_HTTP_METHOD_UNKNOWN
, AISL_HTTP_GET
, AISL_HTTP_PUT
, AISL_HTTP_POST
, AISL_HTTP_HEAD
, AISL_HTTP_TRACE
, AISL_HTTP_DELETE
, AISL_HTTP_OPTIONS
, AISL_HTTP_CONNECT
, AISL_HTTP_PRI
} AislHttpMethod;</code>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_http_method_to_string"><span class="keyword">const char</span> *
aisl_http_method_to_string(<a href="#AislHttpMethod">AislHttpMethod</a> method);</code>
<div class="h5-like">Description</div>
<p>Converts <a href="#AislHttpMethod">AislHttpMethod</a> enumeration to a NULL-terminated string.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>method</b> — a constant from <a href="#AislHttpMethod">AislHttpMethod</a> enumeration</li>
</ul>
<div class="h5-like">Return value</div>
<p>A NULL-terminated string representation of <a href="#AislHttpMethod">AislHttpMethod</a></p>
</div>
<h3 id="AislHttpResponse">Enumeration AislHttpResponse</h3>
<code><span class="keyword">typedef enum</span> {
AISL_HTTP_CONTINUE = 100
, AISL_HTTP_SWITCHING_PROTOCOLS
, AISL_HTTP_OK = 200
, AISL_HTTP_CREATED
, AISL_HTTP_ACCEPTED
, AISL_HTTP_NON_AUTHORITATIVE_INFORMATION
, AISL_HTTP_NO_CONTENT
, AISL_HTTP_RESET_CONTENT
, AISL_HTTP_PARTIAL_CONTENT
, AISL_HTTP_MULTIPLE_CHOICES = 300
, AISL_HTTP_MOVED_PERMANENTLY
, AISL_HTTP_FOUND
, AISL_HTTP_SEE_OTHER
, AISL_HTTP_NOT_MODIFIED
, AISL_HTTP_USE_PROXY
, AISL_HTTP_UNUSED
, AISL_HTTP_TEMPORARY_REDIRECT
, AISL_HTTP_BAD_REQUEST = 400
, AISL_HTTP_UNAUTHORIZED
, AISL_HTTP_PAYMENT_REQUIRED
, AISL_HTTP_FORBIDDEN
, AISL_HTTP_NOT_FOUND
, AISL_HTTP_METHOD_NOT_ALLOWED
, AISL_HTTP_NOT_ACCEPTABLE
, AISL_HTTP_PROXY_AUTHENTICATION_REQUIRED
, AISL_HTTP_REQUEST_TIMEOUT
, AISL_HTTP_CONFLICT
, AISL_HTTP_GONE
, AISL_HTTP_LENGTH_REQUIRED
, AISL_HTTP_PRECONDITION_FAILED
, AISL_HTTP_REQUEST_ENTITY_TOO_LARGE
, AISL_HTTP_REQUEST_URI_TOO_LONG
, AISL_HTTP_UNSUPPORTED_MEDIA_TYPE
, AISL_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE
, AISL_HTTP_EXPECTATION_FAILED
, AISL_HTTP_INTERNAL_SERVER_ERROR = 500
, AISL_HTTP_NOT_IMPLEMENTED
, AISL_HTTP_BAD_GATEWAY
, AISL_HTTP_SERVICE_UNAVAILABLE
, AISL_HTTP_GATEWAY_TIMEOUT
, AISL_HTTP_VERSION_NOT_SUPPORTED
} AislHttpResponse;</code>
<h4>Functions</h4>
<div class="code-doc">
<code id="aisl_http_response_to_string"><span class="keyword">const char</span> *
aisl_http_response_to_string(<a href="#AislHttpResponse">AislHttpResponse</a> code);</code>
<div class="h5-like">Description</div>
<p>Converts <a href="#AislHttpResponse">AislHttpResponse</a> enumeration to a NULL-terminated string.</p>
<div class="h5-like">Arguments</div>
<ul>
<li><b>code</b> — a constant from <a href="#AislHttpResponse">AislHttpResponse</a> enumeration</li>
</ul>
<div class="h5-like">Return value</div>
<p>A NULL-terminated string representation of <a href="#AislHttpResponse">AislHttpResponse</a></p>
</div>
<h2>Configuration structures</h2>
<div class="code-doc">
<code id="aisl_cfg"><span class="keyword">struct</span> aisl_cfg {
<a href="#AislCallback">AislCallback</a> callback;
<span class="keyword">void</span> *p_ctx;
<span class="keyword">const struct</span> <a href="#aisl_cfg_srv">aisl_cfg_srv</a> *srv;
<span class="keyword">const struct</span> <a href="#aisl_cfg_ssl">aisl_cfg_ssl</a> *ssl;
<span class="keyword">int</span> srv_cnt;
<span class="keyword">int</span> ssl_cnt;
<span class="keyword">int</span> client_spool_size;
<span class="keyword">int</span> initial_buffer_size;
<span class="keyword">int</span> client_accept_limit;
<span class="keyword">int</span> client_silence_timeout;
};</code>
<ul>
<li><b>callback</b> — address of the event handler function.</li>
<li><b>p_ctx</b> — user defined pointer that will be passed to the event handler function.</li>
<li><b>srv</b> — array of servers to be handled by AISL.</li>
<li><b>ssl</b> — array of SSL certificates for secure servers.</li>
<li><b>srv_cnt</b> — size of <code class="inline">srv</code> array.</li>
<li><b>ssl_cnt</b> — size of <code class="inline">ssl</code> array.</li>
<li><b>client_spool_size</b> — Initial size of the spool (number of clients).</li>
<li><b>initial_buffer_size</b> — Initial size of communication buffer. Limits maximal length of supported HTTP
headers length.</li>
<li><b>client_accept_limit</b> — Maximal number of clients to accept at the same time.</li>
<li><b>client_silence_timeout</b> — A time while AISL will wait for incoming data from client.</li>
</ul>
</div>
<p>A recommended configuration is defined in a preprocessor macro <a href="#AISL_CFG_DEFAULTS">AISL_CFG_DEFAULTS</a>.</p>
<div class="code-doc">
<code id="aisl_cfg_srv"><span class="keyword">struct</span> aisl_cfg_srv {
<span class="keyword">const char</span> *host;
<span class="keyword">uint16_t</span> port;
<span class="keyword">bool</span> secure;
};</code>
<ul>
<li><b>host</b> — network interface address to listen.</li>
<li><b>port</b> — TCP port to start server on.</li>
<li><b>secure</b> — set to <code class="inline">true</code> to enable
SSL for this server, or <code class="inline">false</code> otherwise.
</ul>
</div>
<div class="code-doc">
<code id="aisl_cfg_ssl"><span class="keyword">struct</span> aisl_cfg_ssl {
<span class="keyword">const char</span> *host;
<span class="keyword">const char</span> *key_file;
<span class="keyword">const char</span> *crt_file;
};</code>
<ul>
<li><b>host</b> — a host name (domain) to apply the SSL certificate.</li>
<li><b>key_file</b> — a path to SSL certificate key file.</li>
<li><b>crt_file</b> — a path to SSL certificate file</li>
</ul>
</div>
<h2>Preprocessor definitions</h2>
<div class="code-doc">
<code id="AISL_CFG_DEFAULTS"><span class="string">#define AISL_CFG_DEFAULTS \
.client_spool_size = 32 \
, .initial_buffer_size = 16536 \
, .client_accept_limit = 1024 \
, .client_silence_timeout = 30 \
</span></code>
<p>Recommended defaults for AISL configuration.</p>
</div>
<div class="code-doc">
<code id="AISL_AUTO_LENGTH"><span class="string">#define AISL_AUTO_LENGTH (~0)</span></code>
<p>Could be used to say AISL to calculate content length automatically.</p>
</div>
<div class="code-doc">
<code id="AISL_CALLBACK"><span class="string">#define AISL_CALLBACK(x) ((AislCallback) x)</span></code>
<p>Prerocessor macro to type cast a function to <a href="#AislCallback">AislCallback</a></p>
</div>
</main>
</div>
<div class="footer">
<div class="footer__logo dark-bg">Löwenware</div>
<div class="footer__above">
<!--div class="newsletter">
<form>
<label for="newsletter__email">Subscribe to newsletter</label>
<div class="newsletter__field">
<input type="email" name="email" id="newsletter__email" placeholder="your@email.address" />
<button type="submit" class="submit" name="submit" value="1">Subscribe</button>
</div>
</form>
</div-->
<div class="footer__social">
<a href="/goto/github" title="Go to GitHub"><svg class="icon"><use xlink:href="/static/sprite.svg#github"/></svg></a>
<a href="/goto/gitter" title="Go to Gitter chat"><svg class="icon"><use xlink:href="/static/sprite.svg#gitter"/></svg></a>
<a href="/goto/youtube" title="Go to YouTube channel"><svg class="icon"><use xlink:href="/static/sprite.svg#youtube"/></svg></a>
<a href="/goto/instagram" title="Go to Instagram"><svg class="icon"><use xlink:href="/static/sprite.svg#instagram"/></svg></a>
<a href="/goto/medium" title="Go to Medium page"><svg class="icon"><use xlink:href="/static/sprite.svg#medium"/></svg></a>
<a href="/goto/linkedin" title="Go to LinkedIn profile"><svg class="icon"><use xlink:href="/static/sprite.svg#linkedin"/></svg></a>
</div>
</div>
<div class="footer__below dark-bg">
<div class="footer__credentials">
<div class="copyright">&copy; 2017 - 2019 by Löwenware s.r.o.</div>
<ul class="legal">
<li class="legal__node legal__first"><a href="/privacy-statement.html">Privacy statement</a></li>
<li class="legal__node legal__marker"><a href="/terms-of-use.html">Terms of use</a></li>
</ul>
<div style="clear:left;"></div>
</div>
</div>
</div>
<script async type="text/javascript" src="/static/main.js"></script>
<script async src="https://www.w3counter.com/tracker.js?id=127316"></script>
</body>
</html>