Hello community,

here is the log from the commit of package ulfius for openSUSE:Factory checked 
in at 2019-07-24 20:33:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ulfius (Old)
 and      /work/SRC/openSUSE:Factory/.ulfius.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ulfius"

Wed Jul 24 20:33:50 2019 rev:6 rq:717781 version:2.6.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/ulfius/ulfius.changes    2019-07-08 
15:11:42.843384755 +0200
+++ /work/SRC/openSUSE:Factory/.ulfius.new.4126/ulfius.changes  2019-07-24 
20:33:52.562585008 +0200
@@ -1,0 +2,12 @@
+Fri Jul 19 06:59:59 UTC 2019 - Martin Hauke <[email protected]>
+
+- Update to version 2.6.2
+  * Fix memory leak in `ulfius_set_string_body_request` and
+    `ulfius_set_string_body_response`
+  * Call callback function websocket_onclose_callback on all times,
+    even if the websocket hasn't properly worked, so the calling
+    program can avoid memory leak and broken resources, fix #126
+- Add patch (fixes a compilation error on Tumbleweed):
+  * 0001-Cast-option-value-for-curl_easy_setopt-on-CURLOPT_PO.patch
+
+-------------------------------------------------------------------

Old:
----
  ulfius-2.6.1.tar.gz

New:
----
  0001-Cast-option-value-for-curl_easy_setopt-on-CURLOPT_PO.patch
  ulfius-2.6.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ulfius.spec ++++++
--- /var/tmp/diff_new_pack.0KpLTl/_old  2019-07-24 20:33:53.086584950 +0200
+++ /var/tmp/diff_new_pack.0KpLTl/_new  2019-07-24 20:33:53.090584949 +0200
@@ -19,13 +19,14 @@
 
 %define sover 2_6
 Name:           ulfius
-Version:        2.6.1
+Version:        2.6.2
 Release:        0
 Summary:        Web Framework for REST Applications in C
 License:        MIT
 Group:          Development/Languages/C and C++
 URL:            https://github.com/babelouest/ulfius
 Source:         
https://github.com/babelouest/ulfius/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
+Patch0:         0001-Cast-option-value-for-curl_easy_setopt-on-CURLOPT_PO.patch
 BuildRequires:  cmake
 BuildRequires:  gcc-c++
 BuildRequires:  pkgconfig
@@ -69,6 +70,7 @@
 
 %prep
 %setup -q
+%patch0 -p1
 
 %build
 %cmake \

++++++ 0001-Cast-option-value-for-curl_easy_setopt-on-CURLOPT_PO.patch ++++++
>From c0d9933e28c2dea4b8589739fe6dfe5ecfe59310 Mon Sep 17 00:00:00 2001
From: Nicolas Mora <[email protected]>
Date: Thu, 18 Jul 2019 19:31:56 -0400
Subject: [PATCH] Cast option value for curl_easy_setopt on
 CURLOPT_POSTFIELDSIZE and CURLOPT_POSTFIELDSIZE_LARGE options to curl_off_t,
 to help gcc 9.1 to be less annoyed by incompatible types (but in fact they
 probably are compatible), closes #128

---
 src/u_send_request.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/u_send_request.c b/src/u_send_request.c
