creating request processing logic
This commit is contained in:
parent
2b86380ff4
commit
cb9ba8e950
2
include/file.h
Normal file
2
include/file.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
char *gen_file_path(char *path);
|
||||||
|
int send_file(int fd, char *path);
|
1
include/mine.h
Normal file
1
include/mine.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
char *get_mine_type(char *file_path);
|
5
include/request.h
Normal file
5
include/request.h
Normal 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);
|
@ -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
35
src/file.c
Normal 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
5
src/mine.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "../include/mine.h"
|
||||||
|
|
||||||
|
char *get_mine_type(char *file_path) {
|
||||||
|
|
||||||
|
}
|
@ -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
136
src/request.c
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
49
src/server.c
49
src/server.c
@ -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
|
||||||
|
17
src/utils.c
17
src/utils.c
@ -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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user