From 4bb1f4c53d592ed390e114c56c08bda75467e3af Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 01:20:54 -0500 Subject: [PATCH 01/13] Added .gitignore for webserver in test --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ee52d22..95e41c4 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,5 @@ *.app # Extras -build +./build +./test/page/web_server From 74db97438b6b404879c5f89c100ea8c7312f8657 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 01:39:58 -0500 Subject: [PATCH 02/13] Fixed .gitignore not working right --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 95e41c4..6dadcdc 100644 --- a/.gitignore +++ b/.gitignore @@ -33,5 +33,5 @@ *.app # Extras -./build -./test/page/web_server +build +test/page/web_server From 42a1213dcc72fea7183800b590da9204b1f0c243 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 01:40:56 -0500 Subject: [PATCH 03/13] Renamed output files to appropriate names --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bcec49c..2cf01d3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,8 @@ -add_executable(proxy-network +add_executable(web_server ./mt_web_server.cpp ) -add_executable(tempmulti +add_executable(proxy ./multi_threads.cpp ) From 15b1b7beb233933d0649ceb086401e61e61deb99 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 01:41:36 -0500 Subject: [PATCH 04/13] Always check before pushing >.> --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2cf01d3..81213aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,5 +6,5 @@ add_executable(proxy ./multi_threads.cpp ) -target_include_directories(proxy-network PUBLIC ${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(web_server PUBLIC ${CMAKE_CURRENT_LIST_DIR}) From 859a2bd525465cf2d6fb67037e74fd8dfd190c73 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 02:29:54 -0500 Subject: [PATCH 05/13] Fixed fork bomb issue and some wrong return codes --- src/mt_web_server.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/mt_web_server.cpp b/src/mt_web_server.cpp index 31c217d..f1da607 100644 --- a/src/mt_web_server.cpp +++ b/src/mt_web_server.cpp @@ -64,7 +64,7 @@ //----- Defines ------------------------------------------------------------- #define BUF_SIZE 4096 // Buffer size (big enough for a GET) -#define PORT_NUM 9080 // Port number for a Web server +#define PORT_NUM 7080 // Port number for a Web server //----- Function prototypes ------------------------------------------------- /* FOR WIN --------------------------------------------------------------- */ @@ -136,7 +136,7 @@ int main(void) nChild_proc_id = fork(); // Separate the parent and child process here ... - if (nChild_proc_id == 0) // if I am a new child, go to the child module. + if (nChild_proc_id == -1) // if I am a new child, go to the child module. { child_proc(server_s, client_s); } @@ -251,7 +251,7 @@ void child_proc(int server_s, int client_s) char *file_name; // File name unsigned int fh; // File handle unsigned int buf_len; // Buffer length for file reads - unsigned int retcode; // Return code + ssize_t retcode; // Return code // Shut down the parent pipe close(server_s); @@ -288,18 +288,19 @@ void child_proc(int server_s, int client_s) else strcpy(out_buf, OK_TEXT); send(client_s, out_buf, strlen(out_buf), 0); - + while (fh != EOF) - { + { buf_len = read(fh, out_buf, BUF_SIZE); send(client_s, out_buf, buf_len, 0); - } + } close(fh); } } // Shut down my (the child) pipe close(client_s); + exit(1); } #endif /* ----------------------------------------------------------------------- */ From 931de23a675d8033cd9e82212eb9380f6171e620 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 02:30:57 -0500 Subject: [PATCH 06/13] Prep for web_server rewrite --- src/CMakeLists.txt | 2 +- src/web_server.cpp | 306 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 src/web_server.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 81213aa..c340c1f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(web_server - ./mt_web_server.cpp + ./web_server.cpp ) add_executable(proxy diff --git a/src/web_server.cpp b/src/web_server.cpp new file mode 100644 index 0000000..f1da607 --- /dev/null +++ b/src/web_server.cpp @@ -0,0 +1,306 @@ +//====================================================== file = weblite.c ===== +//= A super light weight HTTP server = +//============================================================================= +//= Notes: = +//= 1) Compiles for Winsock only since uses Windows threads. Generates = +//= one warning about unreachable code in main. Ignore this warning. = +//= 2) Serves HTML and GIF only. = +//= 3) Sometimes the browser drops a connection when doing a refresh. = +//= This is handled by checking the recv() return code in the function = +//= that handles GETs. = +//= 4) The 404 HTML message does not always display in Explorer. = +//=---------------------------------------------------------------------------= +//= Execution notes: = +//= 1) Execute this program in the directory which will be the root for = +//= all file references (i.e., the directory that is considered at = +//= "public.html"). = +//= 2) Open a Web browser and surf to http://xxx.xxx.xxx.xxx/yyy where = +//= xxx.xxx.xxx.xxx is the IP address or hostname of the machine that = +//= weblite is executing on and yyy is the requested object. = +//= 3) The only output (to stdout) from weblite is a message with the = +//= of the file currently being sent = +//=---------------------------------------------------------------------------= +//= Build: bcc32 weblite.c, cl weblite.c wsock32.lib (or ws2_32.lib) = +//= gcc weblite.c -lsocket -lnsl for BSD = +//=---------------------------------------------------------------------------= +//= Execute: weblite = +//=---------------------------------------------------------------------------= +//= History: KJC (12/29/00) - Genesis (from server.c) = +//= HF (01/25/01) - Ported to multi-platform environment = +//============================================================================= +#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. + +//----- Include files --------------------------------------------------------- +#include // Needed for printf() +#include // Needed for exit() +#include // Needed for strcpy() and strlen() +#include // Needed for file i/o constants +#include // Needed for file i/o constants + +/* FOR BSD UNIX/LINUX ---------------------------------------------------- */ +#ifdef UNIX +#include // +#include // +#include // +#include // +#include +#endif +/* ------------------------------------------------------------------------ */ + +/* FOR WIN ---------------------------------------------------------------- */ +#ifdef WIN +#include // Needed for _threadid +#include // Needed for _beginthread() and _endthread() +#include // Needed for open(), close(), and eof() +#include // Needed for all Winsock stuff +#endif +/* ------------------------------------------------------------------------ */ + +//----- HTTP response messages ---------------------------------------------- +#define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n" +#define OK_TEXT "HTTP/1.0 200 OK\nContent-Type:text/html\n\n" +#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 7080 // Port number for a Web server + +//----- Function prototypes ------------------------------------------------- +/* FOR WIN --------------------------------------------------------------- */ +#ifdef WIN +void handle_get(void *in_arg); // Thread function to handle GET +#endif +/* ----------------------------------------------------------------------- */ + +/* FOR UNIX/LINUX -------------------------------------------------------- */ +#ifdef UNIX +void child_proc(int server_s, int client_s); // Fork function for GET +#endif +/* ----------------------------------------------------------------------- */ + +//===== modeule main ======================================================== +int main(void) +{ + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + WORD wVersionRequested = MAKEWORD(1, 1); // Stuff for WSA functions + WSADATA wsaData; // Stuff for WSA functions +#endif + /* --------------------------------------------------------------------- */ + + unsigned int server_s; // Server socket descriptor + struct sockaddr_in server_addr; // Server Internet address + unsigned int client_s; // Client socket descriptor + struct sockaddr_in client_addr; // Client Internet address + struct in_addr client_ip_addr; // Client IP address + socklen_t addr_len; // Internet address length + + /* FOR UNIX/LINUX ------------------------------------------------------ */ +#ifdef UNIX + int nChild_proc_id; // New child process ID. +#endif + /* --------------------------------------------------------------------- */ + + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + // Initialize winsock + WSAStartup(wVersionRequested, &wsaData); +#endif + /* --------------------------------------------------------------------- */ + + // Create a socket, fill-in address information, and then bind it + server_s = socket(AF_INET, SOCK_STREAM, 0); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(PORT_NUM); + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); + + // Main loop to listen, accept, and then spin-off a thread to handle the GET + while (1) + { + // Listen for connections and then accept + listen(server_s, 100); + addr_len = sizeof(client_addr); + + client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len); + if (client_s == 0) + { + printf("ERROR - Unable to create socket \n"); + exit(1); + } + + /* FOR UNIX/LINUX ---------------------------------------------------- */ +#ifdef UNIX + // Spin-off a child process by fork + nChild_proc_id = fork(); + + // Separate the parent and child process here ... + if (nChild_proc_id == -1) // if I am a new child, go to the child module. + { + child_proc(server_s, client_s); + } +#endif + /* ------------------------------------------------------------------- */ + + /* FOR WIN ----------------------------------------------------------- */ +#ifdef WIN + // Spin-off a thread to handle this request (pass only client_s) + if (_beginthread(handle_get, 4096, (void *)client_s) < 0) + { + printf("ERROR - Unable to create thread \n"); + exit(1); + } +#endif + /* ------------------------------------------------------------------- */ + } + + /* FOR UNIX/LINUX ------------------------------------------------------ */ +#ifdef UNIX + // Close the server socket + close(server_s); +#endif + /* --------------------------------------------------------------------- */ + + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + // Close the server socket and clean-up winsock + printf("this web server is shutting down .....\a\n"); + + closesocket(server_s); + WSACleanup(); +#endif + /* --------------------------------------------------------------------- */ + + // To make sure this "main" returns an integer. + return (1); +} + +/* FOR WIN --------------------------------------------------------------- */ +#ifdef WIN +//=========================================================================== +//= This is is the thread function to handle the GET = +//= - It is assumed that the request is a GET = +//=========================================================================== +void handle_get(void *in_arg) +{ + unsigned int client_s; // Client socket descriptor + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + unsigned int retcode; // Return code + + // Set client_s to in_arg + client_s = (unsigned int)in_arg; + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" + fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + while (!eof(fh)) + { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } + close(fh); + } + } + + // Close the client socket and end the thread + closesocket(client_s); + _endthread(); +} +#endif +/* ----------------------------------------------------------------------- */ + +/* FOR UNIX/LINUX -------------------------------------------------------- */ +#ifdef UNIX +void child_proc(int server_s, int client_s) +{ + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + ssize_t retcode; // Return code + + // Shut down the parent pipe + close(server_s); + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" + // fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); + fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + + while (fh != EOF) + { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } + close(fh); + } + } + + // Shut down my (the child) pipe + close(client_s); + exit(1); +} +#endif +/* ----------------------------------------------------------------------- */ From 3b3c421bae55cd6510709bda50d7edbda4fb96a3 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 02:36:18 -0500 Subject: [PATCH 07/13] Converted web_server to unix --- src/web_server.cpp | 613 +++++++++++++++++++++++---------------------- 1 file changed, 307 insertions(+), 306 deletions(-) diff --git a/src/web_server.cpp b/src/web_server.cpp index f1da607..cb0dbc8 100644 --- a/src/web_server.cpp +++ b/src/web_server.cpp @@ -1,306 +1,307 @@ -//====================================================== file = weblite.c ===== -//= A super light weight HTTP server = -//============================================================================= -//= Notes: = -//= 1) Compiles for Winsock only since uses Windows threads. Generates = -//= one warning about unreachable code in main. Ignore this warning. = -//= 2) Serves HTML and GIF only. = -//= 3) Sometimes the browser drops a connection when doing a refresh. = -//= This is handled by checking the recv() return code in the function = -//= that handles GETs. = -//= 4) The 404 HTML message does not always display in Explorer. = -//=---------------------------------------------------------------------------= -//= Execution notes: = -//= 1) Execute this program in the directory which will be the root for = -//= all file references (i.e., the directory that is considered at = -//= "public.html"). = -//= 2) Open a Web browser and surf to http://xxx.xxx.xxx.xxx/yyy where = -//= xxx.xxx.xxx.xxx is the IP address or hostname of the machine that = -//= weblite is executing on and yyy is the requested object. = -//= 3) The only output (to stdout) from weblite is a message with the = -//= of the file currently being sent = -//=---------------------------------------------------------------------------= -//= Build: bcc32 weblite.c, cl weblite.c wsock32.lib (or ws2_32.lib) = -//= gcc weblite.c -lsocket -lnsl for BSD = -//=---------------------------------------------------------------------------= -//= Execute: weblite = -//=---------------------------------------------------------------------------= -//= History: KJC (12/29/00) - Genesis (from server.c) = -//= HF (01/25/01) - Ported to multi-platform environment = -//============================================================================= -#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. - -//----- Include files --------------------------------------------------------- -#include // Needed for printf() -#include // Needed for exit() -#include // Needed for strcpy() and strlen() -#include // Needed for file i/o constants -#include // Needed for file i/o constants - -/* FOR BSD UNIX/LINUX ---------------------------------------------------- */ -#ifdef UNIX -#include // -#include // -#include // -#include // -#include -#endif -/* ------------------------------------------------------------------------ */ - -/* FOR WIN ---------------------------------------------------------------- */ -#ifdef WIN -#include // Needed for _threadid -#include // Needed for _beginthread() and _endthread() -#include // Needed for open(), close(), and eof() -#include // Needed for all Winsock stuff -#endif -/* ------------------------------------------------------------------------ */ - -//----- HTTP response messages ---------------------------------------------- -#define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n" -#define OK_TEXT "HTTP/1.0 200 OK\nContent-Type:text/html\n\n" -#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 7080 // Port number for a Web server - -//----- Function prototypes ------------------------------------------------- -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -void handle_get(void *in_arg); // Thread function to handle GET -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s); // Fork function for GET -#endif -/* ----------------------------------------------------------------------- */ - -//===== modeule main ======================================================== -int main(void) -{ - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - WORD wVersionRequested = MAKEWORD(1, 1); // Stuff for WSA functions - WSADATA wsaData; // Stuff for WSA functions -#endif - /* --------------------------------------------------------------------- */ - - unsigned int server_s; // Server socket descriptor - struct sockaddr_in server_addr; // Server Internet address - unsigned int client_s; // Client socket descriptor - struct sockaddr_in client_addr; // Client Internet address - struct in_addr client_ip_addr; // Client IP address - socklen_t addr_len; // Internet address length - - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX - int nChild_proc_id; // New child process ID. -#endif - /* --------------------------------------------------------------------- */ - - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - // Initialize winsock - WSAStartup(wVersionRequested, &wsaData); -#endif - /* --------------------------------------------------------------------- */ - - // Create a socket, fill-in address information, and then bind it - server_s = socket(AF_INET, SOCK_STREAM, 0); - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(PORT_NUM); - server_addr.sin_addr.s_addr = htonl(INADDR_ANY); - bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); - - // Main loop to listen, accept, and then spin-off a thread to handle the GET - while (1) - { - // Listen for connections and then accept - listen(server_s, 100); - addr_len = sizeof(client_addr); - - client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len); - if (client_s == 0) - { - printf("ERROR - Unable to create socket \n"); - exit(1); - } - - /* FOR UNIX/LINUX ---------------------------------------------------- */ -#ifdef UNIX - // Spin-off a child process by fork - nChild_proc_id = fork(); - - // Separate the parent and child process here ... - if (nChild_proc_id == -1) // if I am a new child, go to the child module. - { - child_proc(server_s, client_s); - } -#endif - /* ------------------------------------------------------------------- */ - - /* FOR WIN ----------------------------------------------------------- */ -#ifdef WIN - // Spin-off a thread to handle this request (pass only client_s) - if (_beginthread(handle_get, 4096, (void *)client_s) < 0) - { - printf("ERROR - Unable to create thread \n"); - exit(1); - } -#endif - /* ------------------------------------------------------------------- */ - } - - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX - // Close the server socket - close(server_s); -#endif - /* --------------------------------------------------------------------- */ - - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - // Close the server socket and clean-up winsock - printf("this web server is shutting down .....\a\n"); - - closesocket(server_s); - WSACleanup(); -#endif - /* --------------------------------------------------------------------- */ - - // To make sure this "main" returns an integer. - return (1); -} - -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -//=========================================================================== -//= This is is the thread function to handle the GET = -//= - It is assumed that the request is a GET = -//=========================================================================== -void handle_get(void *in_arg) -{ - unsigned int client_s; // Client socket descriptor - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - char out_buf[BUF_SIZE]; // Output buffer for HTML response - char *file_name; // File name - unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads - unsigned int retcode; // Return code - - // Set client_s to in_arg - client_s = (unsigned int)in_arg; - - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - while (!eof(fh)) - { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } - close(fh); - } - } - - // Close the client socket and end the thread - closesocket(client_s); - _endthread(); -} -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s) -{ - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - char out_buf[BUF_SIZE]; // Output buffer for HTML response - char *file_name; // File name - unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads - ssize_t retcode; // Return code - - // Shut down the parent pipe - close(server_s); - - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - // fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - - while (fh != EOF) - { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } - close(fh); - } - } - - // Shut down my (the child) pipe - close(client_s); - exit(1); -} -#endif -/* ----------------------------------------------------------------------- */ +//====================================================== file = weblite.c ===== +//= A super light weight HTTP server = +//============================================================================= +//= Notes: = +//= 1) Compiles for Winsock only since uses Windows threads. Generates = +//= one warning about unreachable code in main. Ignore this warning. = +//= 2) Serves HTML and GIF only. = +//= 3) Sometimes the browser drops a connection when doing a refresh. = +//= This is handled by checking the recv() return code in the function = +//= that handles GETs. = +//= 4) The 404 HTML message does not always display in Explorer. = +//=---------------------------------------------------------------------------= +//= Execution notes: = +//= 1) Execute this program in the directory which will be the root for = +//= all file references (i.e., the directory that is considered at = +//= "public.html"). = +//= 2) Open a Web browser and surf to http://xxx.xxx.xxx.xxx/yyy where = +//= xxx.xxx.xxx.xxx is the IP address or hostname of the machine that = +//= weblite is executing on and yyy is the requested object. = +//= 3) The only output (to stdout) from weblite is a message with the = +//= of the file currently being sent = +//=---------------------------------------------------------------------------= +//= Build: bcc32 weblite.c, cl weblite.c wsock32.lib (or ws2_32.lib) = +//= gcc weblite.c -lsocket -lnsl for BSD = +//=---------------------------------------------------------------------------= +//= Execute: weblite = +//=---------------------------------------------------------------------------= +//= History: KJC (12/29/00) - Genesis (from server.c) = +//= HF (01/25/01) - Ported to multi-platform environment = +//============================================================================= +#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. + +//----- Include files --------------------------------------------------------- +#include // Needed for printf() +#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 + +/* FOR BSD UNIX/LINUX ---------------------------------------------------- */ +#ifdef UNIX +#include // +#include // +#include // +#include // +#include +#endif +/* ------------------------------------------------------------------------ */ + +/* FOR WIN ---------------------------------------------------------------- */ +#ifdef WIN +#include // Needed for _threadid +#include // Needed for _beginthread() and _endthread() +#include // Needed for open(), close(), and eof() +#include // Needed for all Winsock stuff +#endif +/* ------------------------------------------------------------------------ */ + +//----- HTTP response messages ---------------------------------------------- +#define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n" +#define OK_TEXT "HTTP/1.0 200 OK\nContent-Type:text/html\n\n" +#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 7080 // Port number for a Web server + +//----- Function prototypes ------------------------------------------------- +/* FOR WIN --------------------------------------------------------------- */ +#ifdef WIN +void handle_get(void *in_arg); // Thread function to handle GET +#endif +/* ----------------------------------------------------------------------- */ + +/* FOR UNIX/LINUX -------------------------------------------------------- */ +#ifdef UNIX +void child_proc(int server_s, int client_s); // Fork function for GET +#endif +/* ----------------------------------------------------------------------- */ + +//===== modeule main ======================================================== +int main(void) +{ + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + WORD wVersionRequested = MAKEWORD(1, 1); // Stuff for WSA functions + WSADATA wsaData; // Stuff for WSA functions +#endif + /* --------------------------------------------------------------------- */ + + unsigned int server_s; // Server socket descriptor + struct sockaddr_in server_addr; // Server Internet address + unsigned int client_s; // Client socket descriptor + struct sockaddr_in client_addr; // Client Internet address + struct in_addr client_ip_addr; // Client IP address + socklen_t addr_len; // Internet address length + + /* FOR UNIX/LINUX ------------------------------------------------------ */ +#ifdef UNIX + int nChild_proc_id; // New child process ID. +#endif + /* --------------------------------------------------------------------- */ + + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + // Initialize winsock + WSAStartup(wVersionRequested, &wsaData); +#endif + /* --------------------------------------------------------------------- */ + + // Create a socket, fill-in address information, and then bind it + server_s = socket(AF_INET, SOCK_STREAM, 0); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(PORT_NUM); + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); + + // Main loop to listen, accept, and then spin-off a thread to handle the GET + while (1) + { + // Listen for connections and then accept + listen(server_s, 100); + addr_len = sizeof(client_addr); + + client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len); + if (client_s == 0) + { + printf("ERROR - Unable to create socket \n"); + exit(1); + } + + /* FOR UNIX/LINUX ---------------------------------------------------- */ +#ifdef UNIX + // Spin-off a child process by fork + nChild_proc_id = fork(); + + // Separate the parent and child process here ... + if (nChild_proc_id == -1) // if I am a new child, go to the child module. + { + child_proc(server_s, client_s); + } +#endif + /* ------------------------------------------------------------------- */ + + /* FOR WIN ----------------------------------------------------------- */ +#ifdef WIN + // Spin-off a thread to handle this request (pass only client_s) + if (_beginthread(handle_get, 4096, (void *)client_s) < 0) + { + printf("ERROR - Unable to create thread \n"); + exit(1); + } +#endif + /* ------------------------------------------------------------------- */ + } + + /* FOR UNIX/LINUX ------------------------------------------------------ */ +#ifdef UNIX + // Close the server socket + close(server_s); +#endif + /* --------------------------------------------------------------------- */ + + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + // Close the server socket and clean-up winsock + printf("this web server is shutting down .....\a\n"); + + closesocket(server_s); + WSACleanup(); +#endif + /* --------------------------------------------------------------------- */ + + // To make sure this "main" returns an integer. + return (1); +} + +/* FOR WIN --------------------------------------------------------------- */ +#ifdef WIN +//=========================================================================== +//= This is is the thread function to handle the GET = +//= - It is assumed that the request is a GET = +//=========================================================================== +void handle_get(void *in_arg) +{ + unsigned int client_s; // Client socket descriptor + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + unsigned int retcode; // Return code + + // Set client_s to in_arg + client_s = (unsigned int)in_arg; + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" + fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + while (!eof(fh)) + { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } + close(fh); + } + } + + // Close the client socket and end the thread + closesocket(client_s); + _endthread(); +} +#endif +/* ----------------------------------------------------------------------- */ + +/* FOR UNIX/LINUX -------------------------------------------------------- */ +#ifdef UNIX +void child_proc(int server_s, int client_s) +{ + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + ssize_t retcode; // Return code + + // Shut down the parent pipe + close(server_s); + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" + // fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); + fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + + while (fh != EOF) + { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } + close(fh); + } + } + + // Shut down my (the child) pipe + close(client_s); + exit(1); +} +#endif +/* ----------------------------------------------------------------------- */ From 985d2d8d77db240e42e628b51830401a866df322 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 04:08:29 -0500 Subject: [PATCH 08/13] Web server works on Linux, multithreaded server is now under async --- src/web_server.cpp | 105 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 15 deletions(-) diff --git a/src/web_server.cpp b/src/web_server.cpp index cb0dbc8..4cab66f 100644 --- a/src/web_server.cpp +++ b/src/web_server.cpp @@ -28,7 +28,7 @@ //= History: KJC (12/29/00) - Genesis (from server.c) = //= HF (01/25/01) - Ported to multi-platform environment = //============================================================================= -#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. +#define WIN // WIN for Windows environment, UNIX for BSD or LINUX env. //----- Include files --------------------------------------------------------- #include // Needed for printf() @@ -36,7 +36,7 @@ #include // Needed for strcpy() and strlen() #include // Needed for file i/o constants #include // Needed for file i/o constants -#include +#include /* FOR BSD UNIX/LINUX ---------------------------------------------------- */ #ifdef UNIX @@ -53,10 +53,14 @@ #include // Needed for _threadid #include // Needed for _beginthread() and _endthread() #include // Needed for open(), close(), and eof() +#include #include // Needed for all Winsock stuff +// Lazy struct fixes +typedef int32_t socklen_t; #endif /* ------------------------------------------------------------------------ */ + //----- HTTP response messages ---------------------------------------------- #define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n" #define OK_TEXT "HTTP/1.0 200 OK\nContent-Type:text/html\n\n" @@ -68,6 +72,7 @@ #define PORT_NUM 7080 // Port number for a Web server //----- Function prototypes ------------------------------------------------- +void ClientRequest(int server_s, int client_s); /* FOR WIN --------------------------------------------------------------- */ #ifdef WIN void handle_get(void *in_arg); // Thread function to handle GET @@ -112,54 +117,70 @@ int main(void) // Create a socket, fill-in address information, and then bind it server_s = socket(AF_INET, SOCK_STREAM, 0); + if (server_s == -1) + { + printf("ERROR - Unable to create socket on server\n"); + exit(1); + } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT_NUM); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); - bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); + int bindRet = bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); + if (bindRet == -1) + { + printf("ERROR - Unable to bind socket\n"); + exit(1); + } + // Listen for connections and then accept + listen(server_s, 100); // Main loop to listen, accept, and then spin-off a thread to handle the GET while (1) { - // Listen for connections and then accept - listen(server_s, 100); addr_len = sizeof(client_addr); client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len); - if (client_s == 0) + if (client_s == -1) { - printf("ERROR - Unable to create socket \n"); - exit(1); + perror("ERROR - Unable to create socket to client\n"); + continue; } + std::async(std::launch::async, ClientRequest, server_s, client_s); + /* FOR UNIX/LINUX ---------------------------------------------------- */ #ifdef UNIX + /* // Spin-off a child process by fork nChild_proc_id = fork(); // Separate the parent and child process here ... if (nChild_proc_id == -1) // if I am a new child, go to the child module. { - child_proc(server_s, client_s); + child_proc(server_s, client_s); } + */ #endif /* ------------------------------------------------------------------- */ /* FOR WIN ----------------------------------------------------------- */ #ifdef WIN + /* // Spin-off a thread to handle this request (pass only client_s) if (_beginthread(handle_get, 4096, (void *)client_s) < 0) { printf("ERROR - Unable to create thread \n"); exit(1); } + */ #endif /* ------------------------------------------------------------------- */ } - + close(server_s); /* FOR UNIX/LINUX ------------------------------------------------------ */ #ifdef UNIX // Close the server socket - close(server_s); + //close(server_s); #endif /* --------------------------------------------------------------------- */ @@ -177,6 +198,61 @@ int main(void) return (1); } +void ClientRequest(int server_s, int client_s) { + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + unsigned int retcode; // Return code + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" +#ifdef WIN + fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); +#endif +#ifdef UNIX + fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); +#endif + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + do { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } while (buf_len != 0); + close(fh); + } + } + // Close the client socket and end the thread + close(client_s); +} + /* FOR WIN --------------------------------------------------------------- */ #ifdef WIN //=========================================================================== @@ -194,7 +270,7 @@ void handle_get(void *in_arg) unsigned int retcode; // Return code // Set client_s to in_arg - client_s = (unsigned int)in_arg; + client_s = (unsigned int&)in_arg; // Receive the GET request from the Web browser retcode = recv(client_s, in_buf, BUF_SIZE, 0); @@ -290,11 +366,10 @@ void child_proc(int server_s, int client_s) strcpy(out_buf, OK_TEXT); send(client_s, out_buf, strlen(out_buf), 0); - while (fh != EOF) - { + do { buf_len = read(fh, out_buf, BUF_SIZE); send(client_s, out_buf, buf_len, 0); - } + } while (buf_len != 0); close(fh); } } From bc23048b94b160fe5ac465647d562aa0118e78ef Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 14:28:48 -0500 Subject: [PATCH 09/13] Setup for implementing proxy --- src/CMakeLists.txt | 4 +- src/proxy.cpp | 382 +++++++++++++++++++++++++++++++++++++++++++++ src/web_server.cpp | 2 +- 3 files changed, 384 insertions(+), 4 deletions(-) create mode 100644 src/proxy.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c340c1f..0636427 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,8 +3,6 @@ add_executable(web_server ) add_executable(proxy - ./multi_threads.cpp + ./proxy.cpp ) -target_include_directories(web_server PUBLIC ${CMAKE_CURRENT_LIST_DIR}) - diff --git a/src/proxy.cpp b/src/proxy.cpp new file mode 100644 index 0000000..b08335b --- /dev/null +++ b/src/proxy.cpp @@ -0,0 +1,382 @@ +//====================================================== file = weblite.c ===== +//= A super light weight HTTP server = +//============================================================================= +//= Notes: = +//= 1) Compiles for Winsock only since uses Windows threads. Generates = +//= one warning about unreachable code in main. Ignore this warning. = +//= 2) Serves HTML and GIF only. = +//= 3) Sometimes the browser drops a connection when doing a refresh. = +//= This is handled by checking the recv() return code in the function = +//= that handles GETs. = +//= 4) The 404 HTML message does not always display in Explorer. = +//=---------------------------------------------------------------------------= +//= Execution notes: = +//= 1) Execute this program in the directory which will be the root for = +//= all file references (i.e., the directory that is considered at = +//= "public.html"). = +//= 2) Open a Web browser and surf to http://xxx.xxx.xxx.xxx/yyy where = +//= xxx.xxx.xxx.xxx is the IP address or hostname of the machine that = +//= weblite is executing on and yyy is the requested object. = +//= 3) The only output (to stdout) from weblite is a message with the = +//= of the file currently being sent = +//=---------------------------------------------------------------------------= +//= Build: bcc32 weblite.c, cl weblite.c wsock32.lib (or ws2_32.lib) = +//= gcc weblite.c -lsocket -lnsl for BSD = +//=---------------------------------------------------------------------------= +//= Execute: weblite = +//=---------------------------------------------------------------------------= +//= History: KJC (12/29/00) - Genesis (from server.c) = +//= HF (01/25/01) - Ported to multi-platform environment = +//============================================================================= +#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. + +//----- Include files --------------------------------------------------------- +#include // Needed for printf() +#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 + +/* FOR BSD UNIX/LINUX ---------------------------------------------------- */ +#ifdef UNIX +#include // +#include // +#include // +#include // +#include +#endif +/* ------------------------------------------------------------------------ */ + +/* FOR WIN ---------------------------------------------------------------- */ +#ifdef WIN +#include // Needed for _threadid +#include // Needed for _beginthread() and _endthread() +#include // Needed for open(), close(), and eof() +#include +#include // Needed for all Winsock stuff +// Lazy struct fixes +typedef int32_t socklen_t; +#endif +/* ------------------------------------------------------------------------ */ + + +//----- HTTP response messages ---------------------------------------------- +#define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n" +#define OK_TEXT "HTTP/1.0 200 OK\nContent-Type:text/html\n\n" +#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 7080 // Port number for a Web server + +//----- Function prototypes ------------------------------------------------- +void ClientRequest(int server_s, int client_s); +/* FOR WIN --------------------------------------------------------------- */ +#ifdef WIN +void handle_get(void *in_arg); // Thread function to handle GET +#endif +/* ----------------------------------------------------------------------- */ + +/* FOR UNIX/LINUX -------------------------------------------------------- */ +#ifdef UNIX +void child_proc(int server_s, int client_s); // Fork function for GET +#endif +/* ----------------------------------------------------------------------- */ + +//===== modeule main ======================================================== +int main(void) +{ + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + WORD wVersionRequested = MAKEWORD(1, 1); // Stuff for WSA functions + WSADATA wsaData; // Stuff for WSA functions +#endif + /* --------------------------------------------------------------------- */ + + unsigned int server_s; // Server socket descriptor + struct sockaddr_in server_addr; // Server Internet address + unsigned int client_s; // Client socket descriptor + struct sockaddr_in client_addr; // Client Internet address + struct in_addr client_ip_addr; // Client IP address + socklen_t addr_len; // Internet address length + + /* FOR UNIX/LINUX ------------------------------------------------------ */ +#ifdef UNIX + int nChild_proc_id; // New child process ID. +#endif + /* --------------------------------------------------------------------- */ + + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + // Initialize winsock + WSAStartup(wVersionRequested, &wsaData); +#endif + /* --------------------------------------------------------------------- */ + + // Create a socket, fill-in address information, and then bind it + server_s = socket(AF_INET, SOCK_STREAM, 0); + if (server_s == -1) + { + printf("ERROR - Unable to create socket on server\n"); + exit(1); + } + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(PORT_NUM); + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + int bindRet = bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); + if (bindRet == -1) + { + printf("ERROR - Unable to bind socket\n"); + exit(1); + } + // Listen for connections and then accept + listen(server_s, 100); + + // Main loop to listen, accept, and then spin-off a thread to handle the GET + while (1) + { + addr_len = sizeof(client_addr); + + client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len); + if (client_s == -1) + { + perror("ERROR - Unable to create socket to client\n"); + continue; + } + + std::async(std::launch::async, ClientRequest, server_s, client_s); + + /* FOR UNIX/LINUX ---------------------------------------------------- */ +#ifdef UNIX + /* + // Spin-off a child process by fork + nChild_proc_id = fork(); + + // Separate the parent and child process here ... + if (nChild_proc_id == -1) // if I am a new child, go to the child module. + { + child_proc(server_s, client_s); + } + */ +#endif + /* ------------------------------------------------------------------- */ + + /* FOR WIN ----------------------------------------------------------- */ +#ifdef WIN + /* + // Spin-off a thread to handle this request (pass only client_s) + if (_beginthread(handle_get, 4096, (void *)client_s) < 0) + { + printf("ERROR - Unable to create thread \n"); + exit(1); + } + */ +#endif + /* ------------------------------------------------------------------- */ + } + close(server_s); + /* FOR UNIX/LINUX ------------------------------------------------------ */ +#ifdef UNIX + // Close the server socket + //close(server_s); +#endif + /* --------------------------------------------------------------------- */ + + /* FOR WIN ------------------------------------------------------------- */ +#ifdef WIN + // Close the server socket and clean-up winsock + printf("this web server is shutting down .....\a\n"); + + closesocket(server_s); + WSACleanup(); +#endif + /* --------------------------------------------------------------------- */ + + // To make sure this "main" returns an integer. + return (1); +} + +void ClientRequest(int server_s, int client_s) { + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + unsigned int retcode; // Return code + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" +#ifdef WIN + fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); +#endif +#ifdef UNIX + fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); +#endif + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + do { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } while (buf_len != 0); + close(fh); + } + } + // Close the client socket and end the thread + close(client_s); +} + +/* FOR WIN --------------------------------------------------------------- */ +#ifdef WIN +//=========================================================================== +//= This is is the thread function to handle the GET = +//= - It is assumed that the request is a GET = +//=========================================================================== +void handle_get(void *in_arg) +{ + unsigned int client_s; // Client socket descriptor + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + unsigned int retcode; // Return code + + // Set client_s to in_arg + client_s = (unsigned int&)in_arg; + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" + fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + while (!eof(fh)) + { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } + close(fh); + } + } + + // Close the client socket and end the thread + closesocket(client_s); + _endthread(); +} +#endif +/* ----------------------------------------------------------------------- */ + +/* FOR UNIX/LINUX -------------------------------------------------------- */ +#ifdef UNIX +void child_proc(int server_s, int client_s) +{ + char in_buf[BUF_SIZE]; // Input buffer for GET resquest + char out_buf[BUF_SIZE]; // Output buffer for HTML response + char *file_name; // File name + unsigned int fh; // File handle + unsigned int buf_len; // Buffer length for file reads + ssize_t retcode; // Return code + + // Shut down the parent pipe + close(server_s); + + // Receive the GET request from the Web browser + retcode = recv(client_s, in_buf, BUF_SIZE, 0); + + // Handle the GET if there is one (see note #3 in the header) + if (retcode != -1) + { + // Parse out the filename from the GET request + strtok(in_buf, " "); + file_name = strtok(NULL, " "); + + // Open the requested file + // - Start at 2nd char to get rid of leading "\" + // fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); + fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); + + // Generate and send the response (404 if could not open the file) + if (fh == -1) + { + printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); + strcpy(out_buf, NOTOK_404); + send(client_s, out_buf, strlen(out_buf), 0); + strcpy(out_buf, MESS_404); + send(client_s, out_buf, strlen(out_buf), 0); + } + else + { + printf("File %s is being sent \n", &file_name[1]); + if (strstr(file_name, ".gif") != NULL) + strcpy(out_buf, OK_IMAGE); + else + strcpy(out_buf, OK_TEXT); + send(client_s, out_buf, strlen(out_buf), 0); + + do { + buf_len = read(fh, out_buf, BUF_SIZE); + send(client_s, out_buf, buf_len, 0); + } while (buf_len != 0); + close(fh); + } + } + + // Shut down my (the child) pipe + close(client_s); + exit(1); +} +#endif +/* ----------------------------------------------------------------------- */ diff --git a/src/web_server.cpp b/src/web_server.cpp index 4cab66f..b08335b 100644 --- a/src/web_server.cpp +++ b/src/web_server.cpp @@ -28,7 +28,7 @@ //= History: KJC (12/29/00) - Genesis (from server.c) = //= HF (01/25/01) - Ported to multi-platform environment = //============================================================================= -#define WIN // WIN for Windows environment, UNIX for BSD or LINUX env. +#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. //----- Include files --------------------------------------------------------- #include // Needed for printf() From 36468aa958d41f6aed65945c76f6f99914382de9 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 16:02:10 -0500 Subject: [PATCH 10/13] Restructured project for simplicity and removed unused cpps --- .gitignore | 2 +- src/mt_web_server.cpp | 306 -------------------------------- src/multi_threads.cpp | 124 ------------- test/CMakeLists.txt | 7 - test/{page => }/almost_done.gif | Bin test/{page => }/index.html | 0 test/{page => }/rule1.gif | Bin test/{page => }/siuebdy1.jpg | Bin test/{page => }/siuebdy4.jpg | Bin test/{page => }/siuehdr2.jpg | Bin test/test.cpp | 28 --- 11 files changed, 1 insertion(+), 466 deletions(-) delete mode 100644 src/mt_web_server.cpp delete mode 100644 src/multi_threads.cpp delete mode 100644 test/CMakeLists.txt rename test/{page => }/almost_done.gif (100%) rename test/{page => }/index.html (100%) rename test/{page => }/rule1.gif (100%) rename test/{page => }/siuebdy1.jpg (100%) rename test/{page => }/siuebdy4.jpg (100%) rename test/{page => }/siuehdr2.jpg (100%) delete mode 100644 test/test.cpp diff --git a/.gitignore b/.gitignore index 6dadcdc..a047907 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,4 @@ # Extras build -test/page/web_server +test/web_server diff --git a/src/mt_web_server.cpp b/src/mt_web_server.cpp deleted file mode 100644 index f1da607..0000000 --- a/src/mt_web_server.cpp +++ /dev/null @@ -1,306 +0,0 @@ -//====================================================== file = weblite.c ===== -//= A super light weight HTTP server = -//============================================================================= -//= Notes: = -//= 1) Compiles for Winsock only since uses Windows threads. Generates = -//= one warning about unreachable code in main. Ignore this warning. = -//= 2) Serves HTML and GIF only. = -//= 3) Sometimes the browser drops a connection when doing a refresh. = -//= This is handled by checking the recv() return code in the function = -//= that handles GETs. = -//= 4) The 404 HTML message does not always display in Explorer. = -//=---------------------------------------------------------------------------= -//= Execution notes: = -//= 1) Execute this program in the directory which will be the root for = -//= all file references (i.e., the directory that is considered at = -//= "public.html"). = -//= 2) Open a Web browser and surf to http://xxx.xxx.xxx.xxx/yyy where = -//= xxx.xxx.xxx.xxx is the IP address or hostname of the machine that = -//= weblite is executing on and yyy is the requested object. = -//= 3) The only output (to stdout) from weblite is a message with the = -//= of the file currently being sent = -//=---------------------------------------------------------------------------= -//= Build: bcc32 weblite.c, cl weblite.c wsock32.lib (or ws2_32.lib) = -//= gcc weblite.c -lsocket -lnsl for BSD = -//=---------------------------------------------------------------------------= -//= Execute: weblite = -//=---------------------------------------------------------------------------= -//= History: KJC (12/29/00) - Genesis (from server.c) = -//= HF (01/25/01) - Ported to multi-platform environment = -//============================================================================= -#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. - -//----- Include files --------------------------------------------------------- -#include // Needed for printf() -#include // Needed for exit() -#include // Needed for strcpy() and strlen() -#include // Needed for file i/o constants -#include // Needed for file i/o constants - -/* FOR BSD UNIX/LINUX ---------------------------------------------------- */ -#ifdef UNIX -#include // -#include // -#include // -#include // -#include -#endif -/* ------------------------------------------------------------------------ */ - -/* FOR WIN ---------------------------------------------------------------- */ -#ifdef WIN -#include // Needed for _threadid -#include // Needed for _beginthread() and _endthread() -#include // Needed for open(), close(), and eof() -#include // Needed for all Winsock stuff -#endif -/* ------------------------------------------------------------------------ */ - -//----- HTTP response messages ---------------------------------------------- -#define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n" -#define OK_TEXT "HTTP/1.0 200 OK\nContent-Type:text/html\n\n" -#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 7080 // Port number for a Web server - -//----- Function prototypes ------------------------------------------------- -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -void handle_get(void *in_arg); // Thread function to handle GET -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s); // Fork function for GET -#endif -/* ----------------------------------------------------------------------- */ - -//===== modeule main ======================================================== -int main(void) -{ - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - WORD wVersionRequested = MAKEWORD(1, 1); // Stuff for WSA functions - WSADATA wsaData; // Stuff for WSA functions -#endif - /* --------------------------------------------------------------------- */ - - unsigned int server_s; // Server socket descriptor - struct sockaddr_in server_addr; // Server Internet address - unsigned int client_s; // Client socket descriptor - struct sockaddr_in client_addr; // Client Internet address - struct in_addr client_ip_addr; // Client IP address - socklen_t addr_len; // Internet address length - - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX - int nChild_proc_id; // New child process ID. -#endif - /* --------------------------------------------------------------------- */ - - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - // Initialize winsock - WSAStartup(wVersionRequested, &wsaData); -#endif - /* --------------------------------------------------------------------- */ - - // Create a socket, fill-in address information, and then bind it - server_s = socket(AF_INET, SOCK_STREAM, 0); - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(PORT_NUM); - server_addr.sin_addr.s_addr = htonl(INADDR_ANY); - bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); - - // Main loop to listen, accept, and then spin-off a thread to handle the GET - while (1) - { - // Listen for connections and then accept - listen(server_s, 100); - addr_len = sizeof(client_addr); - - client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len); - if (client_s == 0) - { - printf("ERROR - Unable to create socket \n"); - exit(1); - } - - /* FOR UNIX/LINUX ---------------------------------------------------- */ -#ifdef UNIX - // Spin-off a child process by fork - nChild_proc_id = fork(); - - // Separate the parent and child process here ... - if (nChild_proc_id == -1) // if I am a new child, go to the child module. - { - child_proc(server_s, client_s); - } -#endif - /* ------------------------------------------------------------------- */ - - /* FOR WIN ----------------------------------------------------------- */ -#ifdef WIN - // Spin-off a thread to handle this request (pass only client_s) - if (_beginthread(handle_get, 4096, (void *)client_s) < 0) - { - printf("ERROR - Unable to create thread \n"); - exit(1); - } -#endif - /* ------------------------------------------------------------------- */ - } - - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX - // Close the server socket - close(server_s); -#endif - /* --------------------------------------------------------------------- */ - - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - // Close the server socket and clean-up winsock - printf("this web server is shutting down .....\a\n"); - - closesocket(server_s); - WSACleanup(); -#endif - /* --------------------------------------------------------------------- */ - - // To make sure this "main" returns an integer. - return (1); -} - -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -//=========================================================================== -//= This is is the thread function to handle the GET = -//= - It is assumed that the request is a GET = -//=========================================================================== -void handle_get(void *in_arg) -{ - unsigned int client_s; // Client socket descriptor - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - char out_buf[BUF_SIZE]; // Output buffer for HTML response - char *file_name; // File name - unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads - unsigned int retcode; // Return code - - // Set client_s to in_arg - client_s = (unsigned int)in_arg; - - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - while (!eof(fh)) - { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } - close(fh); - } - } - - // Close the client socket and end the thread - closesocket(client_s); - _endthread(); -} -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s) -{ - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - char out_buf[BUF_SIZE]; // Output buffer for HTML response - char *file_name; // File name - unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads - ssize_t retcode; // Return code - - // Shut down the parent pipe - close(server_s); - - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - // fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - - while (fh != EOF) - { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } - close(fh); - } - } - - // Shut down my (the child) pipe - close(client_s); - exit(1); -} -#endif -/* ----------------------------------------------------------------------- */ diff --git a/src/multi_threads.cpp b/src/multi_threads.cpp deleted file mode 100644 index e64fd4d..0000000 --- a/src/multi_threads.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* ************************************************************************* * - * * - * Multi.cpp: * - * This is a sample program for multi-threaded applications. * - * * - * As soon as this program starts, the main thread generates two child * - * threads. The two child threads wait for 10 seconds and terminate. * - * * - * While the two child threads are running, the main thread waits. The * - * main thread waits until both threads finish. * - * * - * Compile: * - * In Project->Setting->C/C++->CodeGenartion(in Category) * - * ->Select Multi-threaded for runtime library * - * * - * Coded by: H. Fujinoki * - * September 12, 11:00 AM at Edwardsville, IL * - * * - * ************************************************************************* */ -#include -#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN -#include // for thread system calls (_beginthread, etc.) -#include // for TRUE, FALSE labels -#endif - /* --------------------------------------------------------------------- */ - - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX -#endif - /* --------------------------------------------------------------------- */ -#include -#include -#include // for printf -#include // for clock() and CLK_TCK - -/* Global label defenition ------------------------------------------------ */ -#define INTERVAL 1 // Transmission interval in seconds -#define REPEATS 10 // Number of child thread's repeats - -/* Global Variables ------------------------------------------------------- */ -int nChild1_status; // Child thread #1 status -int nChild2_status; // Child thread #2 status - -/* Prototypes ------------------------------------------------------------- */ -void ChildThread1(void); // The child thread #1 -void ChildThread2(void); // The child thread #2 - -/* The MAIN --------------------------------------------------------------- */ -int main (void) -{ - /* Set the child thread status (TRUE = RUNNING) --- */ - nChild1_status = true; - nChild2_status = true; - - /* Create and start the two threads --- */ - std::thread nChild1(ChildThread1); // Start child process #1 - std::thread nChild2(ChildThread2); // Start child process #2 - nChild1.join(); - nChild2.join(); - - /* Spin-loop until both threads finish --- */ - while ((nChild1_status == true)||(nChild2_status == true)) - { ; } - - /* Two threads are now finished --- */ - printf("Both child threads are finished ... \n"); - printf("The main thread is finishing ... \n"); -} - -// The Child-Thread #1 /////////////////////////////////////////////////////// -void ChildThread1(void) -{ - /* Child #1 local variable(s) --- */ - int i; // Loop counter - - /* This thread is started --- */ - printf("Child Thread #1 has started ... \n"); - - /* wait for 10 seconds w/ count down --- */ - for (i = 0; i < REPEATS; i++) - { - /* Wait for 10 seconds --- */ - std::this_thread::sleep_for(std::chrono::duration(1000)); - - /* Display count down --- */ - printf("Child #1: %d more second(s) to finish ...\n", REPEATS -i); - } - - /* Reset the status flag --- */ - nChild1_status = false; - - /* Terminate this thread --- */ - //_endthread(); -} - -// The Child-Thread #2 /////////////////////////////////////////////////////// -void ChildThread2(void) -{ - /* Child #2 local variable(s) --- */ - int i; // Loop counter - - /* This thread is started --- */ - printf("Child Thread #2 has started ... \n"); - - /* wait for 10 seconds w/ count down --- */ - for (i = 0; i < REPEATS; i++) - { - /* Wait for 10 seconds --- */ - std::this_thread::sleep_for(std::chrono::duration(1000)); - - /* Display count down --- */ - printf("Child #2: %d more second(s) to finish ...\n", REPEATS -i); - } - - /* Reset the status flag --- */ - nChild2_status = false; - - /* Terminate this thread --- */ - //_endthread(); -} - -// THE END OF LINES ////////////////////////////////////////////////////////// diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index 72a93d2..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -find_package(unity REQUIRED) -include_directories(${CMAKE_SOURCE_DIR}/src) -add_executable(testing - ./test.cpp -) -set_target_properties(testing PROPERTIES LINKER_LANGUAGE CXX) -target_link_libraries(testing unity) diff --git a/test/page/almost_done.gif b/test/almost_done.gif similarity index 100% rename from test/page/almost_done.gif rename to test/almost_done.gif diff --git a/test/page/index.html b/test/index.html similarity index 100% rename from test/page/index.html rename to test/index.html diff --git a/test/page/rule1.gif b/test/rule1.gif similarity index 100% rename from test/page/rule1.gif rename to test/rule1.gif diff --git a/test/page/siuebdy1.jpg b/test/siuebdy1.jpg similarity index 100% rename from test/page/siuebdy1.jpg rename to test/siuebdy1.jpg diff --git a/test/page/siuebdy4.jpg b/test/siuebdy4.jpg similarity index 100% rename from test/page/siuebdy4.jpg rename to test/siuebdy4.jpg diff --git a/test/page/siuehdr2.jpg b/test/siuehdr2.jpg similarity index 100% rename from test/page/siuehdr2.jpg rename to test/siuehdr2.jpg diff --git a/test/test.cpp b/test/test.cpp deleted file mode 100644 index 326bdab..0000000 --- a/test/test.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -int math(); -void test_math(); -void IsEqual(bool lhs, bool rhs); - -int main() { - test_math(); - return 0; -} - -int math() { - return 2+2; -} - -void test_math() { - IsEqual(math(), 4); - IsEqual(math(), 6); -} - -void IsEqual(bool lhs, bool rhs) { - if (lhs == rhs) { - std::cout << "Test Success" << std::endl; - } else { - std::cout << "Test Failure" << std::endl; - } -} From c4cd468480b6b6a2efcdc797fb863953caea999f Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 16:04:48 -0500 Subject: [PATCH 11/13] Removed CMake testing information --- CMakeLists.txt | 4 ---- README.md | 16 ++-------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d066651..ac0a717 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,3 @@ include_directories(${proxy-network_SOURCE_DIR}/src) add_subdirectory(src) -if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - add_subdirectory(test) -endif() - diff --git a/README.md b/README.md index c72bbe3..1fd686c 100644 --- a/README.md +++ b/README.md @@ -11,20 +11,8 @@ In order to compile the project, simply run these two commands: cmake --build build ## Running the Project -The program should now be compiled at ./build/bin/proxy-network +The program should now be compiled at ./build/bin/proxy Simply run the program using: - build/bin/proxy-network - -## Testing the Project -The Unity framework is used for testing - -Build the tests using: - - cmake -DCMAKE_BUILD_TYPE=Debug -B build -S . - cmake --build build - -Then run the tests using: - - build/bin/testing + build/bin/proxy From 98af3a223ddab1e515a1dad6d0b6c9331bc0aafe Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 17:10:42 -0500 Subject: [PATCH 12/13] Trimmed web_server --- src/web_server.cpp | 192 +-------------------------------------------- 1 file changed, 4 insertions(+), 188 deletions(-) diff --git a/src/web_server.cpp b/src/web_server.cpp index b08335b..c09fe76 100644 --- a/src/web_server.cpp +++ b/src/web_server.cpp @@ -72,18 +72,7 @@ typedef int32_t socklen_t; #define PORT_NUM 7080 // Port number for a Web server //----- Function prototypes ------------------------------------------------- -void ClientRequest(int server_s, int client_s); -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -void handle_get(void *in_arg); // Thread function to handle GET -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s); // Fork function for GET -#endif -/* ----------------------------------------------------------------------- */ +void ClientRequest(int client_s); //===== modeule main ======================================================== int main(void) @@ -146,59 +135,13 @@ int main(void) continue; } - std::async(std::launch::async, ClientRequest, server_s, client_s); - - /* FOR UNIX/LINUX ---------------------------------------------------- */ -#ifdef UNIX - /* - // Spin-off a child process by fork - nChild_proc_id = fork(); - - // Separate the parent and child process here ... - if (nChild_proc_id == -1) // if I am a new child, go to the child module. - { - child_proc(server_s, client_s); - } - */ -#endif - /* ------------------------------------------------------------------- */ - - /* FOR WIN ----------------------------------------------------------- */ -#ifdef WIN - /* - // Spin-off a thread to handle this request (pass only client_s) - if (_beginthread(handle_get, 4096, (void *)client_s) < 0) - { - printf("ERROR - Unable to create thread \n"); - exit(1); - } - */ -#endif - /* ------------------------------------------------------------------- */ - } + std::async(std::launch::async, ClientRequest, client_s); + } close(server_s); - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX - // Close the server socket - //close(server_s); -#endif - /* --------------------------------------------------------------------- */ - - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - // Close the server socket and clean-up winsock - printf("this web server is shutting down .....\a\n"); - - closesocket(server_s); - WSACleanup(); -#endif - /* --------------------------------------------------------------------- */ - - // To make sure this "main" returns an integer. return (1); } -void ClientRequest(int server_s, int client_s) { +void ClientRequest(int client_s) { char in_buf[BUF_SIZE]; // Input buffer for GET resquest char out_buf[BUF_SIZE]; // Output buffer for HTML response char *file_name; // File name @@ -253,130 +196,3 @@ void ClientRequest(int server_s, int client_s) { close(client_s); } -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -//=========================================================================== -//= This is is the thread function to handle the GET = -//= - It is assumed that the request is a GET = -//=========================================================================== -void handle_get(void *in_arg) -{ - unsigned int client_s; // Client socket descriptor - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - char out_buf[BUF_SIZE]; // Output buffer for HTML response - char *file_name; // File name - unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads - unsigned int retcode; // Return code - - // Set client_s to in_arg - client_s = (unsigned int&)in_arg; - - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - while (!eof(fh)) - { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } - close(fh); - } - } - - // Close the client socket and end the thread - closesocket(client_s); - _endthread(); -} -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s) -{ - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - char out_buf[BUF_SIZE]; // Output buffer for HTML response - char *file_name; // File name - unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads - ssize_t retcode; // Return code - - // Shut down the parent pipe - close(server_s); - - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - // fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - - do { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } while (buf_len != 0); - close(fh); - } - } - - // Shut down my (the child) pipe - close(client_s); - exit(1); -} -#endif -/* ----------------------------------------------------------------------- */ From aa70c8d7baf9cdc217d66b0c145dcedc5409e7a0 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 17:13:09 -0500 Subject: [PATCH 13/13] Proxy base setup, successfully exits despite no data in browser --- src/proxy.cpp | 356 +++++++------------------------------------------- 1 file changed, 48 insertions(+), 308 deletions(-) diff --git a/src/proxy.cpp b/src/proxy.cpp index b08335b..7422c2e 100644 --- a/src/proxy.cpp +++ b/src/proxy.cpp @@ -1,35 +1,3 @@ -//====================================================== file = weblite.c ===== -//= A super light weight HTTP server = -//============================================================================= -//= Notes: = -//= 1) Compiles for Winsock only since uses Windows threads. Generates = -//= one warning about unreachable code in main. Ignore this warning. = -//= 2) Serves HTML and GIF only. = -//= 3) Sometimes the browser drops a connection when doing a refresh. = -//= This is handled by checking the recv() return code in the function = -//= that handles GETs. = -//= 4) The 404 HTML message does not always display in Explorer. = -//=---------------------------------------------------------------------------= -//= Execution notes: = -//= 1) Execute this program in the directory which will be the root for = -//= all file references (i.e., the directory that is considered at = -//= "public.html"). = -//= 2) Open a Web browser and surf to http://xxx.xxx.xxx.xxx/yyy where = -//= xxx.xxx.xxx.xxx is the IP address or hostname of the machine that = -//= weblite is executing on and yyy is the requested object. = -//= 3) The only output (to stdout) from weblite is a message with the = -//= of the file currently being sent = -//=---------------------------------------------------------------------------= -//= Build: bcc32 weblite.c, cl weblite.c wsock32.lib (or ws2_32.lib) = -//= gcc weblite.c -lsocket -lnsl for BSD = -//=---------------------------------------------------------------------------= -//= Execute: weblite = -//=---------------------------------------------------------------------------= -//= History: KJC (12/29/00) - Genesis (from server.c) = -//= HF (01/25/01) - Ported to multi-platform environment = -//============================================================================= -#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env. - //----- Include files --------------------------------------------------------- #include // Needed for printf() #include // Needed for exit() @@ -38,27 +6,11 @@ #include // Needed for file i/o constants #include -/* FOR BSD UNIX/LINUX ---------------------------------------------------- */ -#ifdef UNIX #include // #include // #include // #include // #include -#endif -/* ------------------------------------------------------------------------ */ - -/* FOR WIN ---------------------------------------------------------------- */ -#ifdef WIN -#include // Needed for _threadid -#include // Needed for _beginthread() and _endthread() -#include // Needed for open(), close(), and eof() -#include -#include // Needed for all Winsock stuff -// Lazy struct fixes -typedef int32_t socklen_t; -#endif -/* ------------------------------------------------------------------------ */ //----- HTTP response messages ---------------------------------------------- @@ -69,314 +21,102 @@ typedef int32_t socklen_t; //----- Defines ------------------------------------------------------------- #define BUF_SIZE 4096 // Buffer size (big enough for a GET) -#define PORT_NUM 7080 // Port number for a Web server +#define PORT_NUM 9080 // Port number for a Web server //----- Function prototypes ------------------------------------------------- -void ClientRequest(int server_s, int client_s); -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -void handle_get(void *in_arg); // Thread function to handle GET -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s); // Fork function for GET -#endif -/* ----------------------------------------------------------------------- */ +void BrowserToProxy(int server_s, int client_s); +void ProxyToServer(int server_s, int client_s); //===== modeule main ======================================================== int main(void) { - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - WORD wVersionRequested = MAKEWORD(1, 1); // Stuff for WSA functions - WSADATA wsaData; // Stuff for WSA functions -#endif - /* --------------------------------------------------------------------- */ - - unsigned int server_s; // Server socket descriptor - struct sockaddr_in server_addr; // Server Internet address - unsigned int client_s; // Client socket descriptor - struct sockaddr_in client_addr; // Client Internet address - struct in_addr client_ip_addr; // Client IP address + 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 - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX - int nChild_proc_id; // New child process ID. -#endif - /* --------------------------------------------------------------------- */ - - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - // Initialize winsock - WSAStartup(wVersionRequested, &wsaData); -#endif - /* --------------------------------------------------------------------- */ - // Create a socket, fill-in address information, and then bind it - server_s = socket(AF_INET, SOCK_STREAM, 0); - if (server_s == -1) + proxy_s = socket(AF_INET, SOCK_STREAM, 0); + if (proxy_s == -1) { printf("ERROR - Unable to create socket on server\n"); exit(1); } - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(PORT_NUM); - server_addr.sin_addr.s_addr = htonl(INADDR_ANY); - int bindRet = bind(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr)); + 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) { printf("ERROR - Unable to bind socket\n"); exit(1); } // Listen for connections and then accept - listen(server_s, 100); + listen(proxy_s, 100); // Main loop to listen, accept, and then spin-off a thread to handle the GET while (1) { - addr_len = sizeof(client_addr); + addr_len = sizeof(browser_addr); - client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len); - if (client_s == -1) + browser_s = accept(proxy_s, (struct sockaddr *)&browser_addr, &addr_len); + if (browser_s == -1) { perror("ERROR - Unable to create socket to client\n"); continue; } + unsigned int server_s = socket(AF_INET, SOCK_STREAM, 0); + connect(server_s, (struct sockaddr *)&server_addr, addr_len); - std::async(std::launch::async, ClientRequest, server_s, client_s); + std::async(std::launch::async, BrowserToProxy, browser_s, server_s); + std::async(std::launch::async, ProxyToServer, server_s, browser_s); - /* FOR UNIX/LINUX ---------------------------------------------------- */ -#ifdef UNIX - /* - // Spin-off a child process by fork - nChild_proc_id = fork(); - - // Separate the parent and child process here ... - if (nChild_proc_id == -1) // if I am a new child, go to the child module. - { - child_proc(server_s, client_s); - } - */ -#endif - /* ------------------------------------------------------------------- */ - - /* FOR WIN ----------------------------------------------------------- */ -#ifdef WIN - /* - // Spin-off a thread to handle this request (pass only client_s) - if (_beginthread(handle_get, 4096, (void *)client_s) < 0) - { - printf("ERROR - Unable to create thread \n"); - exit(1); - } - */ -#endif - /* ------------------------------------------------------------------- */ } - close(server_s); - /* FOR UNIX/LINUX ------------------------------------------------------ */ -#ifdef UNIX - // Close the server socket - //close(server_s); -#endif - /* --------------------------------------------------------------------- */ - - /* FOR WIN ------------------------------------------------------------- */ -#ifdef WIN - // Close the server socket and clean-up winsock - printf("this web server is shutting down .....\a\n"); - - closesocket(server_s); - WSACleanup(); -#endif - /* --------------------------------------------------------------------- */ - - // To make sure this "main" returns an integer. + close(browser_s); return (1); } -void ClientRequest(int server_s, int client_s) { +void BrowserToProxy(int server_s, int client_s) { char in_buf[BUF_SIZE]; // Input buffer for GET resquest char out_buf[BUF_SIZE]; // Output buffer for HTML response char *file_name; // File name unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads + ssize_t buf_len; // Buffer length for file reads unsigned int retcode; // Return code // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" -#ifdef WIN - fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); -#endif -#ifdef UNIX - fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); -#endif - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - do { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } while (buf_len != 0); - close(fh); - } - } - // Close the client socket and end the thread - close(client_s); + do { + buf_len = recv(server_s, in_buf, BUF_SIZE, 0); + send(client_s, in_buf, buf_len, 0); + } while (buf_len != 0); } -/* FOR WIN --------------------------------------------------------------- */ -#ifdef WIN -//=========================================================================== -//= This is is the thread function to handle the GET = -//= - It is assumed that the request is a GET = -//=========================================================================== -void handle_get(void *in_arg) -{ - unsigned int client_s; // Client socket descriptor +void ProxyToServer(int server_s, int client_s) { + /* + + loop { + recv from browser + send to server + } + + */ char in_buf[BUF_SIZE]; // Input buffer for GET resquest char out_buf[BUF_SIZE]; // Output buffer for HTML response char *file_name; // File name unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads + ssize_t buf_len; // Buffer length for file reads unsigned int retcode; // Return code - // Set client_s to in_arg - client_s = (unsigned int&)in_arg; - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - while (!eof(fh)) - { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } - close(fh); - } - } - - // Close the client socket and end the thread - closesocket(client_s); - _endthread(); + do { + buf_len = recv(server_s, in_buf, BUF_SIZE, 0); + send(client_s, in_buf, buf_len, 0); + } while (buf_len != 0); + close(server_s); + close(client_s); } -#endif -/* ----------------------------------------------------------------------- */ - -/* FOR UNIX/LINUX -------------------------------------------------------- */ -#ifdef UNIX -void child_proc(int server_s, int client_s) -{ - char in_buf[BUF_SIZE]; // Input buffer for GET resquest - char out_buf[BUF_SIZE]; // Output buffer for HTML response - char *file_name; // File name - unsigned int fh; // File handle - unsigned int buf_len; // Buffer length for file reads - ssize_t retcode; // Return code - - // Shut down the parent pipe - close(server_s); - - // Receive the GET request from the Web browser - retcode = recv(client_s, in_buf, BUF_SIZE, 0); - - // Handle the GET if there is one (see note #3 in the header) - if (retcode != -1) - { - // Parse out the filename from the GET request - strtok(in_buf, " "); - file_name = strtok(NULL, " "); - - // Open the requested file - // - Start at 2nd char to get rid of leading "\" - // fh = open(&file_name[1], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE); - fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE); - - // Generate and send the response (404 if could not open the file) - if (fh == -1) - { - printf("File %s not found - sending an HTTP 404 \n", &file_name[1]); - strcpy(out_buf, NOTOK_404); - send(client_s, out_buf, strlen(out_buf), 0); - strcpy(out_buf, MESS_404); - send(client_s, out_buf, strlen(out_buf), 0); - } - else - { - printf("File %s is being sent \n", &file_name[1]); - if (strstr(file_name, ".gif") != NULL) - strcpy(out_buf, OK_IMAGE); - else - strcpy(out_buf, OK_TEXT); - send(client_s, out_buf, strlen(out_buf), 0); - - do { - buf_len = read(fh, out_buf, BUF_SIZE); - send(client_s, out_buf, buf_len, 0); - } while (buf_len != 0); - close(fh); - } - } - - // Shut down my (the child) pipe - close(client_s); - exit(1); -} -#endif -/* ----------------------------------------------------------------------- */