[Debian-iot-packaging] [ulfius] 01/02: Import Upstream version 2.2.4
Thorsten Alteholz
alteholz at moszumanska.debian.org
Sun Jan 28 18:20:14 UTC 2018
This is an automated email from the git hooks/post-receive script.
alteholz pushed a commit to branch master
in repository ulfius.
commit 3d88f28ae684c80b3112bc144c3cf8eb08d91775
Author: Thorsten Alteholz <debian at alteholz.de>
Date: Sun Jan 28 19:15:45 2018 +0100
Import Upstream version 2.2.4
---
API.md | 2 +-
README.md | 3 +-
.../oauth2_bearer/glewlwyd_resource.c | 63 ++++++++++-------
.../oauth2_bearer/glewlwyd_resource.h | 2 +-
.../static_file/static_file_callback.c | 82 ++++++++++++++--------
.../static_file/static_file_callback.h | 18 +++--
example_programs/websocket_example/Makefile | 4 +-
.../websocket_example/websocket_example.c | 29 ++++----
src/Makefile | 2 +-
src/u_request.c | 24 +++++--
src/u_response.c | 8 +--
src/u_websocket.c | 6 +-
src/ulfius.c | 74 +++++++++++--------
src/ulfius.h | 12 ++--
14 files changed, 203 insertions(+), 126 deletions(-)
diff --git a/API.md b/API.md
index 3ec125b..72a85ca 100644
--- a/API.md
+++ b/API.md
@@ -59,7 +59,7 @@ If you already have programs that use Ulfius 1.x and want to update them to the
#### Endpoints definitions
-Endpoints structure have change, `ulfius_add_endpoint_by_val` now requires only one callback function, but requires a priority number.
+Endpoints structure have changed, `ulfius_add_endpoint_by_val` now requires only one callback function, but requires a priority number.
If you don't use authentication callback functions, you can simply remove the `NULL, NULL, NULL` parameters corresponding to the former authentication callback function pointer, the authentication callback user data, and the realm value. Then add any number as a priority, 0 for example.
diff --git a/README.md b/README.md
index 8f332d9..87507d9 100644
--- a/README.md
+++ b/README.md
@@ -87,7 +87,8 @@ Example callback functions are available in the folder [example_callbacks](https
- [Angharad](https://github.com/babelouest/angharad), House automation system for ZWave and other types of devices
- [Glewlwyd](https://github.com/babelouest/glewlwyd), a lightweight OAuth2 authentication server that provides [JSON Web Tokens](https://jwt.io/)
-- [Hutch](https://github.com/babelouest/hutch), a safe locker for passwords and other secrets, using encryption on the client side only
+- [Hutch](https://github.com/babelouest/hutch), a safe locker for passwords and other secrets, using client side encryption only
+- [Taliesin](https://github.com/babelouest/taliesin), a lightweight audio streaming server
- [Taulas Raspberry Pi Serial interface](https://github.com/babelouest/taulas/tree/master/taulas_raspberrypi_serial), an interface for Arduino devices that implent [Taulas](https://github.com/babelouest/taulas/) protocol, a house automation protocol
## What's new in Ulfius 2.2?
diff --git a/example_callbacks/oauth2_bearer/glewlwyd_resource.c b/example_callbacks/oauth2_bearer/glewlwyd_resource.c
index b063686..8866eca 100644
--- a/example_callbacks/oauth2_bearer/glewlwyd_resource.c
+++ b/example_callbacks/oauth2_bearer/glewlwyd_resource.c
@@ -28,12 +28,12 @@
#include "glewlwyd_resource.h"
/**
- * check if bearer token has the specified scope
+ * check if bearer token has some of the specified scope
*/
int callback_check_glewlwyd_access_token (const struct _u_request * request, struct _u_response * response, void * user_data) {
struct _glewlwyd_resource_config * config = (struct _glewlwyd_resource_config *)user_data;
- json_t * j_access_token = NULL;
- int res = U_CALLBACK_UNAUTHORIZED, res_scope, res_validity;
+ json_t * j_access_token = NULL, * j_res_scope;
+ int res = U_CALLBACK_UNAUTHORIZED, res_validity;
const char * token_value = NULL;
char * response_value = NULL;
@@ -42,7 +42,7 @@ int callback_check_glewlwyd_access_token (const struct _u_request * request, str
case G_METHOD_HEADER:
if (u_map_get(request->map_header, HEADER_AUTHORIZATION) != NULL) {
if (o_strstr(u_map_get(request->map_header, HEADER_AUTHORIZATION), HEADER_PREFIX_BEARER) == u_map_get(request->map_header, HEADER_AUTHORIZATION)) {
- token_value = u_map_get(request->map_header, HEADER_AUTHORIZATION) + strlen(HEADER_PREFIX_BEARER);
+ token_value = u_map_get(request->map_header, HEADER_AUTHORIZATION) + o_strlen(HEADER_PREFIX_BEARER);
}
}
break;
@@ -60,18 +60,23 @@ int callback_check_glewlwyd_access_token (const struct _u_request * request, str
if (check_result_value(j_access_token, G_OK)) {
res_validity = access_token_check_validity(config, json_object_get(j_access_token, "grants"));
if (res_validity == G_OK) {
- res_scope = access_token_check_scope(config, json_object_get(j_access_token, "grants"));
- if (res_scope == G_ERROR_INSUFFICIENT_SCOPE) {
+ j_res_scope = access_token_check_scope(config, json_object_get(j_access_token, "grants"));
+ if (check_result_value(j_res_scope, G_ERROR_INSUFFICIENT_SCOPE)) {
response_value = msprintf(HEADER_PREFIX_BEARER "%s%s%serror=\"insufficient_scope\",error_description=\"The scope is invalid\"", (config->realm!=NULL?"realm=":""), (config->realm!=NULL?config->realm:""), (config->realm!=NULL?",":""));
u_map_put(response->map_header, HEADER_RESPONSE, response_value);
o_free(response_value);
- } else if (res_scope != G_OK) {
+ } else if (!check_result_value(j_res_scope, G_OK)) {
response_value = msprintf(HEADER_PREFIX_BEARER "%s%s%serror=\"invalid_request\",error_description=\"Internal server error\"", (config->realm!=NULL?"realm=":""), (config->realm!=NULL?config->realm:""), (config->realm!=NULL?",":""));
u_map_put(response->map_header, HEADER_RESPONSE, response_value);
o_free(response_value);
} else {
res = U_CALLBACK_CONTINUE;
+ response->shared_data = (void*)json_pack("{ssso}", "username", json_string_value(json_object_get(json_object_get(j_access_token, "grants"), "username")), "scope", json_copy(json_object_get(j_res_scope, "scope")));
+ if (response->shared_data == NULL) {
+ res = U_CALLBACK_ERROR;
+ }
}
+ json_decref(j_res_scope);
} else if (res_validity == G_ERROR_INVALID_TOKEN) {
response_value = msprintf(HEADER_PREFIX_BEARER "%s%s%serror=\"invalid_request\",error_description=\"The access token is invalid\"", (config->realm!=NULL?"realm=":""), (config->realm!=NULL?config->realm:""), (config->realm!=NULL?",":""));
u_map_put(response->map_header, HEADER_RESPONSE, response_value);
@@ -98,31 +103,41 @@ int callback_check_glewlwyd_access_token (const struct _u_request * request, str
/**
* Validates if an access_token grants has a valid scope
+ * return the final scope list on success
*/
-int access_token_check_scope(struct _glewlwyd_resource_config * config, json_t * j_access_token) {
- int res, i, scope_count_token, scope_count_expected, count;
+json_t * access_token_check_scope(struct _glewlwyd_resource_config * config, json_t * j_access_token) {
+ int i, scope_count_token, scope_count_expected;
char ** scope_list_token, ** scope_list_expected;
+ json_t * j_res = NULL, * j_scope_final_list = json_array();
- if (j_access_token != NULL) {
- scope_count_token = split_string(json_string_value(json_object_get(j_access_token, "scope")), " ", &scope_list_token);
- scope_count_expected = split_string(config->oauth_scope, " ", &scope_list_expected);
- count = 0;
- if (scope_count_token > 0 && scope_count_expected > 0) {
- for (i=0; scope_count_expected > 0 && scope_list_expected[i] != NULL; i++) {
- if (string_array_has_value((const char **)scope_list_token, scope_list_expected[i])) {
- count++;
+ if (j_scope_final_list != NULL) {
+ if (j_access_token != NULL) {
+ scope_count_token = split_string(json_string_value(json_object_get(j_access_token, "scope")), " ", &scope_list_token);
+ scope_count_expected = split_string(config->oauth_scope, " ", &scope_list_expected);
+ if (scope_count_token > 0 && scope_count_expected > 0) {
+ for (i=0; scope_count_expected > 0 && scope_list_expected[i] != NULL; i++) {
+ if (string_array_has_value((const char **)scope_list_token, scope_list_expected[i])) {
+ json_array_append_new(j_scope_final_list, json_string(scope_list_expected[i]));
+ }
+ }
+ if (json_array_size(j_scope_final_list) > 0) {
+ j_res = json_pack("{siso}", "result", G_OK, "scope", json_copy(j_scope_final_list));
+ } else {
+ j_res = json_pack("{si}", "result", G_ERROR_INSUFFICIENT_SCOPE);
}
+ } else {
+ j_res = json_pack("{si}", "result", G_ERROR_INTERNAL);
}
- res = (count==scope_count_expected?G_OK:G_ERROR_INSUFFICIENT_SCOPE);
+ free_string_array(scope_list_token);
+ free_string_array(scope_list_expected);
} else {
- res = G_ERROR_INVALID_TOKEN;
+ j_res = json_pack("{si}", "result", G_ERROR_INVALID_TOKEN);
}
- free_string_array(scope_list_token);
- free_string_array(scope_list_expected);
} else {
- res = G_ERROR_INVALID_TOKEN;
+ j_res = json_pack("{si}", "result", G_ERROR_INTERNAL);
}
- return res;
+ json_decref(j_scope_final_list);
+ return j_res;
}
/**
@@ -166,7 +181,7 @@ json_t * access_token_check_signature(struct _glewlwyd_resource_config * config,
char * grants;
if (token_value != NULL) {
- if (!jwt_decode(&jwt, token_value, (const unsigned char *)config->jwt_decode_key, strlen(config->jwt_decode_key)) && jwt_get_alg(jwt) == config->jwt_alg) {
+ if (!jwt_decode(&jwt, token_value, (const unsigned char *)config->jwt_decode_key, o_strlen(config->jwt_decode_key)) && jwt_get_alg(jwt) == config->jwt_alg) {
grants = jwt_get_grants_json(jwt, NULL);
j_grants = json_loads(grants, JSON_DECODE_ANY, NULL);
if (j_grants != NULL) {
diff --git a/example_callbacks/oauth2_bearer/glewlwyd_resource.h b/example_callbacks/oauth2_bearer/glewlwyd_resource.h
index e363cbd..e00a994 100644
--- a/example_callbacks/oauth2_bearer/glewlwyd_resource.h
+++ b/example_callbacks/oauth2_bearer/glewlwyd_resource.h
@@ -48,4 +48,4 @@ int callback_check_glewlwyd_access_token (const struct _u_request * request, str
json_t * access_token_check_signature(struct _glewlwyd_resource_config * config, const char * token_value);
json_t * access_token_get_payload(const char * token_value);
int access_token_check_validity(struct _glewlwyd_resource_config * config, json_t * j_access_token);
-int access_token_check_scope(struct _glewlwyd_resource_config * config, json_t * j_access_token);
+json_t * access_token_check_scope(struct _glewlwyd_resource_config * config, json_t * j_access_token);
diff --git a/example_callbacks/static_file/static_file_callback.c b/example_callbacks/static_file/static_file_callback.c
index e606285..5197be5 100644
--- a/example_callbacks/static_file/static_file_callback.c
+++ b/example_callbacks/static_file/static_file_callback.c
@@ -39,18 +39,52 @@ const char * get_filename_ext(const char *path) {
}
/**
+ * Streaming callback function to ease sending large files
+ */
+static ssize_t callback_static_file_stream(void * cls, uint64_t pos, char * buf, size_t max) {
+ if (cls != NULL) {
+ return fread (buf, 1, max, (FILE *)cls);
+ } else {
+ return U_STREAM_END;
+ }
+}
+
+/**
+ * Cleanup FILE* structure when streaming is complete
+ */
+static void callback_static_file_stream_free(void * cls) {
+ if (cls != NULL) {
+ fclose((FILE *)cls);
+ }
+}
+
+/**
* static file callback endpoint
*/
int callback_static_file (const struct _u_request * request, struct _u_response * response, void * user_data) {
- void * buffer = NULL;
- size_t length, res;
+ size_t length;
FILE * f;
- char * file_requested;
- char * file_path;
+ char * file_requested, * file_path, * url_dup_save;
const char * content_type;
- if (user_data != NULL && ((struct static_file_config *)user_data)->files_path != NULL) {
- file_requested = o_strdup((request->http_url + (((struct static_file_config *)user_data)->url_prefix!=NULL?strlen(((struct static_file_config *)user_data)->url_prefix):0)));
+ /*
+ * Comment this if statement if you put static files url not in root, like /app
+ */
+ if (response->shared_data != NULL) {
+ return U_CALLBACK_CONTINUE;
+ }
+
+ if (user_data != NULL && ((struct _static_file_config *)user_data)->files_path != NULL) {
+ file_requested = o_strdup(request->http_url);
+ url_dup_save = file_requested;
+
+ while (file_requested[0] == '/') {
+ file_requested++;
+ }
+ file_requested += o_strlen(((struct _static_file_config *)user_data)->url_prefix);
+ while (file_requested[0] == '/') {
+ file_requested++;
+ }
if (strchr(file_requested, '#') != NULL) {
*strchr(file_requested, '#') = '\0';
@@ -60,12 +94,12 @@ int callback_static_file (const struct _u_request * request, struct _u_response
*strchr(file_requested, '?') = '\0';
}
- if (file_requested == NULL || strlen(file_requested) == 0 || 0 == o_strcmp("/", file_requested)) {
- o_free(file_requested);
- file_requested = o_strdup("index.html");
+ if (file_requested == NULL || o_strlen(file_requested) == 0 || 0 == o_strcmp("/", file_requested)) {
+ o_free(url_dup_save);
+ url_dup_save = file_requested = o_strdup("index.html");
}
- file_path = msprintf("%s/%s", ((struct static_file_config *)user_data)->files_path, file_requested);
+ file_path = msprintf("%s/%s", ((struct _static_file_config *)user_data)->files_path, file_requested);
if (access(file_path, F_OK) != -1) {
f = fopen (file_path, "rb");
@@ -73,34 +107,24 @@ int callback_static_file (const struct _u_request * request, struct _u_response
fseek (f, 0, SEEK_END);
length = ftell (f);
fseek (f, 0, SEEK_SET);
- buffer = o_malloc(length*sizeof(void));
- if (buffer) {
- res = fread (buffer, 1, length, f);
- if (res != length) {
- y_log_message(Y_LOG_LEVEL_WARNING, "callback_angharad_static_file - fread warning, reading %ld while expecting %ld", res, length);
- }
- }
- fclose (f);
- }
-
- if (buffer) {
- content_type = u_map_get_case(&((struct static_file_config *)user_data)->mime_types, get_filename_ext(file_requested));
+
+ content_type = u_map_get_case(((struct _static_file_config *)user_data)->mime_types, get_filename_ext(file_requested));
if (content_type == NULL) {
- content_type = u_map_get(&((struct static_file_config *)user_data)->mime_types, "*");
+ content_type = u_map_get(((struct _static_file_config *)user_data)->mime_types, "*");
y_log_message(Y_LOG_LEVEL_WARNING, "Static File Server - Unknown mime type for extension %s", get_filename_ext(file_requested));
}
- response->binary_body = buffer;
- response->binary_body_length = length;
u_map_put(response->map_header, "Content-Type", content_type);
- } else {
- ulfius_set_string_body_response(response, 500, "Error processing static file");
- y_log_message(Y_LOG_LEVEL_ERROR, "Static File Server - Internal error in %s", request->http_url);
+ u_map_put(response->map_header, "Cache-Control", "public, max-age=31536000");
+
+ if (ulfius_set_stream_response(response, 200, callback_static_file_stream, callback_static_file_stream_free, length, STATIC_FILE_CHUNK, f) != U_OK) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "callback_static_file - Error ulfius_set_stream_response");
+ }
}
} else {
ulfius_set_string_body_response(response, 404, "File not found");
}
o_free(file_path);
- o_free(file_requested);
+ o_free(url_dup_save);
return U_CALLBACK_CONTINUE;
} else {
y_log_message(Y_LOG_LEVEL_ERROR, "Static File Server - Error, user_data is NULL or inconsistent");
diff --git a/example_callbacks/static_file/static_file_callback.h b/example_callbacks/static_file/static_file_callback.h
index c44c453..a57c72c 100644
--- a/example_callbacks/static_file/static_file_callback.h
+++ b/example_callbacks/static_file/static_file_callback.h
@@ -1,4 +1,3 @@
-
/**
* struct static_file_config must be initialized with proper values
* files_path: path (relative or absolute) to the DocumentRoot folder
@@ -52,10 +51,19 @@
* }
*
*/
-struct static_file_config {
- char * files_path;
- char * url_prefix;
- struct _u_map mime_types;
+
+#ifndef _STATIC_FILE
+#define _STATIC_FILE
+
+#define STATIC_FILE_CHUNK 256
+
+struct _static_file_config {
+ char * files_path;
+ char * url_prefix;
+ struct _u_map * mime_types;
};
int callback_static_file (const struct _u_request * request, struct _u_response * response, void * user_data);
+const char * get_filename_ext(const char *path);
+
+#endif
\ No newline at end of file
diff --git a/example_programs/websocket_example/Makefile b/example_programs/websocket_example/Makefile
index d6cd1bb..b0187ce 100644
--- a/example_programs/websocket_example/Makefile
+++ b/example_programs/websocket_example/Makefile
@@ -31,10 +31,10 @@ libulfius.so:
cd $(ULFIUS_LOCATION) && $(MAKE) debug JANSSONFLAG=-DU_DISABLE_JANSSON CURLFLAG=-DU_DISABLE_CURL
static_file_callback.o: $(STATIC_FILE_LOCATION)/static_file_callback.c
- $(CC) $(CFLAGS) $(STATIC_FILE_LOCATION)/static_file_callback.c -DDEBUG -g -O0
+ $(CC) $(CFLAGS) $(STATIC_FILE_LOCATION)/static_file_callback.c
websocket_example.o: websocket_example.c
- $(CC) $(CFLAGS) websocket_example.c -DDEBUG -g -O0
+ $(CC) $(CFLAGS) websocket_example.c
websocket_example: libulfius.so static_file_callback.o websocket_example.o
$(CC) -o websocket_example websocket_example.o static_file_callback.o $(LIBS)
diff --git a/example_programs/websocket_example/websocket_example.c b/example_programs/websocket_example/websocket_example.c
index e87d08e..13da001 100644
--- a/example_programs/websocket_example/websocket_example.c
+++ b/example_programs/websocket_example/websocket_example.c
@@ -93,23 +93,24 @@ char * read_file(const char * filename) {
int main(int argc, char ** argv) {
int ret;
struct _u_instance instance;
- struct static_file_config file_config;
+ struct _static_file_config file_config;
char * cert_file = NULL, * key_file = NULL;
y_init_logs("websocket_example", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting websocket_example");
- u_map_init(&file_config.mime_types);
- u_map_put(&file_config.mime_types, ".html", "text/html");
- u_map_put(&file_config.mime_types, ".css", "text/css");
- u_map_put(&file_config.mime_types, ".js", "application/javascript");
- u_map_put(&file_config.mime_types, ".png", "image/png");
- u_map_put(&file_config.mime_types, ".jpg", "image/jpeg");
- u_map_put(&file_config.mime_types, ".jpeg", "image/jpeg");
- u_map_put(&file_config.mime_types, ".ttf", "font/ttf");
- u_map_put(&file_config.mime_types, ".woff", "font/woff");
- u_map_put(&file_config.mime_types, ".woff2", "font/woff2");
- u_map_put(&file_config.mime_types, ".map", "application/octet-stream");
- u_map_put(&file_config.mime_types, "*", "application/octet-stream");
+ file_config.mime_types = o_malloc(sizeof(struct _u_map));
+ u_map_init(file_config.mime_types);
+ u_map_put(file_config.mime_types, ".html", "text/html");
+ u_map_put(file_config.mime_types, ".css", "text/css");
+ u_map_put(file_config.mime_types, ".js", "application/javascript");
+ u_map_put(file_config.mime_types, ".png", "image/png");
+ u_map_put(file_config.mime_types, ".jpg", "image/jpeg");
+ u_map_put(file_config.mime_types, ".jpeg", "image/jpeg");
+ u_map_put(file_config.mime_types, ".ttf", "font/ttf");
+ u_map_put(file_config.mime_types, ".woff", "font/woff");
+ u_map_put(file_config.mime_types, ".woff2", "font/woff2");
+ u_map_put(file_config.mime_types, ".map", "application/octet-stream");
+ u_map_put(file_config.mime_types, "*", "application/octet-stream");
file_config.files_path = "static";
file_config.url_prefix = PREFIX_STATIC;
@@ -152,7 +153,7 @@ int main(int argc, char ** argv) {
ulfius_stop_framework(&instance);
ulfius_clean_instance(&instance);
- u_map_clean(&file_config.mime_types);
+ u_map_clean_full(file_config.mime_types);
y_close_logs();
return 0;
diff --git a/src/Makefile b/src/Makefile
index c50cfbe..f921c22 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -26,7 +26,7 @@ CC=gcc
CFLAGS=-c -pedantic -std=gnu99 -fPIC -Wall -D_REENTRANT -I$(PREFIX)/include -I$(LIBORCANIA_LOCATION) -I$(LIBYDER_LOCATION) $(ADDITIONALFLAGS) $(JANSSONFLAG) $(CURLFLAG) $(WEBSOCKETFLAG)
LIBS=-L$(PREFIX)/lib -L$(LIBORCANIA_LOCATION) -L$(LIBYDER_LOCATION) -lc -lmicrohttpd -lyder -lorcania -lpthread
OUTPUT=libulfius.so
-VERSION=2.2
+VERSION=2.2.4
ifndef JANSSONFLAG
LJANSSON=-ljansson
diff --git a/src/u_request.c b/src/u_request.c
index dac1fe1..5e9421a 100644
--- a/src/u_request.c
+++ b/src/u_request.c
@@ -402,17 +402,17 @@ struct _u_request * ulfius_duplicate_request(const struct _u_request * request)
#ifndef U_DISABLE_JANSSON
/**
* ulfius_set_json_body_request
- * Add a json_t binary_body to a response
+ * Add a json_t j_body to a response
* return U_OK on success
*/
-int ulfius_set_json_body_request(struct _u_request * request, json_t * body) {
- if (request != NULL && body != NULL) {
+int ulfius_set_json_body_request(struct _u_request * request, json_t * j_body) {
+ if (request != NULL && j_body != NULL && (json_is_array(j_body) || json_is_object(j_body))) {
// Free all the bodies available
o_free(request->binary_body);
request->binary_body = NULL;
request->binary_body_length = 0;
- request->binary_body = (void*) json_dumps(body, JSON_COMPACT);
+ request->binary_body = (void*) json_dumps(j_body, JSON_COMPACT);
if (request->binary_body == NULL) {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for request->binary_body");
return U_ERROR_MEMORY;
@@ -430,10 +430,24 @@ int ulfius_set_json_body_request(struct _u_request * request, json_t * body) {
* Get JSON structure from the request body if the request is valid
* request: struct _u_request used
* json_error: structure to store json_error_t if specified
- */
+ */
json_t * ulfius_get_json_body_request(const struct _u_request * request, json_error_t * json_error) {
if (request != NULL && request->map_header != NULL && NULL != o_strstr(u_map_get_case(request->map_header, ULFIUS_HTTP_HEADER_CONTENT), ULFIUS_HTTP_ENCODING_JSON)) {
return json_loadb(request->binary_body, request->binary_body_length, JSON_DECODE_ANY, json_error);
+ } else if (json_error != NULL) {
+ json_error->line = 1;
+ json_error->position = 1;
+ snprintf(json_error->source, (JSON_ERROR_SOURCE_LENGTH - 1), "ulfius_get_json_body_request");
+ if (NULL == request) {
+ json_error->column = 7;
+ snprintf(json_error->text, (JSON_ERROR_TEXT_LENGTH - 1), "Request not set.");
+ } else if (NULL == request->map_header) {
+ json_error->column = 26;
+ snprintf(json_error->text, (JSON_ERROR_TEXT_LENGTH - 1), "Request header not set.");
+ } else if (NULL == o_strstr(u_map_get_case(request->map_header, ULFIUS_HTTP_HEADER_CONTENT), ULFIUS_HTTP_ENCODING_JSON)) {
+ json_error->column = 57;
+ snprintf(json_error->text, (JSON_ERROR_TEXT_LENGTH - 1), "HEADER content not valid. Expected containging '%s' in header - received '%s'.", ULFIUS_HTTP_ENCODING_JSON, u_map_get_case(request->map_header, ULFIUS_HTTP_HEADER_CONTENT));
+ }
}
return NULL;
}
diff --git a/src/u_response.c b/src/u_response.c
index bc98bb4..0b9e6e9 100644
--- a/src/u_response.c
+++ b/src/u_response.c
@@ -664,17 +664,17 @@ int ulfius_set_stream_response(struct _u_response * response,
#ifndef U_DISABLE_JANSSON
/**
* ulfius_set_json_body_response
- * Add a json_t binary_body to a response
+ * Add a json_t j_body to a response
* return U_OK on success
*/
-int ulfius_set_json_body_response(struct _u_response * response, const unsigned int status, const json_t * binary_body) {
- if (response != NULL && binary_body != NULL) {
+int ulfius_set_json_body_response(struct _u_response * response, const unsigned int status, const json_t * j_body) {
+ if (response != NULL && j_body != NULL && (json_is_array(j_body) || json_is_object(j_body))) {
// Free all the bodies available
o_free(response->binary_body);
response->binary_body = NULL;
response->binary_body_length = 0;
- response->binary_body = (void*) json_dumps(binary_body, JSON_COMPACT);
+ response->binary_body = (void*) json_dumps(j_body, JSON_COMPACT);
if (response->binary_body == NULL) {
y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for response->binary_body");
return U_ERROR_MEMORY;
diff --git a/src/u_websocket.c b/src/u_websocket.c
index 1b0cefd..bda627d 100644
--- a/src/u_websocket.c
+++ b/src/u_websocket.c
@@ -32,7 +32,6 @@
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
-#include <sys/poll.h>
#include <gnutls/gnutls.h>
/**
@@ -112,7 +111,7 @@ void * ulfius_thread_websocket(void * data) {
if (websocket != NULL && websocket->websocket_manager != NULL) {
pthread_mutexattr_init ( &mutexattr );
- pthread_mutexattr_settype( &mutexattr, PTHREAD_MUTEX_RECURSIVE_NP );
+ pthread_mutexattr_settype( &mutexattr, PTHREAD_MUTEX_RECURSIVE );
if (pthread_mutex_init(&(websocket->websocket_manager->read_lock), &mutexattr) != 0 || pthread_mutex_init(&(websocket->websocket_manager->write_lock), &mutexattr) != 0) {
y_log_message(Y_LOG_LEVEL_ERROR, "Impossible to initialize Mutex Lock for websocket");
websocket->websocket_manager->connected = 0;
@@ -344,6 +343,7 @@ int ulfius_clear_websocket(struct _websocket * websocket) {
}
ulfius_instance_remove_websocket_active(websocket->instance, websocket);
ulfius_clear_websocket_manager(websocket->websocket_manager);
+ ulfius_clean_request_full(websocket->request);
o_free(websocket->websocket_manager);
websocket->websocket_manager = NULL;
o_free(websocket);
@@ -735,7 +735,7 @@ int ulfius_instance_remove_websocket_active(struct _u_instance * instance, struc
}
((struct _websocket_handler *)instance->websocket_handler)->nb_websocket_active--;
pthread_mutex_lock(&((struct _websocket_handler *)instance->websocket_handler)->websocket_close_lock);
- pthread_cond_signal(&((struct _websocket_handler *)instance->websocket_handler)->websocket_close_cond);
+ pthread_cond_broadcast(&((struct _websocket_handler *)instance->websocket_handler)->websocket_close_cond);
pthread_mutex_unlock(&((struct _websocket_handler *)instance->websocket_handler)->websocket_close_lock);
return U_OK;
}
diff --git a/src/ulfius.c b/src/ulfius.c
index 37a2cdf..2dc56b9 100644
--- a/src/ulfius.c
+++ b/src/ulfius.c
@@ -431,36 +431,50 @@ static int ulfius_webservice_dispatcher (void * cls, struct MHD_Connection * con
if (ulfius_generate_handshake_answer(u_map_get(con_info->request->map_header, "Sec-WebSocket-Key"), websocket_accept)) {
struct _websocket * websocket = o_malloc(sizeof(struct _websocket));
if (websocket != NULL) {
- websocket->instance = (struct _u_instance *)cls;
- websocket->request = con_info->request;
- websocket->websocket_protocol = ((struct _websocket_handle *)response->websocket_handle)->websocket_protocol;
- websocket->websocket_extensions = ((struct _websocket_handle *)response->websocket_handle)->websocket_extensions;
- websocket->websocket_manager_callback = ((struct _websocket_handle *)response->websocket_handle)->websocket_manager_callback;
- websocket->websocket_manager_user_data = ((struct _websocket_handle *)response->websocket_handle)->websocket_manager_user_data;
- websocket->websocket_incoming_message_callback = ((struct _websocket_handle *)response->websocket_handle)->websocket_incoming_message_callback;
- websocket->websocket_incoming_user_data = ((struct _websocket_handle *)response->websocket_handle)->websocket_incoming_user_data;
- websocket->websocket_onclose_callback = ((struct _websocket_handle *)response->websocket_handle)->websocket_onclose_callback;
- websocket->websocket_onclose_user_data = ((struct _websocket_handle *)response->websocket_handle)->websocket_onclose_user_data;
- websocket->tls = 0;
- mhd_response = MHD_create_response_for_upgrade(ulfius_start_websocket_cb, websocket);
- if (mhd_response == NULL) {
- y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error MHD_create_response_for_upgrade");
- mhd_ret = MHD_NO;
- } else {
- MHD_add_response_header (mhd_response,
- MHD_HTTP_HEADER_UPGRADE,
- U_WEBSOCKET_UPGRADE_VALUE);
- MHD_add_response_header (mhd_response,
- "Sec-WebSocket-Accept",
- websocket_accept);
- if (ulfius_set_response_header(mhd_response, response->map_header) == -1 || ulfius_set_response_cookie(mhd_response, response) == -1) {
- y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting headers or cookies");
- mhd_ret = MHD_NO;
- } else {
- ulfius_instance_add_websocket_active((struct _u_instance *)cls, websocket);
- upgrade_protocol = 1;
- }
- }
+ websocket->request = ulfius_duplicate_request(con_info->request);
+ if (websocket->request != NULL) {
+ websocket->instance = (struct _u_instance *)cls;
+ websocket->websocket_protocol = ((struct _websocket_handle *)response->websocket_handle)->websocket_protocol;
+ websocket->websocket_extensions = ((struct _websocket_handle *)response->websocket_handle)->websocket_extensions;
+ websocket->websocket_manager_callback = ((struct _websocket_handle *)response->websocket_handle)->websocket_manager_callback;
+ websocket->websocket_manager_user_data = ((struct _websocket_handle *)response->websocket_handle)->websocket_manager_user_data;
+ websocket->websocket_incoming_message_callback = ((struct _websocket_handle *)response->websocket_handle)->websocket_incoming_message_callback;
+ websocket->websocket_incoming_user_data = ((struct _websocket_handle *)response->websocket_handle)->websocket_incoming_user_data;
+ websocket->websocket_onclose_callback = ((struct _websocket_handle *)response->websocket_handle)->websocket_onclose_callback;
+ websocket->websocket_onclose_user_data = ((struct _websocket_handle *)response->websocket_handle)->websocket_onclose_user_data;
+ websocket->tls = 0;
+ mhd_response = MHD_create_response_for_upgrade(ulfius_start_websocket_cb, websocket);
+ if (mhd_response == NULL) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error MHD_create_response_for_upgrade");
+ mhd_ret = MHD_NO;
+ } else {
+ MHD_add_response_header (mhd_response,
+ MHD_HTTP_HEADER_UPGRADE,
+ U_WEBSOCKET_UPGRADE_VALUE);
+ MHD_add_response_header (mhd_response,
+ "Sec-WebSocket-Accept",
+ websocket_accept);
+ if (ulfius_set_response_header(mhd_response, response->map_header) == -1 || ulfius_set_response_cookie(mhd_response, response) == -1) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting headers or cookies");
+ mhd_ret = MHD_NO;
+ } else {
+ ulfius_instance_add_websocket_active((struct _u_instance *)cls, websocket);
+ upgrade_protocol = 1;
+ }
+ }
+ } else {
+ o_free(websocket);
+ // Error building struct _websocket, sending error 500
+ response->status = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ response_buffer = o_strdup(ULFIUS_HTTP_ERROR_BODY);
+ if (response_buffer == NULL) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for websocket->request");
+ mhd_ret = MHD_NO;
+ } else {
+ response_buffer_len = strlen(ULFIUS_HTTP_ERROR_BODY);
+ mhd_response = MHD_create_response_from_buffer (response_buffer_len, response_buffer, MHD_RESPMEM_MUST_FREE );
+ }
+ }
} else {
// Error building struct _websocket, sending error 500
response->status = MHD_HTTP_INTERNAL_SERVER_ERROR;
diff --git a/src/ulfius.h b/src/ulfius.h
index 7f32a66..f94ccba 100644
--- a/src/ulfius.h
+++ b/src/ulfius.h
@@ -27,7 +27,7 @@
#define __ULFIUS_H__
/** External dependencies **/
-#include <sys/poll.h>
+#include <poll.h>
#include <pthread.h>
#include <microhttpd.h>
@@ -56,7 +56,7 @@
#define U_ERROR_LIBCURL 5 // Error in libcurl execution
#define U_ERROR_NOT_FOUND 6 // Something was not found
-#define ULFIUS_VERSION 2.2
+#define ULFIUS_VERSION 2.2.4
#define U_CALLBACK_CONTINUE 0
#define U_CALLBACK_COMPLETE 1
@@ -661,17 +661,17 @@ json_t * ulfius_get_json_body_request(const struct _u_request * request, json_er
/**
* ulfius_set_json_body_request
- * Add a json_t body to a request
+ * Add a json_t j_body to a request
* return U_OK on success
*/
-int ulfius_set_json_body_request(struct _u_request * request, json_t * body);
+int ulfius_set_json_body_request(struct _u_request * request, json_t * j_body);
/**
* ulfius_set_json_body_response
- * Add a json_t body to a response
+ * Add a json_t j_body to a response
* return U_OK on success
*/
-int ulfius_set_json_body_response(struct _u_response * response, const unsigned int status, const json_t * body);
+int ulfius_set_json_body_response(struct _u_response * response, const unsigned int status, const json_t * j_body);
/**
* ulfius_get_json_body_response
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-iot/ulfius.git
More information about the Debian-iot-packaging
mailing list