2024-09-03 20:44:06 +00:00
|
|
|
#ifndef HTTP_PARSER_H
|
|
|
|
#define HTTP_PARSER_H
|
|
|
|
|
|
|
|
#include "llhttp.h"
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
#define HTTP_RESPONSE_HEADER_TEMPLATE "HTTP/1.1 %d %s\nContent-Length: %d\nContent-Type: %s; charset=utf-8\nConnection: close\n\n"
|
|
|
|
|
2024-09-03 20:44:06 +00:00
|
|
|
typedef struct HTTP_REQUEST_DATA_T_ {
|
2024-09-04 20:14:59 +00:00
|
|
|
llhttp_method_t method;
|
2024-09-03 20:44:06 +00:00
|
|
|
char url[128];
|
|
|
|
char body[128];
|
|
|
|
} HTTP_REQUEST_DATA_T;
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
typedef struct HTTP_REQUEST_PARSER_T_ {
|
2024-09-03 20:44:06 +00:00
|
|
|
llhttp_t parser;
|
|
|
|
llhttp_settings_t settings;
|
2024-09-04 20:14:59 +00:00
|
|
|
} HTTP_REQUEST_PARSER_T;
|
2024-09-03 20:44:06 +00:00
|
|
|
|
|
|
|
int request_parser_on_url(llhttp_t * parser, const char * start, size_t length) {
|
|
|
|
HTTP_REQUEST_DATA_T * http_request = parser->data;
|
|
|
|
strncat(http_request->url, start, length);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int request_parser_on_body(llhttp_t * parser, const char * start, size_t length) {
|
|
|
|
HTTP_REQUEST_DATA_T * http_request = parser->data;
|
|
|
|
strncat(http_request->body, start, length);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
int parse_http_request (HTTP_REQUEST_PARSER_T * wrapper, char * content, size_t len) {
|
2024-09-03 20:44:06 +00:00
|
|
|
llhttp_t parser = wrapper->parser;
|
|
|
|
|
|
|
|
llhttp_errno_t err = llhttp_execute(&parser, content, len);
|
|
|
|
HTTP_REQUEST_DATA_T * http_request = parser.data;
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
llhttp_method_t method = llhttp_get_method(&parser);
|
|
|
|
http_request->method = method;
|
2024-09-03 20:44:06 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
llhttp_method_t get_method (HTTP_REQUEST_PARSER_T * wrapper) {
|
2024-09-03 20:44:06 +00:00
|
|
|
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
|
|
|
return http_request->method;
|
|
|
|
}
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
char * get_url (HTTP_REQUEST_PARSER_T * wrapper) {
|
2024-09-03 20:44:06 +00:00
|
|
|
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
|
|
|
return http_request->url;
|
|
|
|
}
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
char * get_body (HTTP_REQUEST_PARSER_T * wrapper) {
|
2024-09-03 20:44:06 +00:00
|
|
|
HTTP_REQUEST_DATA_T * http_request = wrapper->parser.data;
|
|
|
|
return http_request->body;
|
|
|
|
}
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
HTTP_REQUEST_PARSER_T * new_request_parser () {
|
|
|
|
// create new response parser wrapper
|
|
|
|
HTTP_REQUEST_PARSER_T * wrapper = calloc(1, sizeof(HTTP_REQUEST_PARSER_T));
|
2024-09-03 20:44:06 +00:00
|
|
|
|
|
|
|
// create a new request data struct
|
|
|
|
HTTP_REQUEST_DATA_T * http_request = calloc(1, sizeof(HTTP_REQUEST_DATA_T));
|
|
|
|
|
|
|
|
// init http parser settings
|
|
|
|
llhttp_settings_init(&wrapper->settings);
|
|
|
|
wrapper->settings.on_url = &request_parser_on_url;
|
|
|
|
wrapper->settings.on_body = &request_parser_on_body;
|
|
|
|
|
|
|
|
// init http request parser parser
|
|
|
|
llhttp_init(&wrapper->parser, HTTP_REQUEST, &wrapper->settings);
|
|
|
|
wrapper->parser.data = http_request;
|
|
|
|
|
|
|
|
return wrapper;
|
|
|
|
}
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
void delete_request_parser (HTTP_REQUEST_PARSER_T * wrapper) {
|
2024-09-03 20:44:06 +00:00
|
|
|
free(wrapper->parser.data);
|
|
|
|
free(wrapper);
|
|
|
|
}
|
|
|
|
|
2024-09-04 20:14:59 +00:00
|
|
|
typedef struct HTTP_RESPONSE_DATA_T_ {
|
|
|
|
llhttp_status_t status;
|
|
|
|
char type[32];
|
|
|
|
char body[128];
|
|
|
|
} HTTP_RESPONSE_DATA_T;
|
|
|
|
|
|
|
|
typedef struct HTTP_RESPONSE_COMPOSER_T_ {
|
|
|
|
HTTP_RESPONSE_DATA_T * response_data;
|
|
|
|
char header[1024];
|
|
|
|
char body[128];
|
|
|
|
uint32_t header_length;
|
|
|
|
uint32_t content_length;
|
|
|
|
} HTTP_RESPONSE_COMPOSER_T;
|
|
|
|
|
|
|
|
void set_status (HTTP_RESPONSE_COMPOSER_T * composer, llhttp_status_t status) {
|
|
|
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
|
|
|
response_data->status = status;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_type (HTTP_RESPONSE_COMPOSER_T * composer, char * type) {
|
|
|
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
|
|
|
strncpy(response_data->type, type, 128);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_body (HTTP_RESPONSE_COMPOSER_T * composer, char * body) {
|
|
|
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
|
|
|
strncpy(response_data->body, body, 128);
|
|
|
|
}
|
|
|
|
|
|
|
|
void compose_http_response (HTTP_RESPONSE_COMPOSER_T * composer) {
|
|
|
|
HTTP_RESPONSE_DATA_T * response_data = composer->response_data;
|
|
|
|
|
|
|
|
composer->content_length = snprintf(composer->body, sizeof(composer->body), "%s", response_data->body);
|
|
|
|
|
|
|
|
const char * status_name = llhttp_status_name(response_data->status);
|
|
|
|
|
|
|
|
composer->header_length = snprintf(composer->header, sizeof(composer->header), HTTP_RESPONSE_HEADER_TEMPLATE, response_data->status, status_name, composer->content_length, response_data->type);
|
|
|
|
}
|
|
|
|
|
|
|
|
HTTP_RESPONSE_COMPOSER_T * new_response_composer () {
|
|
|
|
// create new response composer wrapper
|
|
|
|
HTTP_RESPONSE_COMPOSER_T * wrapper = calloc(1, sizeof(HTTP_RESPONSE_COMPOSER_T));
|
|
|
|
|
|
|
|
// create a new response data struct
|
|
|
|
HTTP_RESPONSE_DATA_T * http_response = calloc(1, sizeof(HTTP_RESPONSE_DATA_T));
|
|
|
|
|
|
|
|
wrapper->response_data = http_response;
|
|
|
|
|
|
|
|
return wrapper;
|
|
|
|
}
|
|
|
|
|
|
|
|
void delete_response_composer (HTTP_RESPONSE_COMPOSER_T * composer) {
|
|
|
|
free(composer->response_data);
|
|
|
|
free(composer);
|
|
|
|
}
|
|
|
|
|
2024-09-03 20:44:06 +00:00
|
|
|
int http_parser_init () {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int http_parser_deinit () {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|