From 3b3c421bae55cd6510709bda50d7edbda4fb96a3 Mon Sep 17 00:00:00 2001 From: TriantaTV Date: Sat, 30 Sep 2023 02:36:18 -0500 Subject: [PATCH] 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 +/* ----------------------------------------------------------------------- */