feat: (Almost) functionnal package

This commit is contained in:
Gu://em_ 2025-11-26 21:57:45 +01:00
parent d2076a5fd5
commit 5dbcc3e3d0
8 changed files with 164 additions and 29 deletions

View file

@ -87,6 +87,19 @@ ssize_t parse_headers(struct http_request *res, struct string *req,
return i + 1; return i + 1;
} }
struct http_header *get_header(struct http_header *headers, const char *field)
{
while (headers != NULL)
{
if (string_compare_n_str(headers->field, field, strlen(field)) == 0)
return headers;
headers = headers->next;
}
return NULL;
}
struct http_header *create_header(const char *field, const char *value) struct http_header *create_header(const char *field, const char *value)
{ {
struct http_header *res = calloc(1, sizeof(struct http_header)); struct http_header *res = calloc(1, sizeof(struct http_header));

View file

@ -1,11 +1,15 @@
#include "http.h" #include "http.h"
#include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/sendfile.h>
#include <sys/socket.h>
#include "../logger/logs.h"
#include "../utils/files/files.h" #include "../utils/files/files.h"
#include "../utils/parsing/words.h" #include "../utils/parsing/words.h"
#include "../utils/time/fmt_time.h" #include "../utils/time/fmt_time.h"
@ -108,6 +112,24 @@ static bool find_target(struct http_request *req)
return true; return true;
} }
// WARNING allocates result on the heap
static char *get_http_method(enum http_method method)
{
char *res = malloc(8 * sizeof(char));
switch (method)
{
case GET:
strcpy(res, "HEAD");
return res;
case HEAD:
strcpy(res, "HEAD");
return res;
default:
free(res);
return NULL;
}
}
static struct string *generate_status_message(int status_code) static struct string *generate_status_message(int status_code)
{ {
char *message; char *message;
@ -145,6 +167,63 @@ void http_init(struct config *cfg)
config = cfg; config = cfg;
} }
// TODO handle logs
void handle_request(int client_fd)
{
ssize_t nread = 0;
char buffer[BUFFER_SIZE]; // Declared in server.h
struct string *str = string_create(NULL, 0);
if (str == NULL)
return;
// Store request
while ((nread = recv(client_fd, buffer, BUFFER_SIZE, 0)) > 0)
{
string_concat_str(str, buffer, nread);
}
// Parse request
struct http_request *req = parse_request(str);
if (req == NULL)
return;
char *method = get_http_method(req->method);
char *target = string_to_charptr(req->target);
log_request(method, target, "127.0.0.1");
free(method);
free(target);
// Generate response
struct http_response *resp = generate_response(req);
if (resp == NULL)
return;
// Format response to string
struct string *res = format_response(resp);
if (res == NULL)
return;
// Send response
ssize_t nsent;
while ((nsent = send(client_fd, res, res->size, 0)) > 0)
;
// Send file
struct http_header *cl_header = get_header(resp->headers, "Content-Length");
if (cl_header != NULL)
{
char *target = string_to_charptr(req->target);
char *cl_str = string_to_charptr(cl_header->value);
int fd = open(target, O_RDONLY);
if (fd > 0)
sendfile(client_fd, fd, 0, atoi(cl_str));
}
// Free
string_destroy(str);
string_destroy(res);
destroy_request(req);
destroy_response(resp);
}
// TODO handle logs and free adequately // TODO handle logs and free adequately
struct http_request *parse_request(struct string *req) struct http_request *parse_request(struct string *req)
{ {
@ -260,3 +339,18 @@ void destroy_request(struct http_request *req)
free(req); free(req);
} }
} }
void destroy_response(struct http_response *resp)
{
if (resp != NULL)
{
if (resp->status_msg != NULL)
string_destroy(resp->status_msg);
if (resp->protocol != NULL)
string_destroy(resp->protocol);
destroy_headers(resp->headers);
free(resp);
}
}

View file

