Ulfius
HTTP Framework for REST Applications in C
|
#include <u_private.h>
#include <ulfius.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <gnutls/crypto.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
#include "yuarel.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 |
#define | U_WEBSOCKET_SEC_KEY_LEN 16 |
#define | U_WEBSOCKET_RESPONSE_BUFFER_LEN 4096 |
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 *j_message) |
json_t * | ulfius_websocket_parse_json_message (const struct _websocket_message *message, json_error_t *json_error) |
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) |
#define STR_HELPER | ( | x | ) | #x |
Ulfius Framework
REST framework library
u_websocket.c: websocket implementation
Copyright 2017-2022 Nicolas Mora mail@ babe loues t.or 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/.
#define STR | ( | x | ) | STR_HELPER(x) |
#define U_WEBSOCKET_DEFAULT_MEMORY_LEVEL 4 |
#define U_WEBSOCKET_DEFAULT_WINDOWS_BITS 15 |
#define U_WEBSOCKET_SEC_KEY_LEN 16 |
#define U_WEBSOCKET_RESPONSE_BUFFER_LEN 4096 |
void ulfius_free_websocket_extension_pointer_list | ( | void * | extension | ) |
Internal websocket functions
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 | ||
) |
Websocket callback function for MHD Starts the websocket manager if set,
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
int ulfius_generate_handshake_answer | ( | const char * | key, |
char * | out_digest | ||
) |
Generates a handhshake answer from the key given in parameter
int ulfius_init_websocket_message_list | ( | struct _websocket_message_list * | message_list | ) |
Initialize a websocket message list Return U_OK on success
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
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
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
int ulfius_close_websocket | ( | struct _websocket * | websocket | ) |
Close the websocket
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
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
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
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
int ulfius_websocket_send_json_message | ( | struct _websocket_manager * | websocket_manager, |
json_t * | j_message | ||
) |
Send a JSON message in the websocket Return U_OK on success
json_t* ulfius_websocket_parse_json_message | ( | const struct _websocket_message * | message, |
json_error_t * | json_error | ||
) |
Parses a websocket message into a JSON object if possible
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
void ulfius_clear_websocket_message | ( | struct _websocket_message * | message | ) |
Clear data of a websocket message
int ulfius_clear_websocket | ( | struct _websocket * | websocket | ) |
Init/clear websocket functions Clear all data related to the websocket
void ulfius_clear_websocket_message_list | ( | struct _websocket_message_list * | message_list | ) |
Clear data of a websocket message list
int ulfius_init_websocket | ( | struct _websocket * | websocket | ) |
Initialize a struct _websocket return U_OK on success
int ulfius_init_websocket_manager | ( | struct _websocket_manager * | websocket_manager | ) |
Initialize a struct _websocket_manager return U_OK on success
void ulfius_clear_websocket_manager | ( | struct _websocket_manager * | websocket_manager | ) |
Clear data of a websocket_manager
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
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 | ||
) |
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 | ) |
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
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
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
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
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 | ||
) |
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
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 | ) |
Send a close signal to the websocket return U_OK when the signal is sent or U_ERROR on error
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
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
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