Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8fa3f68e5 | ||
|
|
85f427ad91 | ||
|
|
2af6556748 | ||
|
|
12be39c747 | ||
|
|
ee90cbc37c | ||
|
|
461f5f52f2 | ||
|
|
bd4273050c | ||
|
|
345450b35b | ||
|
|
d28f942cf7 | ||
|
|
8847f92528 | ||
|
|
fc33a0e49e | ||
|
|
a49e32dff8 | ||
|
|
0b05984f85 | ||
|
|
3efc86a341 | ||
|
|
d87c7454b5 | ||
|
|
86b69c89b8 |
+2
-1
@@ -7,7 +7,6 @@ demo/*
|
||||
bin/*
|
||||
obj/*
|
||||
webstuff-*
|
||||
Makefile
|
||||
tmp
|
||||
tmp/*
|
||||
*.tar.gz
|
||||
@@ -16,6 +15,8 @@ tmp/*
|
||||
*.gz
|
||||
*.bz2
|
||||
pkg/*
|
||||
doc/html
|
||||
vgcore.*
|
||||
|
||||
include/webstuff_bak
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
[submodule "cStuff"]
|
||||
path = cStuff
|
||||
url = git@lowenware.com:lowenware/cStuff.git
|
||||
[submodule "aisl-sdk"]
|
||||
path = aisl-sdk
|
||||
url = git@lowenware.com:lowenware/aisl-sdk.git
|
||||
@@ -1,8 +0,0 @@
|
||||
# Release 1.0.0
|
||||
|
||||
By Ilja Kartašov <ik@lowenware.com>, 2019-06-02
|
||||
|
||||
1. Library release with new and final API and documented code.
|
||||
2. Previous version is being called `aisl-legacy` and will be maintained in
|
||||
security aspects in branch called `legacy` until all applications using it will
|
||||
be updated.
|
||||
@@ -0,0 +1,90 @@
|
||||
#
|
||||
# Makefile
|
||||
# Ilja Kartašov, 2019-03-02 17:32
|
||||
#
|
||||
.POSIX:
|
||||
|
||||
# Project directories
|
||||
SRC_DIR ?= src
|
||||
SDK_DIR ?= sdk
|
||||
OUT_DIR ?= build
|
||||
LIB_DIR ?= lib
|
||||
DESTDIR ?=
|
||||
|
||||
# Project definition
|
||||
include project.mk
|
||||
|
||||
# Examples submodule
|
||||
include examples.mk
|
||||
|
||||
# CFLAGS
|
||||
|
||||
CFLAGS := \
|
||||
$(PROJECT_INCLUDES) \
|
||||
-std=c99 \
|
||||
-pedantic \
|
||||
-Wall \
|
||||
-Wmissing-prototypes \
|
||||
-Wstrict-prototypes \
|
||||
-Wold-style-definition \
|
||||
-O2 \
|
||||
-s \
|
||||
-fvisibility=hidden \
|
||||
-DVERSION_MAJOR=$(PROJECT_VERSION_MAJOR) \
|
||||
-DVERSION_MINOR=$(PROJECT_VERSION_MINOR) \
|
||||
-DVERSION_TWEAK=$(PROJECT_VERSION_TWEAK) \
|
||||
-DVERSION_LABEL=$(PROJECT_VERSION_LABEL) \
|
||||
$(CPPFLAGS) \
|
||||
$(CFLAGS) \
|
||||
$(PROJECT_CFLAGS) \
|
||||
|
||||
|
||||
LDFLAGS := \
|
||||
$(PROJECT_LIBRARIES) \
|
||||
$(LDFLAGS) \
|
||||
$(PROJECT_LDFLAGS) \
|
||||
|
||||
|
||||
SOURCE_LIST := $(wildcard $(PROJECT_SOURCES))
|
||||
OBJECT_FILES := $(addprefix $(OUT_DIR)/o_, ${SOURCE_LIST:.c=.o})
|
||||
|
||||
|
||||
library: dirs $(OBJECT_FILES)
|
||||
$(info linking target: $@)
|
||||
@$(CC) -shared -o $(OUT_DIR)/lib$(PROJECT_NAME).so $(OBJECT_FILES) $(LDFLAGS)
|
||||
$(info done: $@)
|
||||
|
||||
|
||||
build/o_%.o: %.c
|
||||
$(info compiling file: $<)
|
||||
@$(CC) $(CFLAGS) -fpic -c $< -o $@
|
||||
|
||||
dirs:
|
||||
$(info preparing: build folders)
|
||||
@mkdir -p $(OUT_DIR)/o_$(SRC_DIR)
|
||||
@mkdir -p $(OUT_DIR)/o_$(SDK_DIR)
|
||||
|
||||
|
||||
clean:
|
||||
$(info cleaning: build files)
|
||||
@rm -Rf $(OUT_DIR)
|
||||
@rm -Rf ./vgcore.*
|
||||
|
||||
doc:
|
||||
doxygen doc/api-reference.conf
|
||||
|
||||
all: library examples doc
|
||||
|
||||
default: library
|
||||
.PHONY: all dirs clean doc install
|
||||
|
||||
install: library
|
||||
$(info installing files)
|
||||
@mkdir -p $(DESTDIR)$(PREFIX)/$(LIB_DIR)
|
||||
@mkdir -p $(DESTDIR)$(PREFIX)/include
|
||||
|
||||
@cp $(OUT_DIR)/lib$(PROJECT_NAME).so $(DESTDIR)$(PREFIX)/$(LIB_DIR)
|
||||
@cp -R include/aisl $(DESTDIR)$(PREFIX)/include
|
||||
|
||||
# vim:ft=make
|
||||
#
|
||||
@@ -1,32 +1,36 @@
|
||||
# AISL
|
||||
Asynchronous Internet Server Library
|
||||
|
||||
Asynchronous Internet Server Library provides innovative way of web development.
|
||||
AISL based applications have built-in web server giving full control of client
|
||||
serving. All you need to know is a request string? - Start prepare the response
|
||||
without waiting for headers and body! Don't need some headers? - Don't save them
|
||||
in memory! Unwanted content-body? - simply ignore it!
|
||||
|
||||
## Documentation
|
||||
|
||||
[Hello World](https://lowenware.com/aisl/handbook.html#getting-started) example
|
||||
and full [API reference](https://lowenware.com/aisl/handbook.html#api-reference)
|
||||
can be found in an oficial [AISL HandBook](https://lowenware.com/aisl/handbook.html).
|
||||
|
||||
## Installation
|
||||
## Installation on CentOS 7 / RedHat 7
|
||||
|
||||
1. Add repository
|
||||
```
|
||||
$ make PREFIX=/usr/local
|
||||
$ sudo make PREFIX=/usr/local install
|
||||
$ sudo cp libaisl.pc.example /usr/lib/pkgconfig/libaisl.pc
|
||||
sudo curl -o /etc/yum.repos.d/lowenware.repo https://lowenware.com/rpm/redhat-7/lowenware.repo
|
||||
```
|
||||
|
||||
ArchLinux users can install from [AUR](https://aur.archlinux.org/packages/aisl-git/) :
|
||||
|
||||
2. Import GPG key
|
||||
```
|
||||
$ yaourt -S aisl-git
|
||||
sudo rpm --import https://lowenware.com/rpm/RPM-GPG-KEY-Lowenware
|
||||
```
|
||||
|
||||
## License
|
||||
3. Install
|
||||
```
|
||||
sudo yum install aisl aisl-devel
|
||||
```
|
||||
|
||||
AISL is free for both commercial and non-commercial use, being distributed under
|
||||
terms of [CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0/).
|
||||
## Installation from sources on any distro
|
||||
|
||||
1. Configuration
|
||||
```
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local
|
||||
```
|
||||
|
||||
2. Compilation
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
3. Installation
|
||||
```
|
||||
sudo make install
|
||||
```
|
||||
|
||||
-1
Submodule aisl-sdk deleted from b9e247b88f
-1
Submodule cStuff deleted from 4ba00ca17a
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
<!-- HTML footer for doxygen 1.8.14-->
|
||||
<!-- start footer part -->
|
||||
<!--BEGIN GENERATE_TREEVIEW-->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
$navpath
|
||||
<li class="footer">$generatedby
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
|
||||
</ul>
|
||||
</div>
|
||||
<!--END GENERATE_TREEVIEW-->
|
||||
<!--BEGIN !GENERATE_TREEVIEW-->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
$generatedby  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
|
||||
</a> $doxygenversion
|
||||
</small></address>
|
||||
<!--END !GENERATE_TREEVIEW-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,56 @@
|
||||
<!-- HTML header for doxygen 1.8.14-->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen $doxygenversion"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
||||
$treeview
|
||||
$search
|
||||
$mathjax
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||
$extrastylesheet
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
|
||||
<!--BEGIN TITLEAREA-->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<!--BEGIN PROJECT_LOGO-->
|
||||
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
|
||||
<!--END PROJECT_LOGO-->
|
||||
<!--BEGIN PROJECT_NAME-->
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">$projectname
|
||||
<!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
|
||||
</div>
|
||||
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
||||
</td>
|
||||
<!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME-->
|
||||
<!--BEGIN PROJECT_BRIEF-->
|
||||
<td style="padding-left: 0.5em;">
|
||||
<div id="projectbrief">$projectbrief</div>
|
||||
</td>
|
||||
<!--END PROJECT_BRIEF-->
|
||||
<!--END !PROJECT_NAME-->
|
||||
<!--BEGIN DISABLE_INDEX-->
|
||||
<!--BEGIN SEARCHENGINE-->
|
||||
<td>$searchbox</td>
|
||||
<!--END SEARCHENGINE-->
|
||||
<!--END DISABLE_INDEX-->
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--END TITLEAREA-->
|
||||
<!-- end header part -->
|
||||
+1596
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -24,7 +24,7 @@ examples: library hello_world
|
||||
|
||||
hello_world:
|
||||
$(info compiling: hello world)
|
||||
@$(CC) $(EXAMPLES_CFLAGS) \
|
||||
$(CC) $(EXAMPLES_CFLAGS) \
|
||||
-o $(OUT_DIR)/hello-world $(EXAMPLES_DIR)/hello-world.c $(EXAMPLES_LDFLAGS)
|
||||
|
||||
# vim:ft=make
|
||||
|
||||
+31
-36
@@ -20,32 +20,18 @@
|
||||
#include <aisl/aisl.h>
|
||||
|
||||
|
||||
static void
|
||||
hello_world(const struct aisl_evt *evt, void *p_ctx);
|
||||
|
||||
|
||||
static const struct aisl_cfg_srv m_srv[] = {{
|
||||
.host = "0.0.0.0",
|
||||
.port = 8080,
|
||||
.secure = false
|
||||
}};
|
||||
|
||||
|
||||
static const struct aisl_cfg m_cfg = {
|
||||
AISL_CFG_DEFAULTS
|
||||
, .srv = m_srv
|
||||
, .srv_cnt = sizeof (m_srv) / sizeof (m_srv[0])
|
||||
, .ssl = NULL
|
||||
, .ssl_cnt = 0
|
||||
, .callback = hello_world
|
||||
, .p_ctx = NULL
|
||||
};
|
||||
#define DEFAULT_HTTP_PORT 8080 /**< Default HTTP server port */
|
||||
|
||||
|
||||
static void
|
||||
hello_world(const struct aisl_evt *evt, void *p_ctx)
|
||||
{
|
||||
AislStream s;
|
||||
if (evt->code != AISL_EVENT_STREAM_REQUEST)
|
||||
return;
|
||||
|
||||
AislStatus status;
|
||||
|
||||
AislStream s = evt->source;
|
||||
|
||||
const char html[] =
|
||||
"<html>"
|
||||
@@ -58,21 +44,18 @@ hello_world(const struct aisl_evt *evt, void *p_ctx)
|
||||
"</body>"
|
||||
"</html>";
|
||||
|
||||
fprintf(stdout, "Event: %s\n", aisl_event_to_string(evt->code) );
|
||||
status = aisl_response(s, AISL_HTTP_OK, sizeof (html)-1);
|
||||
|
||||
if (evt->code != AISL_EVENT_STREAM_REQUEST)
|
||||
return;
|
||||
|
||||
s = evt->source;
|
||||
|
||||
if (aisl_response(s, AISL_HTTP_OK, sizeof (html)-1) == AISL_SUCCESS) {
|
||||
if (aisl_write(s, html, sizeof (html)-1) != -1) {
|
||||
if (status == AISL_SUCCESS)
|
||||
{
|
||||
if (aisl_write(s, html, sizeof (html)-1) != -1)
|
||||
{
|
||||
aisl_flush(s);
|
||||
return;
|
||||
}
|
||||
else
|
||||
aisl_reject(s);
|
||||
}
|
||||
|
||||
aisl_reject(s);
|
||||
(void) p_ctx;
|
||||
}
|
||||
|
||||
@@ -82,12 +65,24 @@ main(int argc, char **argv)
|
||||
{
|
||||
AislInstance aisl; /**< AISL instance pointer */
|
||||
AislStatus status; /**< AISL status code */
|
||||
struct aisl_cfg cfg = AISL_CFG_DEFAULT;
|
||||
struct aisl_cfg_srv srv = {
|
||||
.host = "0.0.0.0",
|
||||
.port = DEFAULT_HTTP_PORT,
|
||||
.secure = false
|
||||
};
|
||||
|
||||
cfg.srv = &srv;
|
||||
cfg.srv_cnt = 1;
|
||||
cfg.callback = hello_world;
|
||||
|
||||
/* Initialize instance */
|
||||
if ( (aisl = aisl_new(&m_cfg)) != NULL ) {
|
||||
if ( (aisl = aisl_new(&cfg)) != NULL )
|
||||
{
|
||||
/* launch application loop */
|
||||
fprintf(stdout, "Entering main loop\n" );
|
||||
for(;;) {
|
||||
fprintf(stdout, "Entering main loop" );
|
||||
for(;;)
|
||||
{
|
||||
status = aisl_run_cycle(aisl);
|
||||
|
||||
if ( status != AISL_SUCCESS )
|
||||
@@ -95,9 +90,9 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
aisl_free(aisl);
|
||||
} else {
|
||||
fprintf(stderr, "Failed to initialize AISL\n");
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Failed to initialize AISL");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -63,11 +63,6 @@ AislHttpVersion
|
||||
aisl_client_get_http_version(AislClient client);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Copies #AislClient network address to provided sockaddr_in structure.
|
||||
* @param client an #AislClient instance pointer.
|
||||
* @param address a pointer to a sockaddr_in structure
|
||||
*/
|
||||
void
|
||||
aisl_client_get_address(AislClient client, struct sockaddr_in *address);
|
||||
|
||||
|
||||
+28
-26
@@ -18,47 +18,49 @@
|
||||
|
||||
#include <aisl/types.h>
|
||||
|
||||
#define AISL_CFG_DEFAULTS \
|
||||
.client_spool_size = 32 \
|
||||
#define AISL_CFG_DEFAULT { \
|
||||
.callback = NULL \
|
||||
, .p_ctx = NULL \
|
||||
, .srv = NULL \
|
||||
, .ssl = NULL \
|
||||
, .srv_cnt = 0 \
|
||||
, .ssl_cnt = 0 \
|
||||
, .client_spool_size = 32 \
|
||||
, .initial_buffer_size = 16536 \
|
||||
, .client_accept_limit = 1024 \
|
||||
, .client_silence_timeout = 30 \
|
||||
} \
|
||||
|
||||
|
||||
/** @brief Server configuration structure
|
||||
*/
|
||||
struct aisl_cfg_srv {
|
||||
const char *host; /**< server IP to listen */
|
||||
uint16_t port; /**< server port to listen */
|
||||
bool secure; /**< shall server use TLS */
|
||||
const char * host;
|
||||
uint16_t port;
|
||||
bool secure;
|
||||
};
|
||||
|
||||
|
||||
/** @brief SSL configuration structure
|
||||
*/
|
||||
struct aisl_cfg_ssl {
|
||||
const char *host; /**< secure server hostname */
|
||||
const char *key_file; /**< path to SSL key file */
|
||||
const char *crt_file; /**< path to SSL certificate file */
|
||||
const char * host;
|
||||
const char * key_file;
|
||||
const char * crt_file;
|
||||
};
|
||||
|
||||
|
||||
/** @brief AISL initial configuration structure
|
||||
*/
|
||||
struct aisl_cfg {
|
||||
AislCallback callback; /**< A pointer to #AislCallback event handler */
|
||||
void *p_ctx; /**< User defined context for #AislCallback */
|
||||
struct aisl_cfg
|
||||
{
|
||||
/* event handlers */
|
||||
AislCallback callback;
|
||||
void *p_ctx;
|
||||
|
||||
const struct aisl_cfg_srv *srv; /**< A pointer to array of #aisl_cfg_srv */
|
||||
const struct aisl_cfg_ssl *ssl; /**< A pointer to array of #aisl_cfg_ssl */
|
||||
struct aisl_cfg_srv *srv;
|
||||
struct aisl_cfg_ssl *ssl;
|
||||
|
||||
int srv_cnt; /**< Size of #aisl_cfg_srv array */
|
||||
int ssl_cnt; /**< Size of #aisl_cfg_ssl array */
|
||||
int srv_cnt;
|
||||
int ssl_cnt;
|
||||
|
||||
int client_spool_size; /**< Initial size of client spool */
|
||||
int initial_buffer_size; /**< Initial size of communication buffer */
|
||||
int client_accept_limit; /**< Maximal number of concurent clients */
|
||||
int client_silence_timeout; /**< Client silence timeout */
|
||||
int client_spool_size;
|
||||
int initial_buffer_size;
|
||||
int client_accept_limit;
|
||||
int client_silence_timeout;
|
||||
};
|
||||
|
||||
#endif /* !AISL_CONFIG_H */
|
||||
|
||||
+1
-94
@@ -19,109 +19,53 @@
|
||||
#include <stdarg.h>
|
||||
#include <aisl/types.h>
|
||||
|
||||
#define aisl_stream_get_instance aisl_get_instance
|
||||
|
||||
/** @brief Gets a value of #AislStream security flag
|
||||
* @param stream an #AislStream instance
|
||||
* @return is true if stream is encrypted and false otherwise
|
||||
*/
|
||||
bool
|
||||
aisl_is_secure(AislStream stream);
|
||||
|
||||
|
||||
/** @brief Gets an #AislClient instance associated with the stream
|
||||
* @param stream an #AislStream instance
|
||||
* @return an #AislClient instance pointer
|
||||
*/
|
||||
AislClient
|
||||
aisl_get_client(AislStream stream);
|
||||
|
||||
|
||||
/** @brief Gets an #AislServer instance associated with the stream
|
||||
* @param stream an #AislStream instance
|
||||
* @return an #AislServer instance pointer
|
||||
*/
|
||||
AislServer
|
||||
aisl_get_server(AislStream stream);
|
||||
|
||||
|
||||
/** @brief Gets an #AislHttpVersion of the stream
|
||||
* @param stream an #AislStream instance
|
||||
* @return an #AislHttpVersion value
|
||||
*/
|
||||
AislHttpVersion
|
||||
aisl_get_http_version(AislStream stream);
|
||||
|
||||
|
||||
/** @brief Gets an #AislInstance pointer associated with the stream
|
||||
* @param stream an #AislStream instance
|
||||
* @return an #AislInstance pointer
|
||||
*/
|
||||
AislInstance
|
||||
aisl_get_instance(AislStream s);
|
||||
aisl_stream_get_instance(AislStream s);
|
||||
|
||||
|
||||
/** @brief Gets the stream context previously set with #aisl_set_context
|
||||
* @param stream an #AislStream instance
|
||||
* @return a pointer to the stream context
|
||||
*/
|
||||
void *
|
||||
aisl_get_context(AislStream stream);
|
||||
|
||||
|
||||
/** @brief Associate a context pointer with the stream until its lifetime.
|
||||
* Previously allocated data should be free'd on #AISL_EVENT_STREAM_CLOSE if
|
||||
* not needed anymore.
|
||||
* @param stream an #AislStream instance
|
||||
* @param context a pointer to any user-defined data
|
||||
*/
|
||||
void
|
||||
aisl_set_context(AislStream stream, void *context);
|
||||
|
||||
|
||||
/** @brief A call to start stream data transmission to a client
|
||||
* @param stream an #AislStream instance
|
||||
* @return a #AislStatus displaying if stream is ready to be proceed by teh engine
|
||||
*/
|
||||
AislStatus
|
||||
aisl_flush(AislStream stream);
|
||||
|
||||
|
||||
/** @brief A call to reject the stream. In HTTP 1.X it also closes client's connection
|
||||
* @param stream an #AislStream instance
|
||||
*/
|
||||
void
|
||||
aisl_reject(AislStream stream);
|
||||
|
||||
|
||||
/** @brief A call to begin the HTTP response
|
||||
* @param stream an #AislStream instance
|
||||
* @param status_code of the HTTP response
|
||||
* @param content_length in bytes or #AISL_AUTO_LENGTH if length is not knonw yet
|
||||
* @return #AislStatus code
|
||||
*/
|
||||
AislStatus
|
||||
aisl_response(AislStream stream,
|
||||
AislHttpResponse status_code,
|
||||
uint64_t content_length);
|
||||
|
||||
|
||||
/** @brief Adds HTTP header to the stream buffer
|
||||
* @param stream an #AislStream instance
|
||||
* @param key of HTTP header
|
||||
* @param value of HTTP header
|
||||
* @return a length of data added to the stream buffer
|
||||
*/
|
||||
int
|
||||
aisl_header(AislStream stream, const char *key, const char *value );
|
||||
|
||||
|
||||
/** @brief Adds printf-like formatted HTTP header to the stream buffer
|
||||
* @param stream an #AislStream instance
|
||||
* @param key of HTTP header
|
||||
* @param format of HTTP header value
|
||||
* @return a length of data added to the stream buffer
|
||||
*/
|
||||
int
|
||||
aisl_header_printf(AislStream stream,
|
||||
const char *key,
|
||||
@@ -129,13 +73,6 @@ aisl_header_printf(AislStream stream,
|
||||
... );
|
||||
|
||||
|
||||
/** @brief Adds vprintf-like formatted HTTP header to the stream buffer
|
||||
* @param stream an #AislStream instance
|
||||
* @param key of HTTP header
|
||||
* @param format of HTTP header value
|
||||
* @param args list for HTTP header value construction
|
||||
* @return a length of data added to the stream buffer
|
||||
*/
|
||||
int
|
||||
aisl_header_vprintf(AislStream stream,
|
||||
const char *key,
|
||||
@@ -143,56 +80,26 @@ aisl_header_vprintf(AislStream stream,
|
||||
va_list args );
|
||||
|
||||
|
||||
/** @brief Adds printf-like formatted HTTP response to the stream buffer
|
||||
* @param stream an #AislStream instance
|
||||
* @param format of the HTTP response
|
||||
* @return a length of data added to the stream buffer
|
||||
*/
|
||||
int
|
||||
aisl_printf(AislStream stream, const char *format, ...);
|
||||
|
||||
|
||||
/** @brief Adds vprintf-like formatted HTTP response to the stream buffer
|
||||
* @param stream an #AislStream instance
|
||||
* @param format of the HTTP response
|
||||
* @param args list for HTTP response construction
|
||||
* @return a length of data added to the stream buffer
|
||||
*/
|
||||
int
|
||||
aisl_vprintf(AislStream stream, const char *format, va_list args);
|
||||
|
||||
|
||||
/** @brief Adds data of the HTTP response to the stream buffer
|
||||
* @param stream an #AislStream instance
|
||||
* @param data a pointer to HTTP response data array
|
||||
* @param d_len size of the HTTP response data array
|
||||
* @return a length of data added to the stream buffer
|
||||
*/
|
||||
int
|
||||
aisl_write(AislStream stream, const char *data, int d_len);
|
||||
|
||||
|
||||
/** @brief Adds a null-terminated string to the stream buffer
|
||||
* @param str_data the HTTP response string
|
||||
* @param stream an #AislStream instance
|
||||
* @return a length of data added to the stream buffer
|
||||
*/
|
||||
int
|
||||
aisl_puts(const char *str_data, AislStream stream);
|
||||
|
||||
|
||||
/** @brief Switches triggering of #AISL_EVENT_STREAM_OUTPUT
|
||||
* @param stream an #AislStream instance
|
||||
* @param value a true to enable or false to disable (default) triggering
|
||||
*/
|
||||
void
|
||||
aisl_set_output_event(AislStream stream, bool value);
|
||||
|
||||
|
||||
/** @brief Gets state of the #AISL_EVENT_STREAM_OUTPUT triggering
|
||||
* @param stream an #AislStream instance
|
||||
* @return true if triggering is enabled and flase otherwise
|
||||
*/
|
||||
bool
|
||||
aisl_get_output_event(AislStream stream);
|
||||
|
||||
|
||||
+31
-49
@@ -20,22 +20,26 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#define AISL_AUTO_LENGTH (~0)
|
||||
|
||||
/** type casts */
|
||||
#define AISL_CALLBACK(x) ((AislCallback) x)
|
||||
|
||||
|
||||
/** @brief AISL Instance */
|
||||
/** AISL Instance */
|
||||
typedef struct aisl_instance * AislInstance;
|
||||
|
||||
/** @brief HTTP(s) Server */
|
||||
/** HTTP(s) Server */
|
||||
typedef struct aisl_server * AislServer;
|
||||
|
||||
/** @brief HTTP(s) Client */
|
||||
/** HTTP(s) Client */
|
||||
typedef struct aisl_client * AislClient;
|
||||
|
||||
/** @brief Server<->Client Stream */
|
||||
/** Server<->Client Stream */
|
||||
typedef struct aisl_stream * AislStream;
|
||||
|
||||
|
||||
@@ -50,16 +54,15 @@ typedef enum {
|
||||
, AISL_IDLE = 1
|
||||
} AislStatus;
|
||||
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
/** @brief Converts #AislStatus code to a null terminated string
|
||||
* @param status an #AislStatus code
|
||||
* @return pointer to the string representing #AislStatus
|
||||
*/
|
||||
const char *
|
||||
aisl_status_to_string(AislStatus status);
|
||||
|
||||
#endif
|
||||
|
||||
/** @brief HTTP version enumeration */
|
||||
|
||||
/** Generic HTTP Enumerations */
|
||||
typedef enum {
|
||||
AISL_HTTP_0_9 = 0x0009
|
||||
, AISL_HTTP_1_0 = 0x0100
|
||||
@@ -68,15 +71,10 @@ typedef enum {
|
||||
} AislHttpVersion;
|
||||
|
||||
|
||||
/** @brief Converts #AislHttpVersion code to a null terminated string
|
||||
* @param version an #AislHttpVersion code
|
||||
* @return pointer to the string representing #AislHttpVersion
|
||||
*/
|
||||
const char *
|
||||
aisl_http_version_to_string(AislHttpVersion version);
|
||||
|
||||
|
||||
/** HTTP method enumeration */
|
||||
typedef enum {
|
||||
AISL_HTTP_METHOD_UNKNOWN
|
||||
, AISL_HTTP_GET
|
||||
@@ -91,15 +89,10 @@ typedef enum {
|
||||
} AislHttpMethod;
|
||||
|
||||
|
||||
/** @brief Converts #AislHttpMethod code to a null terminated string
|
||||
* @param method an #AislHttpMethod code
|
||||
* @return pointer to the string representing #AislHttpMethod
|
||||
*/
|
||||
const char *
|
||||
aisl_http_method_to_string( AislHttpMethod method );
|
||||
|
||||
|
||||
/** @brief HTTP response status enumeration */
|
||||
typedef enum {
|
||||
AISL_HTTP_CONTINUE = 100
|
||||
, AISL_HTTP_SWITCHING_PROTOCOLS
|
||||
@@ -149,15 +142,11 @@ typedef enum {
|
||||
} AislHttpResponse;
|
||||
|
||||
|
||||
/** @brief Converts #AislHttpResponse code to a null terminated string
|
||||
* @param code an #AislHttpResponse code
|
||||
* @return pointer to the string representing #AislHttpResponse
|
||||
*/
|
||||
const char *
|
||||
aisl_http_response_to_string( AislHttpResponse code );
|
||||
|
||||
|
||||
/** @brief AISL events enumeration */
|
||||
/** Codes of AISL events */
|
||||
typedef enum {
|
||||
AISL_EVENT_SERVER_READY = 100
|
||||
, AISL_EVENT_SERVER_ERROR = 190
|
||||
@@ -175,52 +164,45 @@ typedef enum {
|
||||
} AislEvent;
|
||||
|
||||
|
||||
/** @brief generic AISL event structure */
|
||||
struct aisl_evt {
|
||||
void *source; /**< Pointer to an event source: #AislServer, #AislClient, #AislStream */
|
||||
AislEvent code; /**< Event code */
|
||||
AislStatus status; /**< Event status */
|
||||
void *source;
|
||||
AislEvent code;
|
||||
AislStatus status;
|
||||
};
|
||||
|
||||
|
||||
/** @brief event handler callback definition
|
||||
* @param evt a pointer to an #aisl_evt structure
|
||||
* @param ctx a pointer to a context defined by user (see #aisl_cfg)
|
||||
*/
|
||||
/* void type event callback */
|
||||
typedef void
|
||||
(* AislCallback) (const struct aisl_evt *evt, void *ctx);
|
||||
|
||||
|
||||
/** @brief AISL event structue passed on stream opening */
|
||||
struct aisl_evt_open {
|
||||
struct aisl_evt evt; /**< generic #aisl_evt structure */
|
||||
const char *path; /**< HTTP request path */
|
||||
const char *query; /**< HTTP request query (GET params) */
|
||||
AislHttpMethod http_method; /**< HTTP request method */
|
||||
struct aisl_evt evt;
|
||||
const char *path;
|
||||
const char *query;
|
||||
AislHttpMethod http_method;
|
||||
};
|
||||
|
||||
|
||||
/** @brief AISL event structue passed on HTTP header reception */
|
||||
struct aisl_evt_header {
|
||||
struct aisl_evt evt; /**< generic #aisl_evt structure */
|
||||
const char *key; /**< low case HTTP header name */
|
||||
const char *value; /**< HTTP header string */
|
||||
struct aisl_evt evt;
|
||||
const char *key;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
|
||||
/** @brief AISL event structue passed on HTTP request data part received */
|
||||
struct aisl_evt_input {
|
||||
struct aisl_evt evt; /**< generic #aisl_evt structure */
|
||||
const char *data; /**< a pointer to received data array */
|
||||
int32_t size; /**< data array size */
|
||||
struct aisl_evt evt;
|
||||
const char *data;
|
||||
int32_t size;
|
||||
};
|
||||
|
||||
|
||||
/** @brief Converts #AislEvent code to a null terminated string
|
||||
* @param evt an #AislEvent code
|
||||
* @return pointer to the string representing #AislEvent
|
||||
*/
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
const char *
|
||||
aisl_event_to_string(AislEvent evt);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !AISL_TYPES_H */
|
||||
|
||||
@@ -12,7 +12,7 @@ PROJECT_NAME = aisl
|
||||
|
||||
PROJECT_VERSION_MAJOR = 1
|
||||
PROJECT_VERSION_MINOR = 0
|
||||
PROJECT_VERSION_TWEAK = 5
|
||||
PROJECT_VERSION_TWEAK = 0
|
||||
PROJECT_VERSION_LABEL = 0
|
||||
|
||||
#SRC_DIR = src
|
||||
@@ -46,17 +46,15 @@ PROJECT_LIBRARIES = \
|
||||
|
||||
|
||||
# compilation macro options:
|
||||
|
||||
AISL_WITH_DEBUG ?= 0 # disable debug output
|
||||
AISL_WITH_SSL ?= 1 # enable SSL support
|
||||
AISL_WITH_STRINGIFIERS ?= 1 # enable *_to_string functions
|
||||
|
||||
# AISL_WITHOUT_SSL - exclude HTTPS support
|
||||
# AISL_WITHOUT_STRINGIFIERS - exclude several *_to_string functions not
|
||||
|
||||
# flags
|
||||
PROJECT_CFLAGS = -D_POSIX_C_SOURCE=200809L
|
||||
PROJECT_CFLAGS += -DAISL_WITH_DEBUG=$(AISL_WITH_DEBUG)
|
||||
PROJECT_CFLAGS += -DAISL_WITH_SSL=$(AISL_WITH_SSL)
|
||||
PROJECT_CFLAGS += -DAISL_WITH_STRINGIFIERS=$(AISL_WITH_STRINGIFIERS)
|
||||
#PROJECT_CFLAGS += -DDEBUG
|
||||
#PROJECT_CFLAGS += -DAISL_WITHOUT_SSL
|
||||
#PROJECT_CFLAGS += -DAISL_WITHOUT_STRINGIFIERS
|
||||
|
||||
|
||||
# PROJECT_LDFLAGS = -L
|
||||
|
||||
@@ -15,19 +15,20 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "debug.h"
|
||||
#include "buffer.h"
|
||||
|
||||
|
||||
static int32_t
|
||||
buffer_set_size(struct buffer *buffer, int32_t new_size)
|
||||
{
|
||||
if (!buffer->size || new_size != buffer->size) {
|
||||
if (new_size != buffer->size) {
|
||||
char *data;
|
||||
|
||||
if (new_size) {
|
||||
if (new_size % 4096) {
|
||||
new_size = (new_size / 4096 + 1) * 4096;
|
||||
int32_t s = new_size / 1024;
|
||||
|
||||
if ( new_size % 1024 ) {
|
||||
new_size = (s+1) * 1024;
|
||||
}
|
||||
} else {
|
||||
new_size = 16*1024;
|
||||
@@ -83,14 +84,14 @@ buffer_move_offset(struct buffer *buffer, int32_t offset, int32_t size)
|
||||
}
|
||||
|
||||
int32_t
|
||||
buffer_insert(struct buffer *buffer, int32_t offset, const char *data,
|
||||
buffer_insert(struct buffer *buffer,
|
||||
int32_t offset,
|
||||
const char *data,
|
||||
int32_t size)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
DPRINTF("Buffer: %d of %d", buffer->used, buffer->size);
|
||||
|
||||
if ( (result = buffer_set_size(buffer, buffer->size + size)) != -1) {
|
||||
if ( (result = buffer_set_size(buffer, size)) != -1) {
|
||||
if ((result = buffer_move_offset(buffer, offset, size)) != -1) {
|
||||
memcpy(&buffer->data[offset], data, size);
|
||||
buffer->used += result;
|
||||
@@ -117,18 +118,17 @@ buffer_append_printf(struct buffer *buffer, const char *format, ...)
|
||||
int32_t
|
||||
buffer_append_vprintf(struct buffer *buffer, const char *format, va_list args)
|
||||
{
|
||||
DPRINTF("Buffer: %d of %d", buffer->used, buffer->size);
|
||||
int32_t space, result;
|
||||
va_list cp_args;
|
||||
|
||||
va_copy(cp_args, args);
|
||||
space = buffer->size - buffer->used;
|
||||
space = buffer->size - buffer->used,
|
||||
result = vsnprintf(&buffer->data[buffer->used], space, format, args);
|
||||
|
||||
if (result < space) { /* enough space */
|
||||
buffer->used += result;
|
||||
} else {
|
||||
result = buffer_set_size(buffer, buffer->size + result - space + 1);
|
||||
result = buffer_set_size(buffer, buffer->size + result - space);
|
||||
if (result != -1)
|
||||
result = buffer_append_vprintf(buffer, format, cp_args);
|
||||
}
|
||||
@@ -140,7 +140,6 @@ buffer_append_vprintf(struct buffer *buffer, const char *format, va_list args)
|
||||
int32_t
|
||||
buffer_append(struct buffer *buffer, const char *data, int32_t size)
|
||||
{
|
||||
DPRINTF("Buffer: %d of %d", buffer->used, buffer->size);
|
||||
int32_t used, space;
|
||||
|
||||
used = buffer->used,
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
@@ -47,15 +47,13 @@ aisl_client_parse(AislClient client, char *data, int32_t size)
|
||||
AislStream s = client->stream;
|
||||
ParserStatus p = HTTP_PARSER_SUCCESS;
|
||||
|
||||
int32_t data_size;
|
||||
int32_t bytes_left = size;
|
||||
|
||||
switch (client->http_version) {
|
||||
case AISL_HTTP_0_9:
|
||||
case AISL_HTTP_1_0:
|
||||
case AISL_HTTP_1_1:
|
||||
while (p == HTTP_PARSER_SUCCESS) {
|
||||
data_size = size;
|
||||
|
||||
switch (aisl_stream_get_state(s)) {
|
||||
case AISL_STREAM_STATE_IDLE:
|
||||
p = http_10_parse_request(data, &size, client->stream);
|
||||
@@ -70,13 +68,13 @@ aisl_client_parse(AislClient client, char *data, int32_t size)
|
||||
break;
|
||||
|
||||
default: /* has input data, but request was already parsed */
|
||||
DPRINTF("misleading request length");
|
||||
p = HTTP_PARSER_ERROR;
|
||||
continue;
|
||||
}
|
||||
// size now has number of parsed bytes
|
||||
DPRINTF("%d bytes parsed, %d bytes left", (data_size - size), size);
|
||||
data += (data_size - size);
|
||||
data += size;
|
||||
bytes_left -= size;
|
||||
size = bytes_left;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -106,6 +104,7 @@ aisl_client_parse(AislClient client, char *data, int32_t size)
|
||||
break;
|
||||
}
|
||||
|
||||
if (size)
|
||||
buffer_shift(&client->in, client->in.used - size); /* reset buffer */
|
||||
|
||||
return result;
|
||||
@@ -123,7 +122,7 @@ aisl_client_input(AislClient client)
|
||||
char *data = &client->in.data[ client->in.used ];
|
||||
int32_t size = client->in.size - client->in.used;
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if (client->ssl) {
|
||||
DPRINTF("SSL_read");
|
||||
if (!(client->flags & FLAG_HANDSHAKE)) {
|
||||
@@ -156,7 +155,7 @@ aisl_client_input(AislClient client)
|
||||
return aisl_client_parse(client, data, size);
|
||||
} else if (l<0) {
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if (client->ssl) {
|
||||
if (SSL_get_error(client->ssl, l) == SSL_ERROR_WANT_READ)
|
||||
return AISL_IDLE;
|
||||
@@ -216,11 +215,12 @@ aisl_client_output(AislClient client)
|
||||
if ( !l )
|
||||
return AISL_IDLE;
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
l = (client->ssl) ? SSL_write(client->ssl, data, l) :
|
||||
send(client->fd, data, l, 0);
|
||||
#else
|
||||
#ifdef AISL_WITHOUT_SSL
|
||||
l = send( client->fd, data, l, 0);
|
||||
#else
|
||||
l = (client->ssl) ?
|
||||
SSL_write(client->ssl, data, l) :
|
||||
send( client->fd, data, l, 0);
|
||||
#endif
|
||||
|
||||
if (l > 0) {
|
||||
@@ -234,8 +234,8 @@ aisl_client_output(AislClient client)
|
||||
if (client->stream != NULL )
|
||||
return AISL_SUCCESS;
|
||||
|
||||
/* in case of malloc error it will not be an error as long as the
|
||||
* request was handled and we just close the connection.
|
||||
/* in case of malloc error it will not be error as long as request was
|
||||
* handled and we just close the connection.
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ aisl_client_output(AislClient client)
|
||||
}
|
||||
|
||||
/* l < 0 */
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if (client->ssl) {
|
||||
if (SSL_get_error(client->ssl, l) == SSL_ERROR_WANT_WRITE)
|
||||
return AISL_IDLE;
|
||||
@@ -288,7 +288,7 @@ aisl_client_new(AislServer server, int fd, struct sockaddr_in *addr)
|
||||
client->stream = stream;
|
||||
DPRINTF("client stream alocated");
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if (server->ssl) {
|
||||
SSL_CTX * ssl_ctx = aisl_get_ssl_ctx(server->instance, NULL);
|
||||
|
||||
@@ -315,7 +315,7 @@ aisl_client_free(AislClient client)
|
||||
{
|
||||
aisl_client_close(client, AISL_SUCCESS);
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if (client->ssl)
|
||||
SSL_free(client->ssl);
|
||||
#endif
|
||||
@@ -406,10 +406,10 @@ __attribute__ ((visibility ("default") ))
|
||||
bool
|
||||
aisl_client_is_secure(AislClient client)
|
||||
{
|
||||
#if AISL_WITH_SSL == 1
|
||||
return (client->ssl == NULL) ? false : true;
|
||||
#else
|
||||
#ifdef AISL_WITHOUT_SSL
|
||||
return false;
|
||||
#else
|
||||
return (client->ssl == NULL) ? false : true;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#include <aisl/client.h>
|
||||
#include "buffer.h"
|
||||
|
||||
@@ -33,7 +29,7 @@ struct aisl_client {
|
||||
struct buffer out; /**< Client's output buffer. */
|
||||
AislServer server; /**< Server instance. */
|
||||
AislStream stream; /**< Pending client's stream. */
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
SSL *ssl; /**< SSL pointer for HTTPS. */
|
||||
#endif
|
||||
time_t timestamp; /**< Last communication timestamp. */
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef AISL_DEBUG_H_703E22F9_4A6E_426F_B708_81BCA019049B
|
||||
#define AISL_DEBUG_H_703E22F9_4A6E_426F_B708_81BCA019049B
|
||||
|
||||
#if AISL_WITH_DEBUG == 1
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
+19
-50
@@ -124,14 +124,12 @@ http_10_parse_request(char *data, int32_t *p_size, AislStream stream)
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (uri && !host) {
|
||||
if (uri && !host)
|
||||
host = data+3;
|
||||
} else if (host && !port) {
|
||||
else if (host && !port)
|
||||
port = data+1;
|
||||
} else if (version) {
|
||||
DPRINTF("bad character in HTTP version (%c)", *data);
|
||||
else if (version)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '/':
|
||||
@@ -140,18 +138,15 @@ http_10_parse_request(char *data, int32_t *p_size, AislStream stream)
|
||||
if (!uri)
|
||||
uri = path;
|
||||
} else if (version && data-version != 4) {
|
||||
DPRINTF("wrong HTTP version length");
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '?':
|
||||
if (!query) {
|
||||
if (!query)
|
||||
query = data+1;
|
||||
} else if (version) {
|
||||
DPRINTF("bad character in HTTP version (%c)", *data);
|
||||
else if (version)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
@@ -159,53 +154,41 @@ http_10_parse_request(char *data, int32_t *p_size, AislStream stream)
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
if (!version) {
|
||||
DPRINTF("unexpected end of HTTP request");
|
||||
if (!version)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!uri && method_end) {
|
||||
if (!uri && method_end)
|
||||
uri = data;
|
||||
} else if (!version && uri_end) {
|
||||
else if (!version && uri_end)
|
||||
version = data;
|
||||
} else if (version && data-version > 7) {
|
||||
DPRINTF("bad HTTP version length");
|
||||
else if (version && data-version > 7)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
}
|
||||
data++;
|
||||
}
|
||||
|
||||
/* STEP 2. Verify splitting was completed */
|
||||
/* STEP 2. Verifly splitting was completed */
|
||||
|
||||
/* Was request sent? */
|
||||
if (!newline)
|
||||
return HTTP_PARSER_HUNGRY;
|
||||
|
||||
/* Check mandatory parts presence */
|
||||
if (!method_end || !path || !uri_end || !version) {
|
||||
DPRINTF("parser error: method=%d, path=%d, uri_end=%d, version=%d",
|
||||
(method_end ? 1 : 0), (path ? 1 : 0), (uri_end ? 1 : 0),
|
||||
(version ? 1: 0));
|
||||
if (!method_end || !path || !uri_end || !version)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
|
||||
*method_end = 0;
|
||||
*newline = 0;
|
||||
*uri_end = 0;
|
||||
|
||||
http_method = http_method_from_string(method, method_end - method);
|
||||
if (http_method == AISL_HTTP_METHOD_UNKNOWN) {
|
||||
DPRINTF("invalid HTTP method");
|
||||
if (http_method == AISL_HTTP_METHOD_UNKNOWN)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
|
||||
if ((http_version = http_version_from_string(version))==0) {
|
||||
DPRINTF("invalid HTTP version");
|
||||
if ((http_version = http_version_from_string(version))==0)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
|
||||
if (query) {
|
||||
*(query-1)=0;
|
||||
@@ -214,10 +197,8 @@ http_10_parse_request(char *data, int32_t *p_size, AislStream stream)
|
||||
}
|
||||
|
||||
if (host) {
|
||||
if (strncmp(uri, "http://", 7) || strncmp(uri, "https://", 8)) {
|
||||
DPRINTF("invalid HTTP uri");
|
||||
if (strncmp(uri, "http://", 7) || strncmp(uri, "https://", 8))
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
|
||||
if (port)
|
||||
*(port-1)=0;
|
||||
@@ -229,7 +210,7 @@ http_10_parse_request(char *data, int32_t *p_size, AislStream stream)
|
||||
if (host)
|
||||
aisl_stream_set_header(stream, "host", host);
|
||||
/* how many characters has been read */
|
||||
*(p_size) = size;
|
||||
*(p_size)-=size;
|
||||
return HTTP_PARSER_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -244,9 +225,6 @@ http_10_parse_header(char *data, int32_t *p_size, AislStream stream)
|
||||
*val_end = NULL,
|
||||
*newline = NULL;
|
||||
|
||||
|
||||
DPRINTF("parse header: %p, %d, %02X %02X", data, *p_size, *data & 0xFF, *(data+1) & 0xFF);
|
||||
|
||||
while(!newline && size-- ) {
|
||||
switch(*data) {
|
||||
case ' ':
|
||||
@@ -256,10 +234,8 @@ http_10_parse_header(char *data, int32_t *p_size, AislStream stream)
|
||||
|
||||
case ':':
|
||||
if (!colon) {
|
||||
if (colon == key) {
|
||||
DPRINTF("parser error: nameless HTTP header");
|
||||
if (colon == key)
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
|
||||
colon = data;
|
||||
}
|
||||
@@ -290,21 +266,17 @@ http_10_parse_header(char *data, int32_t *p_size, AislStream stream)
|
||||
if (!newline)
|
||||
return HTTP_PARSER_HUNGRY;
|
||||
|
||||
/* DPRINTF("(%p == %p); *key == 0x%02x", newline, key, *key & 0xFF); */
|
||||
|
||||
if (colon && val && val_end) {
|
||||
*colon = 0;
|
||||
*val_end = 0;
|
||||
aisl_stream_set_header(stream, key, val);
|
||||
*p_size = size;
|
||||
*p_size -= size;
|
||||
return HTTP_PARSER_SUCCESS;
|
||||
} else if (newline == key || (newline == key+1 && *key == '\r')) {
|
||||
*p_size = size;
|
||||
DPRINTF("end of headers received");
|
||||
*p_size -= size;
|
||||
return (aisl_stream_set_end_of_headers(stream) == 0) ?
|
||||
HTTP_PARSER_READY : HTTP_PARSER_SUCCESS;
|
||||
HTTP_PARSER_SUCCESS : HTTP_PARSER_READY;
|
||||
}
|
||||
DPRINTF("parser error: invalid HTTP header");
|
||||
return HTTP_PARSER_ERROR;
|
||||
}
|
||||
|
||||
@@ -317,13 +289,10 @@ http_10_parse_body(char *data, int32_t *p_size, AislStream stream)
|
||||
if (!size)
|
||||
return HTTP_PARSER_HUNGRY;
|
||||
|
||||
*p_size = 0;
|
||||
|
||||
switch (aisl_stream_set_body(stream, data, size)) {
|
||||
case 0:
|
||||
return HTTP_PARSER_READY;
|
||||
case -1:
|
||||
DPRINTF("parser error: invalid HTTP body length");
|
||||
return HTTP_PARSER_ERROR;
|
||||
default:
|
||||
return HTTP_PARSER_SUCCESS;
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "instance.h"
|
||||
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
|
||||
static uint32_t m_instances = 0;
|
||||
|
||||
@@ -89,7 +89,7 @@ aisl_new(const struct aisl_cfg *cfg)
|
||||
goto release;
|
||||
}
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if ((m_instances++) == 0) {
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_ssl_algorithms();
|
||||
@@ -140,7 +140,7 @@ aisl_free(AislInstance instance)
|
||||
|
||||
list_release(&instance->client_spool, (list_destructor_t)aisl_client_free);
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
if (instance->ssl) {
|
||||
struct aisl_ssl **ssl = instance->ssl;
|
||||
|
||||
@@ -159,7 +159,7 @@ aisl_free(AislInstance instance)
|
||||
}
|
||||
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
|
||||
SSL_CTX *
|
||||
aisl_get_ssl_ctx(AislInstance instance, const char * host)
|
||||
@@ -185,10 +185,10 @@ aisl_get_ssl_ctx(AislInstance instance, const char * host)
|
||||
void
|
||||
aisl_raise_evt(AislInstance instance, const struct aisl_evt *evt)
|
||||
{
|
||||
#if AISL_WITH_STRINGIFIERS == 1
|
||||
DPRINTF("! %s", aisl_event_to_string(evt->code));
|
||||
#else
|
||||
#ifdef AISL_WITHOUT_STRINGIFIERS
|
||||
DPRINTF("! %d", evt->code);
|
||||
#else
|
||||
DPRINTF("! %s", aisl_event_to_string(evt->code));
|
||||
#endif
|
||||
|
||||
if (instance->callback)
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef AISL_INSTANCE_H_814CF474_A646_45B7_B6B2_3F4C7BEFA484
|
||||
#define AISL_INSTANCE_H_814CF474_A646_45B7_B6B2_3F4C7BEFA484
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
struct aisl_instance {
|
||||
AislServer *srv;
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
struct aisl_ssl * *ssl;
|
||||
#endif
|
||||
struct list client_spool;
|
||||
@@ -40,7 +40,7 @@ struct aisl_instance {
|
||||
};
|
||||
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
/**
|
||||
* @brief Gets SSL context for appropriate server name.
|
||||
* @param instance a pointer to #AislInstance instance.
|
||||
@@ -157,7 +157,7 @@ aisl_server_get_address(AislServer server, struct sockaddr_in *address)
|
||||
}
|
||||
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
bool
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "ssl.h"
|
||||
|
||||
|
||||
#if AISL_WITH_SSL == 1
|
||||
#ifndef AISL_WITHOUT_SSL
|
||||
|
||||
|
||||
static int
|
||||
@@ -24,14 +24,14 @@ static void
|
||||
aisl_stream_reset(AislStream stream, bool initial)
|
||||
{
|
||||
if (!initial) {
|
||||
aisl_raise(aisl_get_instance(stream), (void*) stream,
|
||||
aisl_raise(aisl_stream_get_instance(stream), (void*) stream,
|
||||
AISL_EVENT_STREAM_CLOSE, AISL_SUCCESS);
|
||||
}
|
||||
|
||||
buffer_release(&stream->buffer);
|
||||
|
||||
stream->u_ptr = NULL;
|
||||
stream->content_length = 0; //AISL_AUTO_LENGTH;
|
||||
stream->content_length = AISL_AUTO_LENGTH;
|
||||
stream->head_offset = 0;
|
||||
stream->flags = 0;
|
||||
stream->state = AISL_STREAM_STATE_IDLE;
|
||||
@@ -125,7 +125,7 @@ aisl_stream_set_request(AislStream stream,
|
||||
on_open.path = path;
|
||||
on_open.query = query;
|
||||
|
||||
aisl_raise_evt(aisl_get_instance(stream), (struct aisl_evt *)&on_open);
|
||||
aisl_raise_evt(aisl_stream_get_instance(stream), (struct aisl_evt *)&on_open);
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ aisl_stream_set_header(AislStream stream, const char *key, const char *value)
|
||||
on_header.key = key;
|
||||
on_header.value = value;
|
||||
|
||||
aisl_raise_evt(aisl_get_instance(stream),
|
||||
aisl_raise_evt(aisl_stream_get_instance(stream),
|
||||
(struct aisl_evt *) &on_header);
|
||||
}
|
||||
|
||||
@@ -162,12 +162,9 @@ aisl_stream_set_end_of_headers(AislStream stream)
|
||||
{
|
||||
int result;
|
||||
|
||||
DPRINTF("stream->content_length == %"PRIu64"", stream->content_length);
|
||||
|
||||
if (stream->state == AISL_STREAM_STATE_WAIT_HEADER) {
|
||||
result = (stream->content_length != 0);
|
||||
stream->state = (result) ? AISL_STREAM_STATE_WAIT_BODY :
|
||||
AISL_STREAM_STATE_READY;
|
||||
stream->state = AISL_STREAM_STATE_WAIT_BODY;
|
||||
result = (stream->content_length == 0);
|
||||
} else {
|
||||
result = 2;
|
||||
}
|
||||
@@ -244,14 +241,6 @@ aisl_set_context(AislStream s, void *u_ptr)
|
||||
}
|
||||
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
bool
|
||||
aisl_is_secure(AislStream stream)
|
||||
{
|
||||
return aisl_client_is_secure(stream->client);
|
||||
}
|
||||
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
AislClient
|
||||
aisl_get_client(AislStream s)
|
||||
@@ -590,7 +579,7 @@ aisl_puts(const char *str, AislStream stream)
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
AislInstance
|
||||
aisl_get_instance(AislStream stream)
|
||||
aisl_stream_get_instance(AislStream stream)
|
||||
{
|
||||
return stream->client->server->instance;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <aisl/types.h>
|
||||
|
||||
|
||||
#if AISL_WITH_STRINGIFIERS == 1
|
||||
#ifndef WITHOUT_STRINGIFIERS
|
||||
|
||||
__attribute__ ((visibility ("default") ))
|
||||
const char *
|
||||
Reference in New Issue
Block a user