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 \
|
||||
src/utils/time/fmt_time.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 \
|
||||
src/server/server.c \
|
||||
src/http/http.c \
|
||||
src/http/headers.c \
|
||||
src/logger/logs.c \
|
||||
src/logger/errors.c
|
||||
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 "../utils/parsing/words.h"
|
||||
#include "headers.h"
|
||||
|
||||
// === 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
|
||||
// number of read characters or a negative number on error
|
||||
// WARNING res must be pre allocated
|
||||
|
|
@ -95,36 +60,31 @@ static ssize_t parse_reqline(struct http_request *res, struct string *req)
|
|||
return i;
|
||||
}
|
||||
|
||||
static ssize_t parse_headers(struct http_header *res, struct string *req,
|
||||
size_t offset)
|
||||
{
|
||||
size_t i = offset;
|
||||
// === Functions
|
||||
|
||||
while (req->data[i] != '\n') // ! Blank line
|
||||
{
|
||||
// Read field
|
||||
ssize_t nread = read_field(req, offset, &res->field);
|
||||
// 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 nread; // Contains error code when negative
|
||||
return NULL;
|
||||
|
||||
i += nread;
|
||||
|
||||
// Read value
|
||||
nread = read_value(req, offset, &res->value);
|
||||
// Headers
|
||||
nread = parse_headers(res, req, i);
|
||||
if (nread <= 0)
|
||||
return nread; // Contains error code when negative
|
||||
return NULL;
|
||||
|
||||
i += nread + 1;
|
||||
}
|
||||
|
||||
return i + 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
// === Functions
|
||||
|
||||
// struct http_request *parse_request(struct string *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();
|
||||
|
||||
/* @brief Prints error logs, just like print_log(), and also to stderr
|
||||
*
|
||||
*/
|
||||
void print_log_err(char* format, ...);
|
||||
|
||||
/* @brief Prints error logs, just like print_log()
|
||||
*
|
||||
*
|
||||
*/
|
||||
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 <ctype.h>
|
||||
#include <stdlib.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)
|
||||
{
|
||||
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);
|
||||
|
||||
/*
|
||||
** @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);
|
||||
|
||||
#endif /* ! STRING_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue