diff --git a/.gitignore b/.gitignore index 3f4d975..51ac26b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.o proxy +compile_commands.json diff --git a/Makefile b/Makefile index 1540786..14a8090 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CC=gcc +CC=bear --append -- gcc CFLAGS= -g -Wall -Werror all: proxy diff --git a/README b/README index 88bc3bd..a9c00c6 100644 --- a/README +++ b/README @@ -4,7 +4,8 @@ CUSTOM PROXY Proxy for HTTP/1.0 standard protocol -RFC: datatracker.ietf.org/doc/html/rfc2616 +RFC: datatracker.ietf.org/doc/html/rfc1945 RES: cs.princeton.edu/courses/archive/spr13/cos461/assignments-proxy.html +RES: Beej's Guide to Network Programming - Using Internet Sockets RES: en.wikipedia.org/wiki/Proxy_server RES: TCP/IP sockets in C - Practical guide for programmers 2nd edition diff --git a/proxy.c b/proxy.c index 716aea4..e3e9337 100644 --- a/proxy.c +++ b/proxy.c @@ -1,16 +1,104 @@ -#include "proxy_parse.h" #include #include +#include +#include #include #include #include +#include "structs.h" -#define PROXY_PORT 80 +#define PROXY_PORT 2020 #define PROXY_CONN 20 +#define PROXY_MAX_MSGLEN 10*1024 +#define TITLE_DELIM " " + +struct http_msg *child_msg; + +int parse_title(char *msgbuff) { + char *title_end = strrchr(msgbuff, '\n'); + if (title_end == NULL) { + return -1; + } + + const int title_len = title_end - msgbuff; + char title[title_len]; + strncpy(title, msgbuff, title_len); + + char *title_sub; + int index; + for (index = 0, title_sub = strtok(title, TITLE_DELIM); + title_sub != NULL; + title_sub = strtok(NULL, TITLE_DELIM), index++) { + + char *destarr = (char *) calloc(1, strlen(title_sub)+1); + if (destarr == NULL) { + goto error_title_props; + } + + if (index == 0) { + child_msg->method = destarr; + strcpy(child_msg->method, title_sub); + } + else if (index == 1) { + child_msg->uri = destarr; + strcpy(child_msg->uri, title_sub); + } + else if (index == 2) { + child_msg->ver = destarr; + strcpy(child_msg->ver, title_sub); + } + else { + goto error_title_props; + } + } + + return 0; + +error_title_props: + for (int i = 0; i <= index; i++) { + free(child_msg+i); + } + + return -1; +} + +void handle_request(int sockfd) { + int ret; + int id = getpid(); + char msgbuff[PROXY_MAX_MSGLEN]; + memset(msgbuff, 0, sizeof(msgbuff)); + + ret = recv(sockfd, msgbuff, sizeof(msgbuff), 0); + if (ret < 0) { + fprintf(stderr, "[CHILD %d] Failed to receive data from client\n", id); + goto end_sock; + } + + fprintf(stdout, "[CHILD %d] Received data from client: %s\n", id, msgbuff); + + // prepare structs + child_msg = (struct http_msg *) calloc(1, sizeof(struct http_msg)); + if (child_msg == NULL) { + fprintf(stderr, "[CHILD %d] Failed to allocate memory for client structs\n", id); + goto end_sock; + } + + // start parsing + ret = parse_title(msgbuff); + if (ret < 0) { + fprintf(stderr, "[CHILD %d] Failed to parse the title of the request\n", id); + goto end_structs; + } + +end_structs: + free(child_msg); + +end_sock: + close(sockfd); +} int main(int argc, char *argv[]) { int server_socket; - int new_fd; int ret; ret = server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -50,10 +138,20 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - fprintf(stdout, "[CLIENT %d] Successfully connected\n", client_socket); + ret = fork(); + switch (ret) { + case -1: + fprintf(stderr, "[CLIENT SOCKET %d] Failed to fork child process to handle the request\n", client_socket); + return EXIT_FAILURE; + break; + case 0: + handle_request(client_socket); + break; + default: + fprintf(stdout, "[PROGRAM] Successfully forked a new child process with PID %d\n", ret); + break; + } } - printf("New connection with fd -> %d\n", new_fd); - return EXIT_SUCCESS; } diff --git a/structs.h b/structs.h new file mode 100644 index 0000000..a6f740d --- /dev/null +++ b/structs.h @@ -0,0 +1,17 @@ +#ifndef STRUCTS_H +#define STRUCTS_H + +struct header { + char *key; + char *value; +}; + +struct http_msg { + char *method; + char *uri; + char *ver; + struct header *headers; + void *body; +}; + +#endif