Ulfius
HTTP Framework for REST Applications in C
ulfius.h
Go to the documentation of this file.
1 
27 #ifndef __ULFIUS_H__
28 #define __ULFIUS_H__
29 
30 #ifdef __cplusplus
31 extern "C"
32 {
33 #endif
34 
35 #include "ulfius-cfg.h"
36 
39 #ifndef U_DISABLE_GNUTLS
40  #ifndef _GNU_SOURCE
41  #define _GNU_SOURCE
42  #endif
43  #include <gnutls/gnutls.h>
44  #include <gnutls/x509.h>
45 #endif
46 
47 #ifndef U_DISABLE_JANSSON
48 #include <jansson.h>
49 #endif
50 
51 #ifndef U_DISABLE_WEBSOCKET
52  #include <poll.h>
53  #include <zlib.h>
54  #ifndef POLLRDHUP
55  #define POLLRDHUP 0x2000
56  #endif
57 #endif
58 
59 #include <pthread.h>
60 #include <microhttpd.h>
61 
62 #if defined(_WIN32) && !defined(U_DISABLE_WEBSOCKET)
63  #define U_DISABLE_WEBSOCKET
64 #endif
65 
66 #if (MHD_VERSION < 0x00095300) && !defined(U_DISABLE_WEBSOCKET)
67  #define U_DISABLE_WEBSOCKET
68 #endif
69 
71 #include <orcania.h>
72 
74 #ifndef U_DISABLE_YDER
75  #include <yder.h>
76 #else
77 
78 #define Y_LOG_MODE_NONE 0
79 #define Y_LOG_MODE_CONSOLE 0
80 #define Y_LOG_MODE_SYSLOG 0
81 #define Y_LOG_MODE_FILE 0
82 #define Y_LOG_MODE_JOURNALD 0
83 #define Y_LOG_MODE_CALLBACK 0
84 #define Y_LOG_MODE_CURRENT 0
85 
86 #define Y_LOG_LEVEL_NONE 0
87 #define Y_LOG_LEVEL_DEBUG 0
88 #define Y_LOG_LEVEL_INFO 0
89 #define Y_LOG_LEVEL_WARNING 0
90 #define Y_LOG_LEVEL_ERROR 0
91 #define Y_LOG_LEVEL_CURRENT 0
92 
93 int y_init_logs(const char * app, const unsigned long init_mode, const unsigned long init_level, const char * init_log_file, const char * message);
94 int y_set_logs_callback(void (* y_callback_log_message) (void * cls, const char * app_name, const time_t date, const unsigned long level, const char * message), void * cls, const char * message);
95 void y_log_message(const unsigned long type, const char * message, ...);
96 int y_close_logs();
97 #endif
98 
104 #define ULFIUS_STREAM_BLOCK_SIZE_DEFAULT 1024
105 #define U_STREAM_END MHD_CONTENT_READER_END_OF_STREAM
106 #define U_STREAM_ERROR MHD_CONTENT_READER_END_WITH_ERROR
107 #define U_STREAM_SIZE_UNKNOWN MHD_SIZE_UNKNOWN
108 #define U_STREAM_SIZE_UNKOWN U_STREAM_SIZE_UNKNOWN // Backward compatibility
109 
110 #define U_OK 0
111 #define U_ERROR 1
112 #define U_ERROR_MEMORY 2
113 #define U_ERROR_PARAMS 3
114 #define U_ERROR_LIBMHD 4
115 #define U_ERROR_LIBCURL 5
116 #define U_ERROR_NOT_FOUND 6
117 #define U_ERROR_DISCONNECTED 7
118 
119 #define U_CALLBACK_CONTINUE 0
120 #define U_CALLBACK_IGNORE 1
121 #define U_CALLBACK_COMPLETE 2
122 #define U_CALLBACK_UNAUTHORIZED 3
123 #define U_CALLBACK_ERROR 4
124 
125 #define U_COOKIE_SAME_SITE_NONE 0
126 #define U_COOKIE_SAME_SITE_STRICT 1
127 #define U_COOKIE_SAME_SITE_LAX 2
128 
129 #define U_USE_IPV4 0x0001
130 #define U_USE_IPV6 0x0010
131 #define U_USE_ALL (U_USE_IPV4|U_USE_IPV6)
132 
133 #define U_SSL_VERIFY_PEER 0x0001
134 #define U_SSL_VERIFY_HOSTNAME 0x0010
135 
136 #define U_POST_PROCESS_NONE 0x0000
137 #define U_POST_PROCESS_URL_ENCODED 0x0001
138 #define U_POST_PROCESS_MULTIPART_FORMDATA 0x0010
139 
144 typedef enum {
149 #if MHD_VERSION >= 0x00095208
150  U_OPT_NETWORK_TYPE = 4,
151 #endif
172 #ifndef U_DISABLE_JANSSON
174 #endif
175 #ifndef U_DISABLE_GNUTLS
179 #endif
185 
190 /*************
191  * Structures
192  *************/
193 
203 struct _u_map {
204  int nb_values; /* !< Values count */
205  char ** keys; /* !< Array of keys */
206  char ** values; /* !< Array of values */
207  size_t * lengths; /* !< Lengths of each values */
208 };
209 
214 struct _u_cookie {
215  char * key; /* !< key if the cookie */
216  char * value; /* !< value of the cookie */
217  char * expires; /* !< expiration date of the cookie */
218  unsigned int max_age; /* !< duration of the cookie in seconds */
219  char * domain; /* !< domain for the cookie */
220  char * path; /* !< url path for the cookie */
221  int secure; /* !< flag to set cookie secure or not */
222  int http_only; /* !< flag to set cookie for HTTP connections only or not */
223  int same_site; /* !< flag to set same_site option to the cookie */
224 };
225 
232 struct _u_request {
233  char * http_protocol; /* !< http protocol used (1.0 or 1.1) */
234  char * http_verb; /* !< http method (GET, POST, PUT, DELETE, etc.) */
235  char * http_url; /* !< full url used to call this callback function or full url to call when used in a ulfius_send_http_request */
236  char * url_path; /* !< url path only used to call this callback function (ex, if http_url is /path/?param=1, url_path is /path/) */
237  char * proxy; /* !<proxy address to use for outgoing connections, used by ulfius_send_http_request */
238 #if MHD_VERSION >= 0x00095208
239  unsigned short network_type; /* !< Force connect to ipv4, ipv6 addresses or both, values available are U_USE_ALL, U_USE_IPV4 or U_USE_IPV6 */
240 #endif
241  int check_server_certificate; /* !< check server certificate and hostname, default true, used by ulfius_send_http_request */
242  int check_server_certificate_flag; /* !< check certificate peer and or server hostname if check_server_certificate is enabled, values available are U_SSL_VERIFY_PEER, U_SSL_VERIFY_HOSTNAME or both, default value is both (U_SSL_VERIFY_PEER|U_SSL_VERIFY_HOSTNAME), used by ulfius_send_http_request */
243  int check_proxy_certificate; /* !< check proxy certificate and hostname, default true, used by ulfius_send_http_request, requires libcurl >= 7.52 */
244  int check_proxy_certificate_flag; /* !< check certificate peer and or proxy hostname if check_proxy_certificate is enabled, values available are U_SSL_VERIFY_PEER, U_SSL_VERIFY_HOSTNAME or both, default value is both (U_SSL_VERIFY_PEER|U_SSL_VERIFY_HOSTNAME), used by ulfius_send_http_request, requires libcurl >= 7.52 */
245  int follow_redirect; /* !< follow url redirections, used by ulfius_send_http_request */
246  char * ca_path; /* !< specify a path to CA certificates instead of system path, used by ulfius_send_http_request */
247  unsigned long timeout; /* !< connection timeout used by ulfius_send_http_request, default is 0 */
248  struct sockaddr * client_address; /* !< IP address of the client */
249  char * auth_basic_user; /* !< basic authentication username */
250  char * auth_basic_password; /* !< basic authentication password */
251  struct _u_map * map_url; /* !< map containing the url variables, both from the route and the ?key=value variables */
252  struct _u_map * map_header; /* !< map containing the header variables */
253  struct _u_map * map_cookie; /* !< map containing the cookie variables */
254  struct _u_map * map_post_body; /* !< map containing the post body variables (if available) */
255  void * binary_body; /* !< raw body */
256  size_t binary_body_length; /* !< length of raw body */
257  unsigned int callback_position; /* !< position of the current callback function in the callback list, starts at 0 */
258 #ifndef U_DISABLE_GNUTLS
259  gnutls_x509_crt_t client_cert; /* !< x509 certificate of the client if the instance uses client certificate authentication and the client is authenticated, available only if GnuTLS support is enabled */
260  char * client_cert_file; /* !< path to client certificate file for sending http requests with certificate authentication, available only if GnuTLS support is enabled */
261  char * client_key_file; /* !< path to client key file for sending http requests with certificate authentication, available only if GnuTLS support is enabled */
262  char * client_key_password; /* !< password to unlock client key file, available only if GnuTLS support is enabled */
263 #endif
264 };
265 
272 struct _u_response {
273  long status; /* !< HTTP status code (200, 404, 500, etc) */
274  char * protocol; /* !< HTTP Protocol sent */
275  struct _u_map * map_header; /* !< map containing the header variables */
276  unsigned int nb_cookies; /* !< number of cookies sent */
277  struct _u_cookie * map_cookie; /* !< array of cookies sent */
278  char * auth_realm; /* !< realm to send to the client on authenticationb failed */
279  void * binary_body; /* !< raw binary content */
280  size_t binary_body_length; /* !< length of the binary_body */
281  ssize_t (* stream_callback) (void * stream_user_data, uint64_t offset, char * out_buf, size_t max); /* !< callback function to stream data in response body */
282  void (* stream_callback_free) (void * stream_user_data); /* !< callback function to free data allocated for streaming */
283  uint64_t stream_size; /* !< size of the streamed data (U_STREAM_SIZE_UNKNOWN if unknown) */
284  size_t stream_block_size; /* !< size of each block to be streamed, set according to your system */
285  void * stream_user_data; /* !< user defined data that will be available in your callback stream functions */
286  void * websocket_handle; /* !< handle for websocket extension */
287  void * shared_data; /* !< any data shared between callback functions, must be allocated and freed by the callback functions */
288  void (* free_shared_data)(void * shared_data); /* !< pointer to a function that will free shared_data */
289  unsigned int timeout; /* !< Timeout in seconds to close the connection because of inactivity between the client and the server */
290 };
291 
298 struct _u_endpoint {
299  char * http_method; /* !< http verb (GET, POST, PUT, etc.) in upper case */
300  char * url_prefix; /* !< prefix for the url (optional) */
301  char * url_format; /* !< string used to define the endpoint format, separate words with / to define a variable in the url, prefix it with @ or :, example: /test/resource/:name/elements, on an url_format that ends with '*', the rest of the url will not be tested */
302  unsigned int priority; /* !< endpoint priority in descending order (0 is the higher priority) */
303  int (* callback_function)(const struct _u_request * request, /* !< pointer to a function that will be executed each time the endpoint is called, you must declare the function as described. */
304  struct _u_response * response,
305  void * user_data);
306  void * user_data; /* !< pointer to a data or a structure that will be available in callback_function */
307 };
308 
315 struct _u_instance {
316  struct MHD_Daemon * mhd_daemon; /* !< pointer to the libmicrohttpd daemon */
317  int status; /* !< status of the current instance, status are U_STATUS_STOP, U_STATUS_RUNNING or U_STATUS_ERROR */
318  unsigned int port; /* !< port number to listen to */
319 #if MHD_VERSION >= 0x00095208
320  unsigned short network_type; /* !< Listen to ipv4 and or ipv6 connections, values available are U_USE_ALL, U_USE_IPV4 or U_USE_IPV6 */
321 #endif
322  struct sockaddr_in * bind_address; /* !< ipv4 address to listen to (optional) */
323  struct sockaddr_in6 * bind_address6; /* !< ipv6 address to listen to (optional) */
324  unsigned int timeout; /* !< Timeout to close the connection because of inactivity between the client and the server */
325  int nb_endpoints; /* !< Number of available endpoints */
326  char * default_auth_realm; /* !< Default realm on authentication error */
327  struct _u_endpoint * endpoint_list; /* !< List of available endpoints */
328  struct _u_endpoint * default_endpoint; /* !< Default endpoint if no other endpoint match the current url */
329  struct _u_map * default_headers; /* !< Default headers that will be added to all response->map_header */
330  size_t max_post_param_size; /* !< maximum size for a post parameter, 0 means no limit, default 0 */
331  size_t max_post_body_size; /* !< maximum size for the entire post body, 0 means no limit, default 0 */
332  void * websocket_handler; /* !< handler for the websocket structure */
333  int (* file_upload_callback) (const struct _u_request * request, /* !< callback function to manage file upload by blocks */
334  const char * key,
335  const char * filename,
336  const char * content_type,
337  const char * transfer_encoding,
338  const char * data,
339  uint64_t off,
340  size_t size,
341  void * cls);
342  void * file_upload_cls; /* !< any pointer to pass to the file_upload_callback function */
343  int mhd_response_copy_data; /* !< to choose between MHD_RESPMEM_MUST_COPY and MHD_RESPMEM_MUST_FREE, only if you use MHD < 0.9.61, otherwise this option is skipped because it's useless */
344  int check_utf8; /* !< check that all parameters values in the request (url, header and post_body), are valid utf8 strings, if a parameter value has non utf8 character, the value, will be ignored, default 1 */
345 #ifndef U_DISABLE_GNUTLS
346  int use_client_cert_auth; /* !< Internal variable use to indicate if the instance uses client certificate authentication, Do not change this value, available only if websocket support is enabled */
347 #endif
348  int allowed_post_processor; /* !< Specifies which content-type are allowed to process in the request->map_post_body parameters list, default value is U_POST_PROCESS_URL_ENCODED|U_POST_PROCESS_MULTIPART_FORMDATA, to disable all, use U_POST_PROCESS_NONE */
349 };
350 
360  struct MHD_PostProcessor * post_processor;
363  struct _u_request * request;
365  struct _u_map map_url_initial;
366 };
367 
368 /**********************************
369  * Instance functions declarations
370  **********************************/
371 
382 void u_free(void * data);
383 
391 int ulfius_global_init(void);
392 
396 void ulfius_global_close(void);
397 
419 int ulfius_init_instance(struct _u_instance * u_instance, unsigned int port, struct sockaddr_in * bind_address, const char * default_auth_realm);
420 
421 #if MHD_VERSION >= 0x00095208
433 int ulfius_init_instance_ipv6(struct _u_instance * u_instance, unsigned int port, struct sockaddr_in6 * bind_address, unsigned short network_type, const char * default_auth_realm);
434 #endif
435 
442 void ulfius_clean_instance(struct _u_instance * u_instance);
443 
451 int ulfius_start_framework(struct _u_instance * u_instance);
452 
462 int ulfius_start_secure_framework(struct _u_instance * u_instance, const char * key_pem, const char * cert_pem);
463 
464 #ifndef U_DISABLE_GNUTLS
476 int ulfius_start_secure_ca_trust_framework(struct _u_instance * u_instance, const char * key_pem, const char * cert_pem, const char * root_ca_pem);
477 #endif
478 
497 int ulfius_start_framework_with_mhd_options(struct _u_instance * u_instance, unsigned int mhd_flags, struct MHD_OptionItem * options);
498 
502 void mhd_request_completed (void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe);
503 void * ulfius_uri_logger (void * cls, const char * uri);
504 
512 int ulfius_stop_framework(struct _u_instance * u_instance);
513 
535  int (* file_upload_callback) (const struct _u_request * request,
536  const char * key,
537  const char * filename,
538  const char * content_type,
539  const char * transfer_encoding,
540  const char * data,
541  uint64_t off,
542  size_t size,
543  void * cls),
544  void * cls);
545 
556 /***********************************
557  * Endpoints functions declarations
558  ***********************************/
559 
567 int ulfius_add_endpoint(struct _u_instance * u_instance, const struct _u_endpoint * u_endpoint);
568 
586 int ulfius_add_endpoint_by_val(struct _u_instance * u_instance,
587  const char * http_method,
588  const char * url_prefix,
589  const char * url_format,
590  unsigned int priority,
591  int (* callback_function)(const struct _u_request * request, // Input parameters (set by the framework)
592  struct _u_response * response, // Output parameters (set by the user)
593  void * user_data),
594  void * user_data);
595 
603 int ulfius_add_endpoint_list(struct _u_instance * u_instance, const struct _u_endpoint ** u_endpoint_list);
604 
614 int ulfius_remove_endpoint(struct _u_instance * u_instance, const struct _u_endpoint * u_endpoint);
615 
627 int ulfius_set_default_endpoint(struct _u_instance * u_instance,
628  int (* callback_function)(const struct _u_request * request, struct _u_response * response, void * user_data),
629  void * user_data);
630 
643 int ulfius_remove_endpoint_by_val(struct _u_instance * u_instance, const char * http_method, const char * url_prefix, const char * url_format);
644 
649 const struct _u_endpoint * ulfius_empty_endpoint(void);
650 
658 int ulfius_copy_endpoint(struct _u_endpoint * dest, const struct _u_endpoint * source);
659 
667 struct _u_endpoint * ulfius_duplicate_endpoint_list(const struct _u_endpoint * endpoint_list);
668 
674 void ulfius_clean_endpoint(struct _u_endpoint * endpoint);
675 
681 void ulfius_clean_endpoint_list(struct _u_endpoint * endpoint_list);
682 
690 int ulfius_equals_endpoints(const struct _u_endpoint * endpoint1, const struct _u_endpoint * endpoint2);
691 
702 #ifndef U_DISABLE_CURL
703 /********************************************
704  * Requests/Responses functions declarations
705  ********************************************/
706 
714 int ulfius_send_http_request(const struct _u_request * request, struct _u_response * response);
715 
726 int ulfius_send_http_streaming_request(const struct _u_request * request, struct _u_response * response, size_t (* write_body_function)(void * contents, size_t size, size_t nmemb, void * user_data), void * write_body_data);
727 
746 int ulfius_send_smtp_email(const char * host,
747  const int port,
748  const int use_tls,
749  const int verify_certificate,
750  const char * user,
751  const char * password,
752  const char * from,
753  const char * to,
754  const char * cc,
755  const char * bcc,
756  const char * subject,
757  const char * mail_body);
758 
778 int ulfius_send_smtp_rich_email(const char * host,
779  const int port,
780  const int use_tls,
781  const int verify_certificate,
782  const char * user,
783  const char * password,
784  const char * from,
785  const char * to,
786  const char * cc,
787  const char * bcc,
788  const char * content_type,
789  const char * subject,
790  const char * mail_body);
791 #endif
792 
817 int ulfius_add_cookie_to_response(struct _u_response * response, const char * key, const char * value, const char * expires, const unsigned int max_age,
818  const char * domain, const char * path, const int secure, const int http_only);
819 
838 int ulfius_add_same_site_cookie_to_response(struct _u_response * response, const char * key, const char * value, const char * expires, const unsigned int max_age,
839  const char * domain, const char * path, const int secure, const int http_only, const int same_site);
840 
859 int ulfius_add_header_to_response(struct _u_response * response, const char * key, const char * value);
860 
868 int ulfius_set_string_body_request(struct _u_request * request, const char * string_body);
869 
878 int ulfius_set_binary_body_request(struct _u_request * request, const char * binary_body, const size_t length);
879 
886 int ulfius_set_empty_body_request(struct _u_request * request);
887 
896 int ulfius_set_string_body_response(struct _u_response * response, const unsigned int status, const char * body);
897 
907 int ulfius_set_binary_body_response(struct _u_response * response, const unsigned int status, const char * body, const size_t length);
908 
916 int ulfius_set_empty_body_response(struct _u_response * response, const unsigned int status);
917 
940 int ulfius_set_stream_response(struct _u_response * response,
941  const unsigned int status,
942  ssize_t (* stream_callback) (void * stream_user_data, uint64_t offset, char * out_buf, size_t max),
943  void (* stream_callback_free) (void * stream_user_data),
944  uint64_t stream_size,
945  size_t stream_block_size,
946  void * stream_user_data);
947 
964 int ulfius_init_request(struct _u_request * request);
965 
974 int ulfius_clean_request(struct _u_request * request);
975 
982 int ulfius_clean_request_full(struct _u_request * request);
983 
991 int ulfius_copy_request(struct _u_request * dest, const struct _u_request * source);
992 
998 int ulfius_set_request_properties(struct _u_request * request, ...);
999 
1006 struct _u_request * ulfius_duplicate_request(const struct _u_request * request);
1007 
1025 char * ulfius_export_request_http(const struct _u_request * request);
1026 
1032 int ulfius_init_response(struct _u_response * response);
1033 
1042 int ulfius_clean_response(struct _u_response * response);
1043 
1049 int ulfius_clean_response_full(struct _u_response * response);
1050 
1057 int ulfius_copy_response(struct _u_response * dest, const struct _u_response * source);
1058 
1065 int ulfius_clean_cookie(struct _u_cookie * cookie);
1066 
1073 int ulfius_copy_cookie(struct _u_cookie * dest, const struct _u_cookie * source);
1074 
1081 struct _u_response * ulfius_duplicate_response(const struct _u_response * response);
1082 
1088 int ulfius_set_response_properties(struct _u_response * response, ...);
1089 
1098 int ulfius_set_response_shared_data(struct _u_response * response, void * shared_data, void (* free_shared_data) (void * shared_data));
1099 
1122 char * ulfius_export_response_http(const struct _u_response * response);
1123 
1142 char * ulfius_url_decode(const char * str);
1143 
1152 char * ulfius_url_encode(const char * str);
1153 
1164 #ifndef U_DISABLE_JANSSON
1175 json_t * ulfius_get_json_body_request(const struct _u_request * request, json_error_t * json_error);
1176 
1184 int ulfius_set_json_body_request(struct _u_request * request, json_t * j_body);
1185 
1196 json_t * ulfius_get_json_body_response(struct _u_response * response, json_error_t * json_error);
1197 
1206 int ulfius_set_json_body_response(struct _u_response * response, const unsigned int status, const json_t * j_body);
1207 #endif
1208 
1219 /************************************************************************
1220  * _u_map declarations *
1221  * _u_map is a simple map structure that handles sets of key/value maps *
1222  ************************************************************************/
1223 
1230 int u_map_init(struct _u_map * u_map);
1231 
1237 int u_map_clean(struct _u_map * u_map);
1238 
1244 int u_map_clean_full(struct _u_map * u_map);
1245 
1251 int u_map_clean_enum(char ** array);
1252 
1258 const char ** u_map_enum_keys(const struct _u_map * u_map);
1259 
1265 const char ** u_map_enum_values(const struct _u_map * u_map);
1266 
1275 int u_map_has_key(const struct _u_map * u_map, const char * key);
1276 
1285 int u_map_has_value(const struct _u_map * u_map, const char * value);
1286 
1296 int u_map_has_value_binary(const struct _u_map * u_map, const char * value, size_t length);
1297 
1306 int u_map_has_key_case(const struct _u_map * u_map, const char * key);
1307 
1316 int u_map_has_value_case(const struct _u_map * u_map, const char * value);
1317 
1326 int u_map_put(struct _u_map * u_map, const char * key, const char * value);
1327 
1339 int u_map_put_binary(struct _u_map * u_map, const char * key, const char * value, uint64_t offset, size_t length);
1340 
1348 ssize_t u_map_get_length(const struct _u_map * u_map, const char * key);
1349 
1357 ssize_t u_map_get_case_length(const struct _u_map * u_map, const char * key);
1358 
1366 const char * u_map_get(const struct _u_map * u_map, const char * key);
1367 
1375 const char * u_map_get_case(const struct _u_map * u_map, const char * key);
1376 
1384 int u_map_remove_from_key(struct _u_map * u_map, const char * key);
1385 
1393 int u_map_remove_from_key_case(struct _u_map * u_map, const char * key);
1394 
1402 int u_map_remove_from_value(struct _u_map * u_map, const char * value);
1403 
1411 int u_map_remove_from_value_case(struct _u_map * u_map, const char * value);
1412 
1420 int u_map_remove_from_value_binary(struct _u_map * u_map, const char * key, size_t length);
1421 
1428 int u_map_remove_at(struct _u_map * u_map, const int index);
1429 
1436 struct _u_map * u_map_copy(const struct _u_map * source);
1437 
1445 int u_map_copy_into(struct _u_map * dest, const struct _u_map * source);
1446 
1453 int u_map_count(const struct _u_map * source);
1454 
1460 int u_map_empty(struct _u_map * u_map);
1461 
1472 #ifndef U_DISABLE_WEBSOCKET
1473 
1474 /**********************************
1475  * Websocket functions declarations
1476  **********************************/
1477 
1478 #define U_WEBSOCKET_USER_AGENT "Ulfius Websocket Client Framework"
1479 
1480 #define U_WEBSOCKET_MAGIC_STRING "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
1481 #define U_WEBSOCKET_UPGRADE_VALUE "websocket"
1482 #define U_WEBSOCKET_BAD_REQUEST_BODY "Error in websocket handshake, wrong parameters"
1483 #define U_WEBSOCKET_USEC_WAIT 50
1484 #define WEBSOCKET_MAX_CLOSE_TRY 10
1485 
1486 #define U_WEBSOCKET_BIT_FIN 0x80
1487 #define U_WEBSOCKET_MASK 0x80
1488 #define U_WEBSOCKET_LEN_MASK 0x7F
1489 #define U_WEBSOCKET_OPCODE_CONTINUE 0x00
1490 #define U_WEBSOCKET_OPCODE_TEXT 0x01
1491 #define U_WEBSOCKET_OPCODE_BINARY 0x02
1492 #define U_WEBSOCKET_OPCODE_CLOSE 0x08
1493 #define U_WEBSOCKET_OPCODE_PING 0x09
1494 #define U_WEBSOCKET_OPCODE_PONG 0x0A
1495 #define U_WEBSOCKET_OPCODE_CLOSED 0xFD
1496 #define U_WEBSOCKET_OPCODE_ERROR 0xFE
1497 #define U_WEBSOCKET_OPCODE_NONE 0xFF
1498 
1499 #define U_WEBSOCKET_NONE 0
1500 #define U_WEBSOCKET_SERVER 1
1501 #define U_WEBSOCKET_CLIENT 2
1502 
1503 #define U_WEBSOCKET_STATUS_OPEN 0
1504 #define U_WEBSOCKET_STATUS_CLOSE 1
1505 #define U_WEBSOCKET_STATUS_ERROR 2
1506 
1507 #define U_WEBSOCKET_RSV1 0x40
1508 #define U_WEBSOCKET_RSV2 0x20
1509 #define U_WEBSOCKET_RSV3 0x10
1510 
1511 #define WEBSOCKET_RESPONSE_HTTP 0x0001
1512 #define WEBSOCKET_RESPONSE_UPGRADE 0x0002
1513 #define WEBSOCKET_RESPONSE_CONNECTION 0x0004
1514 #define WEBSOCKET_RESPONSE_ACCEPT 0x0008
1515 #define WEBSOCKET_RESPONSE_PROTCOL 0x0010
1516 #define WEBSOCKET_RESPONSE_EXTENSION 0x0020
1517 
1518 #define WEBSOCKET_DEFLATE_CHUNK_SIZE 32768
1519 #define WEBSOCKET_DEFLATE_WINDOWS_BITS 15
1520 
1521 #define U_WEBSOCKET_KEEP_NONE 0x00
1522 #define U_WEBSOCKET_KEEP_INCOMING 0x01
1523 #define U_WEBSOCKET_KEEP_OUTCOMING 0x10
1524 
1528 struct _websocket_deflate_context {
1529  z_stream infstream;
1530  z_stream defstream;
1531  int deflate_mask;
1532  int inflate_mask;
1533  unsigned int server_no_context_takeover;
1534  unsigned int client_no_context_takeover;
1535  unsigned int server_max_window_bits;
1536  unsigned int client_max_window_bits;
1537 };
1538 
1543 struct _websocket_extension {
1544  char * extension_server;
1545  char * extension_client;
1546  uint8_t rsv;
1547  int (* websocket_extension_message_out_perform)(const uint8_t opcode,
1548  const uint64_t data_len_in,
1549  const char * data_in,
1550  uint64_t * data_len_out,
1551  char ** data_out,
1552  const uint64_t fragment_len,
1553  void * user_data,
1554  void * context);
1555  void * websocket_extension_message_out_perform_user_data;
1556  int (* websocket_extension_message_in_perform)(const uint8_t opcode,
1557  const uint64_t data_len_in,
1558  const char * data_in,
1559  uint64_t * data_len_out,
1560  char ** data_out,
1561  const uint64_t fragment_len,
1562  void * user_data,
1563  void * context);
1564  void * websocket_extension_message_in_perform_user_data;
1565  int (* websocket_extension_server_match)(const char * extension_client,
1566  const char ** extension_client_list,
1567  char ** extension_server,
1568  void * user_data,
1569  void ** context);
1570  void * websocket_extension_server_match_user_data;
1571  int (* websocket_extension_client_match)(const char * extension_server,
1572  void * user_data,
1573  void ** context);
1574  void * websocket_extension_client_match_user_data;
1575  void (* websocket_extension_free_context)(void * user_data,
1576  void * context);
1577  void * websocket_extension_free_context_user_data;
1578  int enabled;
1579  void * context;
1580 };
1581 
1588 struct _websocket_manager {
1589  struct _websocket_message_list * message_list_incoming; /* !< list of incoming messages */
1590  struct _websocket_message_list * message_list_outcoming; /* !< list of outcoming messages */
1591  int keep_messages; /* !< keep incoming and/or outcoming messages, flags available are U_WEBSOCKET_KEEP_INCOMING, U_WEBSOCKET_KEEP_OUTCOMING, U_WEBSOCKET_KEEP_NONE, default is U_WEBSOCKET_KEEP_INCOMING|U_WEBSOCKET_KEEP_OUTCOMING */
1592  int connected; /* !< flag to know if the websocket is connected or not */
1593  int ping_sent; /* !< flag to know if the websocket has sent a ping frame or not, before receiving a pong */
1594  int close_flag; /* !< flag to set before closing a websocket */
1595  MHD_socket mhd_sock; /* !< reference to libmicrohttpd's socket for websocket server */
1596  int tcp_sock; /* !< tcp socket for websocket client */
1597  int tls; /* !< set to 1 if the websocket is in a TLS socket */
1598  gnutls_session_t gnutls_session; /* !< GnuTLS session for websocket client */
1599  gnutls_certificate_credentials_t xcred; /* !< certificate credential used by GnuTLS */
1600  char * protocol; /* !< websocket protocol */
1601  char * extensions; /* !< websocket extension */
1602  pthread_mutex_t read_lock; /* !< mutex to read data in the socket */
1603  pthread_mutex_t write_lock; /* !< mutex to write data in the socket */
1604  pthread_mutex_t status_lock; /* !< mutex to broadcast new status */
1605  pthread_cond_t status_cond; /* !< condition to broadcast new status */
1606  struct pollfd fds_in;
1607  struct pollfd fds_out;
1608  int type;
1609  int rsv_expected;
1610  struct _pointer_list * websocket_extension_list;
1611 };
1612 
1618 struct _websocket_message {
1619  time_t datestamp; /* !< date stamp of the message */
1620  uint8_t rsv; /* !< flags RSV1-3 of the message */
1621  uint8_t opcode; /* !< opcode for the message (string or binary) */
1622  uint8_t has_mask; /* !< does the message contain a mask? */
1623  uint8_t mask[4]; /* !< mask used if any */
1624  size_t data_len; /* !< length of the data */
1625  char * data; /* !< message data */
1626  size_t fragment_len; /* !< length of the fragment, 0 if not fragmented */
1627  uint8_t fin; /* !< flag fin (end of fragmented message) */
1628 };
1629 
1633 struct _websocket_message_list {
1634  struct _websocket_message ** list; /* !< messages list */
1635  size_t len; /* !< message list length */
1636 };
1637 
1642 struct _websocket {
1643  struct _u_instance * instance; /* !< reference to the ulfius instance if any */
1644  struct _u_request * request; /* !< refrence to the ulfius request of any */
1645  void (* websocket_manager_callback) (const struct _u_request * request, /* !< reference to a function called after the websocket handshake */
1646  struct _websocket_manager * websocket_manager,
1647  void * websocket_manager_user_data);
1648  void * websocket_manager_user_data; /* !< a user-defined reference that will be available in websocket_manager_callback */
1649  void (* websocket_incoming_message_callback) (const struct _u_request * request, /* !< reference to a function called each time a message arrives */
1650  struct _websocket_manager * websocket_manager,
1651  const struct _websocket_message * message,
1652  void * websocket_incoming_user_data);
1653  void * websocket_incoming_user_data; /* !< a user-defined reference that will be available in websocket_incoming_message_callback */
1654  void (* websocket_onclose_callback) (const struct _u_request * request, /* !< reference to a function called after the websocket connection ends */
1655  struct _websocket_manager * websocket_manager,
1656  void * websocket_onclose_user_data);
1657  void * websocket_onclose_user_data; /* !< a user-defined reference that will be available in websocket_onclose_callback */
1658  struct _websocket_manager * websocket_manager; /* !< refrence to the websocket manager if any */
1659  struct MHD_UpgradeResponseHandle * urh; /* !< reference used by libmicrohttpd to upgrade the connection */
1660 };
1661 
1665 struct _websocket_client_handler {
1666  struct _websocket * websocket; /* !< the websocket to use */
1667  struct _u_response * response; /* !< the response attached to the websocket */
1668 };
1669 
1670 /********************************/
1672 /********************************/
1673 
1683 int ulfius_websocket_send_message(struct _websocket_manager * websocket_manager,
1684  const uint8_t opcode,
1685  const uint64_t data_len,
1686  const char * data);
1687 
1699 int ulfius_websocket_send_fragmented_message(struct _websocket_manager * websocket_manager,
1700  const uint8_t opcode,
1701  const uint64_t data_len,
1702  const char * data,
1703  const uint64_t fragment_len);
1704 
1711 #ifndef U_DISABLE_JANSSON
1712 int ulfius_websocket_send_json_message(struct _websocket_manager * websocket_manager,
1713  json_t * message);
1714 #endif
1715 
1725 struct _websocket_message * ulfius_websocket_pop_first_message(struct _websocket_message_list * message_list);
1726 
1731 void ulfius_clear_websocket_message(struct _websocket_message * message);
1732 
1733 /********************************/
1735 /********************************/
1736 
1751 int ulfius_set_websocket_response(struct _u_response * response,
1752  const char * websocket_protocol,
1753  const char * websocket_extensions,
1754  void (* websocket_manager_callback) (const struct _u_request * request,
1755  struct _websocket_manager * websocket_manager,
1756  void * websocket_manager_user_data),
1757  void * websocket_manager_user_data,
1758  void (* websocket_incoming_message_callback) (const struct _u_request * request,
1759  struct _websocket_manager * websocket_manager,
1760  const struct _websocket_message * message,
1761  void * websocket_incoming_user_data),
1762  void * websocket_incoming_user_data,
1763  void (* websocket_onclose_callback) (const struct _u_request * request,
1764  struct _websocket_manager * websocket_manager,
1765  void * websocket_onclose_user_data),
1766  void * websocket_onclose_user_data);
1767 
1785  const char * extension_server,
1786  uint8_t rsv,
1787  int (* websocket_extension_message_out_perform)(const uint8_t opcode,
1788  const uint64_t data_len_in,
1789  const char * data_in,
1790  uint64_t * data_len_out,
1791  char ** data_out,
1792  const uint64_t fragment_len,
1793  void * user_data,
1794  void * context),
1795  void * websocket_extension_message_out_perform_user_data,
1796  int (* websocket_extension_message_in_perform)(const uint8_t opcode,
1797  const uint64_t data_len_in,
1798  const char * data_in,
1799  uint64_t * data_len_out,
1800  char ** data_out,
1801  const uint64_t fragment_len,
1802  void * user_data,
1803  void * context),
1804  void * websocket_extension_message_in_perform_user_data,
1805  int (* websocket_extension_server_match)(const char * extension_client,
1806  const char ** extension_client_list,
1807  char ** extension_server,
1808  void * user_data,
1809  void ** context),
1810  void * websocket_extension_server_match_user_data,
1811  void (* websocket_extension_free_context)(void * user_data,
1812  void * context),
1813  void * websocket_extension_free_context_user_data);
1814 
1829 int websocket_extension_message_out_deflate(const uint8_t opcode,
1830  const uint64_t data_len_in,
1831  const char * data_in,
1832  uint64_t * data_len_out,
1833  char ** data_out,
1834  const uint64_t fragment_len,
1835  void * user_data,
1836  void * context);
1837 
1851 int websocket_extension_message_in_inflate(const uint8_t opcode,
1852  const uint64_t data_len_in,
1853  const char * data_in,
1854  uint64_t * data_len_out,
1855  char ** data_out,
1856  const uint64_t fragment_len,
1857  void * user_data,
1858  void * context);
1859 
1866 void websocket_extension_deflate_free_context(void * user_data, void * context);
1867 
1877 int websocket_extension_server_match_deflate(const char * extension_client, const char ** extension_client_list, char ** extension_server, void * user_data, void ** context);
1878 
1888 
1898 int ulfius_websocket_send_close_signal(struct _websocket_manager * websocket_manager);
1899 
1907 int ulfius_websocket_status(struct _websocket_manager * websocket_manager);
1908 
1917 int ulfius_websocket_wait_close(struct _websocket_manager * websocket_manager, unsigned int timeout);
1918 
1919 /********************************/
1921 /********************************/
1922 
1937  void (* websocket_manager_callback) (const struct _u_request * request,
1938  struct _websocket_manager * websocket_manager,
1939  void * websocket_manager_user_data),
1940  void * websocket_manager_user_data,
1941  void (* websocket_incoming_message_callback) (const struct _u_request * request,
1942  struct _websocket_manager * websocket_manager,
1943  const struct _websocket_message * message,
1944  void * websocket_incoming_user_data),
1945  void * websocket_incoming_user_data,
1946  void (* websocket_onclose_callback) (const struct _u_request * request,
1947  struct _websocket_manager * websocket_manager,
1948  void * websocket_onclose_user_data),
1949  void * websocket_onclose_user_data,
1950  struct _websocket_client_handler * websocket_client_handler,
1951  struct _u_response * response);
1952 
1968 int ulfius_add_websocket_client_extension_message_perform(struct _websocket_client_handler * websocket_client_handler,
1969  const char * extension,
1970  uint8_t rsv,
1971  int (* websocket_extension_message_out_perform)(const uint8_t opcode,
1972  const uint64_t data_len_in,
1973  const char * data_in,
1974  uint64_t * data_len_out,
1975  char ** data_out,
1976  const uint64_t fragment_len,
1977  void * user_data,
1978  void * context),
1979  void * websocket_extension_message_out_perform_user_data,
1980  int (* websocket_extension_message_in_perform)(const uint8_t opcode,
1981  const uint64_t data_len_in,
1982  const char * data_in,
1983  uint64_t * data_len_out,
1984  char ** data_out,
1985  const uint64_t fragment_len,
1986  void * user_data,
1987  void * context),
1988  void * websocket_extension_message_in_perform_user_data,
1989  int (* websocket_extension_client_match)(const char * extension_server,
1990  void * user_data,
1991  void ** context),
1992  void * websocket_extension_client_match_user_data,
1993  void (* websocket_extension_free_context)(void * user_data,
1994  void * context),
1995  void * websocket_extension_free_context_user_data);
1996 
2004 int websocket_extension_client_match_deflate(const char * extension_server, void * user_data, void ** context);
2005 
2013 int ulfius_add_websocket_client_deflate_extension(struct _websocket_client_handler * websocket_client_handler);
2014 
2020 int ulfius_websocket_client_connection_send_close_signal(struct _websocket_client_handler * websocket_client_handler);
2021 
2027 int ulfius_websocket_client_connection_close(struct _websocket_client_handler * websocket_client_handler);
2028 
2035 int ulfius_websocket_client_connection_status(struct _websocket_client_handler * websocket_client_handler);
2036 
2045 int ulfius_websocket_client_connection_wait_close(struct _websocket_client_handler * websocket_client_handler, unsigned int timeout);
2046 
2056 int ulfius_set_websocket_request(struct _u_request * request,
2057  const char * url,
2058  const char * websocket_protocol,
2059  const char * websocket_extensions);
2060 
2061 #endif
2062 
2064 #define ULFIUS_URL_SEPARATOR "/"
2065 #define ULFIUS_HTTP_ENCODING_JSON "application/json"
2066 #define ULFIUS_HTTP_HEADER_CONTENT "Content-Type"
2067 #define ULFIUS_HTTP_NOT_FOUND_BODY "Resource not found"
2068 #define ULFIUS_HTTP_ERROR_BODY "Server Error"
2069 
2070 #define ULFIUS_COOKIE_ATTRIBUTE_EXPIRES "Expires"
2071 #define ULFIUS_COOKIE_ATTRIBUTE_MAX_AGE "Max-Age"
2072 #define ULFIUS_COOKIE_ATTRIBUTE_DOMAIN "Domain"
2073 #define ULFIUS_COOKIE_ATTRIBUTE_PATH "Path"
2074 #define ULFIUS_COOKIE_ATTRIBUTE_SECURE "Secure"
2075 #define ULFIUS_COOKIE_ATTRIBUTE_HTTPONLY "HttpOnly"
2076 
2077 #define ULFIUS_POSTBUFFERSIZE 65536
2078 
2079 #define U_STATUS_STOP 0
2080 #define U_STATUS_RUNNING 1
2081 #define U_STATUS_ERROR 2
2082 
2083 #ifndef U_DISABLE_WEBSOCKET
2084 
2088 struct _websocket_handle {
2089  char * websocket_protocol; /* !< protocol for the websocket */
2090  char * websocket_extensions; /* !< extensions for the websocket */
2091  void (* websocket_manager_callback) (const struct _u_request * request, /* !< callback function for working with the websocket */
2092  struct _websocket_manager * websocket_manager,
2093  void * websocket_manager_user_data);
2094  void * websocket_manager_user_data; /* !< user-defined data that will be handled to websocket_manager_callback */
2095  void (* websocket_incoming_message_callback) (const struct _u_request * request, /* !< callback function that will be called every time a message arrives from the client in the websocket */
2096  struct _websocket_manager * websocket_manager,
2097  const struct _websocket_message * message,
2098  void * websocket_incoming_user_data);
2099  void * websocket_incoming_user_data; /* !< user-defined data that will be handled to websocket_incoming_message_callback */
2100  void (* websocket_onclose_callback) (const struct _u_request * request, /* !< callback function that will be called if the websocket is open while the program calls ulfius_stop_framework */
2101  struct _websocket_manager * websocket_manager,
2102  void * websocket_onclose_user_data);
2103  void * websocket_onclose_user_data; /* !< user-defined data that will be handled to websocket_onclose_callback */
2104  int rsv_expected;
2105  struct _pointer_list * websocket_extension_list;
2106 };
2107 
2111 struct _websocket_handler {
2112  pthread_mutex_t websocket_active_lock; /* !< mutex to change nb_websocket_active value */
2113  size_t nb_websocket_active; /* !< number of active websocket */
2114  struct _websocket ** websocket_active; /* !< array of active websocket */
2115  pthread_mutex_t websocket_close_lock; /* !< mutex to broadcast close signal */
2116  pthread_cond_t websocket_close_cond; /* !< condition to broadcast close signal */
2117  int pthread_init;
2118 };
2119 
2120 #endif // U_DISABLE_WEBSOCKET
2121 
2132 #ifndef U_DISABLE_GNUTLS
2140 char * ulfius_export_client_certificate_pem(const struct _u_request * request);
2141 
2149 int ulfius_import_client_certificate_pem(struct _u_request * request, const char * str_cert);
2150 
2151 #endif // U_DISABLE_GNUTLS
2152 
2157 #ifdef __cplusplus
2158 }
2159 #endif
2160 
2161 #endif // __ULFIUS_H__
char * ulfius_export_client_certificate_pem(const struct _u_request *request)
Definition: u_request.c:1052
int ulfius_import_client_certificate_pem(struct _u_request *request, const char *str_cert)
Definition: u_request.c:1076
u_option
Definition: ulfius.h:144
@ U_OPT_POST_BODY_PARAMETER_REMOVE
Remove from map containing the post body variables (if available), expected option value type: const ...
Definition: ulfius.h:169
@ U_OPT_CHECK_PROXY_CERTIFICATE
check proxy certificate and hostname, default true, used by ulfius_send_http_request,...
Definition: ulfius.h:154
@ U_OPT_CLIENT_KEY_PASSWORD
password to unlock client key file, available only if GnuTLS support is enabled, expected option valu...
Definition: ulfius.h:178
@ U_OPT_STATUS
HTTP response status code (200, 404, 500, etc), expected option value type: long.
Definition: ulfius.h:180
@ U_OPT_FOLLOW_REDIRECT
follow url redirections, used by ulfius_send_http_request, expected option value type: int
Definition: ulfius.h:156
@ U_OPT_COOKIE_PARAMETER
Add to the map containing the cookie variables, expected option value type: const char *,...
Definition: ulfius.h:164
@ U_OPT_TIMEOUT
connection timeout used by ulfius_send_http_request, default is 0 or Timeout in seconds to close the ...
Definition: ulfius.h:158
@ U_OPT_AUTH_BASIC_USER
basic authentication username, expected option value type: const char *
Definition: ulfius.h:159
@ U_OPT_CA_PATH
specify a path to CA certificates instead of system path, used by ulfius_send_http_request,...
Definition: ulfius.h:157
@ U_OPT_AUTH_REALM
realm to send to the client response on authenticationb failed, expected option value type: const cha...
Definition: ulfius.h:181
@ U_OPT_HTTP_URL
full url used to call this callback function or full url to call when used in a ulfius_send_http_requ...
Definition: ulfius.h:147
@ U_OPT_HEADER_PARAMETER_REMOVE
Remove from map containing the header variables, expected option value type: const char *.
Definition: ulfius.h:167
@ U_OPT_CLIENT_CERT_FILE
path to client certificate file for sending http requests with certificate authentication,...
Definition: ulfius.h:176
@ U_OPT_CLIENT_KEY_FILE
path to client key file for sending http requests with certificate authentication,...
Definition: ulfius.h:177
@ U_OPT_JSON_BODY
Set a stringified json_t * body to the request or the reponse, expected option value type: json_t *.
Definition: ulfius.h:173
@ U_OPT_HTTP_PROXY
proxy address to use for outgoing connections, used by ulfius_send_http_request, expected option valu...
Definition: ulfius.h:148
@ U_OPT_COOKIE_PARAMETER_REMOVE
Remove from map containing the cookie variables, expected option value type: const char *.
Definition: ulfius.h:168
@ U_OPT_HTTP_VERB
http method (GET, POST, PUT, DELETE, etc.), expected option value type: const char *
Definition: ulfius.h:146
@ U_OPT_NONE
Empty option to complete a ulfius_set_request_properties or ulfius_set_request_properties.
Definition: ulfius.h:145
@ U_OPT_BINARY_BODY
Set a raw body to the request or the reponse, expected option value type: const char *,...
Definition: ulfius.h:170
@ U_OPT_AUTH_BASIC_PASSWORD
basic authentication password, expected option value type: const char *
Definition: ulfius.h:160
@ U_OPT_SHARED_DATA
any data shared between callback functions, must be allocated and freed by the callback functions,...
Definition: ulfius.h:182
@ U_OPT_URL_PARAMETER_REMOVE
Remove from the map containing the url variables, both from the route and the ?key=value variables,...
Definition: ulfius.h:166
@ U_OPT_CHECK_SERVER_CERTIFICATE
check server certificate and hostname, default true, used by ulfius_send_http_request,...
Definition: ulfius.h:152
@ U_OPT_POST_BODY_PARAMETER
Add to the map containing the post body variables (if available), expected option value type: const c...
Definition: ulfius.h:165
@ U_OPT_CHECK_PROXY_CERTIFICATE_FLAG
check certificate peer and or proxy hostname if check_proxy_certificate is enabled,...
Definition: ulfius.h:155
@ U_OPT_STRING_BODY
Set a char * body to the request or the reponse, expected option value type: const char *.
Definition: ulfius.h:171
@ U_OPT_URL_PARAMETER
Add to the map containing the url variables, both from the route and the ?key=value variables,...
Definition: ulfius.h:162
@ U_OPT_HEADER_PARAMETER
Add to the map containing the header variables, expected option value type: const char *,...
Definition: ulfius.h:163
@ U_OPT_AUTH_BASIC
basic authentication user, then password, expected option value type: const char *,...
Definition: ulfius.h:161
@ U_OPT_HTTP_URL_APPEND
append char * value to the current url, expected option value type: const char *
Definition: ulfius.h:183
@ U_OPT_CHECK_SERVER_CERTIFICATE_FLAG
check certificate peer and or server hostname if check_server_certificate is enabled,...
Definition: ulfius.h:153
void ulfius_clean_endpoint_list(struct _u_endpoint *endpoint_list)
Definition: ulfius.c:1407
int ulfius_add_endpoint_list(struct _u_instance *u_instance, const struct _u_endpoint **u_endpoint_list)
Definition: ulfius.c:1458
int ulfius_add_endpoint(struct _u_instance *u_instance, const struct _u_endpoint *u_endpoint)
Definition: ulfius.c:1418
int ulfius_remove_endpoint(struct _u_instance *u_instance, const struct _u_endpoint *u_endpoint)
Definition: ulfius.c:1475
int ulfius_copy_endpoint(struct _u_endpoint *dest, const struct _u_endpoint *source)
Definition: ulfius.c:1349
int ulfius_remove_endpoint_by_val(struct _u_instance *u_instance, const char *http_method, const char *url_prefix, const char *url_format)
Definition: ulfius.c:1581
int ulfius_add_endpoint_by_val(struct _u_instance *u_instance, const char *http_method, const char *url_prefix, const char *url_format, unsigned int priority, int(*callback_function)(const struct _u_request *request, struct _u_response *response, void *user_data), void *user_data)
Definition: ulfius.c:1558
const struct _u_endpoint * ulfius_empty_endpoint(void)
Definition: ulfius.c:1529
int ulfius_equals_endpoints(const struct _u_endpoint *endpoint1, const struct _u_endpoint *endpoint2)
Definition: ulfius.c:1540
int ulfius_set_default_endpoint(struct _u_instance *u_instance, int(*callback_function)(const struct _u_request *request, struct _u_response *response, void *user_data), void *user_data)
Definition: ulfius.c:1594
struct _u_endpoint * ulfius_duplicate_endpoint_list(const struct _u_endpoint *endpoint_list)
Definition: ulfius.c:1371
void ulfius_clean_endpoint(struct _u_endpoint *endpoint)
Definition: ulfius.c:1392
int ulfius_send_smtp_email(const char *host, const int port, const int use_tls, const int verify_certificate, const char *user, const char *password, const char *from, const char *to, const char *cc, const char *bcc, const char *subject, const char *mail_body)
Definition: u_send_request.c:912
int ulfius_send_http_streaming_request(const struct _u_request *request, struct _u_response *response, size_t(*write_body_function)(void *contents, size_t size, size_t nmemb, void *user_data), void *write_body_data)
Definition: u_send_request.c:194
int ulfius_send_smtp_rich_email(const char *host, const int port, const int use_tls, const int verify_certificate, const char *user, const char *password, const char *from, const char *to, const char *cc, const char *bcc, const char *content_type, const char *subject, const char *mail_body)
Definition: u_send_request.c:709
int ulfius_send_http_request(const struct _u_request *request, struct _u_response *response)
Definition: u_send_request.c:162
void mhd_request_completed(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: ulfius.c:308
int ulfius_init_instance(struct _u_instance *u_instance, unsigned int port, struct sockaddr_in *bind_address, const char *default_auth_realm)
Definition: ulfius.c:1744
void * ulfius_uri_logger(void *cls, const char *uri)
Definition: ulfius.c:208
void ulfius_clean_instance(struct _u_instance *u_instance)
Definition: ulfius.c:1637
int ulfius_stop_framework(struct _u_instance *u_instance)
Definition: ulfius.c:1314
int ulfius_start_secure_ca_trust_framework(struct _u_instance *u_instance, const char *key_pem, const char *cert_pem, const char *root_ca_pem)
Definition: ulfius.c:1227
int ulfius_start_framework(struct _u_instance *u_instance)
Definition: ulfius.c:1161
int ulfius_start_framework_with_mhd_options(struct _u_instance *u_instance, unsigned int mhd_flags, struct MHD_OptionItem *options)
Definition: ulfius.c:1287
int ulfius_start_secure_framework(struct _u_instance *u_instance, const char *key_pem, const char *cert_pem)
Definition: ulfius.c:1178
int ulfius_set_upload_file_callback_function(struct _u_instance *u_instance, int(*file_upload_callback)(const struct _u_request *request, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size, void *cls), void *cls)
Definition: ulfius.c:1617
void ulfius_global_close(void)
Definition: ulfius.c:1942
int ulfius_global_init(void)
Definition: ulfius.c:1918
void u_free(void *data)
Definition: ulfius.c:1758
int ulfius_add_header_to_response(struct _u_response *response, const char *key, const char *value)
Definition: u_response.c:710
int ulfius_set_empty_body_request(struct _u_request *request)
Definition: u_request.c:787
int ulfius_set_string_body_response(struct _u_response *response, const unsigned int status, const char *body)
Definition: u_response.c:509
int ulfius_set_string_body_request(struct _u_request *request, const char *string_body)
Definition: u_request.c:740
int ulfius_set_binary_body_response(struct _u_response *response, const unsigned int status, const char *body, const size_t length)
Definition: u_response.c:527
int ulfius_set_binary_body_request(struct _u_request *request, const char *binary_body, const size_t length)
Definition: u_request.c:762
int ulfius_set_empty_body_response(struct _u_response *response, const unsigned int status)
Definition: u_response.c:548
int ulfius_set_stream_response(struct _u_response *response, const unsigned int status, ssize_t(*stream_callback)(void *stream_user_data, uint64_t offset, char *out_buf, size_t max), void(*stream_callback_free)(void *stream_user_data), uint64_t stream_size, size_t stream_block_size, void *stream_user_data)
Definition: u_response.c:562
int u_map_init(struct _u_map *u_map)
Definition: u_map.c:32
int u_map_remove_from_value_binary(struct _u_map *u_map, const char *key, size_t length)
Definition: u_map.c:288
int u_map_remove_from_key(struct _u_map *u_map, const char *key)
Definition: u_map.c:238
int u_map_clean(struct _u_map *u_map)
Definition: u_map.c:65
int u_map_remove_at(struct _u_map *u_map, const int index)
Definition: u_map.c:334
int u_map_remove_from_value_case(struct _u_map *u_map, const char *value)
Definition: u_map.c:311
struct _u_map * u_map_copy(const struct _u_map *source)
Definition: u_map.c:453
ssize_t u_map_get_case_length(const struct _u_map *u_map, const char *key)
Definition: u_map.c:439
const char * u_map_get(const struct _u_map *u_map, const char *key)
Definition: u_map.c:369
int u_map_remove_from_key_case(struct _u_map *u_map, const char *key)
Definition: u_map.c:261
int u_map_has_value(const struct _u_map *u_map, const char *value)
Definition: u_map.c:124
int u_map_has_value_case(const struct _u_map *u_map, const char *value)
Definition: u_map.c:399
int u_map_clean_enum(char **array)
Definition: u_map.c:90
int u_map_clean_full(struct _u_map *u_map)
Definition: u_map.c:81
const char ** u_map_enum_keys(const struct _u_map *u_map)
Definition: u_map.c:104
int u_map_has_key_case(const struct _u_map *u_map, const char *key)
Definition: u_map.c:387
ssize_t u_map_get_length(const struct _u_map *u_map, const char *key)
Definition: u_map.c:425
int u_map_empty(struct _u_map *u_map)
Definition: u_map.c:508
int u_map_copy_into(struct _u_map *dest, const struct _u_map *source)
Definition: u_map.c:481
int u_map_put(struct _u_map *u_map, const char *key, const char *value)
Definition: u_map.c:140
int u_map_has_value_binary(const struct _u_map *u_map, const char *value, size_t length)
Definition: u_map.c:128
const char ** u_map_enum_values(const struct _u_map *u_map)
Definition: u_map.c:108
int u_map_has_key(const struct _u_map *u_map, const char *key)
Definition: u_map.c:112
int u_map_remove_from_value(struct _u_map *u_map, const char *value)
Definition: u_map.c:284
int u_map_put_binary(struct _u_map *u_map, const char *key, const char *value, uint64_t offset, size_t length)
Definition: u_map.c:148
int u_map_count(const struct _u_map *source)
Definition: u_map.c:499
const char * u_map_get_case(const struct _u_map *u_map, const char *key)
Definition: u_map.c:411
char * ulfius_url_encode(const char *str)
Definition: ulfius.c:1855
char * ulfius_url_decode(const char *str)
Definition: ulfius.c:1889
Contains all informations needed for an endpoint.
Definition: ulfius.h:298
int(* callback_function)(const struct _u_request *request, struct _u_response *response, void *user_data)
Definition: ulfius.h:303
void * user_data
Definition: ulfius.h:306
unsigned int priority
Definition: ulfius.h:302
char * http_method
Definition: ulfius.h:299
char * url_format
Definition: ulfius.h:301
char * url_prefix
Definition: ulfius.h:300
Contains the needed data for an ulfius instance to work.
Definition: ulfius.h:315
int status
Definition: ulfius.h:317
size_t max_post_param_size
Definition: ulfius.h:330
struct MHD_Daemon * mhd_daemon
Definition: ulfius.h:316
int allowed_post_processor
Definition: ulfius.h:348
unsigned int port
Definition: ulfius.h:318
unsigned int timeout
Definition: ulfius.h:324
size_t max_post_body_size
Definition: ulfius.h:331
struct sockaddr_in * bind_address
Definition: ulfius.h:322
void * file_upload_cls
Definition: ulfius.h:342
struct _u_map * default_headers
Definition: ulfius.h:329
int check_utf8
Definition: ulfius.h:344
struct sockaddr_in6 * bind_address6
Definition: ulfius.h:323
struct _u_endpoint * endpoint_list
Definition: ulfius.h:327
int nb_endpoints
Definition: ulfius.h:325
struct _u_endpoint * default_endpoint
Definition: ulfius.h:328
void * websocket_handler
Definition: ulfius.h:332
int(* file_upload_callback)(const struct _u_request *request, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size, void *cls)
Definition: ulfius.h:333
char * default_auth_realm
Definition: ulfius.h:326
int mhd_response_copy_data
Definition: ulfius.h:343
int use_client_cert_auth
Definition: ulfius.h:346
Definition: ulfius.h:203
int nb_values
Definition: ulfius.h:204
size_t * lengths
Definition: ulfius.h:207
char ** keys
Definition: ulfius.h:205
char ** values
Definition: ulfius.h:206
definition of the parameters available in a struct _u_request
Definition: ulfius.h:232
unsigned long timeout
Definition: ulfius.h:247
int check_server_certificate_flag
Definition: ulfius.h:242
int follow_redirect
Definition: ulfius.h:245
char * auth_basic_password
Definition: ulfius.h:250
char * http_protocol
Definition: ulfius.h:233
int check_proxy_certificate_flag
Definition: ulfius.h:244
char * client_key_password
Definition: ulfius.h:262
void * binary_body
Definition: ulfius.h:255
gnutls_x509_crt_t client_cert
Definition: ulfius.h:259
struct _u_map * map_cookie
Definition: ulfius.h:253
size_t binary_body_length
Definition: ulfius.h:256
struct _u_map * map_header
Definition: ulfius.h:252
int check_server_certificate
Definition: ulfius.h:241
struct sockaddr * client_address
Definition: ulfius.h:248
char * ca_path
Definition: ulfius.h:246
struct _u_map * map_post_body
Definition: ulfius.h:254
int check_proxy_certificate
Definition: ulfius.h:243
char * client_key_file
Definition: ulfius.h:261
char * url_path
Definition: ulfius.h:236
char * auth_basic_user
Definition: ulfius.h:249
char * http_verb
Definition: ulfius.h:234
unsigned int callback_position
Definition: ulfius.h:257
char * proxy
Definition: ulfius.h:237
char * http_url
Definition: ulfius.h:235
struct _u_map * map_url
Definition: ulfius.h:251
char * client_cert_file
Definition: ulfius.h:260
definition of the parameters available in a struct _u_response
Definition: ulfius.h:272
char * protocol
Definition: ulfius.h:274
size_t stream_block_size
Definition: ulfius.h:284
void * stream_user_data
Definition: ulfius.h:285
ssize_t(* stream_callback)(void *stream_user_data, uint64_t offset, char *out_buf, size_t max)
Definition: ulfius.h:281
void * websocket_handle
Definition: ulfius.h:286
uint64_t stream_size
Definition: ulfius.h:283
size_t binary_body_length
Definition: ulfius.h:280
struct _u_map * map_header
Definition: ulfius.h:275
long status
Definition: ulfius.h:273
unsigned int nb_cookies
Definition: ulfius.h:276
unsigned int timeout
Definition: ulfius.h:289
struct _u_cookie * map_cookie
Definition: ulfius.h:277
char * auth_realm
Definition: ulfius.h:278
void(* stream_callback_free)(void *stream_user_data)
Definition: ulfius.h:282
void(* free_shared_data)(void *shared_data)
Definition: ulfius.h:288
void * binary_body
Definition: ulfius.h:279
void * shared_data
Definition: ulfius.h:287
Definition: ulfius.h:358
struct _u_request * request
Definition: ulfius.h:363
struct _u_map map_url_initial
Definition: ulfius.h:365
struct _u_instance * u_instance
Definition: ulfius.h:359
size_t max_post_param_size
Definition: ulfius.h:364
struct MHD_PostProcessor * post_processor
Definition: ulfius.h:360
int callback_first_iteration
Definition: ulfius.h:362
int has_post_processor
Definition: ulfius.h:361
int websocket_extension_message_in_inflate(const uint8_t opcode, const uint64_t data_len_in, const char *data_in, uint64_t *data_len_out, char **data_out, const uint64_t fragment_len, void *user_data, void *context)
Definition: u_websocket.c:1970
int ulfius_add_websocket_extension_message_perform(struct _u_response *response, const char *extension_server, uint8_t rsv, int(*websocket_extension_message_out_perform)(const uint8_t opcode, const uint64_t data_len_in, const char *data_in, uint64_t *data_len_out, char **data_out, const uint64_t fragment_len, void *user_data, void *context), void *websocket_extension_message_out_perform_user_data, int(*websocket_extension_message_in_perform)(const uint8_t opcode, const uint64_t data_len_in, const char *data_in, uint64_t *data_len_out, char **data_out, const uint64_t fragment_len, void *user_data, void *context), void *websocket_extension_message_in_perform_user_data, int(*websocket_extension_server_match)(const char *extension_client, const char **extension_client_list, char **extension_server, void *user_data, void **context), void *websocket_extension_server_match_user_data, void(*websocket_extension_free_context)(void *user_data, void *context), void *websocket_extension_free_context_user_data)
Definition: u_websocket.c:1811
int ulfius_websocket_client_connection_send_close_signal(struct _websocket_client_handler *websocket_client_handler)
Definition: u_websocket.c:2678
int ulfius_websocket_send_close_signal(struct _websocket_manager *websocket_manager)
Definition: u_websocket.c:2208
int ulfius_websocket_send_json_message(struct _websocket_manager *websocket_manager, json_t *message)
Definition: u_websocket.c:1557
int websocket_extension_server_match_deflate(const char *extension_client, const char **extension_client_list, char **extension_server, void *user_data, void **context)
Definition: u_websocket.c:2048
int ulfius_add_websocket_client_deflate_extension(struct _websocket_client_handler *websocket_client_handler)
Definition: u_websocket.c:2669
int ulfius_websocket_client_connection_wait_close(struct _websocket_client_handler *websocket_client_handler, unsigned int timeout)
Definition: u_websocket.c:2732
int ulfius_add_websocket_client_extension_message_perform(struct _websocket_client_handler *websocket_client_handler, const char *extension, uint8_t rsv, int(*websocket_extension_message_out_perform)(const uint8_t opcode, const uint64_t data_len_in, const char *data_in, uint64_t *data_len_out, char **data_out, const uint64_t fragment_len, void *user_data, void *context), void *websocket_extension_message_out_perform_user_data, int(*websocket_extension_message_in_perform)(const uint8_t opcode, const uint64_t data_len_in, const char *data_in, uint64_t *data_len_out, char **data_out, const uint64_t fragment_len, void *user_data, void *context), void *websocket_extension_message_in_perform_user_data, int(*websocket_extension_client_match)(const char *extension_server, void *user_data, void **context), void *websocket_extension_client_match_user_data, void(*websocket_extension_free_context)(void *user_data, void *context), void *websocket_extension_free_context_user_data)
Definition: u_websocket.c:2353
int ulfius_websocket_client_connection_status(struct _websocket_client_handler *websocket_client_handler)
Definition: u_websocket.c:2718
int ulfius_websocket_wait_close(struct _websocket_manager *websocket_manager, unsigned int timeout)
Definition: u_websocket.c:2237
int ulfius_websocket_status(struct _websocket_manager *websocket_manager)
Definition: u_websocket.c:2223
int ulfius_open_websocket_client_connection(struct _u_request *request, void(*websocket_manager_callback)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_manager_user_data), void *websocket_manager_user_data, void(*websocket_incoming_message_callback)(const struct _u_request *request, struct _websocket_manager *websocket_manager, const struct _websocket_message *message, void *websocket_incoming_user_data), void *websocket_incoming_user_data, void(*websocket_onclose_callback)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_onclose_user_data), void *websocket_onclose_user_data, struct _websocket_client_handler *websocket_client_handler, struct _u_response *response)
Definition: u_websocket.c:2439
int websocket_extension_message_out_deflate(const uint8_t opcode, const uint64_t data_len_in, const char *data_in, uint64_t *data_len_out, char **data_out, const uint64_t fragment_len, void *user_data, void *context)
Definition: u_websocket.c:1880
int ulfius_set_websocket_response(struct _u_response *response, const char *websocket_protocol, const char *websocket_extensions, void(*websocket_manager_callback)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_manager_user_data), void *websocket_manager_user_data, void(*websocket_incoming_message_callback)(const struct _u_request *request, struct _websocket_manager *websocket_manager, const struct _websocket_message *message, void *websocket_incoming_user_data), void *websocket_incoming_user_data, void(*websocket_onclose_callback)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_onclose_user_data), void *websocket_onclose_user_data)
Definition: u_websocket.c:1764
int ulfius_add_websocket_deflate_extension(struct _u_response *response)
Definition: u_websocket.c:2196
void websocket_extension_deflate_free_context(void *user_data, void *context)
Definition: u_websocket.c:2189
int ulfius_websocket_client_connection_close(struct _websocket_client_handler *websocket_client_handler)
Definition: u_websocket.c:2691
int ulfius_set_websocket_request(struct _u_request *request, const char *url, const char *websocket_protocol, const char *websocket_extensions)
Definition: u_websocket.c:2315
int ulfius_websocket_send_message(struct _websocket_manager *websocket_manager, const uint8_t opcode, const uint64_t data_len, const char *data)
Definition: u_websocket.c:1545
int ulfius_websocket_send_fragmented_message(struct _websocket_manager *websocket_manager, const uint8_t opcode, const uint64_t data_len, const char *data, const uint64_t fragment_len)
Definition: u_websocket.c:1451
struct _websocket_message * ulfius_websocket_pop_first_message(struct _websocket_message_list *message_list)
Definition: u_websocket.c:1571
int websocket_extension_client_match_deflate(const char *extension_server, void *user_data, void **context)
Definition: u_websocket.c:2558
void ulfius_clear_websocket_message(struct _websocket_message *message)
Definition: u_websocket.c:1593