Ulfius
HTTP Framework for REST Applications in C
Macros | Functions
u_websocket.c File Reference
#include "u_private.h"
#include "ulfius.h"
#include "yuarel.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <gnutls/crypto.h>
#include <zlib.h>

Macros

#define STR_HELPER(x)   #x
 
#define STR(x)   STR_HELPER(x)
 
#define U_WEBSOCKET_DEFAULT_MEMORY_LEVEL   4
 
#define U_WEBSOCKET_DEFAULT_WINDOWS_BITS   15
 

Functions

void ulfius_free_websocket_extension_pointer_list (void *extension)
 
void ulfius_free_websocket_extension (struct _websocket_extension *websocket_extension)
 
int ulfius_init_websocket_extension (struct _websocket_extension *websocket_extension)
 
void ulfius_start_websocket_cb (void *cls, struct MHD_Connection *connection, void *con_cls, const char *extra_in, size_t extra_in_size, MHD_socket sock, struct MHD_UpgradeResponseHandle *urh)
 
int ulfius_check_handshake_response (const char *key, const char *response)
 
int ulfius_generate_handshake_answer (const char *key, char *out_digest)
 
int ulfius_init_websocket_message_list (struct _websocket_message_list *message_list)
 
int ulfius_push_websocket_message (struct _websocket_message_list *message_list, struct _websocket_message *message)
 
int ulfius_check_list_match (const char *source, const char *match, const char *separator, char **result)
 
int ulfius_check_first_match (const char *source, const char *match, const char *separator, char **result)
 
int ulfius_close_websocket (struct _websocket *websocket)
 
int ulfius_instance_add_websocket_active (struct _u_instance *instance, struct _websocket *websocket)
 
int ulfius_instance_remove_websocket_active (struct _u_instance *instance, struct _websocket *websocket)
 
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)
 
int ulfius_websocket_send_message (struct _websocket_manager *websocket_manager, const uint8_t opcode, const uint64_t data_len, const char *data)
 
int ulfius_websocket_send_json_message (struct _websocket_manager *websocket_manager, json_t *message)
 
struct _websocket_message * ulfius_websocket_pop_first_message (struct _websocket_message_list *message_list)
 
void ulfius_clear_websocket_message (struct _websocket_message *message)
 
int ulfius_clear_websocket (struct _websocket *websocket)
 
void ulfius_clear_websocket_message_list (struct _websocket_message_list *message_list)
 
int ulfius_init_websocket (struct _websocket *websocket)
 
int ulfius_init_websocket_manager (struct _websocket_manager *websocket_manager)
 
void ulfius_clear_websocket_manager (struct _websocket_manager *websocket_manager)
 
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)
 
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)
 
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)
 
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)
 
int websocket_extension_server_match_deflate (const char *extension_client, const char **extension_client_list, char **extension_server, void *user_data, void **context)
 
void websocket_extension_deflate_free_context (void *user_data, void *context)
 
int ulfius_add_websocket_deflate_extension (struct _u_response *response)
 
int ulfius_websocket_send_close_signal (struct _websocket_manager *websocket_manager)
 
int ulfius_websocket_status (struct _websocket_manager *websocket_manager)
 
int ulfius_websocket_wait_close (struct _websocket_manager *websocket_manager, unsigned int timeout)
 
int ulfius_set_websocket_request (struct _u_request *request, const char *url, const char *websocket_protocol, const char *websocket_extensions)
 
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)
 
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)
 
int websocket_extension_client_match_deflate (const char *extension_server, void *user_data, void **context)
 
int ulfius_add_websocket_client_deflate_extension (struct _websocket_client_handler *websocket_client_handler)
 
int ulfius_websocket_client_connection_send_close_signal (struct _websocket_client_handler *websocket_client_handler)
 
int ulfius_websocket_client_connection_close (struct _websocket_client_handler *websocket_client_handler)
 
int ulfius_websocket_client_connection_status (struct _websocket_client_handler *websocket_client_handler)
 
