Skip to content
Snippets Groups Projects
ulfius.h 46.2 KiB
Newer Older
                      const char *filename, const char *content_type,
                      const char *transfer_encoding, const char *data, uint64_t off,
                      size_t size);

/**
 * mhd_request_completed
 * function used to clean data allocated after a web call is complete
 */
void mhd_request_completed (void *cls, struct MHD_Connection *connection,
                        void **con_cls, enum MHD_RequestTerminationCode toe);

/**
 * ulfius_split_url
 * return an array of char based on the url words
 * returned value must be u_free'd after use
 */
char ** ulfius_split_url(const char * prefix, const char * url);

/**
 * Sort an array of struct _u_endpoint * using bubble sort algorithm
 */
void sort_endpoint_list (struct _u_endpoint ** endpoint_list, int length);

/**
 * ulfius_endpoint_match
 * return the endpoint array matching the url called with the proper http method
 * the returned array always has its last value to NULL
 * return NULL on memory error
 */
struct _u_endpoint ** ulfius_endpoint_match(const char * method, const char * url, struct _u_endpoint * endpoint_list);

/**
 * ulfius_url_format_match
 * return true if splitted_url matches splitted_url_format
 * false otherwise
 */
int ulfius_url_format_match(const char ** splitted_url, const char ** splitted_url_format);

/**
 * ulfius_parse_url
 * fills map with the keys/values defined in the url that are described in the endpoint format url
 * return U_OK on success
 */
int ulfius_parse_url(const char * url, const struct _u_endpoint * endpoint, struct _u_map * map);

/**
 * ulfius_set_response_header
 * adds headers defined in the response_map_header to the response
 * return the number of added headers, -1 on error
 */
int ulfius_set_response_header(struct MHD_Response * response, const struct _u_map * response_map_header);

/**
 * ulfius_set_response_cookie
 * adds cookies defined in the response_map_cookie
 * return the number of added headers, -1 on error
 */
int ulfius_set_response_cookie(struct MHD_Response * mhd_response, const struct _u_response * response);

/**
 * Add a cookie in the cookie map as defined in the RFC 6265
 * Returned value must be u_free'd after use
 */
char * ulfius_get_cookie_header(const struct _u_cookie * cookie);

/** Macro values **/
#define ULFIUS_URL_SEPARATOR       "/"
#define ULFIUS_HTTP_ENCODING_JSON  "application/json"
#define ULFIUS_HTTP_HEADER_CONTENT "Content-Type"
#define ULFIUS_HTTP_NOT_FOUND_BODY "Resource not found"
#define ULFIUS_HTTP_ERROR_BODY     "Server Error"

#define ULFIUS_COOKIE_ATTRIBUTE_EXPIRES  "Expires"
#define ULFIUS_COOKIE_ATTRIBUTE_MAX_AGE  "Max-Age"
#define ULFIUS_COOKIE_ATTRIBUTE_DOMAIN   "Domain"
#define ULFIUS_COOKIE_ATTRIBUTE_PATH     "Path"
#define ULFIUS_COOKIE_ATTRIBUTE_SECURE   "Secure"
#define ULFIUS_COOKIE_ATTRIBUTE_HTTPONLY "HttpOnly"

#define ULFIUS_POSTBUFFERSIZE 1024

#define U_STATUS_STOP     0
#define U_STATUS_RUNNING  1
#define U_STATUS_ERROR    2

#ifndef U_DISABLE_WEBSOCKET

/**
 * websocket_manager_callback:          callback function for working with the websocket
 * websocket_manager_user_data:         user-defined data that will be handled to websocket_manager_callback
 * websocket_incoming_message_callback: callback function that will be called every time a message arrives from the client in the websocket
 * websocket_incoming_user_data:        user-defined data that will be handled to websocket_incoming_message_callback
 * websocket_onclose_callback:          callback function that will be called if the websocket is open while the program calls ulfius_stop_framework
 * websocket_onclose_user_data:         user-defined data that will be handled to websocket_onclose_callback
 */
struct _websocket_handle {
  char             * websocket_protocol;
  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;
};

struct _websocket_handler {
  size_t                        nb_websocket_active;
  struct _websocket          ** websocket_active;
  pthread_mutex_t               websocket_close_lock;
  pthread_cond_t                websocket_close_cond;
  int                           pthread_init;
};

/**
 * Websocket callback function for MHD
 * Starts the websocket manager if set,
 * then sets a listening message loop
 * Complete the callback when the websocket is closed
 * The websocket can be closed by the client, the manager, the program, or on network disconnect
 */
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);

/**
 * Workaround to make sure a message, as long as it can be is complete sent
 */
void ulfius_websocket_send_all(MHD_socket sock, const uint8_t * data, size_t len);

/**
 * Centralise socket reading in this function
 * so if options or check must be done, it's done here instead of each read call
 */
size_t ulfius_websocket_recv_all(MHD_socket sock, uint8_t * data, size_t len);

/**
 * Generates a handhshake answer from the key given in parameter
 */
int ulfius_generate_handshake_answer(const char * key, char * out_digest);

/**
 * Close the websocket
 */
int ulfius_close_websocket(struct _websocket * websocket);

/**
 * Return a match list between two list of items
 * If match is NULL, then return source duplicate
 * Returned value must be u_free'd after use
 */
char * ulfius_check_list_match(const char * source, const char * match);

/**
 * Initialize a websocket message list
 * Return U_OK on success
 */
int ulfius_init_websocket_message_list(struct _websocket_message_list * message_list);

/**
 * Clear data of a websocket message list
 */
void ulfius_clear_websocket_message_list(struct _websocket_message_list * message_list);

/**
 * Append a message in a message list
 * Return U_OK on success
 */
int ulfius_push_websocket_message(struct _websocket_message_list * message_list, struct _websocket_message * message);

/**
 * Clear data of a websocket
 */
int ulfius_clear_websocket(struct _websocket * websocket);

/**
 * Clear data of a websocket_manager
 */
void ulfius_clear_websocket_manager(struct _websocket_manager * websocket_manager);

/**
 * Read and parse a new message from the websocket
 * Return the opcode of the new websocket, U_WEBSOCKET_OPCODE_NONE if no message arrived, or U_WEBSOCKET_OPCODE_ERROR on error
 * Sets the new message in the message variable if available
 */
int ulfius_read_incoming_message(struct _websocket_manager * websocket_manager, struct _websocket_message ** message);

/**
 * Run the websocket manager in a separated detached thread
 */
void * ulfius_thread_websocket_manager_run(void * args);

/**
 * Send a message in the websocket without lock
 * Return U_OK on success
 */
int ulfius_websocket_send_message_nolock(struct _websocket_manager * websocket_manager,
                                  const uint8_t opcode,
                                  const uint64_t data_len,
                                  const char * data);

 /**
 * Add a websocket in the list of active websockets of the instance
 */
int ulfius_instance_add_websocket_active(struct _u_instance * instance, struct _websocket * websocket);

/**
 * Remove a websocket from the list of active websockets of the instance
 */
int ulfius_instance_remove_websocket_active(struct _u_instance * instance, struct _websocket * websocket); 
#endif // U_DISABLE_WEBSOCKET

#endif // __ULFIUS_H__