From 9e94f77a839da1a737c30fc6e4244eb47e40ee25 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sun, 1 Oct 2023 18:24:47 -0500 Subject: [PATCH] Abstracted code for ease of use --- src/CMakeLists.txt | 9 ++-- src/network.cpp | 80 ++++++++++++++++++++++++++++++++++ src/network.hpp | 32 ++++++++++++++ src/proxy.cpp | 104 +++++++++------------------------------------ 4 files changed, 137 insertions(+), 88 deletions(-) create mode 100644 src/network.cpp create mode 100644 src/network.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0636427..f6601ad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,9 @@ +add_executable(proxy + ./proxy.cpp + ./network.cpp +) + add_executable(web_server ./web_server.cpp ) -add_executable(proxy - ./proxy.cpp -) - diff --git a/src/network.cpp b/src/network.cpp new file mode 100644 index 0000000..addff4d --- /dev/null +++ b/src/network.cpp @@ -0,0 +1,80 @@ +#include "network.hpp" +#include +#include // Needed for exit() +#include + +void HandleClient(int browser_s, int server_s) { + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + ssize_t buf_len; // Buffer length for file reads + + // Pass GET along from browser to server + do { + buf_len = recv(browser_s, in_buf, BUF_SIZE, 0); + send(server_s, in_buf, buf_len, 0); + } while (buf_len != 0); + + // Pass response along from server to browser + do { + buf_len = recv(server_s, out_buf, BUF_SIZE, 0); + send(browser_s, out_buf, buf_len, 0); + } while (buf_len != 0); + close(server_s); + close(browser_s); +} + +Client::Client(void) { + addressLength = sizeof(address); + address.sin_family = AF_INET; +} + +bool Client::ConnectFrom(int socketFD) { + socketFD = accept(socketFD, (struct sockaddr *)&address, &addressLength); + if (socketFD == -1) { return 1; } + return 0; +} + +bool Client::ConnectTo(int portNumber) { + std::cout << "Attempting to connect to " << kWebserverIP << " on " << portNumber << std::endl; + address.sin_port = htons(portNumber); + if (inet_pton(address.sin_family, kWebserverIP, &address.sin_addr) <= 0) { + std::cerr << "ERROR (info) - inet_pton" << std::endl; + return 1; + } + socketFD = socket(address.sin_family, SOCK_STREAM, 0); + if (connect(socketFD, (struct sockaddr *)&address, addressLength) == -1) { + std::cerr << "ERROR (info) - connect" << std::endl; + return 1; + } + std::cout << "Connection successful" << std::endl; + return 0; +} + +Server::Server(int portNumber) { + address.sin_family = AF_INET; + address.sin_port = htons(portNumber); + address.sin_addr.s_addr = htonl(INADDR_ANY); +} + +void Server::Open(void) { + std::cout << "Opening the server" << std::endl; + // Create a socket, fill-in address information, and then bind it + socketFD = socket(address.sin_family, SOCK_STREAM, 0); + if (socketFD == -1) + { + std::cerr << "ERROR - Unable to create socket on server" << std::endl; + exit(1); + } + if (bind(socketFD, (struct sockaddr *)&address, sizeof(address)) == -1) + { + std::cerr << "ERROR - Unable to bind socket" << std::endl; + exit(1); + } + // Listen for connections and then accept + listen(socketFD, 100); +} + +void Server::Close(void) { + std::cout << "Closing the server" << std::endl; + close(socketFD); +} diff --git a/src/network.hpp b/src/network.hpp new file mode 100644 index 0000000..7bae37e --- /dev/null +++ b/src/network.hpp @@ -0,0 +1,32 @@ +#ifndef NETWORK_HPP +#define NETWORK_HPP + +#include +#include + +#define BUF_SIZE 4096 // Buffer size (big enough for a GET) + +#define kProxyPort 9080 +#define kWebserverIP "127.0.0.1" +#define kWebserverPort 7080 + +void HandleClient(int browser_s, int server_s); + +struct Client { + unsigned int socketFD; // Client socket descriptor + sockaddr_in address; // Client IP address + socklen_t addressLength; // Internet address length + Client(void); + bool ConnectFrom(int socketFD); + bool ConnectTo(int portNumber); +}; + +struct Server { + unsigned int socketFD; // Server socket descriptor + sockaddr_in address; // Server Internet address + Server(int portNumber); + void Open(void); + void Close(void); +}; + +#endif diff --git a/src/proxy.cpp b/src/proxy.cpp index 367f9f6..31a0ed8 100644 --- a/src/proxy.cpp +++ b/src/proxy.cpp @@ -1,17 +1,9 @@ //----- Include files --------------------------------------------------------- -#include // Needed for exit() -#include // Needed for strcpy() and strlen() -#include // Needed for file i/o constants -#include // Needed for file i/o constants +#include #include #include - -#include // -#include // -#include // -#include // -#include - +#include +#include "network.hpp" //----- HTTP response messages ---------------------------------------------- #define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n" @@ -19,88 +11,32 @@ #define NOTOK_404 "HTTP/1.0 404 Not Found\nContent-Type:text/html\n\n" #define MESS_404 "

