feat: new file management utility, splitted http into http and http headers, new string function (to_lowercase) + other small things
This commit is contained in:
parent
573e53ef79
commit
5236d71e7e
9 changed files with 269 additions and 67 deletions
|
|
@ -9,10 +9,12 @@ ASAN_DBG_FLAGS = -fsanitize=address
|
||||||
UTILS_SRCS = src/utils/string/string.c \
|
UTILS_SRCS = src/utils/string/string.c \
|
||||||
src/utils/time/fmt_time.c \
|
src/utils/time/fmt_time.c \
|
||||||
src/utils/parsing/words.c \
|
src/utils/parsing/words.c \
|
||||||
src/utils/parsing/blanks.c
|
src/utils/parsing/blanks.c \
|
||||||
|
utils/files/files.c
|
||||||
MODULES_SRCS = src/config/config.c \
|
MODULES_SRCS = src/config/config.c \
|
||||||
src/server/server.c \
|
src/server/server.c \
|
||||||
src/http/http.c \
|
src/http/http.c \
|
||||||
|
src/http/headers.c \
|
||||||
src/logger/logs.c \
|
src/logger/logs.c \
|
||||||
src/logger/errors.c
|
src/logger/errors.c
|
||||||
SRCS = $(UTILS_SRCS) \
|
SRCS = $(UTILS_SRCS) \
|
||||||
|
|
|
||||||
86
httpd/src/http/headers.c
Normal file
86
httpd/src/http/headers.c
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "../utils/parsing/words.h"
|
||||||
|
|
||||||
|
void destroy_headers(struct http_header *headers)
|
||||||
|
{
|
||||||
|
while (headers != NULL)
|
||||||
|
{
|
||||||
|
struct http_header *next = headers->next;
|
||||||
|
free(headers);
|
||||||
|
headers = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t read_field(struct string *str, size_t offset, struct string **res)
|
||||||
|
{
|
||||||
|
ssize_t nread = read_word_delim(str, offset, res, ":\n");
|
||||||
|
if (nread <= 0)
|
||||||
|
return ERR_HTTP_INVALID_INPUT;
|
||||||
|
|
||||||
|
if (str->size <= offset + nread || str->data[offset + nread] != ':')
|
||||||
|
return ERR_HTTP_INVALID_INPUT;
|
||||||
|
|
||||||
|
string_to_lowercase(*res);
|
||||||
|
|
||||||
|
return nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t read_value(struct string *str, size_t offset, struct string **res)
|
||||||
|
{
|
||||||
|
ssize_t nread = read_word_delim(str, offset, res, "\n");
|
||||||
|
if (nread <= 0)
|
||||||
|
return ERR_HTTP_INVALID_INPUT;
|
||||||
|
|
||||||
|
if (str->size <= offset + nread || str->data[offset + nread] != '\n')
|
||||||
|
return ERR_HTTP_INVALID_INPUT;
|
||||||
|
|
||||||
|
return nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t parse_headers(struct http_request *res, struct string *req,
|
||||||
|
size_t offset)
|
||||||
|
{
|
||||||
|
size_t i = offset;
|
||||||
|
struct http_header *header = NULL;
|
||||||
|
|
||||||
|
// Yes I know I do one useless allocation but I really don't care at this
|
||||||
|
// point
|
||||||
|
while (req->data[i] != '\n') // ! Blank line
|
||||||
|
{
|
||||||
|
if (header == NULL)
|
||||||
|
{
|
||||||
|
// Init list
|
||||||
|
header = calloc(1, sizeof(struct http_header));
|
||||||
|
res->headers = header;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Append
|
||||||
|
header->next = calloc(1, sizeof(struct http_header));
|
||||||
|
header = header->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check allocation
|
||||||
|
if (header == NULL)
|
||||||
|
return ERR_HTTP_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
// Read field
|
||||||
|
ssize_t nread = read_field(req, offset, &header->field);
|
||||||
|
if (nread <= 0)
|
||||||
|
return nread; // Contains error code when negative
|
||||||
|
|
||||||
|
i += nread;
|
||||||
|
|
||||||
|
// Read value
|
||||||
|
nread = read_value(req, offset, &header->value);
|
||||||
|
if (nread <= 0)
|
||||||
|
return nread; // Contains error code when negative
|
||||||
|
|
||||||
|
i += nread + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
62
httpd/src/http/headers.h
Normal file
62
httpd/src/http/headers.h
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef HEADERS_H
|
||||||
|
#define HEADERS_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "http.h"
|
||||||
|
|
||||||
|
// === Functions
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param headers
|
||||||
|
*/
|
||||||
|
void destroy_headers(struct http_header *headers);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* @param offset
|
||||||
|
* @param res
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ssize_t read_field(struct string *str, size_t offset, struct string **res);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* @param offset
|
||||||
|
* @param res
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ssize_t read_value(struct string *str, size_t offset, struct string **res);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param res
|
||||||
|
* @param req
|
||||||
|
* @param offset
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ssize_t parse_headers(struct http_request *res, struct string *req,
|
||||||
|
size_t offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param headers
|
||||||
|
* @param field
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
struct http_header* get_header(struct http_header *headers, const char* field);
|
||||||
|
|
||||||
|
#endif // ! HEADERS_H
|
||||||
|
|
@ -5,45 +5,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../utils/parsing/words.h"
|
#include "../utils/parsing/words.h"
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
// === Static functions
|
// === Static functions
|
||||||
|
|
||||||
static void destroy_headers(struct http_header *headers)
|
|
||||||
{
|
|
||||||
while (headers != NULL)
|
|
||||||
{
|
|
||||||
struct http_header *next = headers->next;
|
|
||||||
free(headers);
|
|
||||||
headers = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t read_field(struct string *str, size_t offset,
|
|
||||||
struct string **res)
|
|
||||||
{
|
|
||||||
ssize_t nread = read_word_delim(str, offset, res, ":\n");
|
|
||||||
if (nread <= 0)
|
|
||||||
return ERR_HTTP_INVALID_INPUT;
|
|
||||||
|
|
||||||
if (str->size <= offset + nread || str->data[offset + nread] != ':')
|
|
||||||
return ERR_HTTP_INVALID_INPUT;
|
|
||||||
|
|
||||||
return nread;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t read_value(struct string *str, size_t offset,
|
|
||||||
struct string **res)
|
|
||||||
{
|
|
||||||
ssize_t nread = read_word_delim(str, offset, res, "\n");
|
|
||||||
if (nread <= 0)
|
|
||||||
return ERR_HTTP_INVALID_INPUT;
|
|
||||||
|
|
||||||
if (str->size <= offset + nread || str->data[offset + nread] != '\n')
|
|
||||||
return ERR_HTTP_INVALID_INPUT;
|
|
||||||
|
|
||||||
return nread;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses the status line of req, stores the result in res and returns the
|
// Parses the status line of req, stores the result in res and returns the
|
||||||
// number of read characters or a negative number on error
|
// number of read characters or a negative number on error
|
||||||
// WARNING res must be pre allocated
|
// WARNING res must be pre allocated
|
||||||
|
|
@ -95,35 +60,30 @@ static ssize_t parse_reqline(struct http_request *res, struct string *req)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t parse_headers(struct http_header *res, struct string *req,
|
|
||||||
size_t offset)
|
|
||||||
{
|
|
||||||
size_t i = offset;
|
|
||||||
|
|
||||||
while (req->data[i] != '\n') // ! Blank line
|
|
||||||
{
|
|
||||||
// Read field
|
|
||||||
ssize_t nread = read_field(req, offset, &res->field);
|
|
||||||
if (nread <= 0)
|
|
||||||
return nread; // Contains error code when negative
|
|
||||||
|
|
||||||
i += nread;
|
|
||||||
|
|
||||||
// Read value
|
|
||||||
nread = read_value(req, offset, &res->value);
|
|
||||||
if (nread <= 0)
|
|
||||||
return nread; // Contains error code when negative
|
|
||||||
|
|
||||||
i += nread + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// === Functions
|
// === Functions
|
||||||
|
|
||||||
// struct http_request *parse_request(struct string *req)
|
// TODO handle logs and free adequately
|
||||||
// {}
|
struct http_request *parse_request(struct string *req)
|
||||||
|
{
|
||||||
|
struct http_request *res = calloc(1, sizeof(struct http_request));
|
||||||
|
if (res == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Status line
|
||||||
|
size_t i = 0;
|
||||||
|
ssize_t nread = parse_reqline(res, req);
|
||||||
|
if (nread <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
i += nread;
|
||||||
|
|
||||||
|
// Headers
|
||||||
|
nread = parse_headers(res, req, i);
|
||||||
|
if (nread <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// struct http_response *generate_response(struct http_request *req)
|
// struct http_response *generate_response(struct http_request *req)
|
||||||
// {}
|
// {}
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,10 @@ void errlog_init(bool enabled, FILE *logfile_stream);
|
||||||
void print_err();
|
void print_err();
|
||||||
|
|
||||||
/* @brief Prints error logs, just like print_log(), and also to stderr
|
/* @brief Prints error logs, just like print_log(), and also to stderr
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void print_log_err(char* format, ...);
|
void print_log_err(char* format, ...);
|
||||||
|
|
||||||
/* @brief Prints error logs, just like print_log()
|
/* @brief Prints error logs, just like print_log()
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
char* get_err();
|
char* get_err();
|
||||||
|
|
||||||
|
|
|
||||||
31
httpd/src/utils/files/files.c
Normal file
31
httpd/src/utils/files/files.c
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "files.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../string/string.h"
|
||||||
|
|
||||||
|
bool file_exists(const char *path)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool is_directory(const char *path)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// TODO handle logging
|
||||||
|
struct string *get_file_content(const char *path)
|
||||||
|
{
|
||||||
|
// Open file
|
||||||
|
FILE *stream = fopen(path, "r");
|
||||||
|
if (stream == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Alloc result
|
||||||
|
char buf[BUFFER_SIZE];
|
||||||
|
struct string *res = string_create(NULL, 0);
|
||||||
|
if (res == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nread;
|
||||||
|
while ((fgets(buf, BUFFER_SIZE, stream)))
|
||||||
|
}
|
||||||
42
httpd/src/utils/files/files.h
Normal file
42
httpd/src/utils/files/files.h
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef FILES_H
|
||||||
|
#define FILES_H
|
||||||
|
|
||||||
|
// === Definitions
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
// === Includes
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// === Functions
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool file_exists(const char *path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool is_directory(const char* path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
struct string* get_file_content(const char *path);
|
||||||
|
|
||||||
|
#endif // ! FILES_H
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -64,6 +65,15 @@ void string_concat_str(struct string *str, const char *to_concat, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void string_to_lowercase(struct string *str)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < str->size; i++)
|
||||||
|
{
|
||||||
|
if (isupper(str->data[i]))
|
||||||
|
str->data[i] += 'a' - 'A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void string_destroy(struct string *str)
|
void string_destroy(struct string *str)
|
||||||
{
|
{
|
||||||
if (str != NULL)
|
if (str != NULL)
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,18 @@ int string_compare_n_str(const struct string *str1, const char *str2, size_t n);
|
||||||
*/
|
*/
|
||||||
void string_concat_str(struct string *str, const char *to_concat, size_t size);
|
void string_concat_str(struct string *str, const char *to_concat, size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Concat a char * with its size in a struct string
|
||||||
|
**
|
||||||
|
** @param str
|
||||||
|
*/
|
||||||
|
void string_to_lowercase(struct string *str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** @brief Free all string content
|
||||||
|
**
|
||||||
|
** @param str
|
||||||
|
*/
|
||||||
void string_destroy(struct string *str);
|
void string_destroy(struct string *str);
|
||||||
|
|
||||||
#endif /* ! STRING_H */
|
#endif /* ! STRING_H */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue