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-03-30 21:10:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ulfius (Old)
 and      /work/SRC/openSUSE:Factory/.ulfius.new.2401 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ulfius"

Tue Mar 30 21:10:17 2021 rev:19 rq:878562 version:2.7.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/ulfius/ulfius.changes    2021-01-04 
19:08:45.183351673 +0100
+++ /work/SRC/openSUSE:Factory/.ulfius.new.2401/ulfius.changes  2021-03-30 
21:18:40.921840789 +0200
@@ -1,0 +2,15 @@
+Thu Mar 11 17:03:17 UTC 2021 - Martin Hauke <[email protected]>
+
+- Adjust BR: liborcania >= 2.1.1 is needed.
+
+-------------------------------------------------------------------
+Sat Mar  6 11:49:59 UTC 2021 - Martin Hauke <[email protected]>
+
+- Update to version 2.7.2
+  * Fix post processor on multiple values with the same key.
+  * Add missing check includes if tests are built.
+  * Add option U_OPT_HTTP_URL_APPEND to
+    ulfius_set_request_properties
+  * Use ulfius_set_request_properties in example programs
+
+-------------------------------------------------------------------

Old:
----
  ulfius-2.7.1.tar.gz

New:
----
  ulfius-2.7.2.tar.gz

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

Other differences:
------------------
++++++ ulfius.spec ++++++
--- /var/tmp/diff_new_pack.QSALiR/_old  2021-03-30 21:18:41.629841307 +0200
+++ /var/tmp/diff_new_pack.QSALiR/_new  2021-03-30 21:18:41.633841310 +0200
@@ -20,7 +20,7 @@
 %define _lto_cflags %{nil}
 %define sover 2_7
 Name:           ulfius
-Version:        2.7.1
+Version:        2.7.2
 Release:        0
 Summary:        Web Framework for REST Applications in C
 License:        MIT
@@ -31,10 +31,10 @@
 BuildRequires:  gcc-c++
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(gnutls)
-BuildRequires:  pkgconfig(jansson) >= 2.4
+BuildRequires:  pkgconfig(jansson) >= 2.1
 BuildRequires:  pkgconfig(libcurl)
 BuildRequires:  pkgconfig(libmicrohttpd) >= 0.9.51
-BuildRequires:  pkgconfig(liborcania) >= 2.1.0
+BuildRequires:  pkgconfig(liborcania) >= 2.1.1
 BuildRequires:  pkgconfig(libyder) >= 1.4.12
 BuildRequires:  pkgconfig(zlib)
 

++++++ ulfius-2.7.1.tar.gz -> ulfius-2.7.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/API.md new/ulfius-2.7.2/API.md
--- old/ulfius-2.7.1/API.md     2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/API.md     2021-03-02 01:02:22.000000000 +0100
@@ -175,6 +175,7 @@
  * port:                   port number to listen to
  * network_type:           Listen to ipv4 and or ipv6 connections, values 
available are U_USE_ALL, U_USE_IPV4 or U_USE_IPV6
  * bind_address:           ipv4 address to listen to (optional)
+ * bind_address6:          ipv6 address to listen to (optional)
  * timeout:                Timeout to close the connection because of 
inactivity between the client and the server
  * nb_endpoints:           Number of available endpoints
  * default_auth_realm:     Default realm on authentication error
@@ -269,6 +270,8 @@
 
 Since Ulfius 2.6, you can bind to IPv4 connections, IPv6 or both. By default, 
`ulfius_init_instance` binds to IPv4 addresses only. If you want to bind to 
both IPv4 and IPv6 addresses, use `ulfius_init_instance_ipv6` with the value 
parameter `network_type` set to `U_USE_ALL`. If you want to bind to IPv6 
addresses only, use `ulfius_init_instance_ipv6` with the value parameter 
`network_type` set to `U_USE_IPV6`.
 
+If you bind your instance to an address, you **MUST** set the port number to 
`struct sockaddr_in.sport` because the `struct _u_instance.port` will be 
ignored.
+
 ### Endpoint structure <a name="endpoint-structure"></a>
 
 The `struct _u_endpoint` is defined as:
@@ -663,6 +666,7 @@
 | U_OPT_NONE | Empty option to complete a ulfius_set_request_properties or 
ulfius_set_request_properties |
 | U_OPT_HTTP_VERB | http method (GET, POST, PUT, DELETE, etc.), expected 
option value type: const char * |
 | U_OPT_HTTP_URL | full URL used to call this callback function or full URL to 
call when used in a ulfius_send_http_request, expected option value type: const 
char * |
+| U_OPT_HTTP_URL_APPEND | append char * value to the current url, expected 
option value type: const char * |
 | U_OPT_HTTP_PROXY | proxy address to use for outgoing connections, used by 
ulfius_send_http_request, expected option value type: const char * |
 | U_OPT_NETWORK_TYPE | Force connect to IPv4, IPv6 addresses or both, values 
available are U_USE_ALL, U_USE_IPV4 or U_USE_IPV6, expected option value type: 
unsigned short |
 | U_OPT_CHECK_SERVER_CERTIFICATE | check server certificate and hostname, 
default true, used by ulfius_send_http_request, expected option value type: int 
|
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/CHANGELOG.md 
new/ulfius-2.7.2/CHANGELOG.md
--- old/ulfius-2.7.1/CHANGELOG.md       2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/CHANGELOG.md       2021-03-02 01:02:22.000000000 +0100
@@ -1,5 +1,13 @@
 # Ulfius Changelog
 
+## 2.7.2
+
+- Fix post processor on multiple values with the same key (Thanks Oliv3)
+- Fix certificate generation on MacOS (Thanks @valera-rozuvan)
+- Add missing check includes if tests are built (Thanks @valera-rozuvan)
+- Add option `U_OPT_HTTP_URL_APPEND` to `ulfius_set_request_properties`
+- Use `ulfius_set_request_properties` in example programs
+
 ## 2.7.1
 
 - Fix websocket protocol and extension management bug, thanks to Olivier 
Girondel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/CMakeLists.txt 
new/ulfius-2.7.2/CMakeLists.txt
--- old/ulfius-2.7.1/CMakeLists.txt     2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/CMakeLists.txt     2021-03-02 01:02:22.000000000 +0100
@@ -4,7 +4,7 @@
 # CMake file used to build all programs
 #
 # Copyright 2018      Silvio Clecio <[email protected]>
-# Copyright 2018-2020 Nicolas Mora <[email protected]>
+# Copyright 2018-2021 Nicolas Mora <[email protected]>
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the MIT License
@@ -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 "1")
+set(LIBRARY_VERSION_PATCH "2")
 
 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.1.1")
-set(YDER_VERSION_REQUIRED "1.4.12")
+set(ORCANIA_VERSION_REQUIRED "2.2.0")
+set(YDER_VERSION_REQUIRED "1.4.13")
 set(JANSSON_VERSION_REQUIRED "2.1")
 
 # cmake modules
@@ -114,6 +114,7 @@
     find_package(GnuTLS REQUIRED)
     if (GNUTLS_FOUND)
         set(LIBS ${LIBS} ${GNUTLS_LIBRARIES})
+        include_directories(${GNUTLS_INCLUDE_DIRS})
     endif ()
 endif ()
 
@@ -370,11 +371,12 @@
 
         set(TST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test)
         set(LIBS ulfius ${LIBS} ${CHECK_LIBRARIES})
+        include_directories(${CHECK_INCLUDE_DIRS})
         if (NOT WIN32)
             find_package(Threads REQUIRED)
             set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT} m)
         endif ()
-         if (NOT APPLE)
+        if (NOT APPLE)
             set(LIBS ${LIBS} rt)
         endif ()
         if (NOT WIN32 AND NOT APPLE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/README.md new/ulfius-2.7.2/README.md
--- old/ulfius-2.7.1/README.md  2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/README.md  2021-03-02 01:02:22.000000000 +0100
@@ -115,8 +115,9 @@
 
 ## Projects using Ulfius framework
 
-- [Angharad](https://github.com/babelouest/angharad), House automation system 
for ZWave and other types of devices
 - [Glewlwyd](https://github.com/babelouest/glewlwyd), a lightweight SSO server 
that provides OAuth2 and OpenID Connect authentication protocols
+- [Le Biniou](https://biniou.net/), user-friendly yet powerful music 
visualization / VJing tool
+- [Angharad](https://github.com/babelouest/angharad), House automation system 
for ZWave and other types of devices
 - [Hutch](https://github.com/babelouest/hutch), a safe locker for passwords 
and other secrets, using JavaScript 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 implement 
[Taulas](https://github.com/babelouest/taulas/) protocol, a house automation 
protocol for Angharad
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ulfius-2.7.1/example_programs/auth_example/auth_client.c 
new/ulfius-2.7.2/example_programs/auth_example/auth_client.c
--- old/ulfius-2.7.1/example_programs/auth_example/auth_client.c        
2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/example_programs/auth_example/auth_client.c        
2021-03-02 01:02:22.000000000 +0100
@@ -5,7 +5,7 @@
  * This example program send several requests to describe
  * the function ulfius_request_http behaviour
  *  
- * Copyright 2015-2017 Nicolas Mora <[email protected]>
+ * Copyright 2015-2021 Nicolas Mora <[email protected]>
  * 
  * License MIT
  *
@@ -63,36 +63,49 @@
   if (argc <= 2) {
 #endif
     ulfius_init_request(&req_list[0]);
-    req_list[0].http_verb = o_strdup("GET");
-    req_list[0].http_url = o_strdup(SERVER_URL);
+    ulfius_set_request_properties(&req_list[0],
+                                  U_OPT_HTTP_VERB, "GET",
+                                  U_OPT_HTTP_URL, SERVER_URL,
+                                  U_OPT_NONE); // Required to close the 
parameters list
   
     ulfius_init_request(&req_list[1]);
-    req_list[1].http_verb = o_strdup("GET");
-    req_list[1].http_url = o_strdup(SERVER_URL);
-    req_list[1].auth_basic_user = o_strdup("test");
-    req_list[1].auth_basic_password = o_strdup("testpassword");
+    ulfius_set_request_properties(&req_list[1],
+                                  U_OPT_HTTP_VERB, "GET",
+                                  U_OPT_HTTP_URL, SERVER_URL,
+                                  U_OPT_AUTH_BASIC_USER, "test",
+                                  U_OPT_AUTH_BASIC_PASSWORD, "testpassword",
+                                  U_OPT_NONE); // Required to close the 
parameters list
   
     ulfius_init_request(&req_list[2]);
-    req_list[2].http_verb = o_strdup("GET");
-    req_list[2].http_url = o_strdup(SERVER_URL);
-    req_list[2].auth_basic_user = o_strdup("test");
-    req_list[2].auth_basic_password = o_strdup("wrongpassword");
+    ulfius_set_request_properties(&req_list[2],
+                                  U_OPT_HTTP_VERB, "GET",
+                                  U_OPT_HTTP_URL, SERVER_URL,
+                                  U_OPT_AUTH_BASIC_USER, "test",
+                                  U_OPT_AUTH_BASIC_PASSWORD, "wrongpassword",
+                                  U_OPT_NONE); // Required to close the 
parameters list
   
     ulfius_init_request(&req_list[3]);
-    req_list[3].http_verb = o_strdup("GET");
-    req_list[3].http_url = o_strdup(SERVER_URL "/404");
+    ulfius_set_request_properties(&req_list[3],
+                                  U_OPT_HTTP_VERB, "GET",
+                                  U_OPT_HTTP_URL, SERVER_URL,
+                                  U_OPT_HTTP_URL_APPEND, "/404",
+                                  U_OPT_NONE); // Required to close the 
parameters list
 
     ulfius_init_request(&req_list[4]);
-    req_list[4].http_verb = o_strdup("GET");
-    req_list[4].http_url = o_strdup(SERVER_URL_DEFAULT);
-    req_list[4].auth_basic_user = o_strdup("test");
-    req_list[4].auth_basic_password = o_strdup("testpassword");
+    ulfius_set_request_properties(&req_list[4],
+                                  U_OPT_HTTP_VERB, "GET",
+                                  U_OPT_HTTP_URL, SERVER_URL_DEFAULT,
+                                  U_OPT_AUTH_BASIC_USER, "test",
+                                  U_OPT_AUTH_BASIC_PASSWORD, "testpassword",
+                                  U_OPT_NONE); // Required to close the 
parameters list
   
     ulfius_init_request(&req_list[5]);
-    req_list[5].http_verb = o_strdup("GET");
-    req_list[5].http_url = o_strdup(SERVER_URL_DEFAULT);
-    req_list[5].auth_basic_user = o_strdup("test");
-    req_list[5].auth_basic_password = o_strdup("wrongpassword");
+    ulfius_set_request_properties(&req_list[5],
+                                  U_OPT_HTTP_VERB, "GET",
+                                  U_OPT_HTTP_URL, SERVER_URL_DEFAULT,
+                                  U_OPT_AUTH_BASIC_USER, "test",
+                                  U_OPT_AUTH_BASIC_PASSWORD, "wrongpassword",
+                                  U_OPT_NONE); // Required to close the 
parameters list
     
     printf("Press <enter> to run auth tests no authentication\n");
     getchar();
@@ -168,12 +181,14 @@
 #ifndef U_DISABLE_GNUTLS
   } else {
     ulfius_init_request(&req_list[0]);
-    req_list[0].http_verb = o_strdup("GET");
-    req_list[0].http_url = o_strdup(SERVER_URL_CLIENT_CERT);
-    req_list[0].check_server_certificate = 0;
-    req_list[0].client_cert_file = o_strdup(argv[1]);
-    req_list[0].client_key_file = o_strdup(argv[2]);
-    req_list[0].client_key_password = argc>=4?o_strdup(argv[3]):NULL;
+    ulfius_set_request_properties(&req_list[0],
+                                  U_OPT_HTTP_VERB, "GET",
+                                  U_OPT_HTTP_URL, SERVER_URL_CLIENT_CERT,
+                                  U_OPT_CHECK_SERVER_CERTIFICATE, 0,
+                                  U_OPT_CLIENT_CERT_FILE, argv[1],
+                                  U_OPT_CLIENT_KEY_FILE, argv[2],
+                                  U_OPT_CLIENT_KEY_PASSWORD, 
argc>=4?argv[3]:NULL,
+                                  U_OPT_NONE); // Required to close the 
parameters list
 
     printf("Press <enter> to run client certificate authentication test\n");
     getchar();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ulfius-2.7.1/example_programs/request_example/client.c 
new/ulfius-2.7.2/example_programs/request_example/client.c
--- old/ulfius-2.7.1/example_programs/request_example/client.c  2021-01-01 
15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/example_programs/request_example/client.c  2021-03-02 
01:02:22.000000000 +0100
@@ -5,7 +5,7 @@
  * This example program send several requests to describe
  * the function ulfius_request_http behaviour
  *  
- * Copyright 2015-2017 Nicolas Mora <[email protected]>
+ * Copyright 2015-2021 Nicolas Mora <[email protected]>
  * 
  * License MIT
  *
@@ -62,26 +62,11 @@
 
 int main (int argc, char **argv) {
   
-  struct _u_map headers, url_params, post_params, req_headers;
   char * string_body = "param1=one&param2=two";
   json_t * json_body = json_object();
   struct _u_response response;
   int res;
   
-  u_map_init(&headers);
-  
-  u_map_init(&url_params);
-  u_map_put(&url_params, "test", "one");
-  u_map_put(&url_params, "other_test", "two");
-  
-  u_map_init(&post_params);
-  u_map_put(&post_params, "third_test", "three");
-  u_map_put(&post_params, "fourth_test", "four");
-  u_map_put(&post_params, "extreme_test", "Here ! are %9_ some $ ??\\)]= 
special ch??ra??ters");
-  
-  u_map_init(&req_headers);
-  u_map_put(&req_headers, "Content-Type", 
MHD_HTTP_POST_ENCODING_FORM_URLENCODED);
-  
   json_object_set_new(json_body, "param1", json_string("one"));
   json_object_set_new(json_body, "param2", json_string("two"));
   
@@ -96,59 +81,87 @@
   ulfius_init_request(&req_list[7]);
   
   // Parameters in url
-  req_list[0].http_verb = o_strdup("GET");
-  req_list[0].http_url = o_strdup(SERVER_URL_PREFIX "/get/");
-  req_list[0].timeout = 20;
-  u_map_copy_into(req_list[0].map_url, &url_params);
+  ulfius_set_request_properties(&req_list[0],
+                                U_OPT_HTTP_VERB, "GET",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/get/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_URL_PARAMETER, "test", "one",
+                                U_OPT_URL_PARAMETER, "other_test", "two",
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   // No parameters
-  req_list[1].http_verb = o_strdup("DELETE");
-  req_list[1].http_url = o_strdup(SERVER_URL_PREFIX "/delete/");
-  req_list[1].timeout = 20;
+  ulfius_set_request_properties(&req_list[1],
+                                U_OPT_HTTP_VERB, "DELETE",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/delete/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   // Parameters in post_map and string_body
-  req_list[2].http_verb = o_strdup("POST");
-  req_list[2].http_url = o_strdup(SERVER_URL_PREFIX "/post/param/");
-  req_list[2].timeout = 20;
-  u_map_copy_into(req_list[2].map_post_body, &post_params);
-  req_list[2].binary_body = o_strdup(string_body);
-  req_list[2].binary_body_length = o_strlen(string_body);
+  ulfius_set_request_properties(&req_list[2],
+                                U_OPT_HTTP_VERB, "POST",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/post/param/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_BINARY_BODY, string_body, 
o_strlen(string_body),
+                                U_OPT_POST_BODY_PARAMETER, "third_test", 
"three",
+                                U_OPT_POST_BODY_PARAMETER, "fourth_test", 
"four",
+                                U_OPT_POST_BODY_PARAMETER, "extreme_test", 
"Here ! are %9_ some $ ??\\)]= special ch??ra??ters",
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   // Paremeters in string body, header MHD_HTTP_POST_ENCODING_FORM_URLENCODED
-  req_list[3].http_verb = o_strdup("POST");
-  req_list[3].http_url = o_strdup(SERVER_URL_PREFIX "/post/plain/");
-  req_list[3].timeout = 20;
-  u_map_copy_into(req_list[3].map_header, &req_headers);
-  req_list[3].binary_body = o_strdup(string_body);
-  req_list[3].binary_body_length = o_strlen(string_body);
+  ulfius_set_request_properties(&req_list[3],
+                                U_OPT_HTTP_VERB, "POST",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/post/plain/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_BINARY_BODY, string_body, 
o_strlen(string_body),
+                                U_OPT_HEADER_PARAMETER, "Content-Type", 
MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   // Parameters in json_body
-  req_list[4].http_verb = o_strdup("POST");
-  req_list[4].http_url = o_strdup(SERVER_URL_PREFIX "/post/json/");
-  req_list[4].timeout = 20;
-  u_map_copy_into(req_list[4].map_url, &url_params);
-  ulfius_set_json_body_request(&req_list[4], json_body);
+  ulfius_set_request_properties(&req_list[4],
+                                U_OPT_HTTP_VERB, "POST",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/post/json/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_JSON_BODY, json_body,
+                                U_OPT_URL_PARAMETER, "test", "one",
+                                U_OPT_URL_PARAMETER, "other_test", "two",
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   // Paremeters in string body, header MHD_HTTP_POST_ENCODING_FORM_URLENCODED
-  req_list[5].http_verb = o_strdup("PUT");
-  req_list[5].http_url = o_strdup(SERVER_URL_PREFIX "/put/plain/");
-  req_list[5].timeout = 20;
-  u_map_copy_into(req_list[5].map_header, &req_headers);
-  req_list[5].binary_body = o_strdup(string_body);
-  req_list[5].binary_body_length = o_strlen(string_body);
+  ulfius_set_request_properties(&req_list[5],
+                                U_OPT_HTTP_VERB, "PUT",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/put/plain/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_BINARY_BODY, string_body, 
o_strlen(string_body),
+                                U_OPT_HEADER_PARAMETER, "Content-Type", 
MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   // Parameters in json_body
-  req_list[6].http_verb = o_strdup("PUT");
-  req_list[6].http_url = o_strdup(SERVER_URL_PREFIX "/put/json/");
-  req_list[6].timeout = 20;
-  u_map_copy_into(req_list[6].map_url, &url_params);
-  ulfius_set_json_body_request(&req_list[6], json_body);
+  ulfius_set_request_properties(&req_list[6],
+                                U_OPT_HTTP_VERB, "PUT",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/put/json/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_JSON_BODY, json_body,
+                                U_OPT_URL_PARAMETER, "test", "one",
+                                U_OPT_URL_PARAMETER, "other_test", "two",
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   // Parameters in post_map
-  req_list[7].http_verb = o_strdup("POST");
-  req_list[7].http_url = o_strdup(SERVER_URL_PREFIX "/post/param/");
-  req_list[7].timeout = 20;
-  u_map_copy_into(req_list[6].map_post_body, &post_params);
+  ulfius_set_request_properties(&req_list[7],
+                                U_OPT_HTTP_VERB, "POST",
+                                U_OPT_HTTP_URL, SERVER_URL_PREFIX,
+                                U_OPT_HTTP_URL_APPEND, "/post/param/",
+                                U_OPT_TIMEOUT, 20,
+                                U_OPT_POST_BODY_PARAMETER, "third_test", 
"three",
+                                U_OPT_POST_BODY_PARAMETER, "fourth_test", 
"four",
+                                U_OPT_POST_BODY_PARAMETER, "extreme_test", 
"Here ! are %9_ some $ ??\\)]= special ch??ra??ters",
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   printf("Press <enter> to run get test\n");
   getchar();
@@ -246,10 +259,6 @@
   printf("Press <enter> to quit test\n");
   getchar();
   json_decref(json_body);
-  u_map_clean(&headers);
-  u_map_clean(&url_params);
-  u_map_clean(&post_params);
-  u_map_clean(&req_headers);
   ulfius_clean_request(&req_list[0]);
   ulfius_clean_request(&req_list[1]);
   ulfius_clean_request(&req_list[2]);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ulfius-2.7.1/example_programs/sheep_counter/README.md 
new/ulfius-2.7.2/example_programs/sheep_counter/README.md
--- old/ulfius-2.7.1/example_programs/sheep_counter/README.md   2021-01-01 
15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/example_programs/sheep_counter/README.md   2021-03-02 
01:02:22.000000000 +0100
@@ -12,7 +12,7 @@
 
 ### Sheep counter
 
-Open in your browser the url 
[http://localhost:7437/index.html](http://localhost:7437/index.html), it's a 
jquery application that will count and display sheeps to help you fall asleep. 
There click on the buttons available to call the underline API.
+Open in your browser the url 
[http://localhost:7437/static/index.html](http://localhost:7437/static/index.html),
 it's a jquery application that will count and display sheeps to help you fall 
asleep. There click on the buttons available to call the underline API.
 
 The API endpoints are the following:
 
@@ -22,8 +22,16 @@
 
 ### File upload
 
-Open in your browser the url 
[http://localhost:7437/upload.html](http://localhost:7437/upload.html), there 
upload a file, preferably not a big one, then click on the `Upload File` button.
+Open in your browser the url 
[http://localhost:7437/static/upload.html](http://localhost:7437/static/upload.html),
 there upload a file, preferably not a big one, then click on the `Upload File` 
button.
 
 The API endpoint is the following:
 
 - `http://localhost:7437/upload`: upload a file and show informations about it 
in the response.
+
+### Form POST
+
+Open in your browser the url 
[http://localhost:7437/static/form.html](http://localhost:7437/static/form.html),
 there enter values in the input, then click on the `send form` button. The 
console will display the form parameters.
+
+The API endpoint is the following:
+
+- `http://localhost:7437/static/submit`: submit a form and show informations 
about it in the response.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ulfius-2.7.1/example_programs/sheep_counter/sheep_counter.c 
new/ulfius-2.7.2/example_programs/sheep_counter/sheep_counter.c
--- old/ulfius-2.7.1/example_programs/sheep_counter/sheep_counter.c     
2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/example_programs/sheep_counter/sheep_counter.c     
2021-03-02 01:02:22.000000000 +0100
@@ -123,11 +123,12 @@
  */
 static int callback_upload_file (const struct _u_request * request, struct 
_u_response * response, void * user_data) {
   char * url_params = print_map(request->map_url), * headers = 
print_map(request->map_header), * cookies = print_map(request->map_cookie), 
-        * post_params = print_map(request->map_post_body);
+       * post_params = print_map(request->map_post_body);
 
   char * string_body = msprintf("Upload file\n\n  method is %s\n  url is 
%s\n\n  parameters from the url are \n%s\n\n  cookies are \n%s\n\n  headers are 
\n%s\n\n  post parameters are \n%s\n\n",
                                   request->http_verb, request->http_url, 
url_params, cookies, headers, post_params);
-  ulfius_set_string_body_response(response, 200, string_body);
+  y_log_message(Y_LOG_LEVEL_DEBUG, "Post parameters:\n%s", post_params);
+  y_log_message(Y_LOG_LEVEL_DEBUG, "URL parameters:\n%s", url_params);
   o_free(url_params);
   o_free(headers);
   o_free(cookies);
@@ -137,6 +138,20 @@
 }
 
 /**
+ * Submit a form
+ */
+static int callback_form_submit (const struct _u_request * request, struct 
_u_response * response, void * user_data) {
+  char * post_params = print_map(request->map_post_body),
+       * url_params = print_map(request->map_url);
+  y_log_message(Y_LOG_LEVEL_DEBUG, "Post parameters:\n%s", post_params);
+  y_log_message(Y_LOG_LEVEL_DEBUG, "URL parameters:\n%s", url_params);
+  o_free(post_params);
+  o_free(url_params);
+  ulfius_set_string_body_response(response, 200, "Form submitted");
+  return U_CALLBACK_CONTINUE;
+}
+
+/**
  * File upload callback function
  */
 static int file_upload_callback (const struct _u_request * request, 
@@ -200,7 +215,8 @@
     ulfius_add_endpoint_by_val(&instance, "PUT", PREFIX, NULL, 1, 
&callback_sheep_counter_add, &nb_sheep);
     ulfius_add_endpoint_by_val(&instance, "DELETE", PREFIX, NULL, 1, 
&callback_sheep_counter_reset, &nb_sheep);
     ulfius_add_endpoint_by_val(&instance, "*", PREFIX, NULL, 2, 
&callback_http_compression, NULL);
-    ulfius_add_endpoint_by_val(&instance, "*", FILE_PREFIX, NULL, 1, 
&callback_upload_file, NULL);
+    ulfius_add_endpoint_by_val(&instance, "*", STATIC_FOLDER, "/upload", 1, 
&callback_upload_file, NULL);
+    ulfius_add_endpoint_by_val(&instance, "*", STATIC_FOLDER, "/submit", 1, 
&callback_form_submit, NULL);
     ulfius_add_endpoint_by_val(&instance, "GET", "*", NULL, 1, 
&callback_static_compressed_inmemory_website, &file_config);
     
     // Start the framework
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ulfius-2.7.1/example_programs/sheep_counter/static/form.html 
new/ulfius-2.7.2/example_programs/sheep_counter/static/form.html
--- old/ulfius-2.7.1/example_programs/sheep_counter/static/form.html    
1970-01-01 01:00:00.000000000 +0100
+++ new/ulfius-2.7.2/example_programs/sheep_counter/static/form.html    
2021-03-02 01:02:22.000000000 +0100
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<form action="submit" method="post">
+    <input type="text" name="textParam" value="textValue"/><br/>
+    <input type="checkbox" name="checkboxParam" id="checkboxParam" 
value="checkboxValue" checked="true"/><label 
for="checkboxParam">Checkbox</label><br/>
+    <input type="radio" name="radioParam" id="radioParam1" value="radioValue1" 
checked="true"/><label for="radioParam1">Radio 1</label><br/>
+    <input type="radio" name="radioParam" id="radioParam2" 
value="radioValue2"/><label for="radioParam2">Radio 2</label><br/>
+    <select name="selectOne">
+      <option value="value1">Value1</option>
+      <option value="value2">Value2</option>
+      <option value="value3">Value3</option>
+    </select><br/>
+    <select name="selectMultiple" multiple>
+      <option value="value1">Value1</option>
+      <option value="value2">Value2</option>
+      <option value="value3">Value3</option>
+    </select><br/>
+    <input type="submit" value="send form" name="submit"/>
+</form>
+
+</body>
+</html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ulfius-2.7.1/example_programs/sheep_counter/static/index.html 
new/ulfius-2.7.2/example_programs/sheep_counter/static/index.html
--- old/ulfius-2.7.1/example_programs/sheep_counter/static/index.html   
2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/example_programs/sheep_counter/static/index.html   
2021-03-02 01:02:22.000000000 +0100
@@ -6,7 +6,7 @@
 </head>
 <script 
src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js";></script>
 <body>
-  <label>Coounter:</label><input type="text" id="counter" name="counter"><br/>
+  <label>Counter:</label><input type="text" id="counter" name="counter"><br/>
   <input type="button" id="start" name="start" value="Start counting"><br/>
   <input type="button" id="pause" name="pause" value="Pause counting"><br/>
   <input type="button" id="reset" name="reset" value="Reset counting"><br/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ulfius-2.7.1/example_programs/stream_example/stream_client.c 
new/ulfius-2.7.2/example_programs/stream_example/stream_client.c
--- old/ulfius-2.7.1/example_programs/stream_example/stream_client.c    
2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/example_programs/stream_example/stream_client.c    
2021-03-02 01:02:22.000000000 +0100
@@ -4,7 +4,7 @@
  * 
  * This example program get a stream data from the server
  * 
- * Copyright 2016 Nicolas Mora <[email protected]>
+ * Copyright 2016-2021 Nicolas Mora <[email protected]>
  * 
  * License MIT
  *
@@ -39,8 +39,11 @@
   
   ulfius_init_response(&response);
   ulfius_init_request(&request);
-  request.http_verb = o_strdup("GET");
-  request.http_url = o_strdup(URL);
+  
+  ulfius_set_request_properties(&request,
+                                U_OPT_HTTP_VERB, "GET",
+                                U_OPT_HTTP_URL, URL,
+                                U_OPT_NONE); // Required to close the 
parameters list
   
   y_log_message(Y_LOG_LEVEL_DEBUG, "Press <enter> to run stream test");
   getchar();
@@ -54,8 +57,8 @@
   
   y_log_message(Y_LOG_LEVEL_DEBUG, "Press <enter> to run stream audio test");
   ulfius_init_response(&response);
-  o_free(request.http_url);
-  request.http_url = o_strdup(URL "/audio");
+  ulfius_set_request_properties(&request, U_OPT_HTTP_VERB, "GET", 
U_OPT_HTTP_URL, URL, U_OPT_HTTP_URL_APPEND, "/audio", U_OPT_NONE);
+  
   getchar();
   res = ulfius_send_http_streaming_request(&request, &response, 
my_write_meta_body, NULL);
   if (res == U_OK) {
@@ -67,8 +70,8 @@
   
   y_log_message(Y_LOG_LEVEL_DEBUG, "Press <enter> to run no stream test");
   ulfius_init_response(&response);
-  o_free(request.http_url);
-  request.http_url = o_strdup("http://www.w3.org/";);
+  ulfius_set_request_properties(&request, U_OPT_HTTP_VERB, "GET", 
U_OPT_HTTP_URL, "http://www.w3.org/";, U_OPT_NONE);
+
   getchar();
   res = ulfius_send_http_request(&request, &response);
   if (res == U_OK) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/include/ulfius.h 
new/ulfius-2.7.2/include/ulfius.h
--- old/ulfius-2.7.1/include/ulfius.h   2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/include/ulfius.h   2021-03-02 01:02:22.000000000 +0100
@@ -174,7 +174,8 @@
 #endif
   U_OPT_STATUS                        = 28, ///< HTTP response status code 
(200, 404, 500, etc), expected option value type: long
   U_OPT_AUTH_REALM                    = 29, ///< realm to send to the client 
response on authenticationb failed, expected option value type: const char *
-  U_OPT_SHARED_DATA                   = 30  ///< any data shared between 
callback functions, must be allocated and freed by the callback functions, 
expected option value type: void *
+  U_OPT_SHARED_DATA                   = 30, ///< any data shared between 
callback functions, must be allocated and freed by the callback functions, 
expected option value type: void *
+  U_OPT_HTTP_URL_APPEND               = 31  ///< append char * value to the 
current url, expected option value type: const char *
 } u_option;
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/src/Makefile 
new/ulfius-2.7.2/src/Makefile
--- old/ulfius-2.7.1/src/Makefile       2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/src/Makefile       2021-03-02 01:02:22.000000000 +0100
@@ -40,7 +40,7 @@
 OUTPUT=libulfius.so
 VERSION_MAJOR=2
 VERSION_MINOR=7
-VERSION_PATCH=1
+VERSION_PATCH=2
 
 ifndef JANSSONFLAG
 DISABLE_JANSSON=0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/src/u_request.c 
new/ulfius-2.7.2/src/u_request.c
--- old/ulfius-2.7.1/src/u_request.c    2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/src/u_request.c    2021-03-02 01:02:22.000000000 +0100
@@ -558,6 +558,10 @@
             request->http_url = NULL;
           }
           break;
+        case U_OPT_HTTP_URL_APPEND:
+          str_value = va_arg(vl, const char *);
+          request->http_url = mstrcatf(request->http_url, "%s", str_value);
+          break;
         case U_OPT_HTTP_PROXY:
           str_value = va_arg(vl, const char *);
           o_free(request->proxy);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/src/ulfius.c 
new/ulfius-2.7.2/src/ulfius.c
--- old/ulfius-2.7.1/src/ulfius.c       2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/src/ulfius.c       2021-03-02 01:02:22.000000000 +0100
@@ -316,50 +316,91 @@
                                   const char * transfer_encoding, const char * 
data, uint64_t off, size_t size) {
 #endif
   struct connection_info_struct * con_info = coninfo_cls;
-  size_t cur_size = size;
-  char * data_dup, * filename_param;
+  size_t data_size = size, cur_size;
+  char * filename_param = NULL, * data_concat = NULL;
+  const char * cur_data;
+#if MHD_VERSION >= 0x00097002
+  enum MHD_Result ret = MHD_YES;
+#else
+  int ret = MHD_YES;
+#endif
   UNUSED(kind);
 
-  if (filename != NULL && con_info->u_instance != NULL && 
con_info->u_instance->file_upload_callback != NULL) {
-    if (con_info->u_instance->file_upload_callback(con_info->request, key, 
filename, content_type, transfer_encoding, data, off, size, 
con_info->u_instance->file_upload_cls) == U_OK) {
-      return MHD_YES;
-    } else {
-      return MHD_NO;
+  if (con_info->u_instance == NULL) {
+    ret = MHD_NO;
+  } else if (filename != NULL && con_info->u_instance->file_upload_callback != 
NULL) {
+    if (con_info->u_instance->file_upload_callback(con_info->request, key, 
filename, content_type, transfer_encoding, data, off, size, 
con_info->u_instance->file_upload_cls) != U_OK) {
+      ret = MHD_NO;
     }
   } else {
-    if (con_info->u_instance) {
-      if (con_info->u_instance->check_utf8 && (utf8_check(key, o_strlen(key)) 
!= NULL || data == NULL || utf8_check(data, o_strlen(data)) != NULL || 
(filename != NULL && utf8_check(filename, o_strlen(filename)) != NULL))) {
-        return MHD_YES;
+    
+    do {
+      if (con_info->u_instance->check_utf8) {
+        if (utf8_check(key, o_strlen(key)) != NULL || data == NULL || 
utf8_check(data, o_strlen(data)) != NULL || (filename != NULL && 
utf8_check(filename, o_strlen(filename)) != NULL)) {
+          break;
+        }
+      }
+      
+      if (con_info->max_post_param_size && off > 
con_info->max_post_param_size) {
+        break;
+      }
+      
+      if (off + size > con_info->max_post_param_size) {
+        data_size = con_info->max_post_param_size - off;
+      }
+      
+      if (filename != NULL) {
+        filename_param = msprintf("%s_filename", key);
+        if (!u_map_has_key((struct _u_map *)con_info->request->map_post_body, 
filename_param) && u_map_put((struct _u_map *)con_info->request->map_post_body, 
filename_param, filename) != U_OK) {
+          y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error u_map_put filename 
value");
+        }
+        cur_data = u_map_get((struct _u_map 
*)con_info->request->map_post_body, key);
+        cur_size = u_map_get_length((struct _u_map 
*)con_info->request->map_post_body, key);
+        if (cur_data != NULL) {
+          if (off) {
+            if (u_map_put_binary((struct _u_map 
*)con_info->request->map_post_body, key, data, cur_size, data_size) != U_OK) {
+              ret = MHD_NO;
+              break;
+            }
+          } else {
+            if (u_map_put_binary((struct _u_map 
*)con_info->request->map_post_body, key, ",", cur_size, 1) != U_OK ||
+                u_map_put_binary((struct _u_map 
*)con_info->request->map_post_body, key, data, cur_size+1, 1) != U_OK) {
+              ret = MHD_NO;
+              break;
+            }
+          }
+        } else {
+          if (u_map_put_binary((struct _u_map 
*)con_info->request->map_post_body, key, data, 0, data_size) != U_OK) {
+            ret = MHD_NO;
+            break;
+          }
+        }
       } else {
-        data_dup = o_strndup(data, size); // Force value to end with a NULL 
character
-        if (con_info->max_post_param_size > 0) {
-          if (off > con_info->max_post_param_size) {
-            return MHD_YES;
-          } else if (off + size > con_info->max_post_param_size) {
-            cur_size = con_info->max_post_param_size - off;
+        cur_data = u_map_get((struct _u_map 
*)con_info->request->map_post_body, key);
+        cur_size = u_map_get_length((struct _u_map 
*)con_info->request->map_post_body, key);
+        if (cur_data != NULL) {
+          if (off) {
+            data_concat = msprintf("%s%s", cur_data, data);
+          } else {
+            data_concat = msprintf("%s,%s", cur_data, data);
+          }
+          if (u_map_put((struct _u_map *)con_info->request->map_post_body, 
key, data_concat) != U_OK) {
+            ret = MHD_NO;
+            break;
+          }
+        } else {
+          if (u_map_put((struct _u_map *)con_info->request->map_post_body, 
key, data) != U_OK) {
+            ret = MHD_NO;
+            break;
           }
         }
       }
-    } else {
-      return MHD_NO;
-    }
-
-    if (filename != NULL) {
-      filename_param = msprintf("%s_filename", key);
-      if (!u_map_has_key((struct _u_map *)con_info->request->map_post_body, 
filename_param) && u_map_put((struct _u_map *)con_info->request->map_post_body, 
filename_param, filename) != U_OK) {
-        y_log_message(Y_LOG_LEVEL_ERROR, "Ulfius - Error u_map_put filename 
value");
-      }
-      o_free(filename_param);
-    }
-
-    if (cur_size > 0 && data_dup != NULL && u_map_put_binary((struct _u_map 
*)con_info->request->map_post_body, key, data_dup, off, cur_size + 1) == U_OK) {
-      o_free(data_dup);
-      return MHD_YES;
-    } else {
-      o_free(data_dup);
-      return MHD_NO;
-    }
+      
+    } while (0);
+    o_free(data_concat);
+    o_free(filename_param);
   }
+  return ret;
 }
 
 #if MHD_VERSION >= 0x00096100
@@ -479,7 +520,8 @@
     content_type = (char*)u_map_get_case(con_info->request->map_header, 
ULFIUS_HTTP_HEADER_CONTENT);
 
     // Set POST Processor if content-type is properly set
-    if (content_type != NULL && (0 == 
o_strncmp(MHD_HTTP_POST_ENCODING_FORM_URLENCODED, content_type, 
o_strlen(MHD_HTTP_POST_ENCODING_FORM_URLENCODED)) ||
+    if (content_type != NULL && 
+       (0 == o_strncmp(MHD_HTTP_POST_ENCODING_FORM_URLENCODED, content_type, 
o_strlen(MHD_HTTP_POST_ENCODING_FORM_URLENCODED)) ||
         0 == o_strncmp(MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, 
content_type, o_strlen(MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))) {
       con_info->has_post_processor = 1;
       con_info->post_processor = MHD_create_post_processor (connection, 
ULFIUS_POSTBUFFERSIZE, mhd_iterate_post_data, (void *) con_info);
@@ -857,7 +899,7 @@
           }
         }
 
-        if (!con_info->request->callback_position && ((struct _u_instance 
*)cls)->default_endpoint != NULL && ((struct _u_instance 
*)cls)->default_endpoint->callback_function != NULL) {
+        if (!con_info->request->callback_position && ((struct _u_instance 
*)cls)->default_endpoint != NULL && ((struct _u_instance 
*)cls)->default_endpoint->callback_function != NULL && mhd_response == NULL) {
           callback_ret = ((struct _u_instance 
*)cls)->default_endpoint->callback_function(con_info->request, response, 
((struct _u_instance *)cls)->default_endpoint->user_data);
           // Test callback_ret to know what to do
           switch (callback_ret) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/test/Makefile 
new/ulfius-2.7.2/test/Makefile
--- old/ulfius-2.7.1/test/Makefile      2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/test/Makefile      2021-03-02 01:02:22.000000000 +0100
@@ -5,6 +5,7 @@
 ULFIUS_INCLUDE=../include
 ULFIUS_LOCATION=../src
 ULFIUS_LIBRARY=$(ULFIUS_LOCATION)/libulfius.so
+ULFIUS_SCRUTINIZE=$(ULFIUS_INCLUDE)/ulfius.h $(ULFIUS_INCLUDE)/u_private.h 
$(ULFIUS_INCLUDE)/yuarel.h $(ULFIUS_LOCATION)/ulfius.c 
$(ULFIUS_LOCATION)/u_map.c $(ULFIUS_LOCATION)/u_request.c 
$(ULFIUS_LOCATION)/u_response.c $(ULFIUS_LOCATION)/u_send_request.c 
$(ULFIUS_LOCATION)/u_websocket.c $(ULFIUS_LOCATION)/yuarel.c
 CC=gcc
 CFLAGS+=-Wall -D_REENTRANT -I$(ULFIUS_INCLUDE) -DDEBUG -g -O0 $(CPPFLAGS)
 LIBS=-lc -lorcania -lulfius -lyder -ljansson -lgnutls -lz $(shell pkg-config 
--libs check) -L$(ULFIUS_LOCATION)
@@ -13,45 +14,39 @@
 # 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
+TARGET=u_map core framework websocket
+VERBOSE=0
+MEMCHECK=0
+
 all: test
 
 clean:
        rm -f *.o u_map core framework websocket valgrind-*.txt
 
-$(ULFIUS_LIBRARY):
+$(ULFIUS_LIBRARY): $(ULFIUS_SCRUTINIZE)
        cd $(ULFIUS_LOCATION) && $(MAKE) debug
 
 u_map: u_map.c
        $(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
-
 core: core.c
        $(CC) $(CFLAGS) core.c -o core $(LIBS)
 
-test_core: $(ULFIUS_LIBRARY) 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
-
 websocket: websocket.c
        $(CC) $(CFLAGS) websocket.c -o websocket $(LIBS)
 
-test_websocket: $(ULFIUS_LIBRARY) websocket
-       LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./websocket
+test: $(ULFIUS_LIBRARY) $(TARGET) test_u_map test_core test_framework 
test_websocket
 
-test: test_u_map test_core test_framework test_websocket
+test_%: % $(ULFIUS_LIBRARY)
+       @if [ "$(VERBOSE)" = "0" ] && [ "$(MEMCHECK)" = "0" ]; then \
+               LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} 
./run_test.sh ./$^; \
+       elif [ "$(MEMCHECK)" = "0" ]; then \
+               LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} ./$^ ; \
+       else \
+               LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} 
$(VALGRIND_COMMAND) ./$^ 2>[email protected]; \
+       fi
 
 check: test
-
-memcheck: $(ULFIUS_LIBRARY) u_map core framework websocket
-       -CK_FORK=no LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} 
$(VALGRIND_COMMAND) ./u_map 2>valgrind-u_map.txt
-       -CK_FORK=no LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} 
$(VALGRIND_COMMAND) ./core 2>valgrind-core.txt
-       # framework ans websocket don't work properly when CK_FORK=no is used, 
so using them old school with forks then
-       -LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} 
$(VALGRIND_COMMAND) ./framework 2>valgrind-framework.txt
-       -LD_LIBRARY_PATH=$(ULFIUS_LOCATION):${LD_LIBRARY_PATH} 
$(VALGRIND_COMMAND) ./websocket 2>valgrind-websocket.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/test/cert/create-cert.sh 
new/ulfius-2.7.2/test/cert/create-cert.sh
--- old/ulfius-2.7.1/test/cert/create-cert.sh   2021-01-01 15:47:01.000000000 
+0100
+++ new/ulfius-2.7.2/test/cert/create-cert.sh   2021-03-02 01:02:22.000000000 
+0100
@@ -3,6 +3,15 @@
 DEST=./cert
 RET=0
 
+case "$OSTYPE" in
+*"darwin"*)
+  # Apple has its own certtool which is incompatible. GnuTLS' certtool is 
renamed as
+  # gnutls-certtool in MacPorts/homebrew.
+  CERTTOOL=gnutls-certtool;;
+         *)
+  CERTTOOL=certtool;;
+esac
+
 # clean old certs
 rm -f $DEST/server.* $DEST/root* $DEST/client*
 
@@ -11,7 +20,7 @@
 echo >> $DEST/certtool.log
 
 # www cert
-certtool --generate-privkey --outfile $DEST/server.key --sec-param High 
2>>$DEST/certtool.log
+$CERTTOOL --generate-privkey --outfile $DEST/server.key --sec-param High 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "server.key         \033[0;32mOK\033[0m\n"
@@ -19,7 +28,7 @@
   printf "server.key         \033[0;31mError\033[0m\n"
   RET=$STATUS
 fi
-certtool --generate-self-signed --load-privkey $DEST/server.key --outfile 
$DEST/server.crt --template $DEST/template-server.cfg 2>>$DEST/certtool.log
+$CERTTOOL --generate-self-signed --load-privkey $DEST/server.key --outfile 
$DEST/server.crt --template $DEST/template-server.cfg 2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "server.crt         \033[0;32mOK\033[0m\n"
@@ -29,7 +38,7 @@
 fi
 
 # CA root
-certtool --generate-privkey --outfile $DEST/root1.key --sec-param High 
2>>$DEST/certtool.log
+$CERTTOOL --generate-privkey --outfile $DEST/root1.key --sec-param High 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "root1.key          \033[0;32mOK\033[0m\n"
@@ -37,7 +46,7 @@
   printf "root1.key          \033[0;31mError\033[0m\n"
   RET=$STATUS
 fi
-certtool --generate-self-signed --load-privkey $DEST/root1.key --outfile 
$DEST/root1.crt --template $DEST/template-ca.cfg 2>>$DEST/certtool.log
+$CERTTOOL --generate-self-signed --load-privkey $DEST/root1.key --outfile 
$DEST/root1.crt --template $DEST/template-ca.cfg 2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "root1.crt          \033[0;32mOK\033[0m\n"
@@ -47,7 +56,7 @@
 fi
 
 # client 1
-certtool --generate-privkey --outfile $DEST/client1.key --sec-param High 
2>>$DEST/certtool.log
+$CERTTOOL --generate-privkey --outfile $DEST/client1.key --sec-param High 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "client1.key        \033[0;32mOK\033[0m\n"
@@ -55,7 +64,7 @@
   printf "client1.key        \033[0;31mError\033[0m\n"
   RET=$STATUS
 fi
-certtool --generate-certificate --load-privkey $DEST/client1.key 
--load-ca-certificate $DEST/root1.crt --load-ca-privkey $DEST/root1.key 
--outfile $DEST/client1.crt --template $DEST/template-client.cfg 
2>>$DEST/certtool.log
+$CERTTOOL --generate-certificate --load-privkey $DEST/client1.key 
--load-ca-certificate $DEST/root1.crt --load-ca-privkey $DEST/root1.key 
--outfile $DEST/client1.crt --template $DEST/template-client.cfg 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "client1.crt        \033[0;32mOK\033[0m\n"
@@ -65,7 +74,7 @@
 fi
 
 # CA root 2
-certtool --generate-privkey --outfile $DEST/root2.key --sec-param High 
2>>$DEST/certtool.log
+$CERTTOOL --generate-privkey --outfile $DEST/root2.key --sec-param High 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "root2.key          \033[0;32mOK\033[0m\n"
@@ -73,7 +82,7 @@
   printf "root2.key          \033[0;31mError\033[0m\n"
   RET=$STATUS
 fi
-certtool --generate-self-signed --load-privkey $DEST/root2.key --outfile 
$DEST/root2.crt --template $DEST/template-ca2.cfg 2>>$DEST/certtool.log
+$CERTTOOL --generate-self-signed --load-privkey $DEST/root2.key --outfile 
$DEST/root2.crt --template $DEST/template-ca2.cfg 2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "root2.crt          \033[0;32mOK\033[0m\n"
@@ -83,7 +92,7 @@
 fi
 
 # client 2
-certtool --generate-privkey --outfile $DEST/client2.key --sec-param High 
2>>$DEST/certtool.log
+$CERTTOOL --generate-privkey --outfile $DEST/client2.key --sec-param High 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "client2.key        \033[0;32mOK\033[0m\n"
@@ -91,7 +100,7 @@
   printf "client2.key        \033[0;31mError\033[0m\n"
   RET=$STATUS
 fi
-certtool --generate-certificate --load-privkey $DEST/client2.key 
--load-ca-certificate $DEST/root2.crt --load-ca-privkey $DEST/root2.key 
--outfile $DEST/client2.crt --template $DEST/template-client.cfg 
2>>$DEST/certtool.log
+$CERTTOOL --generate-certificate --load-privkey $DEST/client2.key 
--load-ca-certificate $DEST/root2.crt --load-ca-privkey $DEST/root2.key 
--outfile $DEST/client2.crt --template $DEST/template-client.cfg 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "client2.crt        \033[0;32mOK\033[0m\n"
@@ -101,7 +110,7 @@
 fi
 
 # client 3 self-signed
-certtool --generate-privkey --outfile $DEST/client3.key --sec-param High 
2>>$DEST/certtool.log
+$CERTTOOL --generate-privkey --outfile $DEST/client3.key --sec-param High 
2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "client3.key        \033[0;32mOK\033[0m\n"
@@ -109,7 +118,7 @@
   printf "client3.key        \033[0;31mError\033[0m\n"
   RET=$STATUS
 fi
-certtool --generate-self-signed --load-privkey $DEST/client3.key --outfile 
$DEST/client3.crt --template $DEST/template-client.cfg 2>>$DEST/certtool.log
+$CERTTOOL --generate-self-signed --load-privkey $DEST/client3.key --outfile 
$DEST/client3.crt --template $DEST/template-client.cfg 2>>$DEST/certtool.log
 STATUS=$?
 if [ $STATUS -eq 0 ]; then
   printf "client3.crt        \033[0;32mOK\033[0m\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/test/core.c new/ulfius-2.7.2/test/core.c
--- old/ulfius-2.7.1/test/core.c        2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/test/core.c        2021-03-02 01:02:22.000000000 +0100
@@ -16,6 +16,7 @@
 #define HTTP_PROTOCOL "http_protocol"
 #define HTTP_VERB "http_verb"
 #define HTTP_URL "http_url"
+#define HTTP_URL_APPEND "http_url_append"
 #define URL_PATH "url_path"
 #define PROXY "proxy"
 #define CA_PATH "ca_path"
@@ -328,6 +329,7 @@
   ck_assert_int_eq(ulfius_set_request_properties(&req,
                                                  U_OPT_HTTP_VERB, HTTP_VERB,
                                                  U_OPT_HTTP_URL, HTTP_URL,
+                                                 U_OPT_HTTP_URL_APPEND, 
HTTP_URL_APPEND,
                                                  U_OPT_HTTP_PROXY, PROXY,
 #if MHD_VERSION >= 0x00095208
                                                  U_OPT_NETWORK_TYPE, 
U_USE_IPV4,
@@ -354,7 +356,7 @@
                                                  U_OPT_NONE), U_OK);
 
   ck_assert_str_eq(req.http_verb, HTTP_VERB);
-  ck_assert_str_eq(req.http_url, HTTP_URL);
+  ck_assert_str_eq(req.http_url, HTTP_URL HTTP_URL_APPEND);
   ck_assert_str_eq(req.proxy, PROXY);
 #if MHD_VERSION >= 0x00095208
   ck_assert_int_eq(req.network_type, U_USE_IPV4);
@@ -409,6 +411,7 @@
   ck_assert_int_eq(ulfius_set_request_properties(&req,
                                                  U_OPT_HTTP_VERB, HTTP_VERB,
                                                  U_OPT_HTTP_URL, HTTP_URL,
+                                                 U_OPT_HTTP_URL_APPEND, 
HTTP_URL_APPEND,
                                                  U_OPT_HTTP_PROXY, PROXY,
 #if MHD_VERSION >= 0x00095208
                                                  U_OPT_NETWORK_TYPE, 
U_USE_IPV4,
@@ -435,7 +438,7 @@
                                                  U_OPT_NONE), U_OK);
 
   ck_assert_str_eq(req.http_verb, HTTP_VERB);
-  ck_assert_str_eq(req.http_url, HTTP_URL);
+  ck_assert_str_eq(req.http_url, HTTP_URL HTTP_URL_APPEND);
   ck_assert_str_eq(req.proxy, PROXY);
 #if MHD_VERSION >= 0x00095208
   ck_assert_int_eq(req.network_type, U_USE_IPV4);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/test/framework.c 
new/ulfius-2.7.2/test/framework.c
--- old/ulfius-2.7.1/test/framework.c   2021-01-01 15:47:01.000000000 +0100
+++ new/ulfius-2.7.2/test/framework.c   2021-03-02 01:02:22.000000000 +0100
@@ -316,17 +316,23 @@
 }
 
 int callback_function_param(const struct _u_request * request, struct 
_u_response * response, void * user_data) {
-  char * param3, * body;
+  char * param3, * param4, * body;
   
   if (u_map_has_key(request->map_url, "param3")) {
     param3 = msprintf(", param3 is %s", u_map_get(request->map_url, "param3"));
   } else {
     param3 = o_strdup("");
   }
-  body = msprintf("param1 is %s, param2 is %s%s", u_map_get(request->map_url, 
"param1"), u_map_get(request->map_url, "param2"), param3);
+  if (u_map_has_key(request->map_url, "param4")) {
+    param4 = msprintf(", param4 is %s", u_map_get(request->map_url, "param4"));
+  } else {
+    param4 = o_strdup("");
+  }
+  body = msprintf("param1 is %s, param2 is %s%s%s", 
u_map_get(request->map_url, "param1"), u_map_get(request->map_url, "param2"), 
param3, param4);
   ulfius_set_string_body_response(response, 200, body);
   o_free(body);
   o_free(param3);
+  o_free(param4);
   return U_CALLBACK_CONTINUE;
 }
 
@@ -817,6 +823,35 @@
   ulfius_clean_response(&response);
   
   ulfius_init_request(&request);
+  request.http_url = 
o_strdup("http://localhost:8080/param/value1/value2?param4=value4";);
+  ulfius_init_response(&response);
+  ck_assert_int_eq(ulfius_send_http_request(&request, &response), U_OK);
+  ck_assert_int_eq(response.status, 200);
+  ck_assert_int_eq(o_strncmp(response.binary_body, "param1 is value1, param2 
is value2, param4 is value4", o_strlen("param1 is value1, param2 is value2, 
param4 is value4")), 0);
+  ulfius_clean_request(&request);
+  ulfius_clean_response(&response);
+  
+  ulfius_init_request(&request);
+  request.http_url = 
o_strdup("http://localhost:8080/param/value1/value2?param4=value4&param2=additional_value2&param4=additional_value4";);
+  ulfius_init_response(&response);
+  ck_assert_int_eq(ulfius_send_http_request(&request, &response), U_OK);
+  ck_assert_int_eq(response.status, 200);
+  ck_assert_int_eq(o_strncmp(response.binary_body, "param1 is value1, param2 
is additional_value2,value2, param4 is value4,additional_value4", 
o_strlen("param1 is value1, param2 is additional_value2,value2, param4 is 
value4,additional_value4")), 0);
+  ulfius_clean_request(&request);
+  ulfius_clean_response(&response);
+  
+#if MHD_VERSION >= 0x00097200
+  ulfius_init_request(&request);
+  request.http_url = 
o_strdup("http://localhost:8080/param/value1/value2?param4=val%26ue4";);
+  ulfius_init_response(&response);
+  ck_assert_int_eq(ulfius_send_http_request(&request, &response), U_OK);
+  ck_assert_int_eq(response.status, 200);
+  ck_assert_int_eq(o_strncmp(response.binary_body, "param1 is value1, param2 
is value2, param4 is val&ue4", o_strlen("param1 is value1, param2 is value2, 
param4 is val&ue4")), 0);
+  ulfius_clean_request(&request);
+  ulfius_clean_response(&response);
+#endif
+  
+  ulfius_init_request(&request);
   request.http_url = 
o_strdup("http://localhost:8080/param/value1/value2/value3.1/value3.2";);
   ulfius_init_response(&response);
   ck_assert_int_eq(ulfius_send_http_request(&request, &response), U_OK);
@@ -1035,7 +1070,7 @@
   ulfius_init_response(&response);
   ck_assert_int_eq(ulfius_set_request_properties(&request, U_OPT_HTTP_VERB, 
"GET", U_OPT_HTTP_URL, "http://localhost:8080/ignore";, U_OPT_NONE), U_OK);
   ck_assert_int_eq(ulfius_send_http_request(&request, &response), U_OK);
-  ck_assert_int_eq(response.status, 205);
+  ck_assert_int_eq(response.status, 200);
   ulfius_clean_request(&request);
   ulfius_clean_response(&response);
   
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ulfius-2.7.1/test/run_test.sh 
new/ulfius-2.7.2/test/run_test.sh
--- old/ulfius-2.7.1/test/run_test.sh   1970-01-01 01:00:00.000000000 +0100
+++ new/ulfius-2.7.2/test/run_test.sh   2021-03-02 01:02:22.000000000 +0100
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+printf_new() {
+ str=$1
+ num=$2
+ v=$(printf "%-${num}s" "$str")
+ printf "${v// / }"
+}
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+NC='\033[0m' # No Color
+COMMAND=$1
+CHRLEN=${#COMMAND}
+NBSP=$((32-$CHRLEN))
+
+printf "Run $1"
+printf_new " " $NBSP
+
+$1 $2 $3 $4 $5 $6 $7 $8 $9 1>$1.log 2>&1
+
+if [ $? -ne 0 ]
+then
+       printf "${RED}FAIL${NC}\n"
+else
+       printf "${GREEN}SUCCESS${NC}\n"
+fi

Reply via email to