int ulfius_websocket_client_connection_wait_close (struct _websocket_client_handler *websocket_client_handler, unsigned int timeout)
 

Macro Definition Documentation

◆ STR_HELPER

#define STR_HELPER (   x)    #x

Ulfius Framework

REST framework library

u_websocket.c: websocket implementation

Copyright 2017-2020 Nicolas Mora mail@.nosp@m.babe.nosp@m.loues.nosp@m.t.or.nosp@m.g

This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 2.1 of the License.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU GENERAL PUBLIC LICENSE for more details.

You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses/.

◆ STR

#define STR (   x)    STR_HELPER(x)

◆ U_WEBSOCKET_DEFAULT_MEMORY_LEVEL

#define U_WEBSOCKET_DEFAULT_MEMORY_LEVEL   4

◆ U_WEBSOCKET_DEFAULT_WINDOWS_BITS

#define U_WEBSOCKET_DEFAULT_WINDOWS_BITS   15

Function Documentation

◆ ulfius_free_websocket_extension_pointer_list()

void ulfius_free_websocket_extension_pointer_list ( void *  extension)

Internal websocket functions

◆ ulfius_free_websocket_extension()

void ulfius_free_websocket_extension ( struct _websocket_extension *  websocket_extension)

◆ ulfius_init_websocket_extension()

int ulfius_init_websocket_extension ( struct _websocket_extension *  websocket_extension)

◆ ulfius_start_websocket_cb()

void ulfius_start_websocket_cb ( void *  cls,
struct MHD_Connection *  connection,
void *  con_cls,
const char *  extra_in,
size_t  extra_in_size,
MHD_socket  sock,
struct MHD_UpgradeResponseHandle *  urh 
)

Websocket callback function for MHD Starts the websocket manager if set,

◆ ulfius_check_handshake_response()

int ulfius_check_handshake_response ( const char *  key,
const char *  response 
)

Check if the response corresponds to the transformation of the key with the magic string

◆ ulfius_generate_handshake_answer()

int ulfius_generate_handshake_answer ( const char *  key,
char *  out_digest 
)

Generates a handhshake answer from the key given in parameter

◆ ulfius_init_websocket_message_list()

int ulfius_init_websocket_message_list ( struct _websocket_message_list *  message_list)

Initialize a websocket message list Return U_OK on success

◆ ulfius_push_websocket_message()

int ulfius_push_websocket_message ( struct _websocket_message_list *  message_list,
struct _websocket_message *  message 
)

Append a message in a message list Return U_OK on success

◆ ulfius_check_list_match()

int ulfius_check_list_match ( const char *  source,
const char *  match,
const char *  separator,
char **  result 
)

Return a match list between two list of items If match is NULL, then result will be NULL and returned value will be U_OK *result value must be u_free'd after use

◆ ulfius_check_first_match()

int ulfius_check_first_match ( const char *  source,
const char *  match,
const char *  separator,
char **  result 
)

Return the first match between two list of items If match is NULL, then return the first element of source Returned value must be u_free'd after use

◆ ulfius_close_websocket()

int ulfius_close_websocket ( struct _websocket *  websocket)

Close the websocket

◆ ulfius_instance_add_websocket_active()

int ulfius_instance_add_websocket_active ( struct _u_instance instance,
struct _websocket *  websocket 
)

Add a websocket in the list of active websockets of the instance

◆ ulfius_instance_remove_websocket_active()

int ulfius_instance_remove_websocket_active ( struct _u_instance instance,
struct _websocket *  websocket 
)

Remove a websocket from the list of active websockets of the instance

◆ ulfius_websocket_send_fragmented_message()

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 
)

Common websocket functions Send a fragmented message in the websocket each fragment size will be at most fragment_len Return U_OK on success

◆ ulfius_websocket_send_message()

int ulfius_websocket_send_message ( struct _websocket_manager *  websocket_manager,
const uint8_t  opcode,
const uint64_t  data_len,
const char *  data 
)

Send a message in the websocket Return U_OK on success

◆ ulfius_websocket_send_json_message()

int ulfius_websocket_send_json_message ( struct _websocket_manager *  websocket_manager,
json_t *  message 
)

Send a JSON message in the websocket Return U_OK on success

◆ ulfius_websocket_pop_first_message()

struct _websocket_message* ulfius_websocket_pop_first_message ( struct _websocket_message_list *  message_list)

Return the first message of the message list Return NULL if message_list has no message Returned value must be cleared after use

◆ ulfius_clear_websocket_message()

void ulfius_clear_websocket_message ( struct _websocket_message *  message)

Clear data of a websocket message

◆ ulfius_clear_websocket()

int ulfius_clear_websocket ( struct _websocket *  websocket)

Init/clear websocket functions Clear all data related to the websocket

◆ ulfius_clear_websocket_message_list()

void ulfius_clear_websocket_message_list ( struct _websocket_message_list *  message_list)

Clear data of a websocket message list

◆ ulfius_init_websocket()

int ulfius_init_websocket ( struct _websocket *  websocket)

Initialize a struct _websocket return U_OK on success

◆ ulfius_init_websocket_manager()

int ulfius_init_websocket_manager ( struct _websocket_manager *  websocket_manager)

Initialize a struct _websocket_manager return U_OK on success

◆ ulfius_clear_websocket_manager()

void ulfius_clear_websocket_manager ( struct _websocket_manager *  websocket_manager)

Clear data of a websocket_manager

◆ ulfius_set_websocket_response()

int ulfius_set_websocket_response ( struct _u_response response,
const char *  websocket_protocol,
const char *  websocket_extensions,
void(*)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_manager_user_data)  websocket_manager_callback,
void *  websocket_manager_user_data,
void(*)(const struct _u_request *request, struct _websocket_manager *websocket_manager, const struct _websocket_message *message, void *websocket_incoming_user_data)  websocket_incoming_message_callback,
void *  websocket_incoming_user_data,
void(*)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_onclose_user_data)  websocket_onclose_callback,
void *  websocket_onclose_user_data 
)

Server websocket functions

◆ ulfius_add_websocket_extension_message_perform()

int ulfius_add_websocket_extension_message_perform ( struct _u_response response,
const char *  extension_server,
uint8_t  rsv,
int(*)(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)  websocket_extension_message_out_perform,
void *  websocket_extension_message_out_perform_user_data,
int(*)(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)  websocket_extension_message_in_perform,
void *  websocket_extension_message_in_perform_user_data,
int(*)(const char *extension_client, const char **extension_client_list, char **extension_server, void *user_data, void **context)  websocket_extension_server_match,
void *  websocket_extension_server_match_user_data,
void(*)(void *user_data, void *context)  websocket_extension_free_context,
void *  websocket_extension_free_context_user_data 
)

◆ websocket_extension_message_out_deflate()

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 
)

◆ websocket_extension_message_in_inflate()

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 
)

◆ websocket_extension_server_match_deflate()

int websocket_extension_server_match_deflate ( const char *  extension_client,
const char **  extension_client_list,
char **  extension_server,
void *  user_data,
void **  context 
)

◆ websocket_extension_deflate_free_context()

void websocket_extension_deflate_free_context ( void *  user_data,
void *  context 
)

◆ ulfius_add_websocket_deflate_extension()

int ulfius_add_websocket_deflate_extension ( struct _u_response response)

◆ ulfius_websocket_send_close_signal()

int ulfius_websocket_send_close_signal ( struct _websocket_manager *  websocket_manager)

Sets the websocket in closing mode The websocket will not necessarily be closed at the return of this function, it will process through the end of the websocket_manager_callback and the websocket_onclose_callback calls first. return U_OK on success or U_ERROR on error

◆ ulfius_websocket_status()

int ulfius_websocket_status ( struct _websocket_manager *  websocket_manager)

Returns the status of the websocket connection Returned values can be U_WEBSOCKET_STATUS_OPEN or U_WEBSOCKET_STATUS_CLOSE wether the websocket is open or closed, or U_WEBSOCKET_STATUS_ERROR on error

