Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
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__