Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ulfius for openSUSE:Factory checked in at 2021-06-09 21:52:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ulfius (Old) and /work/SRC/openSUSE:Factory/.ulfius.new.32437 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ulfius" Wed Jun 9 21:52:01 2021 rev:20 rq:897973 version:2.7.3 Changes: -------- --- /work/SRC/openSUSE:Factory/ulfius/ulfius.changes 2021-03-30 21:18:40.921840789 +0200 +++ /work/SRC/openSUSE:Factory/.ulfius.new.32437/ulfius.changes 2021-06-09 21:52:17.050472826 +0200 @@ -1,0 +2,9 @@ +Sat Jun 5 13:30:48 UTC 2021 - Martin Hauke <[email protected]> + +- Update to version 2.7.3 + * Add ULFIUS_CHECK_VERSION macro. + * Add struct _websocket_manager.keep_messages flag. + * Add struct _u_response.free_shared_data and + ulfius_set_response_shared_data. + +------------------------------------------------------------------- Old: ---- ulfius-2.7.2.tar.gz New: ---- ulfius-2.7.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ulfius.spec ++++++ --- /var/tmp/diff_new_pack.MGB8IV/_old 2021-06-09 21:52:18.334475114 +0200 +++ /var/tmp/diff_new_pack.MGB8IV/_new 2021-06-09 21:52:18.338475121 +0200 @@ -20,7 +20,7 @@ %define _lto_cflags %{nil} %define sover 2_7 Name: ulfius -Version: 2.7.2 +Version: 2.7.3 Release: 0 Summary: Web Framework for REST Applications in C License: MIT @@ -34,7 +34,7 @@ BuildRequires: pkgconfig(jansson) >= 2.1 BuildRequires: pkgconfig(libcurl) BuildRequires: pkgconfig(libmicrohttpd) >= 0.9.51 -BuildRequires: pkgconfig(liborcania) >= 2.1.1 +BuildRequires: pkgconfig(liborcania) >= 2.2.1 BuildRequires: pkgconfig(libyder) >= 1.4.12 BuildRequires: pkgconfig(zlib) ++++++ ulfius-2.7.2.tar.gz -> ulfius-2.7.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/API.md new/ulfius-2.7.3/API.md --- old/ulfius-2.7.2/API.md 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/API.md 2021-05-23 15:15:08.000000000 +0200 @@ -411,7 +411,7 @@ `Warning`: Having 2 callback functions with the same priority number will result in an undefined execution order result. -To help passing parameters between callback functions of the same request, the value `struct _u_response.shared_data` can be used. But it will not be allocated or freed by the framework, the program using this variable must free by itself. +To help passing parameters between callback functions of the same request, the value `struct _u_response.shared_data` can be used. It's recommended to use the function `ulfius_set_response_shared_data` with a pointer to a free function for `shared_data`, therefore the framework will automatically clean `struct _u_response.shared_data` at the end of the callback list. ### Multiple URLs with similar pattern <a name="multiple-urls-with-similar-pattern"></a> @@ -724,6 +724,7 @@ * stream_user_data: user defined data that will be available in your callback stream functions * websocket_handle: handle for websocket extension * shared_data: any data shared between callback functions, must be allocated and freed by the callback functions + * free_shared_data: pointer to a function that will free shared_data * timeout: Timeout in seconds to close the connection because of inactivity between the client and the server * */ @@ -743,6 +744,7 @@ void * stream_user_data; void * websocket_handle; void * shared_data; + void (* free_shared_data)(void * shared_data); unsigned int timeout; }; ``` @@ -1012,7 +1014,7 @@ ### Memory management <a name="memory-management-1"></a> -The Ulfius framework will automatically free the variables referenced by the request and responses structures, except for `struct _u_response.shared_data`, so you must use dynamically allocated values for the response pointers. +The Ulfius framework will automatically free the variables referenced by the request and responses structures, so you must use dynamically allocated values for the response pointers. ### Character encoding <a name="character-encoding"></a> @@ -1245,7 +1247,7 @@ U_WEBSOCKET_OPCODE_PING ``` -If you want to send a message to the client, you must use the dedicated functions `ulfius_websocket_send_message`, `ulfius_websocket_send_fragmented_message` or `ulfius_websocket_send_json_message`: +To send a message to the client, use the dedicated functions `ulfius_websocket_send_message`, `ulfius_websocket_send_fragmented_message` or `ulfius_websocket_send_json_message`: ```C /** @@ -1277,6 +1279,8 @@ To get the first message of the incoming or outcoming if you need to with `ulfius_websocket_pop_first_message`, this will remove the first message of the list, and return it as a pointer. You must free the message using the function `ulfius_clear_websocket_message` after use: +All the sent or received messages are stored by default in the `struct _websocket_manager` attributes `message_list_incoming` and `message_list_outcoming`. To skip storing incoming and/or outcoming messages, you can set the flag `struct _websocket_manager.keep_messages` with the values `U_WEBSOCKET_KEEP_INCOMING`, `U_WEBSOCKET_KEEP_OUTCOMING` or `U_WEBSOCKET_KEEP_NONE`. The flag is set to default with `U_WEBSOCKET_KEEP_INCOMING|U_WEBSOCKET_KEEP_OUTCOMING`. + ```C /** * Return the first message of the message list @@ -2075,7 +2079,11 @@ *Warning:* In this example, the URL parameter `myPotato` will be available only in the `potato_get_callback` function, because the other endpoints did not defined a URL parameter after `/potato`. -If you need to communicate between callback functions for any purpose, you can use the new parameter `struct _u_response.shared_data`. This is a `void *` pointer initialized to `NULL`. If you use it, remember to free it after use, because the framework won't. +If you need to communicate between callback functions for any purpose, you can use the new parameter `struct _u_response.shared_data`. This is a `void *` pointer initialized to `NULL`. + +The dedicated function `ulfius_set_response_shared_data` can be used to set `struct _u_response.shared_data` and `struct _u_response.free_shared_data`. If `struct _u_response.free_shared_data` is set, the function will be used to free `struct _u_response.shared_data` at the end of the callback list. + +Note: If you call `ulfius_set_response_shared_data` multiple times in the same request, before replacing `_u_response.shared_data`, the function `ulfius_set_response_shared_data` will free the previous pointer with the previous `struct _u_response.free_shared_data` if set. ### Keep only binary_body in struct _u_request and struct _u_response <a name="keep-only-binary_body-in-struct-_u_request-and-struct-_u_response"></a> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/CHANGELOG.md new/ulfius-2.7.3/CHANGELOG.md --- old/ulfius-2.7.2/CHANGELOG.md 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/CHANGELOG.md 2021-05-23 15:15:08.000000000 +0200 @@ -1,5 +1,11 @@ # Ulfius Changelog +## 2.7.3 + +- Add `ULFIUS_CHECK_VERSION` macro (Thanks Oliv3) +- Add `struct _websocket_manager.keep_messages` flag +- Add `struct _u_response.free_shared_data` and `ulfius_set_response_shared_data` + ## 2.7.2 - Fix post processor on multiple values with the same key (Thanks Oliv3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/CMakeLists.txt new/ulfius-2.7.3/CMakeLists.txt --- old/ulfius-2.7.2/CMakeLists.txt 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/CMakeLists.txt 2021-05-23 15:15:08.000000000 +0200 @@ -30,7 +30,7 @@ set(PROJECT_BUGREPORT_PATH "https://github.com/babelouest/ulfius/issues") set(LIBRARY_VERSION_MAJOR "2") set(LIBRARY_VERSION_MINOR "7") -set(LIBRARY_VERSION_PATCH "2") +set(LIBRARY_VERSION_PATCH "3") set(PROJECT_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") set(PROJECT_VERSION_MAJOR ${LIBRARY_VERSION_MAJOR}) @@ -56,8 +56,8 @@ set(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") set(LIBRARY_SOVERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}") -set(ORCANIA_VERSION_REQUIRED "2.2.0") -set(YDER_VERSION_REQUIRED "1.4.13") +set(ORCANIA_VERSION_REQUIRED "2.2.1") +set(YDER_VERSION_REQUIRED "1.4.14") set(JANSSON_VERSION_REQUIRED "2.1") # cmake modules diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/cmake-modules/DownloadProject.CMakeLists.cmake.in new/ulfius-2.7.3/cmake-modules/DownloadProject.CMakeLists.cmake.in --- old/ulfius-2.7.2/cmake-modules/DownloadProject.CMakeLists.cmake.in 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/cmake-modules/DownloadProject.CMakeLists.cmake.in 2021-05-23 15:15:08.000000000 +0200 @@ -1,7 +1,7 @@ # Distributed under the OSI-approved MIT License. See accompanying # file LICENSE or https://github.com/Crascit/DownloadProject for details. -cmake_minimum_required(VERSION 2.8.2) +cmake_minimum_required(VERSION 2.8.12) project(${DL_ARGS_PROJ}-download NONE) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/example_programs/websocket_example/websocket_client.c new/ulfius-2.7.3/example_programs/websocket_example/websocket_client.c --- old/ulfius-2.7.2/example_programs/websocket_example/websocket_client.c 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/example_programs/websocket_example/websocket_client.c 2021-05-23 15:15:08.000000000 +0200 @@ -1,11 +1,11 @@ /** - * + * * Ulfius Framework example program - * + * * This example program implements a websocket - * + * * Copyright 2017 Nicolas Mora <[email protected]> - * + * * License MIT * */ @@ -34,39 +34,41 @@ void websocket_manager_callback(const struct _u_request * request, struct _websocket_manager * websocket_manager, void * websocket_manager_user_data) { - + + websocket_manager->keep_messages = U_WEBSOCKET_KEEP_INCOMING; + if (websocket_manager_user_data != NULL) { y_log_message(Y_LOG_LEVEL_DEBUG, "websocket_manager_user_data is %s", websocket_manager_user_data); } - + // Send text message without fragmentation if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { if (ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_TEXT, o_strlen("Message without fragmentation from client"), "Message without fragmentation from client") != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error send message without fragmentation"); } } - + // Send text message with fragmentation if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { if (ulfius_websocket_send_fragmented_message(websocket_manager, U_WEBSOCKET_OPCODE_TEXT, o_strlen("Message with fragmentation from client"), "Message with fragmentation from client", 5) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error send message with fragmentation"); } } - + // Send ping message if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { if (ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_PING, 0, NULL) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error send ping message"); } } - + // Send binary message without fragmentation if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { if (ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_BINARY, o_strlen("Message without fragmentation from client"), "Message without fragmentation from client") != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error send binary message without fragmentation"); } } - + // Send JSON message without fragmentation #ifndef U_DISABLE_JANSSON if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { @@ -115,7 +117,7 @@ struct _websocket_client_handler websocket_client_handler = {NULL, NULL}; char * websocket_user_data = o_strdup("my user data"); char * url = (argc>1&&0==o_strcmp("-https", argv[1]))?"wss://localhost:" PORT PREFIX_WEBSOCKET:"ws://localhost:" PORT PREFIX_WEBSOCKET; - + y_init_logs("websocket_client", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting websocket_client"); ulfius_init_request(&request); ulfius_init_response(&response); @@ -135,7 +137,7 @@ y_log_message(Y_LOG_LEVEL_ERROR, "Error ulfius_set_websocket_request"); o_free(websocket_user_data); } - + ulfius_clean_request(&request); ulfius_clean_response(&response); y_close_logs(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/example_programs/websocket_example/websocket_server.c new/ulfius-2.7.3/example_programs/websocket_example/websocket_server.c --- old/ulfius-2.7.2/example_programs/websocket_example/websocket_server.c 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/example_programs/websocket_example/websocket_server.c 2021-05-23 15:15:08.000000000 +0200 @@ -1,11 +1,11 @@ /** - * + * * Ulfius Framework example program - * + * * This example program implements a websocket - * + * * Copyright 2017 Nicolas Mora <[email protected]> - * + * * License MIT * */ @@ -70,9 +70,9 @@ struct _u_instance instance; struct _u_compressed_inmemory_website_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"); - + if (u_init_compressed_inmemory_website_config(&file_config) == U_OK) { u_map_put(&file_config.mime_types, ".html", "text/html"); u_map_put(&file_config.mime_types, ".css", "text/css"); @@ -88,20 +88,20 @@ u_map_put(&file_config.mime_types, "*", "application/octet-stream"); file_config.files_path = "static"; file_config.url_prefix = PREFIX_STATIC; - + if (ulfius_init_instance(&instance, PORT, NULL, NULL) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error ulfius_init_instance, abort"); return(1); } - + u_map_put(instance.default_headers, "Access-Control-Allow-Origin", "*"); - + // Endpoint list declaration ulfius_add_endpoint_by_val(&instance, "GET", PREFIX_WEBSOCKET, NULL, 0, &callback_websocket, NULL); ulfius_add_endpoint_by_val(&instance, "GET", PREFIX_WEBSOCKET, "/echo", 0, &callback_websocket_echo, NULL); ulfius_add_endpoint_by_val(&instance, "GET", PREFIX_WEBSOCKET, "/file", 0, &callback_websocket_file, NULL); ulfius_add_endpoint_by_val(&instance, "GET", PREFIX_STATIC, "*", 0, &callback_static_compressed_inmemory_website, &file_config); - + // Start the framework if (argc > 3 && 0 == o_strcmp(argv[1], "-https")) { key_file = read_file(argv[2]); @@ -117,24 +117,24 @@ } else { ret = ulfius_start_framework(&instance); } - + if (ret == U_OK) { y_log_message(Y_LOG_LEVEL_INFO, "Start framework on port %d %s", instance.port, (argc > 1 && 0 == o_strcmp(argv[1], "-https"))?"https mode":"http mode"); - + // Wait for the user to press <enter> on the console to quit the application getchar(); } else { y_log_message(Y_LOG_LEVEL_ERROR, "Error starting framework"); } y_log_message(Y_LOG_LEVEL_INFO, "End framework"); - + ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); u_clean_compressed_inmemory_website_config(&file_config); } y_close_logs(); - + return 0; } @@ -168,14 +168,16 @@ if (websocket_manager_user_data != NULL) { y_log_message(Y_LOG_LEVEL_DEBUG, "websocket_manager_user_data is %s", websocket_manager_user_data); } - + + websocket_manager->keep_messages = U_WEBSOCKET_KEEP_OUTCOMING; + // Send text message without fragmentation if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { if (ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_TEXT, o_strlen("Message without fragmentation from server"), "Message without fragmentation from server") != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error send message without fragmentation"); } } - + // Send text message with fragmentation for ulfius clients only, browsers seem to dislike fragmented messages if (o_strncmp(u_map_get(request->map_header, "User-Agent"), U_WEBSOCKET_USER_AGENT, o_strlen(U_WEBSOCKET_USER_AGENT)) == 0 && ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { @@ -183,21 +185,21 @@ y_log_message(Y_LOG_LEVEL_ERROR, "Error send message with fragmentation"); } } - + // Send ping message if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { if (ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_PING, 0, NULL) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error send ping message"); } } - + // Send binary message without fragmentation if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { if (ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_BINARY, o_strlen("Message without fragmentation from server"), "Message without fragmentation from server") != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Error send binary message without fragmentation"); } } - + // Send JSON message without fragmentation #ifndef U_DISABLE_JANSSON if (ulfius_websocket_wait_close(websocket_manager, 2000) == U_WEBSOCKET_STATUS_OPEN) { @@ -270,7 +272,7 @@ int callback_websocket (const struct _u_request * request, struct _u_response * response, void * user_data) { char * websocket_user_data = o_strdup("my_user_data"); int ret; - + if ((ret = ulfius_set_websocket_response(response, NULL, NULL, &websocket_manager_callback, websocket_user_data, &websocket_incoming_message_callback, websocket_user_data, &websocket_onclose_callback, websocket_user_data)) == U_OK) { ulfius_add_websocket_deflate_extension(response); return U_CALLBACK_CONTINUE; @@ -282,7 +284,7 @@ int callback_websocket_echo (const struct _u_request * request, struct _u_response * response, void * user_data) { char * websocket_user_data = o_strdup("my_user_data"); int ret; - + y_log_message(Y_LOG_LEVEL_DEBUG, "Client connected to echo websocket"); if ((ret = ulfius_set_websocket_response(response, NULL, NULL, NULL, NULL, &websocket_echo_message_callback, websocket_user_data, &websocket_onclose_callback, websocket_user_data)) == U_OK) { ulfius_add_websocket_deflate_extension(response); @@ -294,7 +296,7 @@ int callback_websocket_file (const struct _u_request * request, struct _u_response * response, void * user_data) { int ret; - + if ((ret = ulfius_set_websocket_response(response, NULL, NULL, &websocket_manager_file_callback, NULL, &websocket_incoming_file_callback, NULL, &websocket_onclose_file_callback, NULL)) == U_OK) { ulfius_add_websocket_deflate_extension(response); return U_CALLBACK_CONTINUE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/include/ulfius-cfg.h.in new/ulfius-2.7.3/include/ulfius-cfg.h.in --- old/ulfius-2.7.2/include/ulfius-cfg.h.in 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/include/ulfius-cfg.h.in 2021-05-23 15:15:08.000000000 +0200 @@ -34,6 +34,12 @@ #define ULFIUS_VERSION_NUMBER ((ULFIUS_VERSION_MAJOR << 16) | (ULFIUS_VERSION_MINOR << 8) | (ULFIUS_VERSION_PATCH << 0)) +#define ULFIUS_CHECK_VERSION(major,minor,patch) \ + (ULFIUS_VERSION_MAJOR > (major) || \ + (ULFIUS_VERSION_MAJOR == (major) && ULFIUS_VERSION_MINOR > (minor)) || \ + (ULFIUS_VERSION_MAJOR == (major) && ULFIUS_VERSION_MINOR == (minor) && \ + ULFIUS_VERSION_PATCH >= (patch))) + #cmakedefine U_DISABLE_JANSSON #cmakedefine U_DISABLE_CURL #cmakedefine U_DISABLE_GNUTLS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/include/ulfius.h new/ulfius-2.7.3/include/ulfius.h --- old/ulfius-2.7.2/include/ulfius.h 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/include/ulfius.h 2021-05-23 15:15:08.000000000 +0200 @@ -280,6 +280,7 @@ void * stream_user_data; /* !< user defined data that will be available in your callback stream functions */ void * websocket_handle; /* !< handle for websocket extension */ void * shared_data; /* !< any data shared between callback functions, must be allocated and freed by the callback functions */ + void (* free_shared_data)(void * shared_data); /* !< pointer to a function that will free shared_data */ unsigned int timeout; /* !< Timeout in seconds to close the connection because of inactivity between the client and the server */ }; @@ -991,7 +992,6 @@ int ulfius_set_request_properties(struct _u_request * request, ...); /** - * ulfius_init_response * Initialize a response structure by allocating inner elements * @param response the response to initialize * @return U_OK on success @@ -1009,7 +1009,6 @@ int ulfius_clean_response(struct _u_response * response); /** - * ulfius_clean_response_full * clean the specified response and all its elements * @param response the response to cleanup * @return U_OK on success @@ -1017,7 +1016,6 @@ int ulfius_clean_response_full(struct _u_response * response); /** - * ulfius_copy_response * Copy the source response elements into the dest response * @param dest the response to receive the copied data * @param source the source response to copy @@ -1058,13 +1056,23 @@ struct _u_response * ulfius_duplicate_response(const struct _u_response * response); /** - * ulfius_set_response_properties * Set a list of properties to a response - * return U_OK on success + * @param response the response to set values to + * @return U_OK on success */ int ulfius_set_response_properties(struct _u_response * response, ...); /** + * Adds a shared_data pointer to the response + * and the function to free the shared_data at the end of the callback list + * @param response the response to set values to + * @param shared_data a pointer that will be transmitted to every callback + * @param free_shared_data a pointer to a function that will free shared_data at the end of the callback list + * @return U_OK on success + */ +int ulfius_set_response_shared_data(struct _u_response * response, void * shared_data, void (* free_shared_data) (void * shared_data)); + +/** * @} */ @@ -1461,6 +1469,10 @@ #define WEBSOCKET_DEFLATE_CHUNK_SIZE 32768 #define WEBSOCKET_DEFLATE_WINDOWS_BITS 15 +#define U_WEBSOCKET_KEEP_NONE 0x00 +#define U_WEBSOCKET_KEEP_INCOMING 0x01 +#define U_WEBSOCKET_KEEP_OUTCOMING 0x10 + /** * @struct _websocket_deflate_context websocket extension permessage-deflate context */ @@ -1527,6 +1539,7 @@ struct _websocket_manager { struct _websocket_message_list * message_list_incoming; /* !< list of incoming messages */ struct _websocket_message_list * message_list_outcoming; /* !< list of outcoming messages */ + int keep_messages; /* !< keep incoming and/or outcoming messages, flags available are U_WEBSOCKET_KEEP_INCOMING, U_WEBSOCKET_KEEP_OUTCOMING, U_WEBSOCKET_KEEP_NONE, default is U_WEBSOCKET_KEEP_INCOMING|U_WEBSOCKET_KEEP_OUTCOMING */ int connected; /* !< flag to know if the websocket is connected or not */ int ping_sent; /* !< flag to know if the websocket has sent a ping frame or not, before receiving a pong */ int close_flag; /* !< flag to set before closing a websocket */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/libulfius.pc.in new/ulfius-2.7.3/libulfius.pc.in --- old/ulfius-2.7.2/libulfius.pc.in 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/libulfius.pc.in 2021-05-23 15:15:08.000000000 +0200 @@ -9,5 +9,5 @@ Version: @LIBRARY_VERSION@ Requires: @PKGCONF_REQ@ Requires.private: @PKGCONF_REQ_PRIVATE@ -Libs: -L${libdir} -lulfius -lorcania -lyder +Libs: -L${libdir} -lulfius -lorcania -lyder @LIB_STATIC@ Cflags: -I${includedir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/src/Makefile new/ulfius-2.7.3/src/Makefile --- old/ulfius-2.7.2/src/Makefile 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/src/Makefile 2021-05-23 15:15:08.000000000 +0200 @@ -31,7 +31,9 @@ DESTDIR=/usr/local CC=gcc CFLAGS+=-c -pedantic -std=gnu99 -fPIC -Wall -Werror -Wextra -D_REENTRANT -I$(ULFIUS_INCLUDE) $(ADDITIONALFLAGS) $(CPPFLAGS) -LIBS=-L$(DESTDIR)/lib -lc -lmicrohttpd -lorcania -lpthread -lz $(LDFLAGS) +LIBSDEP=-lmicrohttpd -lpthread -lz +LIBS=-L$(DESTDIR)/lib -lc $(LDFLAGS) +LIB_STATIC= SONAME = -soname ifeq ($(shell uname -s),Darwin) SONAME = -install_name @@ -40,7 +42,7 @@ OUTPUT=libulfius.so VERSION_MAJOR=2 VERSION_MINOR=7 -VERSION_PATCH=2 +VERSION_PATCH=3 ifndef JANSSONFLAG DISABLE_JANSSON=0 @@ -170,17 +172,18 @@ @sed -i -e 's/@LIBRARY_VERSION@/$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)/g' $(PKGCONFIG_FILE) @sed -i -e 's/@PKGCONF_REQ@/$(PKGCONF_REQ)/g' $(PKGCONFIG_FILE) @sed -i -e 's/@PKGCONF_REQ_PRIVATE@/$(PKGCONF_REQ_PRIVATE)/g' $(PKGCONFIG_FILE) + @sed -i -e 's/@LIB_STATIC@/$(LIB_STATIC)/g' $(PKGCONFIG_FILE) target: $(OBJECTS) %.o: %.c $(CONFIG_FILE) $(ULFIUS_INCLUDE)/ulfius.h $(ULFIUS_INCLUDE)/u_private.h $(ULFIUS_INCLUDE)/yuarel.h $(CC) $(CFLAGS) $< -libulfius.so: $(OBJECTS) - $(CC) -shared -fPIC -Wl,$(SONAME),$(OUTPUT) -o $(OUTPUT).$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) $(OBJECTS) $(LIBS) $(LYDER) $(LJANSSON) $(LCURL) $(LGNUTLS) +libulfius.so: $(OBJECTS) $(PKGCONFIG_FILE) + $(CC) -shared -fPIC -Wl,$(SONAME),$(OUTPUT) -o $(OUTPUT).$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) $(OBJECTS) $(LIBS) $(LIBSDEP) $(LYDER) $(LJANSSON) $(LCURL) $(LGNUTLS) ln -sf $(OUTPUT).$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) $(OUTPUT) -libulfius.a: $(OBJECTS) +libulfius.a: $(OBJECTS) $(PKGCONFIG_FILE) ar rcs libulfius.a $(OBJECTS) clean: @@ -218,6 +221,8 @@ static: ADDITIONALFLAGS=-O3 +static: LIB_STATIC=$(LIBSDEP) $(LYDER) $(LJANSSON) $(LCURL) $(LGNUTLS) + static: libulfius.a static-debug: ADDITIONALFLAGS=-DDEBUG -g -O0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/src/u_response.c new/ulfius-2.7.3/src/u_response.c --- old/ulfius-2.7.2/src/u_response.c 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/src/u_response.c 2021-05-23 15:15:08.000000000 +0200 @@ -388,6 +388,7 @@ response->stream_user_data = NULL; response->timeout = 0; response->shared_data = NULL; + response->free_shared_data = NULL; #ifndef U_DISABLE_WEBSOCKET response->websocket_handle = o_malloc(sizeof(struct _websocket_handle)); if (response->websocket_handle == NULL) { @@ -653,6 +654,19 @@ return ret; } +int ulfius_set_response_shared_data(struct _u_response * response, void * shared_data, void (* free_shared_data) (void * shared_data)) { + if (response != NULL && shared_data != NULL) { + if (response->free_shared_data != NULL && response->shared_data != NULL) { + response->free_shared_data(response->shared_data); + } + response->shared_data = shared_data; + response->free_shared_data = free_shared_data; + return U_OK; + } else { + return U_ERROR_PARAMS; + } +} + #ifndef U_DISABLE_JANSSON /** * ulfius_set_json_body_response @@ -697,7 +711,6 @@ int ulfius_add_header_to_response(struct _u_response * response, const char * key, const char * value) { if (response != NULL && key != NULL && value != NULL) { return u_map_put(response->map_header, key, value); - return U_OK; } else { return U_ERROR_PARAMS; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/src/u_websocket.c new/ulfius-2.7.3/src/u_websocket.c --- old/ulfius-2.7.2/src/u_websocket.c 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/src/u_websocket.c 2021-05-23 15:15:08.000000000 +0200 @@ -339,7 +339,7 @@ } else { message = ulfius_build_message(opcode, rsv, (websocket_manager->type == U_WEBSOCKET_CLIENT), data, data_len); if (message != NULL) { - if (ulfius_push_websocket_message(websocket_manager->message_list_outcoming, message) != U_OK) { + if ((websocket_manager->keep_messages&U_WEBSOCKET_KEEP_OUTCOMING) && ulfius_push_websocket_message(websocket_manager->message_list_outcoming, message) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error pushing new websocket message in list"); } if (data_len) { @@ -367,6 +367,10 @@ } o_free(frame); } + if (!(websocket_manager->keep_messages&U_WEBSOCKET_KEEP_OUTCOMING)) { + ulfius_clear_websocket_message(message); + message = NULL; + } } else { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error ulfius_build_message"); ret = U_ERROR; @@ -538,6 +542,7 @@ } if (ret != U_OK) { ulfius_clear_websocket_message(*message); + *message = NULL; } return ret; } @@ -702,10 +707,15 @@ if (websocket->websocket_incoming_message_callback != NULL) { websocket->websocket_incoming_message_callback(websocket->request, websocket->websocket_manager, message, websocket->websocket_incoming_user_data); } - if (ulfius_push_websocket_message(websocket->websocket_manager->message_list_incoming, message) != U_OK) { - y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error pushing new websocket message in list"); - websocket->websocket_manager->connected = 0; + if (websocket->websocket_manager->keep_messages&U_WEBSOCKET_KEEP_INCOMING) { + if (ulfius_push_websocket_message(websocket->websocket_manager->message_list_incoming, message) != U_OK) { + y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error pushing new websocket message in list"); + websocket->websocket_manager->connected = 0; + } else { + message = NULL; + } } else { + ulfius_clear_websocket_message(message); message = NULL; } } else { @@ -1455,12 +1465,16 @@ if (message->opcode == U_WEBSOCKET_OPCODE_CLOSE) { websocket_manager->connected = 0; } - if (ulfius_push_websocket_message(websocket_manager->message_list_incoming, message) != U_OK) { + if ((websocket_manager->keep_messages&U_WEBSOCKET_KEEP_INCOMING) && ulfius_push_websocket_message(websocket_manager->message_list_incoming, message) != U_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error pushing new websocket message in list"); } } else { websocket_manager->connected = 0; } + if (!(websocket_manager->keep_messages&U_WEBSOCKET_KEEP_INCOMING)) { + ulfius_clear_websocket_message(message); + message = NULL; + } } } while (websocket_manager->connected && (count-- > 0)); } else { @@ -1571,6 +1585,7 @@ void ulfius_clear_websocket_message(struct _websocket_message * message) { if (message != NULL) { o_free(message->data); + message->data = NULL; o_free(message); } } @@ -1613,8 +1628,10 @@ if (message_list != NULL) { for (i=0; i < message_list->len; i++) { ulfius_clear_websocket_message(message_list->list[i]); + message_list->list[i] = NULL; } o_free(message_list->list); + message_list->list = NULL; } } @@ -1669,6 +1686,7 @@ websocket_manager->protocol = NULL; websocket_manager->extensions = NULL; websocket_manager->rsv_expected = 0; + websocket_manager->keep_messages = U_WEBSOCKET_KEEP_INCOMING|U_WEBSOCKET_KEEP_OUTCOMING; pthread_mutexattr_init ( &mutexattr ); pthread_mutexattr_settype( &mutexattr, PTHREAD_MUTEX_RECURSIVE ); if (pthread_mutex_init(&(websocket_manager->read_lock), &mutexattr) != 0 || pthread_mutex_init(&(websocket_manager->write_lock), &mutexattr) != 0) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/src/ulfius.c new/ulfius-2.7.3/src/ulfius.c --- old/ulfius-2.7.2/src/ulfius.c 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/src/ulfius.c 2021-05-23 15:15:08.000000000 +0200 @@ -780,9 +780,9 @@ o_strcasestr(u_map_get_case(con_info->request->map_header, "upgrade"), U_WEBSOCKET_UPGRADE_VALUE)==NULL?"No Upgrade websocket header\n":"", o_strcasestr(u_map_get_case(con_info->request->map_header, "Connection"), "Upgrade")==NULL?"No Connection Upgrade header\n":"", u_map_get_case(con_info->request->map_header, "Sec-WebSocket-Key")==NULL?"No Sec-WebSocket-Key header\n":"", - o_strcmp(con_info->request->http_protocol, "HTTP/1.1")!=0?"Wrong HTTP Protocol":"", + o_strcmp(con_info->request->http_protocol, "HTTP/1.1")!=0?"Wrong HTTP Protocol\n":"", o_strcmp(u_map_get_case(con_info->request->map_header, "Sec-WebSocket-Version"), "13")!=0?"Wrong websocket version\n":"", - o_strcmp(con_info->request->http_verb, "GET")!=0?"Method is not GET":""); + o_strcmp(con_info->request->http_verb, "GET")!=0?"Method is not GET\n":""); response->status = MHD_HTTP_BAD_REQUEST; y_log_message(Y_LOG_LEVEL_DEBUG, "Ulfius - Error websocket connection: %s", response_buffer); mhd_response = MHD_CREATE_RESPONSE_FROM_BUFFER_PIMPED (o_strlen(response_buffer), response_buffer, mhd_response_flag ); @@ -999,6 +999,9 @@ } MHD_destroy_response (mhd_response); // Free Response parameters + if (response->free_shared_data != NULL && response->shared_data != NULL) { + response->free_shared_data(response->shared_data); + } ulfius_clean_response_full(response); response = NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/test/framework.c new/ulfius-2.7.3/test/framework.c --- old/ulfius-2.7.2/test/framework.c 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/test/framework.c 2021-05-23 15:15:08.000000000 +0200 @@ -38,6 +38,16 @@ #define BODY_NOT_REDIRECTED "This is the blue pill" #define BODY_REDIRECTED "Welcome to the Matrix, Neo!" +#define PORT_PLAIN 2525 +#define PORT_RICH 2526 +#define FROM "from" +#define TO "to" +#define CC "cc" +#define BCC "bcc" +#define CONTENT_TYPE "text/ulfius; charset=utf-42" +#define SUBJECT "subject" +#define BODY "mail body" + struct smtp_manager { char * mail_data; unsigned int port; @@ -483,6 +493,34 @@ return U_CALLBACK_CONTINUE; } +int shared_data_counter = 0; + +static void free_with_counter(void * ptr) { + shared_data_counter++; + o_free(ptr); +} + +static void free_json_with_counter(json_t * ptr) { + shared_data_counter++; + json_decref(ptr); +} + +int callback_function_shared_data_1(const struct _u_request * request, struct _u_response * response, void * user_data) { + ck_assert_int_eq(ulfius_set_response_shared_data(response, o_strdup("grut"), &free_with_counter), U_OK); + ck_assert_ptr_eq(response->free_shared_data, &free_with_counter); + ck_assert_int_eq(0, o_strncmp((const char *)response->shared_data, "grut", o_strlen("grut"))); + return U_CALLBACK_CONTINUE; +} + +int callback_function_shared_data_2(const struct _u_request * request, struct _u_response * response, void * user_data) { + ck_assert_ptr_eq(response->free_shared_data, &free_with_counter); + ck_assert_int_eq(0, o_strncmp((const char *)response->shared_data, "grut", o_strlen("grut"))); + ck_assert_int_eq(ulfius_set_response_shared_data(response, json_string("grut"), (void (*)(void *))&free_json_with_counter), U_OK); + ck_assert_ptr_eq(response->free_shared_data, &free_json_with_counter); + ck_assert_int_eq(0, o_strncmp(json_string_value((json_t *)response->shared_data), "grut", o_strlen("grut"))); + return U_CALLBACK_CONTINUE; +} + int via_free_with_test = 0; void free_with_test(void * ptr) { @@ -1204,16 +1242,6 @@ } END_TEST -#define PORT_PLAIN 2525 -#define PORT_RICH 2526 -#define FROM "from" -#define TO "to" -#define CC "cc" -#define BCC "bcc" -#define CONTENT_TYPE "text/ulfius; charset=utf-42" -#define SUBJECT "subject" -#define BODY "mail body" - START_TEST(test_ulfius_send_smtp) { pthread_t thread; @@ -1302,6 +1330,27 @@ } END_TEST +START_TEST(test_ulfius_shared_data) +{ + struct _u_instance u_instance; + struct _u_request request; + + ck_assert_int_eq(ulfius_init_instance(&u_instance, 8080, NULL, NULL), U_OK); + ck_assert_int_eq(ulfius_add_endpoint_by_val(&u_instance, "GET", NULL, "*", 0, &callback_function_shared_data_1, NULL), U_OK); + ck_assert_int_eq(ulfius_add_endpoint_by_val(&u_instance, "GET", NULL, "*", 0, &callback_function_shared_data_2, NULL), U_OK); + ck_assert_int_eq(ulfius_start_framework(&u_instance), U_OK); + + ulfius_init_request(&request); + ck_assert_int_eq(ulfius_set_request_properties(&request, U_OPT_HTTP_URL, "http://localhost:8080/", U_OPT_NONE), U_OK); + ck_assert_int_eq(ulfius_send_http_request(&request, NULL), U_OK); + ck_assert_int_eq(2, shared_data_counter); + + ulfius_clean_request(&request); + ulfius_stop_framework(&u_instance); + ulfius_clean_instance(&u_instance); +} +END_TEST + #ifndef U_DISABLE_GNUTLS START_TEST(test_ulfius_server_ca_trust) { @@ -1427,6 +1476,7 @@ tcase_add_test(tc_core, test_ulfius_send_smtp); tcase_add_test(tc_core, test_ulfius_send_rich_smtp); tcase_add_test(tc_core, test_ulfius_follow_redirect); + tcase_add_test(tc_core, test_ulfius_shared_data); #ifndef U_DISABLE_GNUTLS tcase_add_test(tc_core, test_ulfius_server_ca_trust); tcase_add_test(tc_core, test_ulfius_client_certificate); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ulfius-2.7.2/test/websocket.c new/ulfius-2.7.3/test/websocket.c --- old/ulfius-2.7.2/test/websocket.c 2021-03-02 01:02:22.000000000 +0100 +++ new/ulfius-2.7.3/test/websocket.c 2021-05-23 15:15:08.000000000 +0200 @@ -24,13 +24,14 @@ #define PORT_6 9280 #define PORT_7 9281 #define PORT_8 9282 +#define PORT_9 9283 #define PREFIX_WEBSOCKET "/websocket" #define MESSAGE "HelloFrom" #define MESSAGE_CLIENT "HelloFromClient" #define MESSAGE_SERVER "HelloFromServer" #define MESSAGE_EXT1 "Grut" #define MESSAGE_EXT2 "Plop" -#define MESSAGE_EXT3 "Gna" +#define MESSAGE_EXT3 "Gnaa" #define MESSAGE_EXT4 "Glop" #define _U_W_BUFF_LEN 256 @@ -38,6 +39,7 @@ #define U_W_FLAG_CONTEXT 0x00000010 #ifndef U_DISABLE_WEBSOCKET + void websocket_manager_callback_empty (const struct _u_request * request, struct _websocket_manager * websocket_manager, void * websocket_manager_user_data) { } @@ -165,6 +167,43 @@ ck_assert_int_eq(last_message->rsv&U_WEBSOCKET_RSV1, 0); } +void websocket_manager_callback_keep_messages (const struct _u_request * request, struct _websocket_manager * websocket_manager, void * websocket_manager_user_data) { + if (websocket_manager_user_data != NULL) { + websocket_manager->keep_messages = *((int*)(websocket_manager_user_data)); + } + ck_assert_int_eq(ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_TEXT, o_strlen(MESSAGE_EXT1), MESSAGE_EXT1), U_OK); + + while (ulfius_websocket_wait_close(websocket_manager, 50) == U_WEBSOCKET_STATUS_OPEN); +} + +void websocket_incoming_keep_messages (const struct _u_request * request, + struct _websocket_manager * websocket_manager, + const struct _websocket_message * last_message, + void * user_data) { + if (0 == o_strncmp(MESSAGE_EXT1, last_message->data, last_message->data_len)) { + ck_assert_int_eq(ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_TEXT, o_strlen(MESSAGE_EXT2), MESSAGE_EXT2), U_OK); + } else if (0 == o_strncmp(MESSAGE_EXT2, last_message->data, last_message->data_len)) { + ck_assert_int_eq(ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_TEXT, o_strlen(MESSAGE_EXT3), MESSAGE_EXT3), U_OK); + } else if (0 == o_strncmp(MESSAGE_EXT3, last_message->data, last_message->data_len)) { + ck_assert_int_eq(ulfius_websocket_send_message(websocket_manager, U_WEBSOCKET_OPCODE_TEXT, o_strlen(MESSAGE_EXT4), MESSAGE_EXT4), U_OK); + } else if (0 == o_strncmp(MESSAGE_EXT4, last_message->data, last_message->data_len)) { + ck_assert_int_eq(ulfius_websocket_send_close_signal(websocket_manager), U_OK); + } +} + +void websocket_onclose_callback_keep_messages (const struct _u_request * request, struct _websocket_manager * websocket_manager, void * websocket_onclose_user_data) { + if (websocket_manager->keep_messages & U_WEBSOCKET_KEEP_INCOMING) { + ck_assert_int_gt(websocket_manager->message_list_incoming->len, 0); + } else { + ck_assert_int_eq(websocket_manager->message_list_incoming->len, 0); + } + if (websocket_manager->keep_messages & U_WEBSOCKET_KEEP_OUTCOMING) { + ck_assert_int_gt(websocket_manager->message_list_outcoming->len, 0); + } else { + ck_assert_int_eq(websocket_manager->message_list_outcoming->len, 0); + } +} + int websocket_extension1_message_out_perform(const uint8_t opcode, const uint64_t data_len_in, const char * data_in, uint64_t * data_len_out, char ** data_out, const uint64_t fragment_len, void * user_data, void * context) { ck_assert_int_eq(opcode, U_WEBSOCKET_OPCODE_TEXT); if (((uintptr_t)user_data)&U_W_FLAG_CONTEXT) { @@ -257,6 +296,14 @@ return (ret == U_OK)?U_CALLBACK_CONTINUE:U_CALLBACK_ERROR; } +int callback_websocket_keep_messages (const struct _u_request * request, struct _u_response * response, void * user_data) { + int ret; + + ret = ulfius_set_websocket_response(response, NULL, NULL, &websocket_manager_callback_keep_messages, user_data, websocket_incoming_keep_messages, NULL, &websocket_onclose_callback_keep_messages, user_data); + ck_assert_int_eq(ret, U_OK); + return (ret == U_OK)?U_CALLBACK_CONTINUE:U_CALLBACK_ERROR; +} + int callback_websocket_onclose (const struct _u_request * request, struct _u_response * response, void * user_data) { int ret; @@ -816,6 +863,67 @@ } END_TEST +START_TEST(test_ulfius_websocket_keep_messages) +{ + struct _u_instance instance; + struct _u_request request; + struct _u_response response; + struct _websocket_client_handler websocket_client_handler = {NULL, NULL}; + char url[64]; + int keep_messages = 0; + + ck_assert_int_eq(ulfius_init_instance(&instance, PORT_9, NULL, NULL), U_OK); + ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", PREFIX_WEBSOCKET, NULL, 0, &callback_websocket_keep_messages, &keep_messages), U_OK); + ck_assert_int_eq(ulfius_start_framework(&instance), U_OK); + sprintf(url, "ws://localhost:%d/%s", PORT_9, PREFIX_WEBSOCKET); + + keep_messages = U_WEBSOCKET_KEEP_NONE; + ulfius_init_request(&request); + ulfius_init_response(&response); + // Test correct websocket connection on correct websocket service + ck_assert_int_eq(ulfius_set_websocket_request(&request, url, NULL, NULL), U_OK); + ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, NULL, NULL, websocket_incoming_keep_messages, NULL, NULL, NULL, &websocket_client_handler, &response), U_OK); + ck_assert_int_eq(ulfius_websocket_client_connection_wait_close(&websocket_client_handler, 0), U_WEBSOCKET_STATUS_CLOSE); + ulfius_clean_request(&request); + ulfius_clean_response(&response); + + keep_messages = U_WEBSOCKET_KEEP_INCOMING|U_WEBSOCKET_KEEP_OUTCOMING; + ulfius_init_request(&request); + ulfius_init_response(&response); + // Test correct websocket connection on correct websocket service + ck_assert_int_eq(ulfius_set_websocket_request(&request, url, NULL, NULL), U_OK); + ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, NULL, NULL, websocket_incoming_keep_messages, NULL, NULL, NULL, &websocket_client_handler, &response), U_OK); + ck_assert_int_eq(ulfius_websocket_client_connection_wait_close(&websocket_client_handler, 0), U_WEBSOCKET_STATUS_CLOSE); + ulfius_clean_request(&request); + ulfius_clean_response(&response); + + keep_messages = U_WEBSOCKET_KEEP_INCOMING; + ulfius_init_request(&request); + ulfius_init_response(&response); + // Test correct websocket connection on correct websocket service + ck_assert_int_eq(ulfius_set_websocket_request(&request, url, NULL, NULL), U_OK); + ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, NULL, NULL, websocket_incoming_keep_messages, NULL, NULL, NULL, &websocket_client_handler, &response), U_OK); + ck_assert_int_eq(ulfius_websocket_client_connection_wait_close(&websocket_client_handler, 0), U_WEBSOCKET_STATUS_CLOSE); + ulfius_clean_request(&request); + ulfius_clean_response(&response); + + keep_messages = U_WEBSOCKET_KEEP_OUTCOMING; + ulfius_init_request(&request); + ulfius_init_response(&response); + // Test correct websocket connection on correct websocket service + ck_assert_int_eq(ulfius_set_websocket_request(&request, url, NULL, NULL), U_OK); + ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, NULL, NULL, websocket_incoming_keep_messages, NULL, NULL, NULL, &websocket_client_handler, &response), U_OK); + ck_assert_int_eq(ulfius_websocket_client_connection_wait_close(&websocket_client_handler, 0), U_WEBSOCKET_STATUS_CLOSE); + ulfius_clean_request(&request); + ulfius_clean_response(&response); + + usleep(50); + ck_assert_int_eq(ulfius_stop_framework(&instance), U_OK); + + ulfius_clean_instance(&instance); +} +END_TEST + #endif static Suite *ulfius_suite(void) @@ -836,6 +944,7 @@ tcase_add_test(tc_websocket, test_ulfius_websocket_extension_deflate); tcase_add_test(tc_websocket, test_ulfius_websocket_extension_deflate_with_all_params); tcase_add_test(tc_websocket, test_ulfius_websocket_extension_deflate_error_params); + tcase_add_test(tc_websocket, test_ulfius_websocket_keep_messages); #endif tcase_set_timeout(tc_websocket, 30); suite_add_tcase(s, tc_websocket);