◆ ulfius_websocket_wait_close()

int ulfius_websocket_wait_close ( struct _websocket_manager *  websocket_manager,
unsigned int  timeout 
)

Wait until the websocket connection is closed or the timeout in milliseconds is reached if timeout is 0, no timeout is set Returned values can be U_WEBSOCKET_STATUS_OPEN or U_WEBSOCKET_STATUS_CLOSE wether the websocket is open or closed, or U_WEBSOCKET_STATUS_ERROR on error

◆ ulfius_set_websocket_request()

int ulfius_set_websocket_request ( struct _u_request request,
const char *  url,
const char *  websocket_protocol,
const char *  websocket_extensions 
)

Set values for a struct _u_request to open a websocket request must be previously initialized Return U_OK on success

◆ ulfius_add_websocket_client_extension_message_perform()

int ulfius_add_websocket_client_extension_message_perform ( struct _websocket_client_handler *  websocket_client_handler,
const char *  extension,
uint8_t  rsv,
int(*)(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)  websocket_extension_message_out_perform,
void *  websocket_extension_message_out_perform_user_data,
int(*)(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)  websocket_extension_message_in_perform,
void *  websocket_extension_message_in_perform_user_data,
int(*)(const char *extension_server, void *user_data, void **context)  websocket_extension_client_match,
void *  websocket_extension_client_match_user_data,
void(*)(void *user_data, void *context)  websocket_extension_free_context,
void *  websocket_extension_free_context_user_data 
)

◆ ulfius_open_websocket_client_connection()

int ulfius_open_websocket_client_connection ( struct _u_request request,
void(*)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_manager_user_data)  websocket_manager_callback,
void *  websocket_manager_user_data,
void(*)(const struct _u_request *request, struct _websocket_manager *websocket_manager, const struct _websocket_message *message, void *websocket_incoming_user_data)  websocket_incoming_message_callback,
void *  websocket_incoming_user_data,
void(*)(const struct _u_request *request, struct _websocket_manager *websocket_manager, void *websocket_onclose_user_data)  websocket_onclose_callback,
void *  websocket_onclose_user_data,
struct _websocket_client_handler *  websocket_client_handler,
struct _u_response response 
)

Open a websocket client connection Return U_OK on success

◆ websocket_extension_client_match_deflate()

int websocket_extension_client_match_deflate ( const char *  extension_server,
void *  user_data,
void **  context 
)

◆ ulfius_add_websocket_client_deflate_extension()

int ulfius_add_websocket_client_deflate_extension ( struct _websocket_client_handler *  websocket_client_handler)

◆ ulfius_websocket_client_connection_send_close_signal()

int ulfius_websocket_client_connection_send_close_signal ( struct _websocket_client_handler *  websocket_client_handler)

Send a close signal to the websocket return U_OK when the signal is sent or U_ERROR on error

◆ ulfius_websocket_client_connection_close()

int ulfius_websocket_client_connection_close ( struct _websocket_client_handler *  websocket_client_handler)

Closes a websocket client connection return U_OK when the websocket is closed or U_ERROR on error

◆ ulfius_websocket_client_connection_status()

int ulfius_websocket_client_connection_status ( struct _websocket_client_handler *  websocket_client_handler)

Returns the status of the websocket client connection Returned values can be U_WEBSOCKET_STATUS_OPEN or U_WEBSOCKET_STATUS_CLOSE wether the websocket is open or closed, or U_WEBSOCKET_STATUS_ERROR on error

◆ ulfius_websocket_client_connection_wait_close()

int ulfius_websocket_client_connection_wait_close ( struct _websocket_client_handler *  websocket_client_handler,
unsigned int  timeout 
)

Wait until the websocket client connection is closed or the timeout in milliseconds is reached if timeout is 0, no timeout is set Returned values can be U_WEBSOCKET_STATUS_OPEN or U_WEBSOCKET_STATUS_CLOSE wether the websocket is open or closed, or U_WEBSOCKET_STATUS_ERROR on error