Browse Source

Update to version 1.0.5

Ilja Kartašov 2 months ago
parent
commit
f7a9f255df
77 changed files with 4540 additions and 4252 deletions
  1. 0
    3
      .gitmodules
  2. 8
    0
      CHANGELOG
  3. 0
    131
      CMakeLists.txt
  4. 19
    23
      README.md
  5. 0
    36
      aisl.proj
  6. 0
    1
      cStuff
  7. 0
    7
      cmake.compiler
  8. 0
    90
      cmake.paths
  9. 0
    18
      cmake.system
  10. 0
    61
      cmake.version
  11. 31
    0
      examples.mk
  12. 104
    0
      examples/hello-world.c
  13. BIN
      examples/vgcore.12255
  14. BIN
      examples/vgcore.13889
  15. BIN
      examples/vgcore.18015
  16. BIN
      examples/vgcore.18664
  17. BIN
      examples/vgcore.18862
  18. BIN
      examples/vgcore.23466
  19. BIN
      examples/vgcore.27845
  20. BIN
      examples/vgcore.28571
  21. BIN
      examples/vgcore.30230
  22. BIN
      examples/vgcore.31633
  23. BIN
      examples/vgcore.7201
  24. BIN
      examples/vgcore.8596
  25. 26
    96
      include/aisl/aisl.h
  26. 74
    0
      include/aisl/client.h
  27. 64
    0
      include/aisl/config.h
  28. 0
    128
      include/aisl/event.h
  29. 0
    76
      include/aisl/handle.h
  30. 0
    104
      include/aisl/http.h
  31. 66
    0
      include/aisl/instance.h
  32. 48
    0
      include/aisl/server.h
  33. 0
    24
      include/aisl/status.h
  34. 173
    146
      include/aisl/stream.h
  35. 226
    0
      include/aisl/types.h
  36. 539
    0
      lib/)
  37. 176
    0
      lib/buffer.c
  38. 59
    0
      lib/buffer.h
  39. 446
    0
      lib/client.c
  40. 106
    0
      lib/client.h
  41. 37
    0
      lib/debug.h
  42. 428
    0
      lib/http.c
  43. 41
    0
      lib/http.h
  44. 301
    0
      lib/instance.c
  45. 70
    0
      lib/instance.h
  46. 97
    0
      lib/list.c
  47. 51
    0
      lib/list.h
  48. 169
    0
      lib/server.c
  49. 83
    0
      lib/server.h
  50. 102
    0
      lib/ssl.c
  51. 54
    0
      lib/ssl.h
  52. 52
    0
      lib/str-utils.c
  53. 26
    0
      lib/str-utils.h
  54. 616
    0
      lib/stream.c
  55. 106
    0
      lib/stream.h
  56. 58
    0
      lib/types.c
  57. 19
    0
      libaisl.pc.example
  58. 0
    367
      library/aisl.c
  59. 0
    129
      library/buffer.c
  60. 0
    49
      library/buffer.h
  61. 0
    460
      library/client.c
  62. 0
    67
      library/client.h
  63. 0
    28
      library/event.c
  64. 0
    48
      library/globals.h
  65. 0
    802
      library/handle.c
  66. 0
    61
      library/handle.h
  67. 0
    112
      library/http.c
  68. 0
    490
      library/parser.c
  69. 0
    52
      library/parser.h
  70. 0
    188
      library/server.c
  71. 0
    47
      library/server.h
  72. 0
    21
      library/status.c
  73. 0
    196
      library/stream.c
  74. 0
    93
      library/stream.h
  75. 65
    0
      project.mk
  76. 0
    97
      project.sh
  77. 0
    1
      version

+ 0
- 3
.gitmodules View File

@@ -1,3 +0,0 @@
1
-[submodule "cStuff"]
2
-	path = cStuff
3
-	url = https://github.com/lowenware/cStuff.git

+ 8
- 0
CHANGELOG View File

@@ -0,0 +1,8 @@
1
+# Release 1.0.0
2
+
3
+By Ilja Kartašov <ik@lowenware.com>, 2019-06-02
4
+
5
+1. Library release with new and final API and documented code.
6
+2. Previous version is being called `aisl-legacy` and will be maintained in 
7
+security aspects in branch called `legacy` until all applications using it will
8
+be updated.

+ 0
- 131
CMakeLists.txt View File

