Updated project structure and makefile. Started creating frontend. Created csv database interphase
This commit is contained in:
85
src/netw_op/netw.c
Normal file
85
src/netw_op/netw.c
Normal file
@ -0,0 +1,85 @@
|
||||
#include "../../include/netw_op/netw.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
|
||||
#define BACKLOG 10
|
||||
|
||||
/**
|
||||
* @brief Get the listener socket object
|
||||
*
|
||||
* @param {char *} port
|
||||
* @return int
|
||||
*/
|
||||
int get_listener_socket(char *port)
|
||||
{
|
||||
int sockfd;
|
||||
struct addrinfo hints, *servinfo, *p;
|
||||
int yes = 1;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
if (getaddrinfo(NULL, port, &hints, &servinfo) != 0)
|
||||
{
|
||||
err_msg("can't get addres info");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (p = servinfo; p != NULL; p = p->ai_next)
|
||||
{
|
||||
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0)
|
||||
{
|
||||
err_msg("can't create socket");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) < 0)
|
||||
{
|
||||
err_msg("can't set socket options");
|
||||
close(sockfd);
|
||||
freeaddrinfo(servinfo);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (bind(sockfd, p->ai_addr, p->ai_addrlen) < 0)
|
||||
{
|
||||
close(sockfd);
|
||||
err_msg("can't bind socket");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
err_msg("failed to find local adress");
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (listen(sockfd, BACKLOG) < 0)
|
||||
{
|
||||
err_msg("failed to listen");
|
||||
return -4;
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get address from sockaddr structure
|
||||
*
|
||||
* @param {struct sockaddr*} sa
|
||||
* @return void*
|
||||
*/
|
||||
void *get_in_addr(struct sockaddr *sa)
|
||||
{
|
||||
if (sa->sa_family == AF_INET) {
|
||||
return &(((struct sockaddr_in*)sa)->sin_addr);
|
||||
}
|
||||
|
||||
return &(((struct sockaddr_in6*)sa)->sin6_addr);
|
||||
}
|
176
src/netw_op/request.c
Normal file
176
src/netw_op/request.c
Normal file
@ -0,0 +1,176 @@
|
||||
#include "../../include/netw_op/request.h"
|
||||
#include "../../include/utils_op/utils.h"
|
||||
#include "../../include/file_op/file.h"
|
||||
#include "../../include/file_op/mime.h"
|
||||
|
||||
/**
|
||||
* @brief Send 404 response
|
||||
*
|
||||
* @param fd
|
||||
* @param path
|
||||
*/
|
||||
void res_404(int fd, char *path)
|
||||
{
|
||||
FILE *fp = fopen("static/404.html", "r");
|
||||
const ssize_t fsize = 512;
|
||||
char buf[fsize], msg[fsize];
|
||||
|
||||
fread(buf, fsize, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
sprintf(msg, buf, path, path);
|
||||
|
||||
struct header_s *header = gen_header(404, strlen(msg), "text/html");
|
||||
send(fd, header->str, header->size - 1, 0);
|
||||
|
||||
send(fd, msg, strlen(msg), 0);
|
||||
close(fd);
|
||||
|
||||
printf("404 ERROR\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the path object
|
||||
*
|
||||
* @param request
|
||||
* @return char*
|
||||
*/
|
||||
char *get_path(char *request)
|
||||
{
|
||||
char *path = strtok(request, " ");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate header string
|
||||
*
|
||||
* @param status_code
|
||||
* @param file_size
|
||||
* @param mime_type
|
||||
* @return char*
|
||||
*/
|
||||
struct header_s *gen_header(int status_code, size_t file_size, char *mime_type)
|
||||
{
|
||||
char *status_message = get_status_message(status_code);
|
||||
|
||||
time_t now = time(NULL);
|
||||
struct tm *ptm = gmtime(&now);
|
||||
char *curr_date = asctime(ptm);
|
||||
|
||||
int header_length = snprintf(NULL, 0, "HTTP/1.1 %d %s\nDate: %sConnection: close\nContent-Length: %ld\nContent-Type: %s\r\n\r\n", status_code, status_message, curr_date, file_size, mime_type) + 1;
|
||||
char *header_string = (char *)malloc(header_length);
|
||||
snprintf(header_string, header_length, "HTTP/1.1 %d %s\nDate: %sConnection: close\nContent-Length: %ld\nContent-Type: %s\r\n\r\n", status_code, status_message, curr_date, file_size, mime_type);
|
||||
|
||||
struct header_s *header = (struct header_s *)malloc(header_length + sizeof(size_t));
|
||||
|
||||
header->size = header_length;
|
||||
header->str = header_string;
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send HTTP response
|
||||
*
|
||||
* @param fd
|
||||
* @param req_path
|
||||
* @return int
|
||||
*/
|
||||
int send_response(int fd, char *req_path)
|
||||
{
|
||||
char *file_path = gen_file_path(req_path);
|
||||
|
||||
struct file_s *file = get_file_info(file_path);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
char *msg = "Server error";
|
||||
|
||||
struct header_s *header = gen_header(500, sizeof(msg), "text/plain");
|
||||
send(fd, header->str, header->size - 1, 0);
|
||||
|
||||
send(fd, msg, sizeof(msg), 0);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file->fd < 0)
|
||||
{
|
||||
// char *msg = "<html>\n<body>404, Not Found. Return to home? <a href=\"/\">Home</a></body><html/>";
|
||||
|
||||
// struct header_s *header = gen_header(404, strlen(msg), "text/html");
|
||||
// send(fd, header->str, header->size - 1, 0);
|
||||
|
||||
// send(fd, msg, strlen(msg), 0);
|
||||
// close(fd);
|
||||
|
||||
// printf("404 ERROR\n");
|
||||
|
||||
res_404(fd, req_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *mime_type = get_mime_type(file_path);
|
||||
|
||||
struct header_s *header = gen_header(200, file->size, mime_type);
|
||||
|
||||
int rv = send(fd, header->str, header->size - 1, 0);
|
||||
|
||||
if (rv < 0)
|
||||
{
|
||||
err_msg("couldn't send header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (send_file(fd, file) < 0)
|
||||
{
|
||||
err_msg("couldn't send file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle POST request
|
||||
*
|
||||
* @param fd
|
||||
* @param request
|
||||
*/
|
||||
void handle_post_request(int fd, char *request)
|
||||
{
|
||||
char *not_supported_msg = "HTTP/1.1 501 Not Implemented\nConnection: close\n\n";
|
||||
send(fd, not_supported_msg, strlen(not_supported_msg), 0);
|
||||
printf("POST requests are not supported yet, closing connection\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle get request
|
||||
*
|
||||
* @param fd
|
||||
* @param request
|
||||
*/
|
||||
void handle_get_request(int fd, char *request)
|
||||
{
|
||||
char *path = get_path(request);
|
||||
printf("Client accessed path: %s\n", path);
|
||||
|
||||
if (strncmp(path, "/blog/", strlen("/blog/")) == 0)
|
||||
{
|
||||
char *id = (char *)malloc(strlen(path) - strlen("/blog/") + 1);
|
||||
memmove(id, path + strlen("/blog/"), strlen(path) - strlen("/blog/") + 1);
|
||||
|
||||
printf("Blog post id = %s\n", id);
|
||||
}
|
||||
|
||||
|
||||
if (send_response(fd, path) < 0)
|
||||
{
|
||||
err_msg("couldn't send response");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user