@ -3,7 +3,7 @@
// === Definitions // === Definitions
#define _POSIX_C_SOURCE 200809L // #define _POSIX_C_SOURCE 200809L
// Error codes // Error codes
#define ERR_HTTP_INVALID_INPUT -1 #define ERR_HTTP_INVALID_INPUT -1
@ -68,6 +68,12 @@ struct http_response
*/ */
void http_init(struct config* cfg); void http_init(struct config* cfg);
/* @brief Reads, parses the request and responds adequately all-in-one
*
* @param client_fd
*/
void handle_request(int client_fd);
/* @brief Parses the HTTP request and splits it into a request structure /* @brief Parses the HTTP request and splits it into a request structure
* *
* @param req * @param req

View file

@ -26,6 +26,9 @@ void print_err()
void print_log_err(char *format, ...) void print_log_err(char *format, ...)
{ {
if (!config.enabled)
return;
// Log prefix (time and server name) // Log prefix (time and server name)
fprintf(config.logfile_stream, "%s [%s] ", get_time(), fprintf(config.logfile_stream, "%s [%s] ", get_time(),
config.server_cfg->server_name); config.server_cfg->server_name);

View file

@ -24,6 +24,9 @@ int log_init(struct config *global_config)
void print_log(char *format, ...) void print_log(char *format, ...)
{ {
if (!config.enabled)
return;
// Log prefix (time and server name) // Log prefix (time and server name)
fprintf(config.logfile_stream, "%s [%s] ", get_time(), fprintf(config.logfile_stream, "%s [%s] ", get_time(),
config.server_cfg->server_name); config.server_cfg->server_name);

View file

@ -1,13 +1,12 @@
#include "server.h" #include "server.h"
#define _POSIX_C_SOURCE 200112L
#include <netdb.h> #include <netdb.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include "../http/http.h"
#include "../logger/errors.h" #include "../logger/errors.h"
// #include "../logger/logs.h" // #include "../logger/logs.h"
@ -70,24 +69,25 @@ static int get_socket(const char *hostname, const char *port)
} }
// Reads and sends back received data to client // Reads and sends back received data to client
static void send_back(int client_fd) // For testing purposes
{ // static void send_back(int client_fd)
ssize_t nread = 0; // {
char buffer[BUFFER_SIZE]; // ssize_t nread = 0;
// char buffer[BUFFER_SIZE];
while ((nread = recv(client_fd, buffer, BUFFER_SIZE, 0)) > 0) // while ((nread = recv(client_fd, buffer, BUFFER_SIZE, 0)) > 0)
{ // {
ssize_t sent; // ssize_t sent;
while (nread > 0) // while (nread > 0)
{ // {
sent = send(client_fd, buffer, nread, 0); // sent = send(client_fd, buffer, nread, 0);
if (sent == -1) // Send failed // if (sent == -1) // Send failed
break; // break;
nread -= sent; // nread -= sent;
} // }
} // }
} // }
// === Functions // === Functions
@ -111,7 +111,8 @@ void start_server(const char *host, const char *port)
// TODO handle signals to stop // TODO handle signals to stop
send_back(client_fd); handle_request(client_fd);
// send_back(client_fd);
close(client_fd); close(client_fd);
} }

View file

@ -1,6 +1,8 @@
#ifndef SERVER_H #ifndef SERVER_H
#define SERVER_H #define SERVER_H
#define _POSIX_C_SOURCE 200112L
/* @brief /* @brief
* *
* @param hpstname * @param hpstname

View file

@ -6,18 +6,22 @@
struct string *string_create(const char *str, size_t size) struct string *string_create(const char *str, size_t size)
{ {
struct string *res = malloc(sizeof(struct string)); struct string *res = calloc(1, sizeof(struct string));
if (res == NULL) if (res == NULL)
return NULL; return NULL;
res->data = malloc(size * sizeof(char)); if (size > 0)
if (res->data == NULL)
{ {
free(res); res->data = malloc(size * sizeof(char));
return NULL; if (res->data == NULL)
{
free(res);
return NULL;
}
memcpy(res->data, str, size);
} }
memcpy(res->data, str, size);
res->size = size; res->size = size;
return res; return res;
} }
@ -55,9 +59,18 @@ void string_concat_str(struct string *str, const char *to_concat, size_t size)
return; return;
str->size = new_size; str->size = new_size;
str->data = realloc(str->data, new_size); if (str_size == 0)
if (str->data == NULL) {
return; // Handle ? str->data = malloc(new_size);
if (str->data == NULL)
return; // Handle ?
}
else
{
str->data = realloc(str->data, new_size);
if (str->data == NULL)
return; // Handle ?
}
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
{ {