Compare commits
6 Commits
master
...
f1ae49da0c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1ae49da0c | ||
|
|
857a38d904 | ||
|
|
2ab5bc546c | ||
|
|
3e24a96f9a | ||
|
|
ba56d0e471 | ||
|
|
140193bbaf |
@@ -6,11 +6,11 @@ It is recommended to run this application using Docker.
|
|||||||
For a deployment running the application without HTTPS run `make dockerTestDeploy`, this will open a socket on port 8080.
|
For a deployment running the application without HTTPS run `make dockerTestDeploy`, this will open a socket on port 8080.
|
||||||
For a deployment running the application with HTTPS run `make dockerReleaseDeploy`, this will also open a socket on port 8080.
|
For a deployment running the application with HTTPS run `make dockerReleaseDeploy`, this will also open a socket on port 8080.
|
||||||
Running `make killTestDocker` will kill the running instance of seaweb:latest running in Docker.
|
Running `make killTestDocker` will kill the running instance of seaweb:latest running in Docker.
|
||||||
To view logs within the running container run `docker exec -it $(docker ps | grep "seaweb:latest" | grep -o '[^ ]*$') tail -f /var/log/seaweb/log`, or manually view the `/var/log/seaweb/log` file within the container.
|
To view logs within the running container run `docker exec -it $(docker ps | grep "seaweb:latest" | grep -o '[^ ]*$') tail -f /var/log/seaweb/log`, or manually view the `/var/log/seaweb/log` file.
|
||||||
|
|
||||||
If you run this application without Docker please ensure the OpenSSL development headers are installed onto your system, this will be important if running with HTTPS.
|
If you run this application without Docker please ensure the OpenSSL development headers are installed onto your system, this will be important if running with HTTPS.
|
||||||
|
|
||||||
To build this application outside of Docker run `make`, and the binary will be built into `./bin`.
|
To build this application outside of Docker run `make`, and the binary will be build into `./bin`.
|
||||||
Running `./bin/seaweb --help` or `./bin/seaweb -h` will show you the help message for the application showing all possible options.
|
Running `./bin/seaweb --help` or `./bin/seaweb -h` will show you the help message for the application showing all possible options.
|
||||||
|
|
||||||
By default the application is compiled to utilize `/var/www/html` as the WEB root, and will output logs to `/var/log/seaweb/log`; if running the application outside of Docker please ensure this is setup with correct permissions to run.
|
By default the application is compiled to utilize `/var/www/html` as the WEB root, and will output logs to `/var/log/seaweb/log`; if running the application outside of Docker please ensure this is setup with correct permissions to run.
|
||||||
|
|||||||
38
cmd/server.c
38
cmd/server.c
@@ -27,10 +27,6 @@ char *WEB_ROOT_DIR = NULL;
|
|||||||
|
|
||||||
static int timeout = 0;
|
static int timeout = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
* Used to print debug messages to the screen
|
|
||||||
* when the --verbose flag is passed
|
|
||||||
*/
|
|
||||||
int printDebug(char message[]) {
|
int printDebug(char message[]) {
|
||||||
if (verbose_flag == 1) {
|
if (verbose_flag == 1) {
|
||||||
printf("[Debug] %s\n", message);
|
printf("[Debug] %s\n", message);
|
||||||
@@ -38,12 +34,6 @@ int printDebug(char message[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function handles incoming requests and stores
|
|
||||||
* the parsed data into the HTTPRequest struct passed
|
|
||||||
* into the function. If any errors are encountered
|
|
||||||
* during this process a negative number will be returned
|
|
||||||
*/
|
|
||||||
int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) {
|
int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) {
|
||||||
char temp[1]; // Used to check newlines
|
char temp[1]; // Used to check newlines
|
||||||
char *token = calloc(8, sizeof(char));
|
char *token = calloc(8, sizeof(char));
|
||||||
@@ -55,8 +45,6 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) {
|
|||||||
char * varCheck;
|
char * varCheck;
|
||||||
|
|
||||||
// Creating empty requestBody
|
// Creating empty requestBody
|
||||||
// Setting values to 0 helps if variable is not
|
|
||||||
// set and determining that later on in handling
|
|
||||||
r->requestBody = malloc(sizeof(char));
|
r->requestBody = malloc(sizeof(char));
|
||||||
r->requestBodyLen = 0;
|
r->requestBodyLen = 0;
|
||||||
r->requestVars = malloc(sizeof(char));
|
r->requestVars = malloc(sizeof(char));
|
||||||
@@ -141,13 +129,11 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) {
|
|||||||
}
|
}
|
||||||
line++;
|
line++;
|
||||||
} else {
|
} else {
|
||||||
// Appending char to checkLine
|
|
||||||
strcat((char *)checkLine, temp);
|
strcat((char *)checkLine, temp);
|
||||||
checkLineLen++;
|
checkLineLen++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return error if request type is not set
|
|
||||||
if (strlen(r->requestType) == 0) {
|
if (strlen(r->requestType) == 0) {
|
||||||
free(logLine);
|
free(logLine);
|
||||||
free(checkLine);
|
free(checkLine);
|
||||||
@@ -159,10 +145,6 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is the entry point for all new requests; this
|
|
||||||
* function will always return 0 regardless of outcome
|
|
||||||
*/
|
|
||||||
int handleRequest(unsigned char buffer[], int socket, SSL *ssl) {
|
int handleRequest(unsigned char buffer[], int socket, SSL *ssl) {
|
||||||
struct HTTPRequest r; // Holds relevant HTTP request information
|
struct HTTPRequest r; // Holds relevant HTTP request information
|
||||||
r.requestConLen = malloc(sizeof(char));
|
r.requestConLen = malloc(sizeof(char));
|
||||||
@@ -207,10 +189,6 @@ int handleRequest(unsigned char buffer[], int socket, SSL *ssl) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is used as a signal to kill child processes that
|
|
||||||
* are triggered by the corresponding alarm
|
|
||||||
*/
|
|
||||||
void timeoutChild(int sig) {
|
void timeoutChild(int sig) {
|
||||||
timeout = 1;
|
timeout = 1;
|
||||||
}
|
}
|
||||||
@@ -251,7 +229,6 @@ int main(int argc, char **argv) {
|
|||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define help message
|
|
||||||
const char* usage =
|
const char* usage =
|
||||||
"Usage: seaweb [options]\n\n"
|
"Usage: seaweb [options]\n\n"
|
||||||
" -h --help\t\t\tShows this message\n"
|
" -h --help\t\t\tShows this message\n"
|
||||||
@@ -264,7 +241,6 @@ int main(int argc, char **argv) {
|
|||||||
" --verbose\t\t\tPrints debug messages\n"
|
" --verbose\t\t\tPrints debug messages\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
// Parsing options
|
|
||||||
int c;
|
int c;
|
||||||
while (1) {
|
while (1) {
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
@@ -317,14 +293,14 @@ int main(int argc, char **argv) {
|
|||||||
enableHTTPS = 1;
|
enableHTTPS = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( enableHTTPS == 1 ) { // Open secure socket
|
if ( enableHTTPS == 1 ) {
|
||||||
printf("Opening secure socket on port: %d\n", port);
|
printf("Opening secure socket on port: %d\n", port);
|
||||||
checkerr = createSecureSocket(port, &server_fd, &address, &addrlen, listenAddrNum,
|
checkerr = createSecureSocket(port, &server_fd, &address, &addrlen, listenAddrNum,
|
||||||
&ctx, certFile, privKeyFile);
|
&ctx, certFile, privKeyFile);
|
||||||
if ( ctx == NULL ) {
|
if ( ctx == NULL ) {
|
||||||
printf("Error creating ctx\n");
|
printf("Error creating ctx\n");
|
||||||
}
|
}
|
||||||
} else { // Open socket
|
} else {
|
||||||
printf("Opening socket on port: %d\n", port);
|
printf("Opening socket on port: %d\n", port);
|
||||||
checkerr = createSocket(port, &server_fd, &address, &addrlen, listenAddrNum);
|
checkerr = createSocket(port, &server_fd, &address, &addrlen, listenAddrNum);
|
||||||
}
|
}
|
||||||
@@ -345,11 +321,11 @@ int main(int argc, char **argv) {
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
pid = fork();
|
pid = fork();
|
||||||
|
|
||||||
if (pid == 0) { // Child process handles sessions
|
if (pid == 0) {
|
||||||
pid_t pid2;
|
pid_t pid2;
|
||||||
pid2 = fork();
|
pid2 = fork();
|
||||||
|
|
||||||
if (pid2 == 0) { // Child child process reads requests and handles return
|
if (pid2 == 0) {
|
||||||
bufSize = BUFF_READ;
|
bufSize = BUFF_READ;
|
||||||
if ( enableHTTPS ) {
|
if ( enableHTTPS ) {
|
||||||
size_t buffCont = 1;
|
size_t buffCont = 1;
|
||||||
@@ -386,14 +362,14 @@ int main(int argc, char **argv) {
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
} else if (pid2 < 0) {
|
} else if (pid2 < 0) {
|
||||||
printDebug("Error forking supervisor...");
|
printDebug("Error forking supervisor...");
|
||||||
} else { // Parent process waits to see if child timeout is triggered
|
} else {
|
||||||
int status;
|
int status;
|
||||||
signal(SIGALRM, timeoutChild);
|
signal(SIGALRM, timeoutChild);
|
||||||
alarm(2);
|
alarm(2);
|
||||||
pause();
|
pause();
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
status = waitpid(pid, NULL, WNOHANG);
|
status = waitpid(pid, NULL, WNOHANG);
|
||||||
if (status == 0) { // If status is not 0 kill child process
|
if (status == 0) {
|
||||||
printDebug("Killing child");
|
printDebug("Killing child");
|
||||||
kill(pid2, 9);
|
kill(pid2, 9);
|
||||||
wait(NULL);
|
wait(NULL);
|
||||||
@@ -404,7 +380,7 @@ int main(int argc, char **argv) {
|
|||||||
close(new_socket);
|
close(new_socket);
|
||||||
} else if (pid < 0) {
|
} else if (pid < 0) {
|
||||||
printDebug("Error forking...");
|
printDebug("Error forking...");
|
||||||
} else { // Ignore exit status of spawned child (proc is not a zombie)
|
} else {
|
||||||
signal(SIGCHLD, SIG_IGN);
|
signal(SIGCHLD, SIG_IGN);
|
||||||
close(new_socket);
|
close(new_socket);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -10,10 +10,6 @@
|
|||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* This funcion handles all GET requests and checks
|
|
||||||
* to see if a php file is being requested
|
|
||||||
*/
|
|
||||||
int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
||||||
char errResponse[256];
|
char errResponse[256];
|
||||||
char ch;
|
char ch;
|
||||||
@@ -23,7 +19,6 @@ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *workingReqDir;
|
char *workingReqDir;
|
||||||
|
|
||||||
// Checking for php extension
|
|
||||||
char *phpReturn = NULL;
|
char *phpReturn = NULL;
|
||||||
char phpEnd[5] = ".php";
|
char phpEnd[5] = ".php";
|
||||||
bool endsWithPhp = false;
|
bool endsWithPhp = false;
|
||||||
@@ -54,7 +49,6 @@ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
|||||||
}
|
}
|
||||||
char *reqDir = calloc((strlen(WEB_ROOT_DIR) + strlen(workingReqDir) + 1), sizeof(char));
|
char *reqDir = calloc((strlen(WEB_ROOT_DIR) + strlen(workingReqDir) + 1), sizeof(char));
|
||||||
|
|
||||||
// Creating absolute path from web root
|
|
||||||
sprintf(reqDir, "%s%s", WEB_ROOT_DIR, workingReqDir);
|
sprintf(reqDir, "%s%s", WEB_ROOT_DIR, workingReqDir);
|
||||||
|
|
||||||
fp = fopen(reqDir, "r");
|
fp = fopen(reqDir, "r");
|
||||||
@@ -83,10 +77,6 @@ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function handles all PUT requests and attempts to create
|
|
||||||
* a fill with the requested content at the web root plus passed path
|
|
||||||
*/
|
|
||||||
int handlePUTRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
int handlePUTRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *reqDir;
|
char *reqDir;
|
||||||
@@ -116,10 +106,6 @@ int handlePUTRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
|||||||
return return201Request(socket, r->requestBody, ssl);
|
return return201Request(socket, r->requestBody, ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function handles all DELETE requests and attempts to delete
|
|
||||||
* the requested file
|
|
||||||
*/
|
|
||||||
int handleDELETERequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
int handleDELETERequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
||||||
char *reqDir;
|
char *reqDir;
|
||||||
char * workingReqDir;
|
char * workingReqDir;
|
||||||
@@ -150,10 +136,6 @@ int handleDELETERequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function handles all POST requests and checks to see
|
|
||||||
* if the file extension is .php
|
|
||||||
*/
|
|
||||||
int handlePOSTRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
int handlePOSTRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
|
||||||
char *phpReturn = NULL;
|
char *phpReturn = NULL;
|
||||||
// Supported data types application/x-www-form-urlencoded application/json
|
// Supported data types application/x-www-form-urlencoded application/json
|
||||||
|
|||||||
@@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* This function returns the requested request's response data
|
|
||||||
*/
|
|
||||||
int returnRequest(int socket, char *message, int status, SSL *ssl) {
|
int returnRequest(int socket, char *message, int status, SSL *ssl) {
|
||||||
if ( enableHTTPS ) {
|
if ( enableHTTPS ) {
|
||||||
SSL_write(ssl, message, strlen(message));
|
SSL_write(ssl, message, strlen(message));
|
||||||
@@ -23,7 +20,7 @@ int returnRequest(int socket, char *message, int status, SSL *ssl) {
|
|||||||
|
|
||||||
int return200Request(int socket, unsigned char *content, SSL *ssl) {
|
int return200Request(int socket, unsigned char *content, SSL *ssl) {
|
||||||
char *message = "";
|
char *message = "";
|
||||||
if (content != NULL) { // If content is passed add it to the return string
|
if (content != NULL) {
|
||||||
message = calloc(strlen((char *)content) + 128, sizeof(char));
|
message = calloc(strlen((char *)content) + 128, sizeof(char));
|
||||||
sprintf(message, "HTTP/1.1 200 OK\nContent-Length: %zu\nContent-Type: text/html\nConnection: close\n\n%s",
|
sprintf(message, "HTTP/1.1 200 OK\nContent-Length: %zu\nContent-Type: text/html\nConnection: close\n\n%s",
|
||||||
strlen((char *)content), content);
|
strlen((char *)content), content);
|
||||||
@@ -90,10 +87,6 @@ int return505Request(int socket, SSL *ssl) {
|
|||||||
return returnRequest(socket, message, 505, ssl);
|
return returnRequest(socket, message, 505, ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function delete the first line of php-cgi return data
|
|
||||||
* and passes the resulting text into return200Request
|
|
||||||
*/
|
|
||||||
int returnPHPRequest(int socket, char *content, SSL *ssl) {
|
int returnPHPRequest(int socket, char *content, SSL *ssl) {
|
||||||
char *message = malloc(1024);
|
char *message = malloc(1024);
|
||||||
memset(message, 0, 1024);
|
memset(message, 0, 1024);
|
||||||
|
|||||||
@@ -9,11 +9,6 @@
|
|||||||
|
|
||||||
#include "socketHelp.h"
|
#include "socketHelp.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* This function turns a IPv4 four byte octet into
|
|
||||||
* an unsigned 32 bit integer which can be used when
|
|
||||||
* opening new socket connections
|
|
||||||
*/
|
|
||||||
uint32_t addr2sin_addr(char *addr) {
|
uint32_t addr2sin_addr(char *addr) {
|
||||||
char *token;
|
char *token;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -23,12 +18,12 @@ uint32_t addr2sin_addr(char *addr) {
|
|||||||
token = strtok(addr, ".");
|
token = strtok(addr, ".");
|
||||||
while(token != NULL) {
|
while(token != NULL) {
|
||||||
addrTempNum = strtoul(token, NULL,10);
|
addrTempNum = strtoul(token, NULL,10);
|
||||||
if ( addrTempNum > 255 ) { // Check if octet is valid
|
if ( addrTempNum > 255 ) {
|
||||||
printf("Invalid IP octet: %ld\n", addrTempNum);
|
printf("Invalid IP octet: %ld\n", addrTempNum);
|
||||||
|
|
||||||
free(token);
|
free(token);
|
||||||
return -1;
|
return -1;
|
||||||
} // Adding value to addr number
|
}
|
||||||
addrNum = addrNum + ( addrTempNum << (8*(3-i)) );
|
addrNum = addrNum + ( addrTempNum << (8*(3-i)) );
|
||||||
|
|
||||||
token = strtok(NULL, ".");
|
token = strtok(NULL, ".");
|
||||||
|
|||||||
15
src/utils.c
15
src/utils.c
@@ -16,11 +16,6 @@ static char supportedHTTPVersions[NUM_SUPPORTED_VERSIONS][16] = {
|
|||||||
"HTTP/1.0"
|
"HTTP/1.0"
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* This function prints logs to the screen if the web root is not absolute,
|
|
||||||
* if web root is /var/www/html then it is assumed to be running in service mode
|
|
||||||
* which means it prints logs to /var/log/seaweb/log
|
|
||||||
*/
|
|
||||||
int PrintLog(unsigned char *message) {
|
int PrintLog(unsigned char *message) {
|
||||||
time_t UTCTime;
|
time_t UTCTime;
|
||||||
// Setting time in EPOC
|
// Setting time in EPOC
|
||||||
@@ -41,10 +36,6 @@ int PrintLog(unsigned char *message) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function checks to see if the requested http version
|
|
||||||
* is with 1.1 or 1.0
|
|
||||||
*/
|
|
||||||
int checkHTTPVersion(char *version) {
|
int checkHTTPVersion(char *version) {
|
||||||
int supported = -1; // Default fail state
|
int supported = -1; // Default fail state
|
||||||
char testVer[16];
|
char testVer[16];
|
||||||
@@ -57,10 +48,6 @@ int checkHTTPVersion(char *version) {
|
|||||||
return supported;
|
return supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function executes php-cgi requests and returns
|
|
||||||
* the response
|
|
||||||
*/
|
|
||||||
char *php_cgi(char *sPath, struct HTTPRequest *r) {
|
char *php_cgi(char *sPath, struct HTTPRequest *r) {
|
||||||
int phpPipe[2];
|
int phpPipe[2];
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
@@ -120,7 +107,7 @@ char *php_cgi(char *sPath, struct HTTPRequest *r) {
|
|||||||
dup2(phpPipe2[0], STDIN_FILENO);
|
dup2(phpPipe2[0], STDIN_FILENO);
|
||||||
execl("/usr/bin/php-cgi", "php-cgi", NULL);
|
execl("/usr/bin/php-cgi", "php-cgi", NULL);
|
||||||
}
|
}
|
||||||
} else { // GET request handlers does not require second fork
|
} else {
|
||||||
putenv("REQUEST_METHOD=GET");
|
putenv("REQUEST_METHOD=GET");
|
||||||
if (r->requestVars != NULL) {
|
if (r->requestVars != NULL) {
|
||||||
queryString = malloc(strlen(r->requestVars) + 24);
|
queryString = malloc(strlen(r->requestVars) + 24);
|
||||||
|
|||||||
Reference in New Issue
Block a user