creating request processing logic

This commit is contained in:
Dmitriy Shishkov 2020-06-22 22:01:16 +05:00
parent 2b86380ff4
commit cb9ba8e950
10 changed files with 258 additions and 11 deletions

2
include/file.h Normal file
View File

@ -0,0 +1,2 @@
char *gen_file_path(char *path);
int send_file(int fd, char *path);

1
include/mine.h Normal file
View File

@ -0,0 +1 @@
char *get_mine_type(char *file_path);

5
include/request.h Normal file
View File

@ -0,0 +1,5 @@
char *get_path(char *request);
void gen_header(int status_code, size_t file_size, char *mine_type);
int send_response(int fd, char *path);
void handle_post_request(int fd, char *request);
void handle_get_request(int fd, char *request);

View File

@ -1 +1,2 @@
void err_msg(char *msg); void err_msg(char *msg);
char *add_to_front(char **str1, char *str2);

35
src/file.c Normal file
View File

@ -0,0 +1,35 @@
#include <string.h>
#include <stdlib.h>
#include "../include/file.h"
#include "../include/utils.h"
char *gen_file_path(char *req_path)
{
char *path = (char *)malloc(sizeof req_path);
strcpy(path, req_path);
if (strchr(req_path, '.') == NULL)
{
if (req_path[strlen(req_path) - 1] != '/')
{
path = realloc(path, sizeof path + 1);
path = strcat(path, "/");
}
path = realloc(path, sizeof path + sizeof "index.html");
path = strcat(path, "index.html");
}
char *webroot = "../static";
path = realloc(path, sizeof path + sizeof webroot);
path = add_to_front(&path, webroot);
return path;
}
int send_file(int fd, char *req_path)
{
char *path = gen_file_path(req_path);
}

5
src/mine.c Normal file
View File

@ -0,0 +1,5 @@
#include "../include/mine.h"
char *get_mine_type(char *file_path) {
}

View File

@ -4,6 +4,7 @@
#include <unistd.h> #include <unistd.h>
#include <netdb.h> #include <netdb.h>
#include "../include/netw.h"
#include "../include/utils.h" #include "../include/utils.h"
#define BACKLOG 10 #define BACKLOG 10
@ -73,7 +74,12 @@ int get_listener_socket(char *port)
return sockfd; return sockfd;
} }
/**
* @brief Get address from sockaddr structure
*
* @param {struct sockaddr*} sa
* @return void*
*/
void *get_in_addr(struct sockaddr *sa) void *get_in_addr(struct sockaddr *sa)
{ {
if (sa->sa_family == AF_INET) { if (sa->sa_family == AF_INET) {

136
src/request.c Normal file
View File

@ -0,0 +1,136 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "../include/request.h"
#include "../include/utils.h"
/**
* @brief Get the status message object
*
* @param status_code
* @return char*
*/
char *get_status_message(int status_code)
{
switch (status_code)
{
case 200:
return "OK";
case 400:
return "Internal Server Error";
case 401:
return "Unauthorized";
case 403:
return "Forbidden";
case 404:
return "NOT FOUND";
case 500:
return "Internal Server Error";
case 501:
return "Not Implemented";
case 502:
return "Bad Gateway";
default:
return "None";
break;
}
}
/**
* @brief Get the path object
*
* @param request
* @return char*
*/
char *get_path(char *request)
{
char *tmp = strtok(request, " ");
char *path = strtok(NULL, " ");
return path;
}
/**
* @brief Generate header string
*
* @param status_code
* @param file_size
* @param mine_type
* @return char*
*/
char *gen_header(int status_code, size_t file_size, char *mine_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: %s\nConnection: close\nContent-Length: %d\nContent-Type: %s\n\n", status_code, status_message, curr_date, file_size, mine_type);
char *header = (char *)malloc(header_length + 1);
snprintf(header, header_length + 1, "HTTP/1.1 %d %s\nDate: %s\nConnection: close\nContent-Length: %d\nContent-Type: %s\n\n", status_code, status_message, curr_date, file_size, mine_type);
printf("%s\n", header);
}
/**
* @brief Send HTTP response
*
* @param fd
* @param file_path
* @return int
*/
int send_response(int fd, char *path)
{
int file_fd;
struct stat stat_buf;
file_fd = open(file_path, O_RDONLY);
fstat(file_fd, &stat_buf);
off_t f_size = stat_buf.st_size;
off_t offset = 0;
char *mine_type;
char *header = gen_header(200, f_size, mine_type);
sendfile(fd, file_fd, &offset, f_size);
close(file_fd);
}
/**
* @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);
int rv = send_response(fd, path);
if (rv < 0)
{
err_msg("couldn't send response");
}
}

View File

@ -10,6 +10,47 @@
#include "../include/netw.h" #include "../include/netw.h"
#include "../include/utils.h" #include "../include/utils.h"
#include "../include/request.h"
void handle_connection(int fd)
{
const size_t request_buffer_size = 512;
char request[request_buffer_size];
char *prt;
int bytes_recv = recv(fd, request, request_buffer_size - 1, 0);
if (bytes_recv < 0)
{
err_msg("failed to receive a request from server");
return;
}
// printf("Request:\n%s---\n", request);
prt = strstr(request, " HTTP/");
if (prt == NULL)
{
err_msg("non-HTTP request received");
}
else
{
if (strncmp(request, "GET ", 4) == 0)
{
handle_get_request(fd, request);
}
else if (strncmp(request, "POST ", 5) == 0)
{
handle_post_request(fd, request);
}
else
{
err_msg("unknown request");
}
}
close(fd);
}
/** /**
* Main * Main
*/ */
@ -45,6 +86,9 @@ int main(int argc, char *argv[])
continue; continue;
} }
inet_ntop(cli_addr.ss_family, get_in_addr((struct sockaddr *)&cli_addr), s, sizeof s);
printf("\nGot connection from %s\n", s);
// | Doesn't work properly yet // | Doesn't work properly yet
// v // v
@ -56,10 +100,7 @@ int main(int argc, char *argv[])
{ {
close(listenfd); close(listenfd);
inet_ntop(cli_addr.ss_family, get_in_addr((struct sockaddr *)&cli_addr), s, sizeof s); handle_connection(client_fd); // Implement
printf("Got connection from %s\n", s);
// connection(client_fd); // Implement
exit(0); exit(0);
} }
else else

View File

@ -1,10 +1,25 @@
#include <stdio.h> #include <stdio.h>
#include "../include/utils.h"
/** /**
* @brief Prints error * @brief Prints error
* *
* @param {char *} msg * @param {char *} msg
*/ */
void err_msg (char *msg) { void err_msg(char *msg)
{
fprintf(stderr, "Error: %s\n", msg); fprintf(stderr, "Error: %s\n", msg);
} }
char *add_to_front(char **str1, char *str2)
{
char *tmp = strdup(*str1);
strcpy(*str1, str2);
strcat(*str1, tmp);
free(tmp);
return *str1;
}