index 0a8010d..0370c6f 100644
--- a/src/u_send_request.c
+++ b/src/u_send_request.c
@@ -370,13 +370,13 @@ int ulfius_send_http_streaming_request(const struct 
_u_request * request,
             // Set body content
             if (copy_request->binary_body_length && copy_request->binary_body 
!= NULL) {
               if (copy_request->binary_body_length < 2147483648) {
-                if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, 
copy_request->binary_body_length) != CURLE_OK) {
+                if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, 
(curl_off_t)copy_request->binary_body_length) != CURLE_OK) {
                   y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting 
POST fields size");
                   ret = U_ERROR_LIBCURL;
                   break;
                 }
               } else {
-                if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE_LARGE, 
copy_request->binary_body_length) != CURLE_OK) {
+                if (curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE_LARGE, 
(curl_off_t)copy_request->binary_body_length) != CURLE_OK) {
                   y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error setting 
POST fields size large");
                   ret = U_ERROR_LIBCURL;
                   break;
-- 
2.16.4

++++++ ulfius-2.6.1.tar.gz -> ulfius-2.6.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/API.md new/ulfius-2.6.2/API.md
--- old/ulfius-2.6.1/API.md     2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/API.md     2019-07-08 13:28:16.000000000 +0200
@@ -24,7 +24,8 @@
     - [Websocket management](#websocket-management)
     - [Messages manipulation](#messages-manipulation)
     - [Server-side websocket](#server-side-websocket)
-      - [Starting a websocket 
communication](#starting-a-websocket-communication)
+      - [Open a websocket communication](#open-a-websocket-communication)
+      - [Close a websocket communication](#close-a-websocket-communication)
       - [Websocket status](#websocket-status)
     - [Client-side websocket](#client-side-websocket)
       - [Prepare the request](#prepare-the-request)
@@ -1081,7 +1082,7 @@
 
 #### Server-side websocket
 
-##### Opening a websocket communication
+##### Open a websocket communication
 
 To start a websocket communication between the client and your application, 
you must use the dedicated function `ulfius_start_websocket_cb` with proper 
values:
 
@@ -1139,7 +1140,7 @@
 
 For each of these callback function, you can specify a `*_user_data` pointer 
containing any data you need.
 
-##### Closing a websocket communication
+##### Close a websocket communication
 
 To close a websocket communication from the server, you can do one of the 
following:
 
@@ -1147,7 +1148,12 @@
 - Send a message with the opcode `U_WEBSOCKET_OPCODE_CLOSE`
 - Call the function `ulfius_websocket_wait_close` or 
`ulfius_websocket_send_close_signal` described below
 
-If no `websocket_manager_callback` is specified, you can send a 
`U_WEBSOCKET_OPCODE_CLOSE` in the `websocket_incoming_message_callback` 
function when you need, or call the function 
`ulfius_websocket_send_close_signal`:
+If no `websocket_manager_callback` is specified, you can send a 
`U_WEBSOCKET_OPCODE_CLOSE` in the `websocket_incoming_message_callback` 
function when you need, or call the function 
`ulfius_websocket_send_close_signal`.
+
+If a callback function `websocket_onclose_callback` has been specified, this 
function will be executed on every case at the end of the websocket connection.
+
+If the websocket handshake hasn't been correctly completed or if an error 
appears during the handshake connection, the callback 
`websocket_onclose_callback` will be called anyway, even if the callback 
functions `websocket_manager_callback` or `websocket_incoming_message_callback` 
are skipped due to no websocket connection.
+This is to allow the calling program to close opened resources or clean 
allocated memory. Beware that in this specific case, the parameter `struct 
_websocket_manager * websocket_manager` may be `NULL`.
 
 ##### Websocket status
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/CHANGELOG.md 
new/ulfius-2.6.2/CHANGELOG.md
--- old/ulfius-2.6.1/CHANGELOG.md       2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/CHANGELOG.md       2019-07-08 13:28:16.000000000 +0200
@@ -1,5 +1,11 @@
 # Ulfius Changelog
 
+## 2.6.2
+
+- Clean build process
+- Fix memory leak in `ulfius_set_string_body_request` and 
`ulfius_set_string_body_response`
+- Call callback function websocket_onclose_callback on all times, even if the 
websocket hasn't properly worked, so the calling program can avoid memory leak 
and broken resources, fix #126
+
 ## 2.6.1
 
 - Fix package dependencies in cmake script
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/CMakeLists.txt 
new/ulfius-2.6.2/CMakeLists.txt
--- old/ulfius-2.6.1/CMakeLists.txt     2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/CMakeLists.txt     2019-07-08 13:28:16.000000000 +0200
@@ -30,13 +30,13 @@
 set(PROJECT_BUGREPORT_PATH "https://github.com/babelouest/ulfius/issues";)
 set(LIBRARY_VERSION_MAJOR "2")
 set(LIBRARY_VERSION_MINOR "6")
-set(LIBRARY_VERSION_PATCH "1")
+set(LIBRARY_VERSION_PATCH "2")
 
 set(PROJECT_VERSION 
"${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}")
 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.0.0")
-set(YDER_VERSION_REQUIRED "1.4.6")
+set(ORCANIA_VERSION_REQUIRED "2.0.1")
+set(YDER_VERSION_REQUIRED "1.4.7")
 
 # cmake modules
 
@@ -298,7 +298,7 @@
     include(FindCheck)
     find_package(Check REQUIRED)
     if (CHECK_FOUND)
-        if (NOT WIN32)
+        if (NOT WIN32 AND NOT APPLE)
             include(FindSubunit)
             find_package(Subunit REQUIRED)
         endif ()
@@ -311,9 +311,15 @@
         set(LIBS ulfius ${LIBS} ${CHECK_LIBRARIES})
         if (NOT WIN32)
             find_package(Threads REQUIRED)
-            set(LIBS ${LIBS} ${SUBUNIT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} m 
rt)
+            set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT} m)
         endif ()
-
+         if (NOT APPLE)
+            set(LIBS ${LIBS} rt)
+        endif ()
+        if (NOT WIN32 AND NOT APPLE)
+            set(LIBS ${LIBS} ${SUBUNIT_LIBRARIES} rt)
+        endif ()
+        
         set(TESTS core u_map framework)
         if (WITH_WEBSOCKET)
             set(TESTS ${TESTS} websocket)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/src/Makefile 
new/ulfius-2.6.2/src/Makefile
--- old/ulfius-2.6.1/src/Makefile       2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/src/Makefile       2019-07-08 13:28:16.000000000 +0200
@@ -32,9 +32,13 @@
 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 $(LDFLAGS)
+SONAME = -soname
+ifeq ($(shell uname -s),Darwin)
+       SONAME = -install_name
+endif
 OBJECTS=ulfius.o u_map.o u_request.o u_response.o u_send_request.o 
u_websocket.o yuarel.o
 OUTPUT=libulfius.so
-VERSION=2.6.1
+VERSION=2.6.2
 
 ifndef JANSSONFLAG
 DISABLE_JANSSON=0
@@ -167,7 +171,7 @@
        $(CC) $(CFLAGS) $<
 
 libulfius.so: $(OBJECTS)
-       $(CC) -shared -fPIC -Wl,-soname,$(OUTPUT) -o $(OUTPUT).$(VERSION) 
$(OBJECTS) $(LIBS) $(LYDER) $(LJANSSON) $(LCURL) $(LGNUTLS)
+       $(CC) -shared -fPIC -Wl,$(SONAME),$(OUTPUT) -o $(OUTPUT).$(VERSION) 
$(OBJECTS) $(LIBS) $(LYDER) $(LJANSSON) $(LCURL) $(LGNUTLS)
        ln -sf $(OUTPUT).$(VERSION) $(OUTPUT)
 
 libulfius.a: $(OBJECTS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/src/u_request.c 
new/ulfius-2.6.2/src/u_request.c
--- old/ulfius-2.6.1/src/u_request.c    2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/src/u_request.c    2019-07-08 13:28:16.000000000 +0200
@@ -526,6 +526,8 @@
  */
 int ulfius_set_string_body_request(struct _u_request * request, const char * 
string_body) {
   if (request != NULL && string_body != NULL) {
+    // Free all the bodies available
+    o_free(request->binary_body);
     request->binary_body = o_strdup(string_body);
     if (request->binary_body == NULL) {
       y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for 
request->binary_body");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/src/u_response.c 
new/ulfius-2.6.2/src/u_response.c
--- old/ulfius-2.6.1/src/u_response.c   2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/src/u_response.c   2019-07-08 13:28:16.000000000 +0200
@@ -568,6 +568,8 @@
  */
 int ulfius_set_string_body_response(struct _u_response * response, const 
unsigned int status, const char * string_body) {
   if (response != NULL && string_body != NULL) {
+    // Free all the bodies available
+    o_free(response->binary_body);
     response->binary_body = o_strdup(string_body);
     if (response->binary_body == NULL) {
       y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error allocating memory for 
response->binary_body");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/src/u_send_request.c 
new/ulfius-2.6.2/src/u_send_request.c
--- old/ulfius-2.6.1/src/u_send_request.c       2019-07-01 16:22:23.000000000 
+0200
+++ new/ulfius-2.6.2/src/u_send_request.c       2019-07-08 13:28:16.000000000 
+0200
@@ -566,11 +566,12 @@
             res = curl_easy_perform(curl_handle);
             if (res != CURLE_OK) {
               y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error 
curl_easy_perform");
+              y_log_message(Y_LOG_LEVEL_DEBUG, "Ulfius - libcurl error: %d, 
error message '%s'", res, curl_easy_strerror(res));
               ret = U_ERROR_LIBCURL;
               break;
             } else if (res == CURLE_OK && response != NULL) {
               if (curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, 
&response->status) != CURLE_OK) {
-                y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error executing 
http request, libcurl error: %d, error message %s", res, 
curl_easy_strerror(res));
+                y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error executing 
http request, libcurl error: %d, error message '%s'", res, 
curl_easy_strerror(res));
                 ret = U_ERROR_LIBCURL;
                 break;
               }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/src/u_websocket.c 
new/ulfius-2.6.2/src/u_websocket.c
--- old/ulfius-2.6.1/src/u_websocket.c  2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/src/u_websocket.c  2019-07-08 13:28:16.000000000 +0200
@@ -833,6 +833,9 @@
     if (thread_ret_websocket || thread_detach_websocket) {
       y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error creating or detaching 
websocket manager thread, return code: %d, detach code: %d",
                     thread_ret_websocket, thread_detach_websocket);
+      if (websocket->websocket_onclose_callback != NULL) {
+        websocket->websocket_onclose_callback(websocket->request, 
websocket->websocket_manager, websocket->websocket_onclose_user_data);
+      }
       ulfius_clear_websocket(websocket);
     }
   } else {
@@ -1179,10 +1182,15 @@
  */
 int ulfius_clear_websocket(struct _websocket * websocket) {
   if (websocket != NULL) {
-    if (websocket->websocket_manager->type == U_WEBSOCKET_SERVER && 
MHD_upgrade_action (websocket->urh, MHD_UPGRADE_ACTION_CLOSE) != MHD_YES) {
+    if (websocket->websocket_manager != NULL &&
+        websocket->urh != NULL &&
+        websocket->websocket_manager->type == U_WEBSOCKET_SERVER &&
+        MHD_upgrade_action (websocket->urh, MHD_UPGRADE_ACTION_CLOSE) != 
MHD_YES) {
       y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error sending 
MHD_UPGRADE_ACTION_CLOSE frame to urh");
     }
-    ulfius_instance_remove_websocket_active(websocket->instance, websocket);
+    if (websocket->instance != NULL) {
+      ulfius_instance_remove_websocket_active(websocket->instance, websocket);
+    }
     ulfius_clean_request_full(websocket->request);
     websocket->request = NULL;
     ulfius_clear_websocket_manager(websocket->websocket_manager);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/src/ulfius.c 
new/ulfius-2.6.2/src/ulfius.c
--- old/ulfius-2.6.1/src/ulfius.c       2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/src/ulfius.c       2019-07-08 13:28:16.000000000 +0200
@@ -546,24 +546,25 @@
 #ifndef U_DISABLE_WEBSOCKET
           } else if (((struct _websocket_handle 
*)response->websocket_handle)->websocket_manager_callback != NULL ||
                      ((struct _websocket_handle 
*)response->websocket_handle)->websocket_incoming_message_callback != NULL) {
-            // if the session is a valid websocket request,
-            // Initiate an UPGRADE session,
-            // then run the websocket callback functions with initialized data
-            if (NULL != 
o_strcasestr(u_map_get_case(con_info->request->map_header, "upgrade"), 
U_WEBSOCKET_UPGRADE_VALUE) &&
-                NULL != u_map_get_case(con_info->request->map_header, 
"Sec-WebSocket-Key") &&
-                NULL != u_map_get_case(con_info->request->map_header, 
"Origin") &&
-                NULL != 
o_strcasestr(u_map_get_case(con_info->request->map_header, "Connection"), 
"Upgrade") &&
-                0 == o_strcmp(con_info->request->http_protocol, "HTTP/1.1") &&
-                0 == o_strcmp(u_map_get_case(con_info->request->map_header, 
"Sec-WebSocket-Version"), "13") &&
-                0 == o_strcmp(con_info->request->http_verb, "GET")) {
-              int ret_protocol = 0, ret_extensions = 0;
-              // Check websocket_protocol and websocket_extensions to match 
ours
-              if ((ret_extensions = 
ulfius_check_list_match(u_map_get(con_info->request->map_header, 
"Sec-WebSocket-Extensions"), ((struct _websocket_handle 
*)response->websocket_handle)->websocket_extensions, ";", &extension)) == U_OK 
&& 
-                  (ret_protocol = 
ulfius_check_first_match(u_map_get(con_info->request->map_header, 
"Sec-WebSocket-Protocol"), ((struct _websocket_handle 
*)response->websocket_handle)->websocket_protocol, ",", &protocol)) == U_OK) {
-                char websocket_accept[32] = {0};
-                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 && ulfius_init_websocket(websocket) == 
U_OK) {
+            struct _websocket * websocket = o_malloc(sizeof(struct 
_websocket));
+            int websocket_has_error = 0;
+            if (websocket != NULL && ulfius_init_websocket(websocket) == U_OK) 
{
+              // if the session is a valid websocket request,
+              // Initiate an UPGRADE session,
+              // then run the websocket callback functions with initialized 
data
+              if (NULL != 
o_strcasestr(u_map_get_case(con_info->request->map_header, "upgrade"), 
U_WEBSOCKET_UPGRADE_VALUE) &&
+                  NULL != u_map_get_case(con_info->request->map_header, 
"Sec-WebSocket-Key") &&
+                  NULL != u_map_get_case(con_info->request->map_header, 
"Origin") &&
+                  NULL != 
o_strcasestr(u_map_get_case(con_info->request->map_header, "Connection"), 
"Upgrade") &&
+                  0 == o_strcmp(con_info->request->http_protocol, "HTTP/1.1") 
&&
+                  0 == o_strcmp(u_map_get_case(con_info->request->map_header, 
"Sec-WebSocket-Version"), "13") &&
+                  0 == o_strcmp(con_info->request->http_verb, "GET")) {
+                int ret_protocol = 0, ret_extensions = 0;
+                // Check websocket_protocol and websocket_extensions to match 
ours
+                if ((ret_extensions = 
ulfius_check_list_match(u_map_get(con_info->request->map_header, 
"Sec-WebSocket-Extensions"), ((struct _websocket_handle 
*)response->websocket_handle)->websocket_extensions, ";", &extension)) == U_OK 
&& 
+                    (ret_protocol = 
ulfius_check_first_match(u_map_get(con_info->request->map_header, 
"Sec-WebSocket-Protocol"), ((struct _websocket_handle 
*)response->websocket_handle)->websocket_protocol, ",", &protocol)) == U_OK) {
+                  char websocket_accept[32] = {0};
+                  if 
(ulfius_generate_handshake_answer(u_map_get(con_info->request->map_header, 
"Sec-WebSocket-Key"), websocket_accept)) {
                     websocket->request = 
ulfius_duplicate_request(con_info->request);
                     if (websocket->request != NULL) {
                       websocket->instance = (struct _u_instance *)cls;
@@ -590,13 +591,13 @@
                         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;
+                          websocket_has_error = 1;
                         } 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);
@@ -607,9 +608,10 @@
                         response_buffer_len = o_strlen(ULFIUS_HTTP_ERROR_BODY);
                         mhd_response = MHD_create_response_from_buffer 
(response_buffer_len, response_buffer, mhd_response_flag );
                       }
+                      websocket_has_error = 1;
                     }
                   } else {
-                    // Error building struct _websocket, sending error 500
+                    // Error building ulfius_generate_handshake_answer, 
sending error 500
                     response->status = MHD_HTTP_INTERNAL_SERVER_ERROR;
                     response_buffer = o_strdup(ULFIUS_HTTP_ERROR_BODY);
                     if (response_buffer == NULL) {
@@ -619,41 +621,51 @@
                       response_buffer_len = o_strlen(ULFIUS_HTTP_ERROR_BODY);
                       mhd_response = MHD_create_response_from_buffer 
(response_buffer_len, response_buffer, mhd_response_flag );
                     }
+                    websocket_has_error = 1;
                   }
                 } else {
-                  // Error building ulfius_generate_handshake_answer, 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 response_buffer");
-                    mhd_ret = MHD_NO;
-                  } else {
-                    response_buffer_len = o_strlen(ULFIUS_HTTP_ERROR_BODY);
-                    mhd_response = MHD_create_response_from_buffer 
(response_buffer_len, response_buffer, mhd_response_flag );
-                  }
+                  response->status = MHD_HTTP_BAD_REQUEST;
+                  response_buffer = msprintf("%s%s", 
(ret_protocol!=U_OK?"Error validating protocol\n":""), 
(ret_extensions!=U_OK?"Error validating extensions":""));
+                  y_log_message(Y_LOG_LEVEL_DEBUG, "Ulfius - Error websocket 
connection: %s", response_buffer);
+                  mhd_response = MHD_create_response_from_buffer 
(o_strlen(response_buffer), response_buffer, mhd_response_flag );
+                  websocket_has_error = 1;
                 }
+                o_free(protocol);
+                o_free(extension);
               } else {
+                response_buffer = msprintf("%s%s%s%s%s%s%s",
+                                           
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":"",
+                                           
u_map_get_case(con_info->request->map_header, "Origin")?"No Origin header\n":"",
+                                           
o_strcmp(con_info->request->http_protocol, "HTTP/1.1")!=0?"Wrong HTTP 
Protocolv":"",
+                                           
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":"");
                 response->status = MHD_HTTP_BAD_REQUEST;
-                response_buffer = msprintf("%s%s", (ret_protocol!=U_OK?"Error 
validating protocol\n":""), (ret_extensions!=U_OK?"Error validating 
extensions":""));
                 y_log_message(Y_LOG_LEVEL_DEBUG, "Ulfius - Error websocket 
connection: %s", response_buffer);
                 mhd_response = MHD_create_response_from_buffer 
(o_strlen(response_buffer), response_buffer, mhd_response_flag );
+                websocket_has_error = 1;
               }
-              o_free(protocol);
-              o_free(extension);
             } else {
-              response_buffer = msprintf("%s%s%s%s%s%s%s",
-                                         
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":"",
-                                         
u_map_get_case(con_info->request->map_header, "Origin")?"No Origin header\n":"",
-                                         
o_strcmp(con_info->request->http_protocol, "HTTP/1.1")!=0?"Wrong HTTP 
Protocolv":"",
-                                         
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":"");
-              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 
(o_strlen(response_buffer), response_buffer, mhd_response_flag );
+              // 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 response_buffer");
+                mhd_ret = MHD_NO;
+              } else {
+                response_buffer_len = o_strlen(ULFIUS_HTTP_ERROR_BODY);
+                mhd_response = MHD_create_response_from_buffer 
(response_buffer_len, response_buffer, mhd_response_flag );
+              }
+              websocket_has_error = 1;
             }
             close_loop = 1;
+            if (websocket_has_error) {
+              if (((struct _websocket_handle 
*)response->websocket_handle)->websocket_onclose_callback != NULL) {
+                ((struct _websocket_handle 
*)response->websocket_handle)->websocket_onclose_callback(con_info->request, 
websocket->websocket_manager!=NULL?websocket->websocket_manager:NULL, ((struct 
_websocket_handle *)response->websocket_handle)->websocket_onclose_user_data);
+              }
+              ulfius_clear_websocket(websocket);
+            }
 #endif
           } else {
             if (callback_ret == U_CALLBACK_CONTINUE && 
current_endpoint_list[i+1] == NULL) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/test/Makefile 
new/ulfius-2.6.2/test/Makefile
--- old/ulfius-2.6.1/test/Makefile      2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/test/Makefile      2019-07-08 13:28:16.000000000 +0200
@@ -24,13 +24,12 @@
 ULFIUS_LIBRARY=$(ULFIUS_LOCATION)/libulfius.so
 CC=gcc
 CFLAGS+=-Wall -D_REENTRANT -I$(ULFIUS_INCLUDE) -DDEBUG -g -O0 $(CPPFLAGS)
-LIBS=-lc -lorcania -lulfius -lyder -ljansson -lgnutls -lcheck -lpthread -lm 
-lrt -lsubunit -L$(ULFIUS_LOCATION)
+LIBS=-lc -lorcania -lulfius -lyder -ljansson -lgnutls $(shell pkg-config 
--libs check) -L$(ULFIUS_LOCATION)
 # Use this LIBS below if you don't have/need gnutls
 #LIBS=-lc -lorcania -lyder -lulfius -lcheck -lpthread -lm -lrt -lsubunit 
-L$(ULFIUS_LOCATION)
 # Use this LIBS below if you use yder logs
 #LIBS=-lc -lorcania -lyder -lulfius -lgnutls -lcheck -lpthread -lm -lrt 
-lsubunit -L$(ULFIUS_LOCATION)
 VALGRIND_COMMAND=valgrind --tool=memcheck --leak-check=full 
--show-leak-kinds=all
-
 all: test
 
 clean:
@@ -43,25 +42,25 @@
        $(CC) $(CFLAGS) u_map.c -o u_map $(LIBS)
 
 test_u_map: $(ULFIUS_LIBRARY) u_map
-       -LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./u_map
+       LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./u_map
 
 core: core.c
        $(CC) $(CFLAGS) core.c -o core $(LIBS)
 
 test_core: $(ULFIUS_LIBRARY) core
-       -LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./core
+       LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./core
 
 framework: framework.c
        $(CC) $(CFLAGS) framework.c -o framework $(LIBS)
 
 test_framework: $(ULFIUS_LIBRARY) framework
-       -LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./framework
+       LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./framework
 
 websocket: websocket.c
        $(CC) $(CFLAGS) websocket.c -o websocket $(LIBS)
 
 test_websocket: $(ULFIUS_LIBRARY) websocket
-       -LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./websocket
+       LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./websocket
 
 test: test_u_map test_core test_framework test_websocket
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.6.1/test/websocket.c 
new/ulfius-2.6.2/test/websocket.c
--- old/ulfius-2.6.1/test/websocket.c   2019-07-01 16:22:23.000000000 +0200
+++ new/ulfius-2.6.2/test/websocket.c   2019-07-08 13:28:16.000000000 +0200
@@ -26,6 +26,10 @@
 void websocket_onclose_callback_empty (const struct _u_request * request, 
struct _websocket_manager * websocket_manager, void * 
websocket_onclose_user_data) {
 }
 
+void websocket_onclose_callback_client (const struct _u_request * request, 
struct _websocket_manager * websocket_manager, void * 
websocket_onclose_user_data) {
+  ck_assert_ptr_ne(websocket_onclose_user_data, NULL);
+}
+
 void websocket_echo_message_callback (const struct _u_request * request,
                                          struct _websocket_manager * 
websocket_manager,
                                          const struct _websocket_message * 
last_message,
@@ -35,6 +39,10 @@
   }
 }
 
+void websocket_onclose_message_callback (const struct _u_request * request, 
struct _websocket_manager * websocket_manager, void * 
websocket_onclose_user_data) {
+  o_free(websocket_onclose_user_data);
+}
+
 void websocket_manager_callback_client (const struct _u_request * request, 
struct _websocket_manager * websocket_manager, void * 
websocket_manager_user_data) {
   int i;
   
@@ -55,6 +63,15 @@
 
 int callback_websocket (const struct _u_request * request, struct _u_response 
* response, void * user_data) {
   int ret;
+  char * websocket_allocated_data = o_strdup("grut");
+  
+  ret = ulfius_set_websocket_response(response, NULL, NULL, NULL, NULL, 
&websocket_echo_message_callback, websocket_allocated_data, 
&websocket_onclose_message_callback, websocket_allocated_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;
   
   ret = ulfius_set_websocket_response(response, NULL, NULL, NULL, NULL, 
&websocket_echo_message_callback, NULL, NULL, NULL);
   ck_assert_int_eq(ret, U_OK);
@@ -116,26 +133,92 @@
   struct _u_request request;
   struct _u_response response;
   struct _websocket_client_handler websocket_client_handler;
-  char url[64];
+  char url[64], * allocated_data = o_strdup("plop");
 
   ck_assert_int_eq(ulfius_init_instance(&instance, PORT, NULL, NULL), U_OK);
-  ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", 
PREFIX_WEBSOCKET, NULL, 0, &callback_websocket, NULL), U_OK);
+  ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", 
PREFIX_WEBSOCKET, NULL, 0, &callback_websocket, allocated_data), U_OK);
   ck_assert_int_eq(ulfius_start_framework(&instance), U_OK);
 
   ulfius_init_request(&request);
   ulfius_init_response(&response);
   sprintf(url, "ws://localhost:%d/%s", PORT, PREFIX_WEBSOCKET);
   
+  // Test correct websocket connection on correct websocket service
   ck_assert_int_eq(ulfius_set_websocket_request(&request, url, 
DEFAULT_PROTOCOL, DEFAULT_EXTENSION), U_OK);
-  ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, 
&websocket_manager_callback_client, NULL, 
&websocket_incoming_message_callback_client, NULL, NULL, NULL, 
&websocket_client_handler, &response), U_OK);
+  ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, 
&websocket_manager_callback_client, NULL, 
&websocket_incoming_message_callback_client, NULL, 
websocket_onclose_callback_client, allocated_data, &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);
+  
+  // Test incorrect websocket connection on correct websocket service
+  ulfius_init_request(&request);
+  ulfius_init_response(&response);
+  request.http_verb = o_strdup("GET");
+  request.http_url = o_strdup(url);
+  ck_assert_int_eq(ulfius_send_http_request(&request, &response), 
U_ERROR_LIBCURL); // On a websocket connection attempt, libcurl return 
'Unsupported protocol'
+  ulfius_clean_request(&request);
+  ulfius_clean_response(&response);
+  
+  // Test incorrect websocket connection on correct websocket service
+  ulfius_init_request(&request);
+  ulfius_init_response(&response);
+  ck_assert_int_eq(ulfius_set_websocket_request(&request, url, 
DEFAULT_PROTOCOL, DEFAULT_EXTENSION), U_OK);
+  ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, 
&websocket_manager_callback_client, NULL, 
&websocket_incoming_message_callback_client, NULL, 
websocket_onclose_callback_client, allocated_data, &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);
   
   ck_assert_int_eq(ulfius_stop_framework(&instance), U_OK);
   ulfius_clean_instance(&instance);
+  o_free(allocated_data);
+}
+END_TEST
+
+START_TEST(test_websocket_ulfius_websocket_client_no_onclose)
+{
+  struct _u_instance instance;
+  struct _u_request request;
+  struct _u_response response;
+  struct _websocket_client_handler websocket_client_handler;
+  char url[64];
+  ck_assert_int_eq(ulfius_init_instance(&instance, PORT, NULL, NULL), U_OK);
+  ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", 
PREFIX_WEBSOCKET, NULL, 0, &callback_websocket_onclose, NULL), U_OK);
+  ck_assert_int_eq(ulfius_start_framework(&instance), U_OK);
+
+  ulfius_init_request(&request);
+  ulfius_init_response(&response);
+  sprintf(url, "ws://localhost:%d/%s", PORT, PREFIX_WEBSOCKET);
+  
+  // Test correct websocket connection on correct websocket service
+  ck_assert_int_eq(ulfius_set_websocket_request(&request, url, 
DEFAULT_PROTOCOL, DEFAULT_EXTENSION), U_OK);
+  ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, 
&websocket_manager_callback_client, NULL, 
&websocket_incoming_message_callback_client, 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);
+  
+  // Test incorrect websocket connection on correct websocket service
+  ulfius_init_request(&request);
+  ulfius_init_response(&response);
+  request.http_verb = o_strdup("GET");
+  request.http_url = o_strdup(url);
+  ck_assert_int_eq(ulfius_send_http_request(&request, &response), 
U_ERROR_LIBCURL); // On a websocket connection attempt, libcurl return 
'Unsupported protocol'
+  ulfius_clean_request(&request);
+  ulfius_clean_response(&response);
+  
+  // Test incorrect websocket connection on correct websocket service
+  ulfius_init_request(&request);
+  ulfius_init_response(&response);
+  ck_assert_int_eq(ulfius_set_websocket_request(&request, url, 
DEFAULT_PROTOCOL, DEFAULT_EXTENSION), U_OK);
+  ck_assert_int_eq(ulfius_open_websocket_client_connection(&request, 
&websocket_manager_callback_client, NULL, 
&websocket_incoming_message_callback_client, 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);
+  
+  ck_assert_int_eq(ulfius_stop_framework(&instance), U_OK);
+  ulfius_clean_instance(&instance);
 }
 END_TEST
+
 #endif
 
 static Suite *ulfius_suite(void)
@@ -150,6 +233,7 @@
        tcase_add_test(tc_websocket, 
test_websocket_ulfius_set_websocket_request);
        tcase_add_test(tc_websocket, 
test_websocket_ulfius_open_websocket_client_connection_error);
        tcase_add_test(tc_websocket, test_websocket_ulfius_websocket_client);
+       tcase_add_test(tc_websocket, 
test_websocket_ulfius_websocket_client_no_onclose);
 #endif
        tcase_set_timeout(tc_websocket, 30);
        suite_add_tcase(s, tc_websocket);


Reply via email to