#ifndef RAWHTTPS_H #define RAWHTTPS_H #include typedef enum { HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_DELETE, HTTP_TRACE, HTTP_OPTIONS, HTTP_CONNECT, HTTP_PATCH } rawhttps_method; typedef struct { void* elements; long long capacity; long long element_size; } rawhttps_hash_table; typedef struct { rawhttps_hash_table ht; } rawhttps_header; // Struct received in the handler callback used to fetch information about the HTTP request. // method: http method (duh) // data: this is a pointer to the raw HTTP request data. You don't need to directly access this field // uri: the received URI, also known as the endpoint... // uri_size: size of the uri in bytes // header: all received headers. Please use the function rawhttp_header_get to retrieve the headers, since this is actually a hash table // connected_socket: connection socket's file descriptor, managed internally by rawhttp typedef struct { rawhttps_method method; const char* data; const char* uri; long long uri_size; rawhttps_header header; int connected_socket; } rawhttps_request; typedef struct { const char* header; long long header_size; const char* value; long long value_size; } rawhttps_response_header; // Struct received in the handler callback used to set information about the HTTP response you want to send. // headers: all response headers. Use the function rawhttp_response_add_header to add new headers here. // headers_size: size of headers, used internally by rawhttp // headers_capacity: capacity of headers, used internally by rawhttp // response_content: a pointer to the response body. You need to set this field before calling rawhttp_response_flush! // response_content_size: size, in bytes, of response_content. You also need to set this field before calling rawhttp_response_flush! // status_code: response's status code. Default value is 200, feel free to change it. typedef struct { rawhttps_response_header* headers; long long headers_size; long long headers_capacity; char* response_content; long long response_content_size; int status_code; } rawhttps_response; // This is the callback function you must implement for each handler you register. All action happens inside this function. // Use rawhttp_server_register_handle to register a new handler. // connection: used internally by rawhttp. You just need to forward this parameter to rawhttp_response_flush // request: has information about the HTTP request. See rawhttp_request struct for more details // response: allows you to set the HTTP response. See rawhttp_response struct for more details typedef void (*rawhttps_server_handle_func)(const void* connection, const rawhttps_request* request, rawhttps_response* response); typedef struct { rawhttps_server_handle_func handle; } rawhttps_server_handler; typedef struct { rawhttps_server_handler handler; int valid; int has_handler; int subtree_root; const char* pattern; long long pattern_size; long long next; long long child; } rawhttps_handler_tree_element; typedef struct { rawhttps_handler_tree_element* elements; long long num_elements; long long capacity; } rawhttps_handler_tree; typedef struct { int sockfd; int port; int initialized; rawhttps_handler_tree handlers; } rawhttps_server; typedef struct { const char* value; long long value_size; } rawhttps_header_value; typedef enum { RAWHTTPS_LOG_LEVEL_DISABLED = 0, RAWHTTPS_LOG_LEVEL_DEBUG = 1, RAWHTTPS_LOG_LEVEL_INFO = 2, RAWHTTPS_LOG_LEVEL_WARNING = 3, RAWHTTPS_LOG_LEVEL_ERROR = 4, } rawhttps_log_level; // Initializes rawhttps logging system. This function must be called to activate logging. // // level (input): Log level. void rawhttps_logger_init(rawhttps_log_level level); // Destroys rawhttps logging system. This function should only be called if rawhttps_logger_init was called before. void rawhttps_logger_destroy(); // Initializes a new rawhttp_server struct. This function will not start the server. // // server (input/output): Struct to be initialized. Must be provided. // port (input): The port that the server will use, when started // certificate_path (input): The path to the PEM certificate // private_key_path (input): The path to the PEM private key // Return value: 0 if success, -1 if error int rawhttps_server_init(rawhttps_server* server, int port, const char* certificate_path, const char* private_key_path); // Destroys an initialized rawhttp_server struct. If the server is listening, this function will also shutdown the server and release resources. // rawhttp_server_init must have been called before calling this function. // // server (input): Reference to the server to be destroyed // Return value: 0 if success, -1 if error int rawhttps_server_destroy(rawhttps_server* server); // Register a new handle. Must be called before calling rawhttp_server_listen. // The pattern defines how rawhttp will treat the handle. If the pattern ends with a slash (/), the handle will be called // regardless of what comes after the slash, unless there is a more specific handler registered. // If, however, the pattern doesn't end with a slash (/), the handle will only be called for its specific endpoint. // Example: if you register 3 handlers using these 3 different patterns: // #1: /bar // #2: /foo/ // #3: /foo/bar // Then, the following endpoint calls will invoke the following handlers: // your-server:80/bar -> invokes #1 (/bar) // your-server:80/bar/ -> no handler associated. // your-server:80/foo/ -> invokes #2 (/foo/) // your-server:80/foo/dummy -> invokes #2 (/foo/) // your-server:80/foo/bar -> invokes #3 (/foo/bar) // your-server:80/foo/bar/dummy -> invokes #2 (/foo/) // // server (input): Initialized rawhttp_server // pattern (input): The pattern to be registered. // pattern_size (input): The size, in bytes, of the pattern being registered // handle (input): The callback function that rawhttp will call when this handle is triggered int rawhttps_server_register_handle(rawhttps_server* server, const char* pattern, long long pattern_size, rawhttps_server_handle_func handle); // Starts listening for HTTP calls. This function is the one that opens the server // This function blocks! // If you are implementing a more 'serious' code, please consider creating a separate thread to call this function, and then // call rawhttp_server_destroy to shutdown the server when exiting // // server (input): Initialized rawhttp_server int rawhttps_server_listen(rawhttps_server* server); // Flushes the HTTP response to the client. // This function must ONLY be called inside the rawhttp_server_handle_func callback, which is registered via rawhttp_server_register_handle // Also, this function can only be called a single time, otherwise multiple HTTP packets will be sent. // You must set response->response_content before calling this function. This value will be used as the response body to the client. // Please also set response->response_content_size with the size of your content. // // _connection (input): the connection parameter received in the callback must be sent here. This is used internally by rawhttp. // response (input): struct containing the response information. It is also received in the callback. However, you should modify it. ssize_t rawhttps_response_flush(const void* _connection, rawhttps_response* response); // Add a new header to the HTTP response. // This function must ONLY be called inside the rawhttp_server_handle_func callback, which is registered via rawhttp_server_register_handle // You must call this function before rawhttp_response_flush // Please use this function to add headers. Do not modify the response struct directly // // response (input): struct containing the response information. It is received in the callback. // header (input): The new header name // header_size (input): Size of header name // value (input): Value of header // header_size (input): Size of the value of header void rawhttps_response_add_header(rawhttps_response* response, const char* header, long long header_size, const char* value, long long value_size); // Retrieve the value of a header received in the HTTP request // This function must ONLY be called inside the rawhttp_server_handle_func callback, which is registered via rawhttp_server_register_handle // // http_header (input): This field is accessible via request->header. The request struct is received as a parameter in the callback // header (input): The name of the header // header_size (input): The size of the name of the header const rawhttps_header_value* rawhttps_header_get(const rawhttps_header* http_header, const char* header, long long header_size); #endif