1539 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			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 <aisl/aisl.h></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>(&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;">
 | 
						|
		"<html>"
 | 
						|
			"<head>"
 | 
						|
				"<title>Hello World</title>"
 | 
						|
			"</head>"
 | 
						|
			"<body>"
 | 
						|
				"<h1>Hello World</h1>"
 | 
						|
				"<p>Powered by AISL</p>"
 | 
						|
			"</body>"
 | 
						|
		"</html>"</span>;
 | 
						|
 | 
						|
	<span class="keyword">if</span> (evt->code != <a href="#AISL_EVENT_STREAM_REQUEST">AISL_EVENT_STREAM_REQUEST</a>)
 | 
						|
		<span class="keyword">return</span>;
 | 
						|
 | 
						|
	s = evt->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 -> 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 > 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->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->source;
 | 
						|
 | 
						|
		printf("Stream (HTTP%s): header received %s = %s\n", <a href="#aisl_is_secure">aisl_is_secure</a>(s) ? "S" : "",
 | 
						|
				evt_header->key, evt_header->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">© 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>
 |