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 -/* ----------------------------------------------------------------------- */