Added proxy base and fixed web server #1
1
.gitignore
vendored
@ -34,3 +34,4 @@
|
|||||||
|
|
||||||
# Extras
|
# Extras
|
||||||
build
|
build
|
||||||
|
test/web_server
|
||||||
|
@ -13,7 +13,3 @@ include_directories(${proxy-network_SOURCE_DIR}/src)
|
|||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
|
||||||
add_subdirectory(test)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
16
README.md
@ -11,20 +11,8 @@ In order to compile the project, simply run these two commands:
|
|||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
## Running the Project
|
## 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:
|
Simply run the program using:
|
||||||
|
|
||||||
build/bin/proxy-network
|
build/bin/proxy
|
||||||
|
|
||||||
## 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
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
add_executable(proxy-network
|
add_executable(web_server
|
||||||
./mt_web_server.cpp
|
./web_server.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(tempmulti
|
add_executable(proxy
|
||||||
./multi_threads.cpp
|
./proxy.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(proxy-network PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
|
||||||
|
|
||||||
|
@ -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 <ratio>
|
|
||||||
#define UNIX // WIN for Windows environment, UNIX for BSD or LINUX env.
|
|
||||||
/* FOR WIN ------------------------------------------------------------- */
|
|
||||||
#ifdef WIN
|
|
||||||
#include <process.h> // for thread system calls (_beginthread, etc.)
|
|
||||||
#include <windows.h> // for TRUE, FALSE labels
|
|
||||||
#endif
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* FOR UNIX/LINUX ------------------------------------------------------ */
|
|
||||||
#ifdef UNIX
|
|
||||||
#endif
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
#include <stdio.h> // for printf
|
|
||||||
#include <time.h> // 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<double, std::milli>(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<double, std::milli>(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 //////////////////////////////////////////////////////////
|
|
122
src/proxy.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//----- Include files ---------------------------------------------------------
|
||||||
|
#include <stdio.h> // Needed for printf()
|
||||||
|
#include <stdlib.h> // Needed for exit()
|
||||||
|
#include <string.h> // Needed for strcpy() and strlen()
|
||||||
|
#include <fcntl.h> // Needed for file i/o constants
|
||||||
|
#include <sys/stat.h> // Needed for file i/o constants
|
||||||
|
#include <future>
|
||||||
|
|
||||||
|
#include <sys/types.h> //
|
||||||
|
#include <netinet/in.h> //
|
||||||
|
#include <sys/socket.h> //
|
||||||
|
#include <arpa/inet.h> //
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
//----- 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 "<html><body><h1>FILE NOT FOUND</h1></body></html>"
|
||||||
|
|
||||||
|
//----- Defines -------------------------------------------------------------
|
||||||
|
#define BUF_SIZE 4096 // Buffer size (big enough for a GET)
|
||||||
|
#define PORT_NUM 9080 // Port number for a Web server
|
||||||
|
|
||||||
|
//----- Function prototypes -------------------------------------------------
|
||||||
|
void BrowserToProxy(int server_s, int client_s);
|
||||||
|
void ProxyToServer(int server_s, int client_s);
|
||||||
|
|
||||||
|
//===== modeule main ========================================================
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
unsigned int proxy_s; // Server socket descriptor
|
||||||
|
struct sockaddr_in proxy_addr; // Server Internet address
|
||||||
|
unsigned int browser_s; // Client socket descriptor
|
||||||
|
struct sockaddr_in browser_addr; // Client Internet address
|
||||||
|
struct in_addr browser_ip_addr; // Client IP address
|
||||||
|
unsigned int server_s; // Client socket descriptor
|
||||||
|
struct sockaddr_in server_addr; // Client Internet address
|
||||||
|
struct in_addr server_ip_addr; // Client IP address
|
||||||
|
socklen_t addr_len; // Internet address length
|
||||||
|
|
||||||
|
// Create a socket, fill-in address information, and then bind it
|
||||||
|
proxy_s = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (proxy_s == -1)
|
||||||
|
{
|
||||||
|
printf("ERROR - Unable to create socket on server\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
proxy_addr.sin_family = AF_INET;
|
||||||
|
proxy_addr.sin_port = htons(PORT_NUM);
|
||||||
|
proxy_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
int bindRet = bind(proxy_s, (struct sockaddr *)&proxy_addr, sizeof(proxy_addr));
|
||||||
|
if (bindRet == -1)
|
||||||
|
{
|
||||||
|
printf("ERROR - Unable to bind socket\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
// Listen for connections and then accept
|
||||||
|
listen(proxy_s, 100);
|
||||||
|
|
||||||
|
// Main loop to listen, accept, and then spin-off a thread to handle the GET
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
addr_len = sizeof(browser_addr);
|
||||||
|
|
||||||
|
browser_s = accept(proxy_s, (struct sockaddr *)&browser_addr, &addr_len);
|
||||||
|
if (browser_s == -1)
|
||||||
|
{
|
||||||
|
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, BrowserToProxy, browser_s, server_s);
|
||||||
|
std::async(std::launch::async, ProxyToServer, server_s, browser_s);
|
||||||
|
|
||||||
|
}
|
||||||
|
close(browser_s);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
ssize_t buf_len; // Buffer length for file reads
|
||||||
|
unsigned int retcode; // Return code
|
||||||
|
|
||||||
|
// Receive the GET request from the Web browser
|
||||||
|
do {
|
||||||
|
buf_len = recv(server_s, in_buf, BUF_SIZE, 0);
|
||||||
|
send(client_s, in_buf, buf_len, 0);
|
||||||
|
} while (buf_len != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
ssize_t buf_len; // Buffer length for file reads
|
||||||
|
unsigned int retcode; // Return code
|
||||||
|
|
||||||
|
// Receive the GET request from the Web browser
|
||||||
|
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);
|
||||||
|
}
|
@ -36,6 +36,7 @@
|
|||||||
#include <string.h> // Needed for strcpy() and strlen()
|
#include <string.h> // Needed for strcpy() and strlen()
|
||||||
#include <fcntl.h> // Needed for file i/o constants
|
#include <fcntl.h> // Needed for file i/o constants
|
||||||
#include <sys/stat.h> // Needed for file i/o constants
|
#include <sys/stat.h> // Needed for file i/o constants
|
||||||
|
#include <future>
|
||||||
|
|
||||||
/* FOR BSD UNIX/LINUX ---------------------------------------------------- */
|
/* FOR BSD UNIX/LINUX ---------------------------------------------------- */
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
@ -52,10 +53,14 @@
|
|||||||
#include <stddef.h> // Needed for _threadid
|
#include <stddef.h> // Needed for _threadid
|
||||||
#include <process.h> // Needed for _beginthread() and _endthread()
|
#include <process.h> // Needed for _beginthread() and _endthread()
|
||||||
#include <io.h> // Needed for open(), close(), and eof()
|
#include <io.h> // Needed for open(), close(), and eof()
|
||||||
|
#include <winsock2.h>
|
||||||
#include <windows.h> // Needed for all Winsock stuff
|
#include <windows.h> // Needed for all Winsock stuff
|
||||||
|
// Lazy struct fixes
|
||||||
|
typedef int32_t socklen_t;
|
||||||
#endif
|
#endif
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
//----- HTTP response messages ----------------------------------------------
|
//----- HTTP response messages ----------------------------------------------
|
||||||
#define OK_IMAGE "HTTP/1.0 200 OK\nContent-Type:image/gif\n\n"
|
#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 OK_TEXT "HTTP/1.0 200 OK\nContent-Type:text/html\n\n"
|
||||||
@ -64,20 +69,10 @@
|
|||||||
|
|
||||||
//----- Defines -------------------------------------------------------------
|
//----- Defines -------------------------------------------------------------
|
||||||
#define BUF_SIZE 4096 // Buffer size (big enough for a GET)
|
#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 -------------------------------------------------
|
//----- Function prototypes -------------------------------------------------
|
||||||
/* FOR WIN --------------------------------------------------------------- */
|
void ClientRequest(int client_s);
|
||||||
#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 ========================================================
|
//===== modeule main ========================================================
|
||||||
int main(void)
|
int main(void)
|
||||||
@ -111,165 +106,67 @@ int main(void)
|
|||||||
|
|
||||||
// Create a socket, fill-in address information, and then bind it
|
// Create a socket, fill-in address information, and then bind it
|
||||||
server_s = socket(AF_INET, SOCK_STREAM, 0);
|
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_family = AF_INET;
|
||||||
server_addr.sin_port = htons(PORT_NUM);
|
server_addr.sin_port = htons(PORT_NUM);
|
||||||
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
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
|
// Main loop to listen, accept, and then spin-off a thread to handle the GET
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// Listen for connections and then accept
|
|
||||||
listen(server_s, 100);
|
|
||||||
addr_len = sizeof(client_addr);
|
addr_len = sizeof(client_addr);
|
||||||
|
|
||||||
client_s = accept(server_s, (struct sockaddr *)&client_addr, &addr_len);
|
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");
|
perror("ERROR - Unable to create socket to client\n");
|
||||||
exit(1);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FOR UNIX/LINUX ---------------------------------------------------- */
|
std::async(std::launch::async, ClientRequest, client_s);
|
||||||
#ifdef UNIX
|
|
||||||
// Spin-off a child process by fork
|
|
||||||
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.
|
|
||||||
{
|
|
||||||
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);
|
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);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FOR WIN --------------------------------------------------------------- */
|
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
|
||||||
|
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
|
#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);
|
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
|
#endif
|
||||||
/* ----------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* FOR UNIX/LINUX -------------------------------------------------------- */
|
|
||||||
#ifdef UNIX
|
#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
|
|
||||||
unsigned int 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);
|
fh = open(&file_name[1], O_RDONLY, S_IREAD | S_IWRITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Generate and send the response (404 if could not open the file)
|
// Generate and send the response (404 if could not open the file)
|
||||||
if (fh == -1)
|
if (fh == -1)
|
||||||
@ -288,18 +185,14 @@ void child_proc(int server_s, int client_s)
|
|||||||
else
|
else
|
||||||
strcpy(out_buf, OK_TEXT);
|
strcpy(out_buf, OK_TEXT);
|
||||||
send(client_s, out_buf, strlen(out_buf), 0);
|
send(client_s, out_buf, strlen(out_buf), 0);
|
||||||
|
do {
|
||||||
while (fh != EOF)
|
|
||||||
{
|
|
||||||
buf_len = read(fh, out_buf, BUF_SIZE);
|
buf_len = read(fh, out_buf, BUF_SIZE);
|
||||||
send(client_s, out_buf, buf_len, 0);
|
send(client_s, out_buf, buf_len, 0);
|
||||||
}
|
} while (buf_len != 0);
|
||||||
close(fh);
|
close(fh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Close the client socket and end the thread
|
||||||
// Shut down my (the child) pipe
|
|
||||||
close(client_s);
|
close(client_s);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/* ----------------------------------------------------------------------- */
|
|
@ -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)
|
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
@ -1,28 +0,0 @@
|
|||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|