diff --git a/WebServer b/WebServer index 33d4802..603b09e 100755 Binary files a/WebServer and b/WebServer differ diff --git a/include/ipaddress.h b/include/ipaddress.h new file mode 100644 index 0000000..7f34cc0 --- /dev/null +++ b/include/ipaddress.h @@ -0,0 +1,16 @@ +#ifndef IPADDRESS_H +#define IPADDRESS_H + +#include +#include +#include +#include + +#define MAX_LINE_LENGTH (1024) + +// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me. + +int extract_ip_address_from_header(char *line, char *address); +char *get_ip_address(FILE *f); + +#endif \ No newline at end of file diff --git a/include/server.h b/include/server.h new file mode 100644 index 0000000..0483c3b --- /dev/null +++ b/include/server.h @@ -0,0 +1,13 @@ +#ifndef SERVER_H +#define SERVER_H + +// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me. + +#include + +void send_response(FILE *f, char *html); +int open_connection(int port); +void accept_client(int sock, char *key); +void send_only(int port, char *key); + +#endif \ No newline at end of file diff --git a/makefile b/makefile index f44e6cf..d4eb631 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ # Makefile for hello.c CC = gcc # C compiler -CFLAGS = -O2 # Compiler flags (optimization level) +CFLAGS = -O2 # Compiler flags (optimization level) SRC_DIR = src BUILD_DIR = build diff --git a/src/ipaddress.c b/src/ipaddress.c new file mode 100644 index 0000000..e0cd140 --- /dev/null +++ b/src/ipaddress.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include "../include/ipaddress.h" + +// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me. + +int extract_ip_address_from_header(char *line, char *address) { + int found = 0; + char *ptr; + char *name; + char *value; + + name = strndup(line, MAX_LINE_LENGTH); + ptr = index(name, (int)':'); + if (ptr == NULL) { + return 0; + } + // end the string at the colon + *ptr = '\0'; + + // get the value part of the header field + ptr = index(line, (int) ':'); + value = strndup(ptr + 2, MAX_LINE_LENGTH); + + // most ugly way to remove \r\n from the end of the string + value[strlen(value)-2] = '\0'; + + if (strncmp(name, "X-Forwarded-For", MAX_LINE_LENGTH) == 0) { + found = 1; + strncpy(address, value, MAX_LINE_LENGTH); + } + + free(name); + free(value); + + return found; +} + +char *get_ip_address(FILE *f) { + int address_found = 0; + char *res; + char *ip_address = malloc (sizeof (char) * MAX_LINE_LENGTH); + char header_line[MAX_LINE_LENGTH]; + + do { + res = fgets(header_line, MAX_LINE_LENGTH, f); + + if (res != NULL) { + printf("%s", res); + + if (!address_found) { + address_found = extract_ip_address_from_header(res, ip_address); + } + } + } while (res != NULL && strcmp(header_line, "\r\n") != 0); + + return ip_address; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 4cf920c..d36b5f1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,27 @@ #include +#include +#include #include "../include/fileReader.h" +#include "../include/server.h" +#include "../include/ipaddress.h" -int main() { - char *file = ReadHTML("/home/skingging/Documents/Projects/C/C-Webserver/HTML/index.html"); - printf(file); +int main(int argc, char *argv[]) { + + if(argc <= 1) { + printf("Please provide options. \n"); + + return 0; + } + + char *file = NULL; + + if(strcasecmp(argv[0], "cache")) { + file = ReadHTML("/home/skingging/Documents/Projects/C/C-Webserver/HTML/index.html"); + } + + int port = 3090; + send_only(port, "address"); + exit(EXIT_SUCCESS); + + return 0; } \ No newline at end of file diff --git a/src/server.c b/src/server.c new file mode 100644 index 0000000..17b9973 --- /dev/null +++ b/src/server.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../include/ipaddress.h" +#include "../include/server.h" + +// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me. + +void send_response(FILE *f, char *html) +{ + fprintf(f, "HTTP/1.1 200 OK\r\n"); + fprintf(f, "Content-Type: application/html\r\n"); + fprintf(f, "\r\n"); + fprintf(f, "%s", html); +} + +int open_connection(int port) +{ + int sock; + struct sockaddr_in addr_in; + + printf("simpleserver::Creating socket: (%d, %d, 0)\n", AF_INET, SOCK_STREAM); + sock = socket(AF_INET, SOCK_STREAM, 0); + printf("simpleserver::Socket created (%d)\n", sock); + + if (sock == -1) + { + printf("Failed to create socket (%d)\n", errno); + exit(EXIT_FAILURE); + } + + addr_in.sin_family = AF_INET; + addr_in.sin_port = htons(port); + addr_in.sin_addr.s_addr = INADDR_ANY; + + printf("simpleserver::bind (%d, (%d, %d, %d), %lu)\n", sock, addr_in.sin_family, addr_in.sin_port, addr_in.sin_addr.s_addr, sizeof(struct sockaddr_in)); + + int lol = bind(sock, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in)); + + printf("simpleserver::listen(%d, 8)\n", sock); + + if (listen(sock, 8) == -1) + { + printf("Failed to get socket to listen (%d)\n", errno); + exit(EXIT_FAILURE); + } + + return sock; +} + +void accept_client(int sock, char *key) +{ + struct sockaddr_in client_addr; + socklen_t clientaddr_len; + FILE *f; + + printf("simpleserver::accept(%d)\n", sock); + + int client_sock = accept(sock, (struct sockaddr *)&client_addr, &clientaddr_len); + printf("simpleserver::accepted (%d)\n", client_sock); + + if (client_sock == -1) + { + printf("Failed to accept connection (%d)\n", errno); + exit(EXIT_FAILURE); + } + + printf("simpleserver::fdopen(%d)\n", client_sock); + + f = fdopen(client_sock, "w+"); + + if (f == NULL){ + printf("simpleserver::Error during fdopen\n"); + } + + printf("simpleserver::send_response(%s)\n", key); + send_response(f, "

Hello

"); + + printf("simpleserver::fclose()\n"); + fclose(f); + + printf("simpleserver::fflush\n"); + // stdout needs to be flushed in order for heroku to read the logs + fflush(stdout); + printf("simpleserver::endfflush\n"); +} + +void send_only(int port, char *key) +{ + int sock = open_connection(port); + + while (1) + { + accept_client(sock, key); + } + + close(sock); +}