FILE NOT FOUND

" -//----- Defines ------------------------------------------------------------- -#define BUF_SIZE 4096 // Buffer size (big enough for a GET) -#define PORT_NUM 9080 // Port number for a Web server - -//----- Function prototypes ------------------------------------------------- -void BrowserToServer(int browser_s, int server_s); -void ServerToBrowser(int server_s, int browser_s); - -//===== modeule main ======================================================== int main(void) { - unsigned int proxy_s; // Server socket descriptor - struct sockaddr_in proxy_addr; // Server Internet address - unsigned int browser_s; // Client socket descriptor - struct sockaddr_in browser_addr; // Client Internet address - struct in_addr browser_ip_addr; // Client IP address - unsigned int server_s; // Client socket descriptor - struct sockaddr_in server_addr; // Client Internet address - struct in_addr server_ip_addr; // Client IP address - socklen_t addr_len; // Internet address length + std::vector> pending_futures; + Server proxy(kProxyPort); + Client browser; + Client webserver; - // Create a socket, fill-in address information, and then bind it - proxy_s = socket(AF_INET, SOCK_STREAM, 0); - if (proxy_s == -1) - { - std::cerr << "ERROR - Unable to create socket on server" << std::endl; - exit(1); - } - proxy_addr.sin_family = AF_INET; - proxy_addr.sin_port = htons(PORT_NUM); - proxy_addr.sin_addr.s_addr = htonl(INADDR_ANY); - int bindRet = bind(proxy_s, (struct sockaddr *)&proxy_addr, sizeof(proxy_addr)); - if (bindRet == -1) - { - std::cerr << "ERROR - Unable to bind socket" << std::endl; - exit(1); - } - // Listen for connections and then accept - listen(proxy_s, 100); + proxy.Open(); // Main loop to listen, accept, and then spin-off a thread to handle the GET while (1) { - addr_len = sizeof(browser_addr); - - browser_s = accept(proxy_s, (struct sockaddr *)&browser_addr, &addr_len); - if (browser_s == -1) - { + if (browser.ConnectFrom(proxy.socketFD) != 0) + { std::cerr << "ERROR - Unable to create socket to client" << std::endl; continue; - } - std::cout << "Got here" << std::endl; - unsigned int server_s = socket(AF_INET, SOCK_STREAM, 0); - connect(server_s, (struct sockaddr *)&server_addr, addr_len); - - std::async(std::launch::async, BrowserToServer, browser_s, server_s); - std::async(std::launch::async, ServerToBrowser, server_s, browser_s); + } + if (webserver.ConnectTo(kWebserverPort) != 0) + { + std::cerr << "ERROR - Unable to connect to webserver" << std::endl; + continue; + } + auto newThreadRequest = std::async(std::launch::async, HandleClient, browser.socketFD, webserver.socketFD); + pending_futures.push_back(std::move(newThreadRequest)); } - close(proxy_s); - return (1); + proxy.Close(); + return 0; } -void BrowserToServer(int browser_s, int server_s) { - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - ssize_t buf_len; // Buffer length for file reads - - // Pass GET along from browser to server - do { - buf_len = recv(browser_s, in_buf, BUF_SIZE, 0); - send(server_s, in_buf, buf_len, 0); - } while (buf_len != 0); -} - -void ServerToBrowser(int server_s, int browser_s) { - char out_buf[BUF_SIZE]; // Output buffer for HTML response - ssize_t buf_len; // Buffer length for file reads - - // Pass response along from server to browser - do { - buf_len = recv(server_s, out_buf, BUF_SIZE, 0); - send(browser_s, out_buf, buf_len, 0); - } while (buf_len != 0); - close(server_s); - close(browser_s); -}