@@ -1,131 +0,0 @@
1
-cmake_minimum_required (VERSION 2.8)
2
-
3
-project ( AISL C)
4
-
5
-set (PROJECT_TITLE "aisl")
6
-set (LIBRARY_NAME  ${PROJECT_TITLE})
7
-# set (DEMO_NAME   "demo")
8
-
9
-# Defaults --------------------------------------------------------------------
10
-
11
-include (cmake.compiler)
12
-include (cmake.version)
13
-include (cmake.system)
14
-include (cmake.paths)
15
-
16
-# Definitions -----------------------------------------------------------------
17
-
18
-add_definitions(
19
-  -DPROJECT_TITLE="${PROJECT_TITLE}"
20
-)
21
-
22
-set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden")
23
-
24
-if(DEFINED CMAKE_DEBUG)
25
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror ")
26
-  add_definitions( -DDEBUG=${CMAKE_DEBUG} )
27
-endif()
28
-
29
-
30
-# Options ---------------------------------------------------------------------
31
-
32
-#if( DEFINED WITH_EVERYTHING )
33
-#  set(WITH_TEMPLIGHT 1)
34
-#  set(WITH_OPTIONS 1)
35
-#  set(WITH_CONFIG 1)
36
-#endif()
37
-
38
-# Sources ---------------------------------------------------------------------
39
-
40
-include_directories( "." ${INCLUDE_DIR} )
41
-  
42
-add_definitions( -DLIST_WITH_APPEND
43
-                 -DCSTUFF_LIST_WITH_REMOVE_INDEX
44
-                 -DCSTUFF_LIST_WITH_REMOVE
45
-                 -DCSTUFF_LIST_WITH_APPEND
46
-                 -DCSTUFF_LIST_WITH_INSERT
47
-                 -DCSTUFF_LIST_WITH_COPY
48
-                 -DCSTUFF_STR_UTILS_WITH_COPY
49
-                 -DCSTUFF_STR_UTILS_WITH_NCAT
50
-                 -DCSTUFF_STR_UTILS_WITH_CMPI
51
-                 -DCSTUFF_STR_UTILS_WITH_PRINTF
52
-                 -DCSTUFF_STR_UTILS_WITH_NCOPY
53
-                 -DSTR_UTILS_WITH_COPY
54
-                 -DSTR_UTILS_WITH_NCOPY
55
-                 -DSTR_UTILS_WITH_CAT
56
-                 -DSTR_UTILS_WITH_PRINTF
57
-                 -DSTR_UTILS_WITH_CMPI
58
-)
59
-
60
-set ( LIBRARY_SOURCES library/aisl.c
61
-                      library/buffer.c 
62
-                      library/server.c 
63
-                      library/client.c 
64
-                      library/stream.c
65
-                      library/parser.c 
66
-                      library/http.c 
67
-                      library/handle.c 
68
-                      library/status.c 
69
-                      library/event.c 
70
-                      cStuff/list.c
71
-                      cStuff/str-utils.c)
72
-
73
-set ( DEMO_SOURCES demo/main.c demo/events.c demo/urls.c )
74
-
75
-set ( META_FILES README.md LICENSE.md AUTHORS.md)
76
-
77
-#if( DEFINED WITH_TEMPLIGHT )
78
-#  set(SOURCE_FILES ${SOURCE_FILES} ${SOURCES_DIR}/templight.c)
79
-#  add_definitions( -DWITH_TEMPLIGHT )
80
-#endif()
81
-
82
-#if( DEFINED WITH_OPTIONS )
83
-#  set(SOURCE_FILES ${SOURCE_FILES} ${SOURCES_DIR}/options.c)
84
-#  add_definitions( -DWITH_OPTIONS )
85
-#endif()
86
-
87
-#if( DEFINED WITH_CONFIG )
88
-#  set(SOURCE_FILES ${SOURCE_FILES} ${SOURCES_DIR}/config.c)
89
-#  add_definitions( -DWITH_CONFIG )
90
-#endif()
91
-
92
-find_package(OpenSSL)
93
-
94
-include_directories(
95
-  ${OPENSSL_INCLUDE_DIRS}
96
-)
97
-
98
-link_directories(
99
-  ${OPENSSL_LIBRARY_DIRS}
100
-)
101
-
102
-# Library ----------------------------------------------------------------------
103
-
104
-add_library(${LIBRARY_NAME} SHARED ${LIBRARY_SOURCES})
105
-
106
-# Demos ------------------------------------------------------------------------
107
-
108
-#add_executable(${DEMO_NAME} ${DEMO_SOURCES})
109
-
110
-#target_link_libraries(${DEMO_NAME} ${LIBRARY_NAME})
111
-target_link_libraries(${LIBRARY_NAME} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
112
-
113
-# Installation ----------------------------------------------------------------
114
-
115
-install(
116
-  TARGETS ${LIBRARY_NAME}
117
-  DESTINATION ${CMAKE_INSTALL_LIBDIR}
118
-)
119
-#  ${LIB_INSTALL_DIR} 
120
-
121
-#install(
122
-#  FILES ${META_FILES}
123
-#  DESTINATION ${SHARE_INSTALL_PREFIX}/doc/packages/${LIBRARY_NAME}/
124
-#)
125
-
126
-install(
127
-  DIRECTORY ${INCLUDE_DIR}/${LIBRARY_NAME} 
128
-  DESTINATION ${INCLUDE_INSTALL_DIR}
129
-)
130
-
131
-

+ 19
- 23
README.md View File

@@ -1,36 +1,32 @@
1 1
 # AISL
2
-Asynchronous Internet Server Library
3 2
 
4
-## Installation on CentOS 7 / RedHat 7
3
+Asynchronous Internet Server Library provides innovative way of web development.
4
+AISL based applications have built-in web server giving full control of client
5
+serving. All you need to know is a request string? - Start prepare the response 
6
+without waiting for headers and body! Don't need some headers? - Don't save them
7
+in memory! Unwanted content-body? - simply ignore it!
5 8
 
6
-1. Add repository
7
-```
8
-sudo curl -o /etc/yum.repos.d/lowenware.repo https://lowenware.com/rpm/redhat-7/lowenware.repo
9
-```
9
+## Documentation
10 10
 
11
-2. Import GPG key
12
-```
13
-sudo rpm --import https://lowenware.com/rpm/RPM-GPG-KEY-Lowenware
14
-```
11
+[Hello World](https://lowenware.com/aisl/handbook.html#getting-started) example
12
+and full [API reference](https://lowenware.com/aisl/handbook.html#api-reference)
13
+can be found in an oficial [AISL HandBook](https://lowenware.com/aisl/handbook.html).
14
+
15
+## Installation
15 16
 
16
-3. Install
17 17
 ```
18
-sudo yum install aisl aisl-devel
18
+$ make PREFIX=/usr/local
19
+$ sudo make PREFIX=/usr/local install
20
+$ sudo cp libaisl.pc.example /usr/lib/pkgconfig/libaisl.pc
19 21
 ```
20 22
 
21
-## Installation from sources on any distro
23
+ArchLinux users can install from [AUR](https://aur.archlinux.org/packages/aisl-git/) :
22 24
 
23
-1. Configuration
24 25
 ```
25
-cmake -DCMAKE_INSTALL_PREFIX=/usr/local
26
+$ yaourt -S aisl-git
26 27
 ```
27 28
 
28
-2. Compilation
29
-```
30
-make
31
-```
29
+## License
32 30
 
33
-3. Installation
34
-```
35
-sudo make install
36
-```
31
+AISL is free for both commercial and non-commercial use, being distributed under
32
+terms of [CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0/).

+ 0
- 36
aisl.proj View File

@@ -1,36 +0,0 @@
1
-name = AISL
2
-todo = aisl.todo
3
-handbook = handbook.md
4
-version:
5
-  major = 0
6
-  minor = 0
7
-
8
-include = 
9
-definitions = 
10
-
11
-profile:
12
-  name = debug
13
-  flags = -Wall -Werror
14
-  definitions =
15
-
16
-profile:
17
-  name = release
18
-  flags =
19
-  definitions =
20
-
21
-
22
-
23
-library:
24
-  output = aisl
25
-  compiler = gcc
26
-
27
-  version:
28
-    major = $version.major
29
-    minor = $version.minor
30
-    tweak = 0
31
-    build = auto
32
-
33
-  sources = library/aisl.c,
34
-            library/buffer.c
35
-
36
-

+ 0
- 1
cStuff

@@ -1 +0,0 @@
1
-Subproject commit a423fa7a6dfbd637f3c0b248123f682456fccad7

+ 0
- 7
cmake.compiler View File

@@ -1,7 +0,0 @@
1
-
2
-if(DEFINED CMAKE_DEBUG)
3
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror ")
4
-    add_definitions(
5
-      -DDEBUG
6
-    )
7
-endif()

+ 0
- 90
cmake.paths View File

@@ -1,90 +0,0 @@
1
-# Paths -----------------------------------------------------------------------
2
-
3
-# Constants -------------------------------------------------------------------
4
-
5
-set(INCLUDE_DIR   "include")
6
-set(BUILD_DIR     "build")
7
-
8
-# CMAKE installation paths ----------------------------------------------------
9
-
10
-
11
-# -DCMAKE_INSTALL_PREFIX:PATH=/usr 
12
-
13
-if(NOT DEFINED CMAKE_INSTALL_PREFIX)
14
-    set(CMAKE_INSTALL_PREFIX "/usr")
15
-endif()
16
-
17
-
18
-# -DINCLUDE_INSTALL_DIR:PATH=/usr/include 
19
-
20
-if(NOT DEFINED INCLUDE_INSTALL_DIR)
21
-    set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include")
22
-endif()
23
-
24
-
25
-# -DSHARE_INSTALL_PREFIX:PATH=/usr/share 
26
-
27
-if(NOT DEFINED SHARE_INSTALL_PREFIX)
28
-    set(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share")
29
-endif()
30
-
31
-
32
-# -DSYSCONF_INSTALL_DIR:PATH=/etc 
33
-
34
-if(NOT DEFINED SYSCONF_INSTALL_DIR)
35
-    set(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc")
36
-endif()
37
-
38
-
39
-# -DCMAKE_INSTALL_LIBDIR:PATH=lib64 
40
-
41
-if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
42
-    set(CMAKE_INSTALL_LIBDIR "lib${SYSTEM_LIB_SUFFIX}")
43
-endif()
44
-
45
-# -DLIB_INSTALL_DIR:PATH=/usr/lib64
46
-if(NOT DEFINED LIB_INSTALL_DIR)
47
-    set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
48
-endif()
49
-
50
-
51
-# -----------------------------------------------------------------------------
52
-
53
-set(PATH_BIN     "${CMAKE_INSTALL_PREFIX}/bin")
54
-set(PATH_INC     "${INCLUDE_INSTALL_DIR}")
55
-set(PATH_CFG     "${SYSCONF_INSTALL_DIR}")
56
-set(PATH_RUN     "/var/run")
57
-set(PATH_LIB     "${LIB_INSTALL_DIR}")
58
-set(PATH_LOG     "/var/log")
59
-set(PATH_RES     "${SHARE_INSTALL_PREFIX}")
60
-set(PATH_LNG     "${SHARE_INSTALL_PREFIX}/locale")
61
-
62
-
63
-
64
-MESSAGE( STATUS "Paths:")
65
-MESSAGE( STATUS "    Prefix:           ${CMAKE_INSTALL_PREFIX}" )
66
-MESSAGE( STATUS "    Binaries:         ${PATH_BIN}" )
67
-MESSAGE( STATUS "    Configuration:    ${PATH_CFG}" )
68
-MESSAGE( STATUS "    Libraries:        ${PATH_LIB}" )
69
-MESSAGE( STATUS "    Includes:         ${PATH_INC}" )
70
-MESSAGE( STATUS "    Run:              ${PATH_RUN}" )
71
-MESSAGE( STATUS "    Log Files:        ${PATH_LOG}" )
72
-MESSAGE( STATUS "    Resources:        ${PATH_RES}" )
73
-MESSAGE( STATUS "    Locale Files:     ${PATH_LNG}" )
74
-MESSAGE( STATUS "")
75
-
76
-# Compiler's Definitions ------------------------------------------------------
77
-
78
-add_definitions(
79
-    -DPREFIX="${CMAKE_INSTALL_PREFIX}"
80
-    -DPATH_BIN="${PATH_BIN}"
81
-    -DPATH_CFG="${PATH_CFG}"
82
-    -DPATH_INC="${PATH_INC}"
83
-    -DPATH_LIB="${PATH_LIB}"
84
-    -DPATH_RUN="${PATH_RUN}"
85
-    -DPATH_LOG="${PATH_LOG}"
86
-    -DPATH_LNG="${PATH_LNG}"
87
-    -DPATH_RES="${PATH_RES}"
88
-)
89
-
90
-# -----------------------------------------------------------------------------

+ 0
- 18
cmake.system View File

@@ -1,18 +0,0 @@
1
-# Architecture ----------------------------------------------------------------
2
-
3
-if(CMAKE_SIZEOF_VOID_P EQUAL 8)
4
-    set(SYSTEM_BITNESS    64)
5
-    set(SYSTEM_ARCH       "amd64")
6
-    set(SYSTEM_LIB_SUFFIX "64")
7
-else()
8
-    set(SYSTEM_BITNESS    32)
9
-    set(SYSTEM_ARCH       "x86")
10
-    set(SYSTEM_LIB_SUFFIX "")
11
-endif()
12
-
13
-add_definitions(
14
-    -DSYSTEM_NAME="${CMAKE_SYSTEM_NAME}"
15
-    -DSYSTEM_BITNESS=${SYSTEM_BITNESS}
16
-    -DSYSTEM_ARCH_${SYSTEM_ARCH}
17
-    -DSYSTEM_ARCH="${SYSTEM_ARCH}"
18
-)

+ 0
- 61
cmake.version View File

@@ -1,61 +0,0 @@
1
-# -----------------------------------------------------------------------------
2
-#
3
-# CMake module for paths generation in DEBUG and RELEASE modes
4
-#
5
-# (c) Copyright Löwenware Ltd. (https://lowenware.com/)
6
-#
7
-# -----------------------------------------------------------------------------
8
-
9
-
10
-## Constants
11
-set (VERSION_FILE "version")
12
-set (
13
-    VERSION_REGEX
14
-    "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-(pre|alpha|beta|rc|release))?"
15
-)
16
-
17
-# Read file
18
-file (READ ${VERSION_FILE} VERSION_STRING)
19
-
20
-# Match file content
21
-string(REGEX MATCH ${VERSION_REGEX} VERSION_STRING ${VERSION_STRING} )
22
-
23
-# Set Version constants
24
-set (VERSION_MAJOR ${CMAKE_MATCH_1})
25
-set (VERSION_MINOR ${CMAKE_MATCH_2})
26
-set (VERSION_TWEAK ${CMAKE_MATCH_3})
27
-
28
-if     (CMAKE_MATCH_5 STREQUAL "pre")
29
-    set(VERSION_CYCLE 1)
30
-elseif (CMAKE_MATCH_5 STREQUAL "alpha")
31
-    set (VERSION_CYCLE 2)
32
-elseif (CMAKE_MATCH_5 STREQUAL "beta")
33
-    set (VERSION_CYCLE 3)
34
-elseif (CMAKE_MATCH_5 STREQUAL "rc")
35
-    set (VERSION_CYCLE 4)
36
-else()
37
-    set (VERSION_CYCLE 0)
38
-endif()
39
-
40
-set (VERSION_LABEL ${CMAKE_MATCH_4})
41
-
42
-# Add compiler macros
43
-
44
-add_definitions(
45
-    -DVERSION_MAJOR=${VERSION_MAJOR}
46
-    -DVERSION_MINOR=${VERSION_MINOR}
47
-    -DVERSION_TWEAK=${VERSION_TWEAK}
48
-    -DVERSION_CYCLE=${VERSION_CYCLE}
49
-    -DVERSION_LABEL="${VERSION_LABEL}"
50
-)
51
-
52
-#Print output
53
-
54
-MESSAGE(
55
-    STATUS "${PROJECT_TITLE} version: " ${VERSION_MAJOR} "."
56
-                                        ${VERSION_MINOR} "."
57
-                                        ${VERSION_TWEAK} "-"
58
-                                        ${VERSION_CYCLE_TEXT} " "
59
-                                        ${VERSION_LABEL}
60
-)
61
-

+ 31
- 0
examples.mk View File

@@ -0,0 +1,31 @@
1
+#
2
+# examples.mk
3
+# Ilja Kartašov, 2019-03-17 17:40
4
+#
5
+
6
+EXAMPLES_DIR ?= examples
7
+
8
+EXAMPLES_CFLAGS := \
9
+  $(PROJECT_INCLUDES) \
10
+  -std=c99 \
11
+  -pedantic \
12
+  -Wall \
13
+  -Wmissing-prototypes \
14
+  -Wstrict-prototypes \
15
+  -Wold-style-definition \
16
+  -O2 \
17
+  -s \
18
+  $(CFLAGS) \
19
+
20
+
21
+EXAMPLES_LDFLAGS = -L./ -L./build -laisl -Wl,-rpath=./build
22
+
23
+examples: library hello_world
24
+
25
+hello_world:
26
+	$(info compiling: hello world)
27
+	@$(CC) $(EXAMPLES_CFLAGS)  \
28
+     -o $(OUT_DIR)/hello-world $(EXAMPLES_DIR)/hello-world.c $(EXAMPLES_LDFLAGS)
29
+
30
+# vim:ft=make
31
+#

+ 104
- 0
examples/hello-world.c View File

@@ -0,0 +1,104 @@
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file hello-world.c
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief AISL usage example: Hello World
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+ */
15
+
16
+#include <stdio.h>
17
+#include <stdlib.h>
18
+
19
+/* Include library meta header */
20
+#include <aisl/aisl.h>
21
+
22
+
23
+static void
24
+hello_world(const struct aisl_evt *evt, void *p_ctx);
25
+
26
+
27
+static const struct aisl_cfg_srv m_srv[] = {{
28
+	.host   = "0.0.0.0",
29
+	.port   = 8080,
30
+	.secure = false
31
+}};
32
+
33
+
34
+static const struct aisl_cfg m_cfg = {
35
+	  AISL_CFG_DEFAULTS
36
+	, .srv = m_srv
37
+	, .srv_cnt = sizeof (m_srv) / sizeof (m_srv[0])
38
+	, .ssl = NULL
39
+	, .ssl_cnt = 0
40
+	, .callback = hello_world
41
+	, .p_ctx = NULL
42
+};
43
+
44
+
45
+static void
46
+hello_world(const struct aisl_evt *evt, void *p_ctx)
47
+{
48
+	AislStream s;
49
+
50
+	const char html[] = 
51
+		"<html>"
52
+			"<head>"
53
+				"<title>Hello World</title>"
54
+			"</head>"
55
+			"<body>"
56
+				"<h1>Hello World</h1>"
57
+				"<p>Powered by AISL</p>"
58
+			"</body>"
59
+		"</html>";
60
+	
61
+	fprintf(stdout, "Event: %s\n", aisl_event_to_string(evt->code) );
62
+
63
+	if (evt->code != AISL_EVENT_STREAM_REQUEST)
64
+		return;
65
+
66
+	s = evt->source;
67
+
68
+	if (aisl_response(s, AISL_HTTP_OK, sizeof (html)-1) == AISL_SUCCESS) {
69
+		if (aisl_write(s, html, sizeof (html)-1) != -1) {
70
+			aisl_flush(s);
71
+			return;
72
+		}
73
+	}
74
+
75
+	aisl_reject(s);
76
+	(void) p_ctx;
77
+}
78
+
79
+
80
+int
81
+main(int argc, char **argv)
82
+{
83
+	AislInstance aisl;    /**< AISL instance pointer */
84
+	AislStatus status;  /**< AISL status code */
85
+
86
+	/* Initialize instance */
87
+	if ( (aisl = aisl_new(&m_cfg)) != NULL ) {
88
+		/* launch application loop */
89
+		fprintf(stdout, "Entering main loop\n" );
90
+		for(;;) {
91
+			status = aisl_run_cycle(aisl);
92
+
93
+			if ( status != AISL_SUCCESS )
94
+				aisl_sleep(aisl, 500);
95
+		}
96
+
97
+		aisl_free(aisl);
98
+	} else {
99
+		fprintf(stderr, "Failed to initialize AISL\n");
100
+	}
101
+
102
+	return 0;
103
+}
104
+

BIN
examples/vgcore.12255 View File


BIN
examples/vgcore.13889 View File


BIN
examples/vgcore.18015 View File


BIN
examples/vgcore.18664 View File


BIN
examples/vgcore.18862 View File


BIN
examples/vgcore.23466 View File


BIN
examples/vgcore.27845 View File


BIN
examples/vgcore.28571 View File


BIN
examples/vgcore.30230 View File


BIN
examples/vgcore.31633 View File


BIN
examples/vgcore.7201 View File


BIN
examples/vgcore.8596 View File


+ 26
- 96
include/aisl/aisl.h View File

@@ -1,107 +1,37 @@
1
-/* ----------------------------------------------------------------------------
2
- * aisl.h - header file for AISL library, part of AISLing Technology
1
+/******************************************************************************
3 2
  *
4
- * Copyright (c) 2017 by Löwenware Ltd. (https://lowenware.com/)
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5 5
  *
6
- * Authors and maintainers:
7
- *   Ilja Kartaschoff <ik@lowenware.com>
8
- *
9
- * DOCUMENTATION
10
- * This file is not designed to be used as a documentation, but for looking at 
11
- * the precise values of constants and definitions.
12
- * Please, for documentation refer to web page https://lowenware.com/aisling/ or
13
- * file READEME.md from library source package.
14
- *
15
- * LICENSE and DISCLAIMER
16
- *
17
- * -------------------------------------------------------------------------- */
18
-
19
-#ifndef _AISL_H_
20
-#define _AISL_H_
21
-
22
-/* system includes ---------------------------------------------------------- */
23
-
24
-#include <stdint.h>
25
-#include <stdbool.h>
26
-#include <stdarg.h>
27
-#include <arpa/inet.h>
28
-
29
-/* aisl includes ------------------------------------------------------------ */
30
-
31
-#include <aisl/status.h>
32
-#include <aisl/event.h>
33
-#include <aisl/stream.h>
34
-#include <aisl/handle.h>
35
-#include <aisl/http.h>
36
-
6
+ ******************************************************************************/
37 7
 
8
+/**
9
+ * @file aisl/aisl.h
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Meta header file of AISL
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+ */
38 15
 
39
-/* Control calls ------------------------------------------------------------ */
40
-
41
-/* DEPRECATED, use aisl_handle_new instead
42
- * */
43
-aisl_status_t
44
-aisl_init();
45
-
46
-/* DEPRECATED, use aisl_handle_free instead
47
- * */
48
-void
49
-aisl_release();
50
-
51
-/* Tell library what socket should be opened. Could be called multiple times.
52
- * This function only save passed data. In fact, sockets are being opened only
53
- * inside aisl_run loop.
54
- * @address : host or IP to listen
55
- * @port    : port to listen
56
- * */
57
-
58
-aisl_status_t
59
-aisl_select(const char *address, int port);
60
-
61
-/* Start main loop
62
- * @result  : exit code
63
- * */
64
-aisl_status_t
65
-aisl_run( int * flags );
66
-
67
-/* Event calls -------------------------------------------------------------- */
68
-
69
-/* Add callback to be executed after timeout. If callback function will return
70
- * true, callback will be kept in main loop and raised again, otherwise it will
71
- * be removed
72
- * @cb       : callback function:  bool callback (void * u_data)
73
- * @usec     : delay in milliseconds
74
- * @data     : user-defined data to be passed to callback
75
- * */
76
-aisl_status_t
77
-aisl_delay(aisl_callback_t cb, uint32_t msec, void *u_data);
78
-
79
-/* Add event listener
80
- * @source : pointer to event source
81
- * @e_id   : event identifier
82
- * @cb     : callback to be executed
83
- * */
84
-aisl_status_t
85
-aisl_listen(void *source, aisl_event_t e_id, aisl_callback_t cb);
16
+#ifndef AISL_H_17EF1616_A00F_49C9_92B6_273AB13BF279
17
+#define AISL_H_17EF1616_A00F_49C9_92B6_273AB13BF279
86 18
 
87
-/* Raise event
88
- * @source : pointer to event source data
89
- * @e_id   : event identifier
90
- * @...    : custom event data
91
- * @result : true if event was handled, false otherwise
92
- * */
93
-bool
94
-aisl_raise(void *source, aisl_event_t e_id, ... );
19
+/* AISL configuration structure */
20
+#include <aisl/config.h>
95 21
 
96
-/* input stream functions --------------------------------------------------- */
22
+/* AISL types and stringifiers */
23
+#include <aisl/types.h>
97 24
 
25
+/* AISL instancing, initialization and processing */
26
+#include <aisl/instance.h>
98 27
 
99
-const char *
100
-aisl_header_get(aisl_stream_t stream, const char *key);
28
+/* Embedded HTTP(s) servers */
29
+#include <aisl/server.h>
101 30
 
102
-const char *
103
-aisl_header_get_by_index(aisl_stream_t stream, const char **key, uint32_t i);
31
+/* HTTP(s) clients */
32
+#include <aisl/client.h>
104 33
 
105
-/* -------------------------------------------------------------------------- */
34
+/* HTTP(s) streaming */
35
+#include <aisl/stream.h>
106 36
 
107
-#endif
37
+#endif /* !AISL_H */

+ 74
- 0
include/aisl/client.h View File

@@ -0,0 +1,74 @@
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file aisl/client.h
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Declarations of #AislCLient functions
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+ */
15
+
16
+#ifndef AISL_CLIENT_H_A6C37DCF_2183_4F22_A5A0_668311757A08
17
+#define AISL_CLIENT_H_A6C37DCF_2183_4F22_A5A0_668311757A08
18
+
19
+#include <aisl/types.h>
20
+
21
+
22
+/**
23
+ * @brief Gets #AislServer instance associated with client.
24
+ * @param client an #AislClient instance pointer.
25
+ * @return an associated #AislServer pointer.
26
+ */
27
+AislServer
28
+aisl_client_get_server(AislClient client);
29
+
30
+
31
+/**
32
+ * @brief Gets security connection status.
33
+ * @param client an #AislClient instance pointer.
34
+ * @return true if SSL is enabled and false if disabled.
35
+ */
36
+bool
37
+aisl_client_is_secure(AislClient client);
38
+
39
+
40
+/**
41
+ * @brief Gets client's connection state.
42
+ * @param client an #AislClient instance pointer.
43
+ * @return true if client is online and false if is offline.
44
+ */
45
+bool
46
+aisl_client_is_online(AislClient client);
47
+
48
+
49
+/**
50
+ * @brief Forcefully closes client's connection.
51
+ * @param client an #AislClient instance pointer.
52
+ */
53
+void
54
+aisl_client_disconnect(AislClient client);
55
+
56
+
57
+/**
58
+ * @brief Gets HTTP protocol version.
59
+ * @param client an #AislClient instance pointer.
60
+ * @return HTTP protocol version
61
+ */
62
+AislHttpVersion
63
+aisl_client_get_http_version(AislClient client);
64
+
65
+
66
+/**
67
+ * @brief Copies #AislClient network address to provided sockaddr_in structure.
68
+ * @param client an #AislClient instance pointer.
69
+ * @param address a pointer to a sockaddr_in structure
70
+ */
71
+void
72
+aisl_client_get_address(AislClient client, struct sockaddr_in *address);
73
+
74
+#endif /* !AISL_CLIENT_H */

+ 64
- 0
include/aisl/config.h View File

@@ -0,0 +1,64 @@
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file aisl/config.h
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Declarations of AISL configuration structures
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+ */
15
+
16
+#ifndef AISL_CONFIG_H_DB67A89B_5CAF_4A5F_AEB1_6DB9F84827D6
17
+#define AISL_CONFIG_H_DB67A89B_5CAF_4A5F_AEB1_6DB9F84827D6
18
+
19
+#include <aisl/types.h>
20
+
21
+#define AISL_CFG_DEFAULTS \
22
+	  .client_spool_size      = 32    \
23
+	, .initial_buffer_size    = 16536 \
24
+	, .client_accept_limit    = 1024  \
25
+	, .client_silence_timeout = 30    \
26
+
27
+
28
+/** @brief Server configuration structure
29
+ */
30
+struct aisl_cfg_srv {
31
+	const char *host;         /**< server IP to listen */
32
+	uint16_t    port;         /**< server port to listen */
33
+	bool        secure;       /**< shall server use TLS */
34
+};
35
+
36
+
37
+/** @brief SSL configuration structure
38
+ */
39
+struct aisl_cfg_ssl {
40
+	const char *host;         /**< secure server hostname */
41
+	const char *key_file;     /**< path to SSL key file */
42
+	const char *crt_file;     /**< path to SSL certificate file */
43
+};
44
+
45
+
46
+/** @brief AISL initial configuration structure
47
+ */
48
+struct aisl_cfg {
49
+	AislCallback callback;         /**< A pointer to #AislCallback event handler */
50
+	void *p_ctx;                   /**< User defined context for #AislCallback */
51
+
52
+	const struct aisl_cfg_srv *srv;      /**< A pointer to array of #aisl_cfg_srv */
53
+	const struct aisl_cfg_ssl *ssl;      /**< A pointer to array of #aisl_cfg_ssl  */
54
+
55
+	int srv_cnt;                   /**< Size of #aisl_cfg_srv array */
56
+	int ssl_cnt;                   /**< Size of #aisl_cfg_ssl array */
57
+
58
+	int client_spool_size;         /**< Initial size of client spool */
59
+	int initial_buffer_size;       /**< Initial size of communication buffer */
60
+	int client_accept_limit;       /**< Maximal number of concurent clients */
61
+	int client_silence_timeout;    /**< Client silence timeout */
62
+};
63
+
64
+#endif /* !AISL_CONFIG_H */

+ 0
- 128
include/aisl/event.h View File

@@ -1,128 +0,0 @@
1
-#ifndef _AISL_EVENT_H_
2
-#define _AISL_EVENT_H_
3
-
4
-#include <stdbool.h>
5
-#include <stdarg.h>
6
-#include <arpa/inet.h>
7
-#include <aisl/stream.h>
8
-#include <aisl/status.h>
9
-#include <aisl/http.h>
10
-
11
-/* -------------------------------------------------------------------------- */
12
-
13
-typedef unsigned int aisl_event_t;
14
-/* -------------------------------------------------------------------------- */
15
-
16
-typedef enum
17
-{
18
-  AISL_SERVER_OPEN        = 100,
19
-  AISL_SERVER_ERROR       = 190,
20
-
21
-  AISL_CLIENT_CONNECT     = 200,
22
-  AISL_CLIENT_DISCONNECT  = 210,
23
-  AISL_CLIENT_TIMEOUT     = 220,
24
-
25
-  AISL_STREAM_OPEN        = 300,   /* 5 - headers recieved */
26
-  AISL_STREAM_HEADER      = 310, /* 5 - headers recieved */
27
-  AISL_STREAM_INPUT       = 320, /* 6 - chunk of data transmission */
28
-  AISL_STREAM_REQUEST     = 330,   /* 7 - data received, response required */
29
-  AISL_STREAM_OUTPUT      = 340,/* event for long-size responses optimal handling */
30
-  AISL_STREAM_CLOSE       = 350,
31
-  AISL_STREAM_ERROR       = 390,   /* 8 - bad request */
32
-
33
-  AISL_EVENTS_CUSTOM      = 999
34
-
35
-} aisl_event_id_t;
36
-
37
-
38
-/* -------------------------------------------------------------------------- */
39
-
40
-/* AISL_SERVER_OPEN event handler */
41
-typedef bool
42
-(*aisl_server_open_t)(       aisl_server_t        server,
43
-                             int                  flags );
44
-
45
-/* AISL_SERVER_ERROR event handler */
46
-typedef bool
47
-(*aisl_server_error_t)(      aisl_server_t        server,
48
-                             int                  flags,
49
-                             const char         * details );
50
-
51
-/* AISL_CLIENT_CONNECT event handler */
52
-typedef bool
53
-(*aisl_client_connect_t)(    aisl_server_t        server,
54
-                             aisl_client_t        client );
55
-
56
-/* AISL_CLIENT_DISCONNECT event handler */
57
-typedef bool
58
-(*aisl_client_disconnect_t)( aisl_server_t        server,
59
-                             aisl_client_t        client );
60
-
61
-/* AISL_CLIENT_DISCONNECT event handler */
62
-typedef bool
63
-(*aisl_client_timeout_t)(    aisl_server_t        server,
64
-                             aisl_client_t        client );
65
-
66
-/* AISL_STREAM_OPEN event handler */
67
-typedef bool
68
-(*aisl_stream_open_t)(       aisl_stream_t        s,
69
-                             aisl_http_method_t   method,
70
-                             const char         * path,
71
-                             const char         * query );
72
-
73
-typedef bool
74
-(*aisl_stream_header_t)(     aisl_stream_t        s,
75
-                             const char         * key,
76
-                             const char         * value );
77
-
78
-
79
-/* AISL_STREAM_INPUT event handler */
80
-typedef bool
81
-(*aisl_stream_input_t)(      aisl_stream_t        s,
82
-                             char               * data,
83
-                             int                  len );
84
-
85
-/* AISL_STREAM_REQUEST event handler */
86
-typedef bool
87
-(*aisl_stream_request_t)(    aisl_stream_t        s );
88
-
89
-/* AISL_STREAM_OUTPUT event handler */
90
-typedef bool
91
-(*aisl_stream_output_t)(     aisl_stream_t        s,
92
-                             uint32_t             buffer_space );
93
-
94
-typedef bool
95
-(*aisl_stream_close_t)(      aisl_stream_t        s );
96
-
97
-/* AISL_STREAM_ERROR event handler */
98
-typedef bool
99
-(*aisl_stream_error_t)(      aisl_stream_t        s,
100
-                             const char         * details );
101
-
102
-/* CUSTOM event_handler */
103
-typedef bool
104
-(*aisl_custom_event_t)(      void               * source,
105
-                             va_list              vl );
106
-
107
-/* on delay timeout */
108
-typedef bool
109
-(*aisl_delay_timeout_t)(     void               * u_data );
110
-
111
-/* -------------------------------------------------------------------------- */
112
-
113
-/* type for event callbacks to use in structures and function prototypes */
114
-typedef bool
115
-(* aisl_callback_t) (void);
116
-
117
-/* cast callback as aisl_callback_t */
118
-#define AISL_CALLBACK(x) ((aisl_callback_t) x)
119
-
120
-/* -------------------------------------------------------------------------- */
121
-
122
-const char *
123
-aisl_event_get_text( aisl_event_t e_id );
124
-
125
-
126
-/* -------------------------------------------------------------------------- */
127
-
128
-#endif

+ 0
- 76
include/aisl/handle.h View File

@@ -1,76 +0,0 @@
1
-#ifndef _AISL_HANDLE_H_
2
-#define _AISL_HANDLE_H_
3
-
4
-#include <aisl/status.h>
5
-#include <aisl/event.h>
6
-
7
-/* -------------------------------------------------------------------------- */
8
-
9
-#define AISL_FLAG_SSL (1<<0)
10
-
11
-/* -------------------------------------------------------------------------- */
12
-
13
-typedef struct aisl_handle * aisl_handle_t;
14
-
15
-
16
-/* -------------------------------------------------------------------------- */
17
-
18
-aisl_handle_t
19
-aisl_handle_new(size_t min_clients, size_t buffer_size);
20
-
21
-/* -------------------------------------------------------------------------- */
22
-
23
-aisl_handle_t
24
-aisl_handle_from_stream( aisl_stream_t s );
25
-
26
-/* -------------------------------------------------------------------------- */
27
-
28
-void
29
-aisl_handle_free( aisl_handle_t self );
30
-
31
-/* -------------------------------------------------------------------------- */
32
-
33
-aisl_status_t
34
-aisl_bind( aisl_handle_t self, const char * address, int port, int flags );
35
-
36
-/* -------------------------------------------------------------------------- */
37
-
38
-aisl_status_t
39
-aisl_set_ssl( aisl_handle_t self, const char * server_name,
40
-                                  const char * key_file,
41
-                                  const char * crt_file );
42
-
43
-/* -------------------------------------------------------------------------- */
44
-
45
-aisl_status_t
46
-aisl_set_callback( aisl_handle_t    self,
47
-                   void           * source,
48
-                   aisl_event_t     e_id,
49
-                   aisl_callback_t  cb );
50
-
51
-/* -------------------------------------------------------------------------- */
52
-
53
-bool
54
-aisl_raise_event( aisl_handle_t   self,
55
-                  void          * source,
56
-                  aisl_event_t    e_id,
57
-                                  ... ); 
58
-
59
-/* -------------------------------------------------------------------------- */
60
-
61
-aisl_status_t
62
-aisl_run_cycle( aisl_handle_t self );
63
-
64
-/* -------------------------------------------------------------------------- */
65
-
66
-const char *
67
-aisl_handle_get_error( aisl_handle_t self );
68
-
69
-/* -------------------------------------------------------------------------- */
70
-
71
-int
72
-aisl_sleep( aisl_handle_t self, unsigned long usec );
73
-
74
-/* -------------------------------------------------------------------------- */
75
-
76
-#endif

+ 0
- 104
include/aisl/http.h View File

@@ -1,104 +0,0 @@
1
-#ifndef _AISL_HTTP_H_
2
-#define _AISL_HTTP_H_
3
-
4
-/* -------------------------------------------------------------------------- */
5
-
6
-typedef enum
7
-{
8
-  AISL_HTTP_1_0,
9
-  AISL_HTTP_1_1,
10
-  AISL_HTTP_2_0
11
-
12
-} aisl_http_version_t;
13
-
14
-/* -------------------------------------------------------------------------- */
15
-
16
-typedef enum {
17
-  AISL_HTTP_GET,
18
-  AISL_HTTP_PUT,
19
-  AISL_HTTP_POST,
20
-  AISL_HTTP_HEAD,
21
-  AISL_HTTP_TRACE,
22
-  AISL_HTTP_DELETE,
23
-  AISL_HTTP_OPTIONS,
24
-  AISL_HTTP_CONNECT,
25
-
26
-  AISL_HTTP_PRI
27
-
28
-} aisl_http_method_t;
29
-
30
-/* -------------------------------------------------------------------------- */
31
-
32
-typedef enum 
33
-{
34
-    /* informational ------------------------------ */
35
-    AISL_HTTP_CONTINUE                      = 100,
36
-    AISL_HTTP_SWITCHING_PROTOCOLS,
37
-    /* Successful --------------------------------- */
38
-    AISL_HTTP_OK                            = 200,
39
-    AISL_HTTP_CREATED,
40
-    AISL_HTTP_ACCEPTED,
41
-    AISL_HTTP_NON_AUTHORITATIVE_INFORMATION,
42
-    AISL_HTTP_NO_CONTENT,
43
-    AISL_HTTP_RESET_CONTENT,
44
-    AISL_HTTP_PARTIAL_CONTENT,
45
-    /* redirection -------------------------------- */
46
-    AISL_HTTP_MULTIPLE_CHOICES              = 300,
47
-    AISL_HTTP_MOVED_PERMANENTLY,
48
-    AISL_HTTP_FOUND,
49
-    AISL_HTTP_SEE_OTHER,
50
-    AISL_HTTP_NOT_MODIFIED,
51
-    AISL_HTTP_USE_PROXY,
52
-    AISL_HTTP_UNUSED,
53
-    AISL_HTTP_TEMPORARY_REDIRECT,
54
-    /* client error ------------------------------- */
55
-    AISL_HTTP_BAD_REQUEST                   = 400,
56
-    AISL_HTTP_UNAUTHORIZED,
57
-    AISL_HTTP_PAYMENT_REQUIRED,
58
-    AISL_HTTP_FORBIDDEN,
59
-    AISL_HTTP_NOT_FOUND,
60
-    AISL_HTTP_METHOD_NOT_ALLOWED,
61
-    AISL_HTTP_NOT_ACCEPTABLE,
62
-    AISL_HTTP_PROXY_AUTHENTICATION_REQUIRED,
63
-    AISL_HTTP_REQUEST_TIMEOUT,
64
-    AISL_HTTP_CONFLICT,
65
-    AISL_HTTP_GONE,
66
-    AISL_HTTP_LENGTH_REQUIRED,
67
-    AISL_HTTP_PRECONDITION_FAILED,
68
-    AISL_HTTP_REQUEST_ENTITY_TOO_LARGE,
69
-    AISL_HTTP_REQUEST_URI_TOO_LONG,
70
-    AISL_HTTP_UNSUPPORTED_MEDIA_TYPE,
71
-    AISL_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE,
72
-    AISL_HTTP_EXPECTATION_FAILED,
73
-    /* server error ------------------------------- */
74
-    AISL_HTTP_INTERNAL_SERVER_ERROR          = 500,
75
-    AISL_HTTP_NOT_IMPLEMENTED,
76
-    AISL_HTTP_BAD_GATEWAY,
77
-    AISL_HTTP_SERVICE_UNAVAILABLE,
78
-    AISL_HTTP_GATEWAY_TIMEOUT,
79
-    AISL_HTTP_VERSION_NOT_SUPPORTED
80
-
81
-} aisl_http_response_t;
82
-/* -------------------------------------------------------------------------- */
83
-
84
-const char *
85
-aisl_http_version_to_string(aisl_http_version_t version);
86
-
87
-/* -------------------------------------------------------------------------- */
88
-
89
-const char *
90
-aisl_http_response_to_string(aisl_http_response_t code);
91
-
92
-/* -------------------------------------------------------------------------- */
93
-
94
-const char *
95
-aisl_http_secure_to_string( int is_secure );
96
-
97
-/* -------------------------------------------------------------------------- */
98
-
99
-const char *
100
-aisl_http_method_to_string( aisl_http_method_t method );
101
-
102
-/* -------------------------------------------------------------------------- */
103
-
104
-#endif

+ 66
- 0
include/aisl/instance.h View File

@@ -0,0 +1,66 @@
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file aisl/instance.h
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Declarations of #AislInstance functions
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+
15
+ */
16
+
17
+#ifndef AISL_INSTANCE_H_60576F41_454C_4189_B91A_F40501132230
18
+#define AISL_INSTANCE_H_60576F41_454C_4189_B91A_F40501132230
19
+
20
+#include <stdint.h>
21
+#include <stdarg.h>
22
+#include <aisl/types.h>
23
+#include <aisl/config.h>
24
+
25
+
26
+
27
+/**
28
+ * @brief Allocates new AISL instance.
29
+ *
30
+ * @param cfg a pointer to #aisl_cfg_t structure.
31
+ * @return an #AislInstance instance pointer.
32
+ */
33
+AislInstance
34
+aisl_new(const struct aisl_cfg *cfg);
35
+
36
+
37
+/**
38
+ * @brief Frees previously allocated pointer of AISL instance.
39
+ * @param instance a pointer to #AislInstance instance.
40
+ */
41
+void
42
+aisl_free(AislInstance instance);
43
+
44
+
45
+/** 
46
+ * @brief A core function doing all the library routines.
47
+ * Designed to be called inside application main loop
48
+ * @param instance a pointer to #AislInstance instance.
49
+ * @return #AislStatus code.
50
+ */
51
+AislStatus
52
+aisl_run_cycle(AislInstance instance);
53
+
54
+
55
+/** 
56
+ * @brief Function to sleep CPU if nothing to do.
57
+ * Calls select on all the opened sockets inside.
58
+ * @param instance a pointer to #AislInstance instance.
59
+ * @param usec a number of miliseconds to wait for any data on sockets.
60
+ * @return #AislStatus code.
61
+ */
62
+AislStatus
63
+aisl_sleep(AislInstance instance, uint32_t usec);
64
+
65
+
66
+#endif /* !AISL_INSTANCE_H */

+ 48
- 0
include/aisl/server.h View File

@@ -0,0 +1,48 @@
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file aisl/server.h
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Declarations of #AislServer functions
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+ */
15
+
16
+#ifndef AISL_SERVER_H_CC564608_7A05_4B31_9E7E_32750BC60768
17
+#define AISL_SERVER_H_CC564608_7A05_4B31_9E7E_32750BC60768
18
+
19
+#include <arpa/inet.h>
20
+#include <aisl/types.h>
21
+
22
+/**
23
+ * @brief Function to get appropriate AISL instance pointer from server pointer.
24
+ * @param server an #AislServer pointer.
25
+ * @return an #AislInstance instance pointer.
26
+ */
27
+AislInstance
28
+aisl_server_get_instance(AislServer server);
29
+
30
+
31
+/**
32
+ * @brief Copies server listen address information to sockaddr_in structure.
33
+ * @param server an #AislServer pointer.
34
+ * @param address a pointer to sockaddr_in structure.
35
+ */
36
+void
37
+aisl_server_get_address(AislServer server, struct sockaddr_in *address);
38
+
39
+
40
+/**
41
+ * @brief Function to get on and off status of SSL for the #AislServer.
42
+ * @param server an #AislServer pointer.
43
+ * @return a boolean value representing SSL enabled/disabled state.
44
+ */
45
+bool
46
+aisl_server_get_ssl(AislServer server);
47
+
48
+#endif /* !AISL_SERVER_H */

+ 0
- 24
include/aisl/status.h View File

@@ -1,24 +0,0 @@
1
-#ifndef _AISL_STATUS_H_
2
-#define _AISL_STATUS_H_
3
-
4
-/* -------------------------------------------------------------------------- */
5
-
6
-typedef enum {
7
-
8
-  AISL_EXTCALL_ERROR  = -3,
9
-  AISL_SYSCALL_ERROR  = -2,
10
-  AISL_MALLOC_ERROR   = -1,
11
-
12
-  AISL_SUCCESS        = 0,
13
-  AISL_IDLE           = 1
14
-
15
-} aisl_status_t;
16
-
17
-/* -------------------------------------------------------------------------- */
18
-
19
-const char *
20
-aisl_status_to_string(aisl_status_t status);
21
-
22
-/* -------------------------------------------------------------------------- */
23
-
24
-#endif

+ 173
- 146
include/aisl/stream.h View File

@@ -1,172 +1,199 @@
1
-#ifndef _AISL_STREAM_H_
2
-#define _AISL_STREAM_H_
3
-
4
-#include <arpa/inet.h>
5
-/* Library statuses */
6
-/* HTTP requests */
7
-#include <aisl/http.h>
8
-#include <aisl/status.h>
9
-
10
-/* -------------------------------------------------------------------------- */
11
-
12
-typedef struct sockaddr_in * aisl_server_t;
13
-typedef struct sockaddr_in * aisl_client_t;
14
-
15
-struct aisl_stream
16
-{
17
-  /* DO NOT USE PROPERTIES DIRECTLY IN NEW CODE */
18
-
19
-  struct sockaddr_in    *client;
20
-
21
-  const char            *host;
22
-  const char            *path;
23
-  const char            *query;
24
-  const char            *scheme;
25
-
26
-  void                  *u_ptr;     /* pointer to bind custom data to stream */
27
-
28
-  aisl_http_method_t     request_method;
29
-};
30
-
31
-/* pointer to stream descriptor */
32
-typedef struct aisl_stream * aisl_stream_t;
33
-
34
-/* -------------------------------------------------------------------------- */
35
-
36
-/* start response to client
37
- * this function should be called before any header or content function
38
- * necessary protocol headers as well as Content-Type and Content-Length
39
- * will be set automaticaly
40
- * @stream         : stream instance
41
- * @status         : HTTP response status code (default 200)
42
- * @content_type   : string with content type (default text/html), NULL -> no
43
- * @content_length : length of content, 0 = no content
44
- * */
45
-aisl_status_t
46
-aisl_response(aisl_stream_t stream, aisl_http_response_t  status_code,
47
-                                    const char           *content_type,
48
-                                    uint32_t              content_length);
49
-
50
-/* send all buffered data to client
51
- * ALL responses should always be finished with calling of this method
52
- * @stream         : stream instance
53
- * */
54
-aisl_status_t
55
-aisl_flush(aisl_stream_t stream);
56
-
57
-/* header functions --------------------------------------------------------- */
58
-
59
-/* add custom header to stream
60
- * this function should be called before content functions
61
- * @stream : stream instance
62
- * @key    : header key string
63
- * @value  : header value string
64
- * */
65
-int
66
-aisl_header(aisl_stream_t stream, const char *key, const char *value);
67
-
68
-/* add custom header to stream
69
- * this function should be called before content functions
70
- * @stream  : stream instance
71
- * @key     : header key string
72
- * @f_value : value format string, same as for printf function
73
- * @...     : arguments according to f_value string
74
- * */
75
-int
76
-aisl_header_printf(aisl_stream_t stream, const char *key,
77
-                                         const char *f_value, ...);
78
-
79
-/* add custom header to stream
80
- * this function should be called before content functions
81
- * @stream  : stream instance
82
- * @key     : header key string
83
- * @f_value : value format string, same as for printf function
84
- * @args    : arguments macro according to f_value string
85
- * */
86
-int
87
-aisl_header_vprintf(aisl_stream_t stream, const char *key,
88
-                                          const char *format,
89
-                                          va_list     args);
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file aisl/stream.h
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Declarations of #AislStream functions
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+ */
15
+#ifndef AISL_STREAM_H_4D8EB622_3CE0_4F1B_AC1F_B27CCB5C2EDC
16
+#define AISL_STREAM_H_4D8EB622_3CE0_4F1B_AC1F_B27CCB5C2EDC
17
+
18
+#include <stdint.h>
19
+#include <stdarg.h>
20
+#include <aisl/types.h>
21
+
22
+#define aisl_stream_get_instance aisl_get_instance
23
+
24
+/** @brief Gets a value of #AislStream security flag
25
+ *  @param stream an #AislStream instance
26
+ *  @return is true if stream is encrypted and false otherwise
27
+ */
28
+bool
29
+aisl_is_secure(AislStream stream);
90 30
 
91 31
 
92
-/* data response functions -------------------------------------------------- */
32
+/** @brief Gets an #AislClient instance associated with the stream
33
+ *  @param stream an #AislStream instance
34
+ *  @return an #AislClient instance pointer
35
+ */
36
+AislClient
37
+aisl_get_client(AislStream stream);
93 38
 
94
-/* response formated data to client
95
- * @stream : stream instance
96
- * @format : format string, same as for printf
97
- * @...    : arguments according to format string
98
- * @result : number of responed bytes
99
- * */
100
-int
101
-aisl_printf(aisl_stream_t stream, const char *format, ...);
102 39
 
40
+/** @brief Gets an #AislServer instance associated with the stream
41
+ *  @param stream an #AislStream instance
42
+ *  @return an #AislServer instance pointer
43
+ */
44
+AislServer
45
+aisl_get_server(AislStream stream);
103 46
 
104
-/* response formated data to client
105
- * @stream : stream instance
106
- * @format : format string, same as for printf
107
- * @args   : arguments macro according to format string
108
- * @result : number of responed bytes
109
- * */
110
-int
111
-aisl_vprintf(aisl_stream_t stream, const char *format, va_list args);
112
-
113
-/* response characters to client
114
- * @stream : stream instance
115
- * @data   : characters to be sent
116
- * @d_len  : number of characters to send
117
- * @result : number of responed bytes
118
- * */
119
-int
120
-aisl_write(aisl_stream_t s, const char *data, int d_len);
121 47
 
122
-/* response string to client
123
- * @string : string to be sent
124
- * @stream : stream instance
125
- * @result : number of responed bytes
126
- * */
127
-int
128
-aisl_puts(const char *string, aisl_stream_t stream);
48
+/** @brief Gets an #AislHttpVersion of the stream
49
+ *  @param stream an #AislStream instance
50
+ *  @return an #AislHttpVersion value
51
+ */
52
+AislHttpVersion
53
+aisl_get_http_version(AislStream stream);
129 54
 
130
-/* -------------------------------------------------------------------------- */
131 55
 
132
-void
133
-aisl_cancel(aisl_stream_t s);
56
+/** @brief Gets an #AislInstance pointer associated with the stream
57
+ *  @param stream an #AislStream instance
58
+ *  @return an #AislInstance pointer
59
+ */
60
+AislInstance
61
+aisl_get_instance(AislStream s);
134 62
 
135
-/* -------------------------------------------------------------------------- */
136 63
 
137
-bool
138
-aisl_is_secure(aisl_stream_t s);
64
+/** @brief Gets the stream context previously set with #aisl_set_context
65
+ *  @param stream an #AislStream instance
66
+ *  @return a pointer to the stream context
67
+ */
68
+void *
69
+aisl_get_context(AislStream stream);
139 70
 
140
-/* -------------------------------------------------------------------------- */
141 71
 
142
-void *
143
-aisl_get_context(aisl_stream_t s);
72
+/** @brief Associate a context pointer with the stream until its lifetime.
73
+ *  Previously allocated data should be free'd on #AISL_EVENT_STREAM_CLOSE if
74
+ *  not needed anymore.
75
+ *  @param stream an #AislStream instance
76
+ *  @param context a pointer to any user-defined data
77
+ */
78
+void
79
+aisl_set_context(AislStream stream, void *context);
80
+
144 81
 
145
-/* -------------------------------------------------------------------------- */
82
+/** @brief A call to start stream data transmission to a client
83
+ *  @param stream an #AislStream instance
84
+ *  @return a #AislStatus displaying if stream is ready to be proceed by teh engine
85
+ */
86
+AislStatus
87
+aisl_flush(AislStream stream);
146 88
 
89
+
90
+/** @brief A call to reject the stream. In HTTP 1.X it also closes client's connection
91
+ *  @param stream an #AislStream instance
92
+ */
147 93
 void
148
-aisl_set_context(aisl_stream_t s, void * u_ptr);
94
+aisl_reject(AislStream stream);
95
+
96
+
97
+/** @brief A call to begin the HTTP response
98
+ *  @param stream an #AislStream instance
99
+ *  @param status_code of the HTTP response
100
+ *  @param content_length in bytes or #AISL_AUTO_LENGTH if length is not knonw yet
101
+ *  @return #AislStatus code
102
+ */
103
+AislStatus
104
+aisl_response(AislStream       stream,
105
+              AislHttpResponse status_code,
106
+              uint64_t         content_length);
107
+
108
+
109
+/** @brief Adds HTTP header to the stream buffer
110
+ *  @param stream an #AislStream instance
111
+ *  @param key of HTTP header
112
+ *  @param value of HTTP header
113
+ *  @return a length of data added to the stream buffer
114
+ */
115
+int
116
+aisl_header(AislStream stream, const char *key, const char *value);
117
+
118
+
119
+/** @brief Adds printf-like formatted HTTP header to the stream buffer
120
+ *  @param stream an #AislStream instance
121
+ *  @param key of HTTP header
122
+ *  @param format of HTTP header value
123
+ *  @return a length of data added to the stream buffer
124
+ */
125
+int
126
+aisl_header_printf(AislStream  stream, 
127
+                   const char *key,
128
+                   const char *format,
129
+                   ... );
130
+
131
+
132
+/** @brief Adds vprintf-like formatted HTTP header to the stream buffer
133
+ *  @param stream an #AislStream instance
134
+ *  @param key of HTTP header
135
+ *  @param format of HTTP header value
136
+ *  @param args list for HTTP header value construction
137
+ *  @return a length of data added to the stream buffer
138
+ */
139
+int
140
+aisl_header_vprintf(AislStream  stream,
141
+                    const char *key,
142
+                    const char *format,
143
+                    va_list     args );
144
+
149 145
 
150
-/* -------------------------------------------------------------------------- */
146
+/** @brief Adds printf-like formatted HTTP response to the stream buffer
147
+ *  @param stream an #AislStream instance
148
+ *  @param format of the HTTP response
149
+ *  @return a length of data added to the stream buffer
150
+ */
151
+int
152
+aisl_printf(AislStream stream, const char *format, ...);
151 153
 
152
-aisl_client_t
153
-aisl_get_client(aisl_stream_t s);
154 154
 
155
-/* -------------------------------------------------------------------------- */
155
+/** @brief Adds vprintf-like formatted HTTP response to the stream buffer
156
+ *  @param stream an #AislStream instance
157
+ *  @param format of the HTTP response
158
+ *  @param args list for HTTP response construction
159
+ *  @return a length of data added to the stream buffer
160
+ */
161
+int
162
+aisl_vprintf(AislStream stream, const char *format, va_list args);
156 163
 
157
-aisl_server_t
158
-aisl_get_server(aisl_stream_t s);
159 164
 
160
-  /* -------------------------------------------------------------------------- */
165
+/** @brief Adds data of the HTTP response to the stream buffer
166
+ *  @param stream an #AislStream instance
167
+ *  @param data a pointer to HTTP response data array
168
+ *  @param d_len size of the HTTP response data array
169
+ *  @return a length of data added to the stream buffer
170
+ */
171
+int
172
+aisl_write(AislStream stream, const char *data, int d_len);
161 173
 
162
-aisl_http_version_t
163
-aisl_get_http_version(aisl_stream_t s);
164 174
 
165
-/* -------------------------------------------------------------------------- */
175
+/** @brief Adds a null-terminated string to the stream buffer
176
+ *  @param str_data the HTTP response string
177
+ *  @param stream an #AislStream instance
178
+ *  @return a length of data added to the stream buffer
179
+ */
180
+int
181
+aisl_puts(const char *str_data, AislStream stream);
166 182
 
183
+
184
+/** @brief Switches triggering of #AISL_EVENT_STREAM_OUTPUT
185
+ *  @param stream an #AislStream instance
186
+ *  @param value a true to enable or false to disable (default) triggering
187
+ */
167 188
 void
168
-aisl_reject( aisl_stream_t s);
189
+aisl_set_output_event(AislStream stream, bool value);
190
+
169 191
 
170
-/* -------------------------------------------------------------------------- */
192
+/** @brief Gets state of the #AISL_EVENT_STREAM_OUTPUT triggering
193
+ *  @param stream an #AislStream instance
194
+ *  @return true if triggering is enabled and flase otherwise
195
+ */
196
+bool
197
+aisl_get_output_event(AislStream stream);
171 198
 
172
-#endif
199
+#endif /* !AISL_STREAM_H */

+ 226
- 0
include/aisl/types.h View File

@@ -0,0 +1,226 @@
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file aisl/types.h
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Declarations of AISL types
12
+ *
13
+ * @see https://lowenware.com/aisl/
14
+ */
15
+
16
+#ifndef AISL_TYPES_H_86A9DBA7_C0E6_4CF4_8A64_DAAD4A81031B
17
+#define AISL_TYPES_H_86A9DBA7_C0E6_4CF4_8A64_DAAD4A81031B
18
+
19
+#include <stdint.h>
20
+#include <stdarg.h>
21
+#include <stdbool.h>
22
+
23
+#define AISL_AUTO_LENGTH (~0)
24
+
25
+/** type casts */
26
+#define AISL_CALLBACK(x) ((AislCallback) x)
27
+
28
+
29
+/** @brief AISL Instance */
30
+typedef struct aisl_instance * AislInstance;
31
+
32
+/** @brief HTTP(s) Server */
33
+typedef struct aisl_server * AislServer;
34
+
35
+/** @brief HTTP(s) Client */
36
+typedef struct aisl_client * AislClient;
37
+
38
+/** @brief Server<->Client Stream */
39
+typedef struct aisl_stream * AislStream;
40
+
41
+
42
+/** status return codes */
43
+typedef enum {
44
+	  AISL_INPUT_ERROR    = -4
45
+	, AISL_EXTCALL_ERROR  = -3
46
+	, AISL_SYSCALL_ERROR  = -2
47
+	, AISL_MALLOC_ERROR   = -1
48
+
49
+	, AISL_SUCCESS        = 0
50
+	, AISL_IDLE           = 1
51
+} AislStatus;
52
+
53
+
54
+/** @brief Converts #AislStatus code to a null terminated string
55
+ *  @param status an #AislStatus code
56
+ *  @return pointer to the string representing #AislStatus
57
+ */
58
+const char *
59
+aisl_status_to_string(AislStatus status);
60
+
61
+
62
+/** @brief HTTP version enumeration */
63
+typedef enum {
64
+	  AISL_HTTP_0_9 = 0x0009
65
+	, AISL_HTTP_1_0 = 0x0100
66
+	, AISL_HTTP_1_1 = 0x0101
67
+	, AISL_HTTP_2_0 = 0x0200
68
+} AislHttpVersion;
69
+
70
+
71
+/** @brief Converts #AislHttpVersion code to a null terminated string
72
+ *  @param version an #AislHttpVersion code
73
+ *  @return pointer to the string representing #AislHttpVersion
74
+ */
75
+const char *
76
+aisl_http_version_to_string(AislHttpVersion version);
77
+
78
+
79
+/** HTTP method enumeration */
80
+typedef enum {
81
+	  AISL_HTTP_METHOD_UNKNOWN
82
+	, AISL_HTTP_GET
83
+	, AISL_HTTP_PUT
84
+	, AISL_HTTP_POST
85
+	, AISL_HTTP_HEAD
86
+	, AISL_HTTP_TRACE
87
+	, AISL_HTTP_DELETE
88
+	, AISL_HTTP_OPTIONS
89
+	, AISL_HTTP_CONNECT
90
+	, AISL_HTTP_PRI
91
+} AislHttpMethod;
92
+
93
+
94
+/** @brief Converts #AislHttpMethod code to a null terminated string
95
+ *  @param method an #AislHttpMethod code
96
+ *  @return pointer to the string representing #AislHttpMethod
97
+ */
98
+const char *
99
+aisl_http_method_to_string(AislHttpMethod method);
100
+
101
+
102
+/** @brief HTTP response status enumeration */
103
+typedef enum {
104
+	  AISL_HTTP_CONTINUE = 100
105
+	, AISL_HTTP_SWITCHING_PROTOCOLS
106
+
107
+	, AISL_HTTP_OK = 200
108
+	, AISL_HTTP_CREATED
109
+	, AISL_HTTP_ACCEPTED
110
+	, AISL_HTTP_NON_AUTHORITATIVE_INFORMATION
111
+	, AISL_HTTP_NO_CONTENT
112
+	, AISL_HTTP_RESET_CONTENT
113
+	, AISL_HTTP_PARTIAL_CONTENT
114
+
115
+	, AISL_HTTP_MULTIPLE_CHOICES = 300
116
+	, AISL_HTTP_MOVED_PERMANENTLY
117
+	, AISL_HTTP_FOUND
118
+	, AISL_HTTP_SEE_OTHER
119
+	, AISL_HTTP_NOT_MODIFIED
120
+	, AISL_HTTP_USE_PROXY
121
+	, AISL_HTTP_UNUSED
122
+	, AISL_HTTP_TEMPORARY_REDIRECT
123
+
124
+	, AISL_HTTP_BAD_REQUEST = 400
125
+	, AISL_HTTP_UNAUTHORIZED
126
+	, AISL_HTTP_PAYMENT_REQUIRED
127
+	, AISL_HTTP_FORBIDDEN
128
+	, AISL_HTTP_NOT_FOUND
129
+	, AISL_HTTP_METHOD_NOT_ALLOWED
130
+	, AISL_HTTP_NOT_ACCEPTABLE
131
+	, AISL_HTTP_PROXY_AUTHENTICATION_REQUIRED
132
+	, AISL_HTTP_REQUEST_TIMEOUT
133
+	, AISL_HTTP_CONFLICT
134
+	, AISL_HTTP_GONE
135
+	, AISL_HTTP_LENGTH_REQUIRED
136
+	, AISL_HTTP_PRECONDITION_FAILED
137
+	, AISL_HTTP_REQUEST_ENTITY_TOO_LARGE
138
+	, AISL_HTTP_REQUEST_URI_TOO_LONG
139
+	, AISL_HTTP_UNSUPPORTED_MEDIA_TYPE
140
+	, AISL_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE
141
+	, AISL_HTTP_EXPECTATION_FAILED
142
+
143
+	, AISL_HTTP_INTERNAL_SERVER_ERROR = 500
144
+	, AISL_HTTP_NOT_IMPLEMENTED
145
+	, AISL_HTTP_BAD_GATEWAY
146
+	, AISL_HTTP_SERVICE_UNAVAILABLE
147
+	, AISL_HTTP_GATEWAY_TIMEOUT
148
+	, AISL_HTTP_VERSION_NOT_SUPPORTED
149
+} AislHttpResponse;
150
+
151
+
152
+/** @brief Converts #AislHttpResponse code to a null terminated string
153
+ *  @param code an #AislHttpResponse code
154
+ *  @return pointer to the string representing #AislHttpResponse
155
+ */
156
+const char *
157
+aisl_http_response_to_string(AislHttpResponse code);
158
+
159
+
160
+/** @brief AISL events enumeration */
161
+typedef enum {
162
+	  AISL_EVENT_SERVER_READY       = 100
163
+	, AISL_EVENT_SERVER_ERROR       = 190
164
+
165
+	, AISL_EVENT_CLIENT_CONNECT     = 200
166
+	, AISL_EVENT_CLIENT_DISCONNECT  = 210
167
+
168
+	, AISL_EVENT_STREAM_OPEN        = 300
169
+	, AISL_EVENT_STREAM_HEADER      = 310
170
+	, AISL_EVENT_STREAM_INPUT       = 320
171
+	, AISL_EVENT_STREAM_REQUEST     = 330
172
+	, AISL_EVENT_STREAM_OUTPUT      = 340
173
+	, AISL_EVENT_STREAM_CLOSE       = 350
174
+	, AISL_EVENT_STREAM_ERROR       = 390
175
+} AislEvent;
176
+
177
+
178
+/** @brief generic AISL event structure  */
179
+struct aisl_evt {
180
+	void         *source;    /**< Pointer to an event source: #AislServer, #AislClient, #AislStream */
181
+	AislEvent     code;      /**< Event code */
182
+	AislStatus    status;    /**< Event status */
183
+};
184
+
185
+
186
+/** @brief event handler callback definition
187
+ *  @param evt a pointer to an #aisl_evt structure 
188
+ *  @param ctx a pointer to a context defined by user (see #aisl_cfg)
189
+ */
190
+typedef void
191
+(* AislCallback) (const struct aisl_evt *evt, void *ctx);
192
+
193
+
194
+/** @brief AISL event structue passed on stream opening */
195
+struct aisl_evt_open {
196
+	struct aisl_evt   evt;           /**< generic #aisl_evt structure */
197
+	const char       *path;          /**< HTTP request path */
198
+	const char       *query;         /**< HTTP request query (GET params) */
199
+	AislHttpMethod    http_method;   /**< HTTP request method */
200
+};
201
+
202
+
203
+/** @brief AISL event structue passed on HTTP header reception */
204
+struct aisl_evt_header {
205
+	struct aisl_evt   evt;           /**< generic #aisl_evt structure */
206
+	const char       *key;           /**< low case HTTP header name */
207
+	const char       *value;         /**< HTTP header string */
208
+};
209
+
210
+
211
+/** @brief AISL event structue passed on HTTP request data part received */
212
+struct aisl_evt_input {
213
+	struct aisl_evt   evt;           /**< generic #aisl_evt structure */
214
+	const char       *data;          /**< a pointer to received data array */
215
+	int32_t           size;          /**< data array size */
216
+};
217
+
218
+
219
+/** @brief Converts #AislEvent code to a null terminated string
220
+ *  @param evt an #AislEvent code
221
+ *  @return pointer to the string representing #AislEvent
222
+ */
223
+const char *
224
+aisl_event_to_string(AislEvent evt);
225
+
226
+#endif /* !AISL_TYPES_H */

+ 539
- 0
lib/) View File

@@ -0,0 +1,539 @@
1
+#include <time.h>
2
+#include <stdio.h>
3
+#include <stdlib.h>
4
+#include <errno.h>
5
+#include <string.h>
6
+#include <unistd.h>
7
+#include <fcntl.h>
8
+
9
+#ifndef AISL_WITHOUT_SSL
10
+#include <openssl/err.h>
11
+#endif
12
+
13
+#include <aisl/aisl.h>
14
+#include "debug.h"
15
+#include "stream.h"
16
+#include "http.h"
17
+#include "server.h"
18
+#include "instance.h"
19
+#include "client.h"
20
+
21
+#define FLAG_KEEPALIVE (1<<0)
22
+#define FLAG_HANDSHAKE (1<<1)
23
+#define FLAG_CAN_READ  (1<<2)
24
+#define FLAG_CAN_WRITE (1<<3)
25
+
26
+#define BUFFER_SIZE (16*1024)
27
+
28
+
29
+static void
30
+aisl_client_close(AislClient client, AislStatus status)
31
+{
32
+  if (client->fd != -1)
33
+  {
34
+    aisl_raise(
35
+        client->server->instance
36
+      , (void *)client
37
+      , AISL_EVENT_CLIENT_DISCONNECT
38
+      , status
39
+    );
40
+
41
+    close(client->fd);
42
+    shutdown(client->fd, SHUT_RDWR);
43
+    client->fd = -1;
44
+  }
45
+}
46
+
47
+
48
+static AislStatus
49
+aisl_client_parse(AislClient client, char * data, int32_t size)
50
+{
51
+  AislStatus    result = AISL_SUCCESS;
52
+  AislStream    s = client->stream;
53
+  ParserStatus    p = HTTP_PARSER_SUCCESS;
54
+
55
+
56
+  int32_t bytes_left = size;
57
+
58
+  switch (client->http_version)
59
+  {
60
+    case AISL_HTTP_0_9:
61
+    case AISL_HTTP_1_0:
62
+    case AISL_HTTP_1_1:
63
+
64
+      /* s = client->stream; */
65
+
66
+      while ( p == HTTP_PARSER_SUCCESS )
67
+      {
68
+
69
+        switch ( aisl_stream_get_state(s) )
70
+        {
71
+          case AISL_STREAM_STATE_IDLE:
72
+            p = http_10_parse_request(data, &size, client->stream);
73
+            break;
74
+
75
+          case AISL_STREAM_STATE_WAIT_HEADER:
76
+            p = http_10_parse_header(data, &size, client->stream);
77
+            break;
78
+
79
+          case AISL_STREAM_STATE_WAIT_BODY:
80
+            p = http_10_parse_body(data, &size, client->stream);
81
+            break;
82
+
83
+          default: /* has input data, but request was already parsed */
84
+            p = HTTP_PARSER_ERROR;
85
+            continue;
86
+        }
87
+        // size now has number of parsed bytes
88
+        data += size;
89
+        bytes_left -= size;
90
+        size = bytes_left;
91
+      }
92
+
93
+
94
+
95
+      break;
96
+
97
+    case AISL_HTTP_2_0:
98
+
99
+      break;
100
+  }
101
+
102
+  switch(p)
103
+  {
104
+    case HTTP_PARSER_READY:
105
+      client->flags &= ~FLAG_CAN_READ;
106
+      client->flags |= FLAG_CAN_WRITE;
107
+
108
+      aisl_raise(
109
+          client->server->instance
110
+        , (void *) s
111
+        , AISL_EVENT_STREAM_REQUEST
112
+        , result 
113
+      );
114
+      break;
115
+
116
+    case HTTP_PARSER_ERROR:
117
+      /* reply Bad Request here */
118
+      client->stream->http_response = AISL_HTTP_BAD_REQUEST;
119
+
120
+      aisl_raise(
121
+          client->server->instance
122
+        , (void *) s
123
+        , AISL_EVENT_STREAM_ERROR 
124
+        , result
125
+      );
126
+
127
+      aisl_client_close(client, result);
128
+
129
+      return result;
130
+
131
+    default:
132
+      break;
133
+  }
134
+
135
+  if (size)
136
+    buffer_shift(&client->in, client->in.used - size); /* reset buffer */
137
+
138
+  return result;
139
+}
140
+
141
+
142
+/* In HTTP 2.0 client->stream will be NULL if stream related data was completely
143
+ * parsed. If it is not NULL, then stream expects additional data -> same like
144
+ * in mono stream HTTP 1.0 
145
+ */
146
+static AislStatus
147
+aisl_client_input(AislClient client)
148
+{
149
+  int                l;
150
+
151
+  char             * data = &client->in.data[ client->in.used ];
152
+  int32_t            size = client->in.size - client->in.used;
153
+
154
+  #ifndef AISL_WITHOUT_SSL
155
+  if (client->ssl)
156
+  {
157
+    DPRINTF("SSL_read");
158
+    if ( !(client->flags & FLAG_HANDSHAKE) )
159
+    {
160
+      if ( (l = SSL_accept(client->ssl)) != 1 )
161
+      {
162
+        l = SSL_get_error(client->ssl, l);
163
+
164
+        if (l == SSL_ERROR_WANT_READ || l == SSL_ERROR_WANT_WRITE)
165
+          return AISL_IDLE;
166
+
167
+        DPRINTF("SSL handshake fail: %s\n", ERR_error_string(l, NULL) );
168
+
169
+        aisl_client_close(client, AISL_EXTCALL_ERROR);
170
+        return AISL_EXTCALL_ERROR;
171
+      }
172
+
173
+      client->flags &= ~FLAG_HANDSHAKE;
174
+    }
175
+
176
+    l = SSL_read(client->ssl, data, size) ;
177
+  }
178
+  else
179
+  #endif
180
+    l = recv( client->fd, data, size, 0);
181
+
182
+  if (l > 0)
183
+  {
184
+    DPRINTF("%d bytes received from client", l);
185
+
186
+    data = client->in.data;
187
+    size = client->in.used + l;
188
+
189
+    client->in.used = size;
190
+
191
+    return aisl_client_parse(client, data, size);
192
+  }
193
+  else if (l<0)
194
+  {
195
+    #ifndef AISL_WITHOUT_SSL
196
+    if (client->ssl)
197
+    {
198
+      if (SSL_get_error(client->ssl, l) == SSL_ERROR_WANT_READ)
199
+        return AISL_IDLE;
200
+    }
201
+    else
202
+    #endif
203
+    {
204
+      if(errno == EWOULDBLOCK)
205
+        return AISL_IDLE;
206
+
207
+      DPRINTF("client - %s", strerror(errno));
208
+    }
209
+  }
210
+
211
+  /* both: client disconnect + on read error  */
212
+  /* todo: raise client error here */
213
+  aisl_client_close(client, AISL_SYSCALL_ERROR);
214
+
215
+  return AISL_SYSCALL_ERROR;
216
+}
217
+
218
+
219
+static AislStatus 
220
+aisl_client_output(AislClient client)
221
+{
222
+  int l;
223
+  char * data;
224
+
225
+  AislStream s = client->stream;
226
+
227
+  /* while stream is not flushed, we should raise event */
228
+  if( aisl_get_output_event(s) )
229
+  {
230
+    /* in case of chunked output ( subscription for AISL_STREAM_OUTPUT event )
231
+     * stream buffer will be initialized with OUTPUT_BUFFER_SIZE size, but
232
+     * buffer->size will be used to carry amount of stored bytes
233
+     * */
234
+    l = aisl_stream_get_buffer_space(s);
235
+
236
+    /*
237
+    if (bsz < OUTPUT_BUFFER_SIZE)
238
+    {
239
+      if (buffer_clear(s->buffer, OUTPUT_BUFFER_SIZE) == 0)
240
+        return false;
241
+
242
+      s->buffer->size = bsz;
243
+      bsz = OUTPUT_BUFFER_SIZE;
244
+    }
245
+    */
246
+
247
+    if ( !(l < aisl_stream_get_buffer_size(s) / 2) )
248
+    {
249
+      aisl_raise(
250
+          client->server->instance
251
+        , (void*)s
252
+        , AISL_EVENT_STREAM_OUTPUT
253
+        , AISL_SUCCESS
254
+      );
255
+    }
256
+  }
257
+
258
+  data = aisl_stream_get_data(s, &l);
259
+
260
+  if ( !l )
261
+    return AISL_IDLE;
262
+
263
+  #ifdef AISL_WITHOUT_SSL
264
+  l = send( client->fd,  data, l, 0);
265
+  #else
266
+  l = (client->ssl) ?
267
+        SSL_write(client->ssl, data, l) :
268
+        send(     client->fd,  data, l, 0);
269
+  #endif
270
+
271
+  if (l > 0)
272
+  {
273
+    aisl_stream_shift(s, l);
274
+
275
+    /*
276
+    if (s->state == STREAM_RESPONSE_READY && / * flushed * /
277
+        s->buffer->size == 0) / * all sent * /
278
+          */
279
+    if ( aisl_stream_is_done(s) )
280
+    {
281
+      /* buffer_clear(s->buffer, 0); */
282
+
283
+      /* data has been sent */
284
+
285
+      if (client->flags & FLAG_KEEPALIVE)
286
+      {
287
+        aisl_stream_free(s);
288
+
289
+        client->stream = aisl_stream_new(client, client->next_id++);
290
+        if (client->stream != NULL )
291
+          return AISL_SUCCESS;
292
+
293
+        /* in case of malloc error it will not be error as long as request was
294
+         * handled and we just close the connection.
295
+         */
296
+      }
297
+
298
+      aisl_client_close(client, AISL_SUCCESS);
299
+    }
300
+
301
+    return AISL_SUCCESS;
302
+  }
303
+
304
+  /* l < 0 */
305
+  #ifndef AISL_WITHOUT_SSL
306
+  if (client->ssl)
307
+  {
308
+    if ( SSL_get_error(client->ssl, l) == SSL_ERROR_WANT_WRITE )
309
+      return AISL_IDLE;
310
+  }
311
+  else
312
+  #endif
313
+  {
314
+    if (errno == EWOULDBLOCK)
315
+      return AISL_IDLE;
316
+  }
317
+
318
+  aisl_client_close(client, AISL_SYSCALL_ERROR);
319
+
320
+  return AISL_SYSCALL_ERROR;
321
+}
322
+
323
+
324
+AislClient
325
+aisl_client_new( AislServer        server,
326
+                 int                  fd,
327
+                 struct sockaddr_in * addr )
328
+{
329
+  AislClient   client;
330
+  AislStream   stream;
331
+
332
+  if ( (client = calloc(1, sizeof (struct aisl_client))) != NULL )
333
+  {
334
+    DPRINTF("client alocated");
335
+    memcpy(&client->address, addr, sizeof (struct sockaddr_in));
336
+    client->server     = server;
337
+    client->fd         = fd;
338
+    client->next_id    = 2;
339
+    client->http_version   = AISL_HTTP_1_0;
340
+    client->timestamp  = time(NULL);
341
+    client->flags      = FLAG_KEEPALIVE | FLAG_HANDSHAKE | FLAG_CAN_READ;
342
+
343
+    if (buffer_init(&client->in, 2*BUFFER_SIZE) != -1)
344
+    {
345
+      DPRINTF("client buffer alocated");
346
+      memcpy(&client->out, &client->in, sizeof (struct buffer));
347
+
348
+      stream = aisl_stream_new(client, 0);
349
+
350
+      if (stream != NULL)
351
+      {
352
+        client->stream = stream;
353
+
354
+        DPRINTF("client stream alocated");
355
+
356
+        #ifdef AISL_WITHOUT_SSL
357
+
358
+        return client;
359
+
360
+        #else
361
+
362
+        SSL_CTX * ssl_ctx;
363
+
364
+        if ( !server->ssl )
365
+          return client;
366
+
367
+        ssl_ctx = aisl_get_ssl_ctx(server->instance, NULL);
368
+
369
+        if ((client->ssl = SSL_new(ssl_ctx)) != NULL )
370
+        {
371
+          SSL_set_fd(client->ssl, fd);
372
+          return client;
373
+        }
374
+
375
+        #endif
376
+      }
377
+    }
378
+    aisl_client_free(client);
379
+
380
+  }
381
+
382
+  return NULL;
383
+}
384
+
385
+
386
+void
387
+aisl_client_free(AislClient client)
388
+{
389
+  aisl_client_close(client, AISL_SUCCESS);
390
+
391
+  #ifndef AISL_WITHOUT_SSL
392
+  if (client->ssl)
393
+    SSL_free(client->ssl);
394
+  #endif
395
+
396
+  if (client->in.data)
397
+    free(client->in.data);
398
+
399
+  /* out buffer is a shared part of input buffer, so no need to free it */
400
+
401
+  if (client->stream)
402
+    aisl_stream_free(client->stream);
403
+
404
+  free(client);
405
+}
406
+
407
+
408
+AislStatus
409
+AislClientouch(AislClient client, int32_t timeout)
410
+{
411
+  AislStatus result = AISL_IDLE,
412
+                status = AISL_IDLE;
413
+
414
+  /* input */
415
+  if (client->flags & FLAG_CAN_READ)
416
+  {
417
+    if ( (result = aisl_client_input(client)) < 0 )
418
+      return result;
419
+  }
420
+
421
+  /* output */
422
+  if (client->flags & FLAG_CAN_WRITE)
423
+  {
424
+    if ( (status = aisl_client_output(client)) < 0 )
425
+      return status;
426
+  }
427
+
428
+
429
+  /*
430
+  if ((client->http_version==AISL_HTTP_2_0 || s->state<STREAM_REQUEST_READY) &&
431
+      (client_input(client)) ) result = true;
432
+  */
433
+  /* output */
434
+  /*
435
+  s = list_index(client->streams, client->ostream);
436
+
437
+  if ( s->flags & (STREAM_FLAG_OUTPUT_READY | STREAM_FLAG_OUTPUT_CHUNKED) )
438
+    result = client_output(client);
439
+  */
440
+  /* update timestamp */
441
+
442
+  if (result == AISL_IDLE)
443
+    result = status;
444
+
445
+  if (result == AISL_SUCCESS)
446
+    client->timestamp = time(NULL);
447
+  else
448
+  {
449
+    time_t now;
450
+    time(&now);
451
+
452
+    if ( !(now - client->timestamp < timeout) )
453
+    {
454
+      aisl_client_close(client, result);
455
+    }
456
+  }
457
+
458
+
459
+  return result;
460
+}
461
+
462
+
463
+int
464
+aisl_client_get_socket(AislClient client)
465
+{
466
+  return client->fd;
467
+}
468
+
469
+
470
+bool
471
+aisl_client_get_keepalive(AislClient client)
472
+{
473
+  return (client->flags & FLAG_KEEPALIVE);
474
+}
475
+
476
+
477
+void
478
+aisl_client_set_keepalive(AislClient client, bool value)
479
+{
480
+  if (value)
481
+    client->flags |= FLAG_KEEPALIVE;
482
+  else
483
+    client->flags &= ~FLAG_KEEPALIVE;
484
+}
485
+
486
+
487
+
488
+/* API Level ---------------------------------------------------------------- */
489
+
490
+__attribute__ ((visibility ("default") ))
491
+AislServer
492
+aisl_client_get_server(AislClient client)
493
+{
494
+  return client->server;
495
+}
496
+
497
+
498
+__attribute__ ((visibility ("default") ))
499
+bool
500
+aisl_client_is_secure(AislClient client)
501
+{
502
+  #ifdef AISL_WITHOUT_SSL
503
+  return false;
504
+  #else
505
+  return (client->ssl == NULL) ? false : true;
506
+  #endif
507
+}
508
+
509
+
510
+__attribute__ ((visibility ("default") ))
511
+bool
512
+aisl_client_is_online(AislClient client)
513
+{
514
+  return (client->fd == -1) ? false : true;
515
+}
516
+
517
+
518
+__attribute__ ((visibility ("default") ))
519
+void
520
+aisl_client_disconnect(AislClient client)
521
+{
522
+  aisl_client_close(client, AISL_SUCCESS);
523
+}
524
+
525
+
526
+__attribute__ ((visibility ("default") ))
527
+AislHttpVersion
528
+aisl_client_get_http_version(AislClient client)
529
+{
530
+  return client->http_version;
531
+}
532
+
533
+
534
+__attribute__ ((visibility ("default") ))
535
+void
536
+aisl_client_get_address( AislClient client, struct sockaddr_in * address)
537
+{
538
+  memcpy(address, &client->address, sizeof (struct sockaddr_in));
539
+}

+ 176
- 0
lib/buffer.c View File

@@ -0,0 +1,176 @@
1
+/******************************************************************************
2
+ *
3
+ *                Copyright (c) 2017-2019 by Löwenware Ltd
4
+ *             Please, refer LICENSE file for legal information
5
+ *
6
+ ******************************************************************************/
7
+
8
+/**
9
+ * @file buffer.c
10
+ * @author Ilja Kartašov <ik@lowenware.com>
11
+ * @brief Buffer module source file
12
+ *
13
+ * @see https://lowenware.com/
14
+ */
15
+#include <stdlib.h>
16
+#include <stdio.h>
17
+#include <string.h>
18
+#include "debug.h"
19
+#include "buffer.h"
20
+
21
+
22
+static int32_t
23
+buffer_set_size(struct buffer *buffer, int32_t new_size)
24
+{
25
+	if (!buffer->size || new_size != buffer->size) {
26
+		char *data;
27
+
28
+		if (new_size) {
29
+			if (new_size % 4096) {
30
+				new_size = (new_size / 4096 + 1) * 4096;
31
+			}
32
+		} else {
33
+			new_size = 16*1024; 
34
+		}
35
+
36
+		if ((data = realloc(buffer->data, new_size)) != NULL) {
37
+			buffer->data = data;
38
+			buffer->size = new_size;
39
+		} else {
40
+			new_size = -1;
41
+		}
42
+	}
43
+
44
+	return new_size;
45
+}
46
+
47
+
48
+int32_t
49
+buffer_init(struct buffer *buffer, int32_t size)
50
+{
51
+	if ((size = buffer_set_size(buffer, size)) != -1)
52
+		buffer->used = 0;
53
+
54
+	return size;
55
+}
56
+
57
+
58
+void
59
+buffer_release(struct buffer *buffer)
60
+{
61
+	if (buffer->data) {
62
+		free(buffer->data);
63
+		buffer->data = NULL;
64
+	}
65
+
66
+	buffer->used = 0;
67
+	buffer->size = 0;
68
+}
69
+
70
+
71
+static int32_t
72
+buffer_move_offset(struct buffer *buffer, int32_t offset, int32_t size)
73
+{
74
+	int32_t to_move = buffer->used - offset;
75
+
76
+	if (to_move < 0) {
77
+		return -1;
78
+	} else if (to_move) {
79
+		memmove(&buffer->data[offset+size], &buffer->data[offset], to_move);
80
+	}
81
+
82
+	return size;
83
+}
84
+
85
+int32_t
86
+buffer_insert(struct buffer *buffer, int32_t offset, const char *data,
87
+		int32_t size)
88
+{
89
+	int32_t result;
90
+
91
+	DPRINTF("Buffer: %d of %d", buffer->used, buffer->size);
92
+
93
+	if ( (result = buffer_set_size(buffer, buffer->size + size)) != -1) {
94
+		if ((result = buffer_move_offset(buffer, offset, size)) != -1) {
95
+			memcpy(&buffer->data[offset], data, size);
96
+			buffer->used += result;
97
+		}
98
+	}
99
+
100
+	return result;
101
+}
102
+
103
+
104
+int32_t
105
+buffer_append_printf(struct buffer *buffer, const char *format, ...)
106
+{
107
+	int32_t result;
108
+	va_list args;
109
+
110
+	va_start(args, format);
111
+	result = buffer_append_vprintf(buffer, format, args);
112
+	va_end(args);
113
+
114
+	return result;
115
+}
116
+
117
+int32_t
118
+buffer_append_vprintf(struct buffer *buffer, const char *format, va_list args)
119
+{
120
+	DPRINTF("Buffer: %d of %d", buffer->used, buffer->size);
121
+	int32_t space, result;
122
+	va_list cp_args;
123
+
124
+	va_copy(cp_args, args);