|
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@.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/.
| #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