updates for summer 2020
this update adds the unit tests as part of the student distribution
This commit is contained in:
parent
b0f08b3e8a
commit
7cbe3af927
@ -14,12 +14,12 @@ git clone https://github.com/akheron/jansson.git
|
||||
(cd jansson;
|
||||
autoreconf -fi;
|
||||
./configure --prefix=${BASE}/deps;
|
||||
make install
|
||||
make -j 40 install
|
||||
)
|
||||
|
||||
git clone https://git@github.com/benmcollins/libjwt.git
|
||||
(cd libjwt;
|
||||
autoreconf -fi;
|
||||
env PKG_CONFIG_PATH=../deps/lib/pkgconfig:${PKG_CONFIG_PATH} ./configure --prefix=${BASE}/deps;
|
||||
make install
|
||||
make -j 40 install
|
||||
)
|
||||
|
@ -2,7 +2,7 @@ DEP_BASE_DIR=../deps
|
||||
DEP_INCLUDE_DIR=$(DEP_BASE_DIR)/include
|
||||
DEP_LIB_DIR=$(abspath $(DEP_BASE_DIR)/lib)
|
||||
|
||||
CFLAGS=-g -O2 -pthread -std=gnu11 -Wall -Werror -Wmissing-prototypes -I$(DEP_INCLUDE_DIR)
|
||||
CFLAGS=-g -O2 -pthread -Wall -Werror -Wmissing-prototypes -I$(DEP_INCLUDE_DIR)
|
||||
|
||||
# include lib directory into runtime path to facilitate dynamic linking
|
||||
LDFLAGS=-pthread -Wl,-rpath -Wl,$(DEP_LIB_DIR)
|
||||
|
@ -24,15 +24,13 @@
|
||||
#include "hexdump.h"
|
||||
#include "socket.h"
|
||||
#include "bufio.h"
|
||||
#include "main.h"
|
||||
|
||||
// Need macros here because of the sizeof
|
||||
#define CRLF "\r\n"
|
||||
#define STARTS_WITH(field_name, header) \
|
||||
(!strncasecmp(field_name, header, sizeof(header) - 1))
|
||||
|
||||
char * server_root; // root from which static files are served
|
||||
|
||||
|
||||
/* Parse HTTP request line, setting req_method, req_path, and req_version. */
|
||||
static bool
|
||||
http_parse_request(struct http_transaction *ta)
|
||||
@ -227,6 +225,7 @@ send_error(struct http_transaction * ta, enum http_response_status status, const
|
||||
ta->resp_body.len += len > MAX_ERROR_LEN ? MAX_ERROR_LEN - 1 : len;
|
||||
va_end(ap);
|
||||
ta->resp_status = status;
|
||||
http_add_header(&ta->resp_headers, "Content-Type", "text/plain");
|
||||
return send_response(ta);
|
||||
}
|
||||
|
||||
|
33
src/main.c
33
src/main.c
@ -8,21 +8,31 @@
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include "buffer.h"
|
||||
#include "hexdump.h"
|
||||
#include "http.h"
|
||||
#include "socket.h"
|
||||
#include "bufio.h"
|
||||
#include "globals.h"
|
||||
#include "main.h"
|
||||
|
||||
/* Implement HTML5 fallback.
|
||||
* This means that if a non-API path refers to a file and that
|
||||
* file is not found or is a directory, return /index.html
|
||||
* instead. Otherwise, return the file.
|
||||
* If HTML5 fallback is implemented and activated, the server should
|
||||
* treat requests to non-API paths specially.
|
||||
* If the requested file is not found, the server will serve /index.html
|
||||
* instead; that is, it should treat the request as if it
|
||||
* had been for /index.html instead.
|
||||
*/
|
||||
bool html5_fallback = false;
|
||||
|
||||
// silent_mode. During benchmarking, this will be true
|
||||
bool silent_mode = false;
|
||||
int token_expiration_time = 24 * 60 * 60; // default token expiration time is 1 day
|
||||
|
||||
// default token expiration time is 1 day
|
||||
int token_expiration_time = 24 * 60 * 60;
|
||||
|
||||
// root from which static files are served
|
||||
char * server_root;
|
||||
|
||||
/*
|
||||
* A non-concurrent, iterative server that serves one client at a time.
|
||||
@ -31,7 +41,7 @@ int token_expiration_time = 24 * 60 * 60; // default token expiration time is
|
||||
static void
|
||||
server_loop(char *port_string)
|
||||
{
|
||||
int accepting_socket = socket_open_bind_listen(port_string, 1024);
|
||||
int accepting_socket = socket_open_bind_listen(port_string, 10000);
|
||||
while (accepting_socket != -1) {
|
||||
fprintf(stderr, "Waiting for client...\n");
|
||||
int client_socket = socket_accept_client(accepting_socket);
|
||||
@ -48,7 +58,7 @@ server_loop(char *port_string)
|
||||
static void
|
||||
usage(char * av0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-p port] [-R rootdir] [-h] [-e seconds]\n"
|
||||
fprintf(stderr, "Usage: %s -p port [-R rootdir] [-h] [-e seconds]\n"
|
||||
" -p port port number to bind to\n"
|
||||
" -R rootdir root directory from which to serve files\n"
|
||||
" -e seconds expiration time for tokens in seconds\n"
|
||||
@ -91,6 +101,15 @@ main(int ac, char *av[])
|
||||
}
|
||||
}
|
||||
|
||||
if (port_string == NULL)
|
||||
usage(av[0]);
|
||||
|
||||
/* We ignore SIGPIPE to prevent the process from terminating when it tries
|
||||
* to send data to a connection that the client already closed.
|
||||
* This may happen, in particular, in bufio_sendfile.
|
||||
*/
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
fprintf(stderr, "Using port %s\n", port_string);
|
||||
server_loop(port_string);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
9
src/main.h
Normal file
9
src/main.h
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Declarations of various global variables.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
extern char *server_root;
|
||||
extern bool silent_mode;
|
||||
extern int token_expiration_time;
|
||||
extern bool html5_fallback;
|
@ -18,11 +18,12 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "socket.h"
|
||||
#include "globals.h"
|
||||
#include "main.h"
|
||||
|
||||
/*
|
||||
* Find a suitable IPv4 address to bind to, create a socket, bind it,
|
||||
|
4
tests/build.sh
Executable file
4
tests/build.sh
Executable file
@ -0,0 +1,4 @@
|
||||
# build the getaddrinfo preloaded library to test IPv4/IPv6 scenarios
|
||||
gcc -fPIC -Wall -c getaddrinfo.c
|
||||
gcc -shared -o getaddrinfo.so.1.0.1 getaddrinfo.o -ldl
|
||||
|
102
tests/getaddrinfo.c
Normal file
102
tests/getaddrinfo.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Intercept getaddrinfo to simulate IPv4-only, IPv6-only, and
|
||||
* environment in which addresses are returned in a different order.
|
||||
*
|
||||
* Written for CS 3214 Virginia Tech, Spring 2018.
|
||||
*
|
||||
* Godmar Back <godmar@gmail.com>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#define __USE_GNU 1 /* for RTLD_NEXT */
|
||||
#include <dlfcn.h>
|
||||
|
||||
static int (*real_getaddrinfo)(const char *node,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res);
|
||||
|
||||
static void (*real_freeaddrinfo)(struct addrinfo *res);
|
||||
|
||||
static void
|
||||
init()
|
||||
{
|
||||
static int inited;
|
||||
|
||||
if (inited++ > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
real_getaddrinfo = dlsym(RTLD_NEXT, "getaddrinfo");
|
||||
if (!real_getaddrinfo) {
|
||||
printf("error in dlsym getaddrinfo %s\n", dlerror());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
real_freeaddrinfo = dlsym(RTLD_NEXT, "freeaddrinfo");
|
||||
if (!real_freeaddrinfo) {
|
||||
printf("error in dlsym freeaddrinfo %s\n", dlerror());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int getaddrinfo(
|
||||
const char *node,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
init();
|
||||
|
||||
struct addrinfo * reallist;
|
||||
int rc = real_getaddrinfo(node, service, hints, &reallist);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
int skipipv4 = getenv("SKIPIPV4") != NULL;
|
||||
int skipipv6 = getenv("SKIPIPV6") != NULL;
|
||||
int reverse = getenv("REVERSEIPADDR") != NULL;
|
||||
if (reverse) {
|
||||
struct addrinfo * rp = reallist;
|
||||
struct addrinfo * last = NULL;
|
||||
while (rp != NULL) {
|
||||
struct addrinfo * next = rp->ai_next;
|
||||
rp->ai_next = last;
|
||||
last = rp;
|
||||
rp = next;
|
||||
}
|
||||
*res = last;
|
||||
} else if (skipipv4 || skipipv6) {
|
||||
struct addrinfo * rp, ** last = &reallist;
|
||||
for (rp = reallist; rp != NULL; ) {
|
||||
if ((skipipv4 && rp->ai_family == AF_INET) || (skipipv6 && rp->ai_family == AF_INET6)) {
|
||||
// skip and free
|
||||
(*last) = rp->ai_next;
|
||||
struct addrinfo * old = rp;
|
||||
rp = rp->ai_next;
|
||||
old->ai_next = NULL;
|
||||
real_freeaddrinfo(old);
|
||||
} else {
|
||||
// include
|
||||
last = &rp->ai_next;
|
||||
rp = rp->ai_next;
|
||||
}
|
||||
}
|
||||
*res = reallist;
|
||||
} else {
|
||||
*res = reallist;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void freeaddrinfo(struct addrinfo *res)
|
||||
{
|
||||
init();
|
||||
real_freeaddrinfo(res);
|
||||
}
|
2067
tests/server_unit_test_pserv.py
Executable file
2067
tests/server_unit_test_pserv.py
Executable file
File diff suppressed because it is too large
Load Diff
7
tests/test_root_data/css/jquery-ui.min.css
vendored
Executable file
7
tests/test_root_data/css/jquery-ui.min.css
vendored
Executable file
File diff suppressed because one or more lines are too long
11
tests/test_root_data/index.html
Executable file
11
tests/test_root_data/index.html
Executable file
@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CS3214 - Personal Server
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Congrats! Your server is up and running.</p>
|
||||
<p>This is a main HTML file for CS3214 - Project 4 - Personal Server.</p>
|
||||
</body>
|
||||
</html>
|
3
tests/test_root_data/js/jquery.min.js
vendored
Executable file
3
tests/test_root_data/js/jquery.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
10
tests/test_root_data/private/secure.html
Executable file
10
tests/test_root_data/private/secure.html
Executable file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CS3214 - Personal Server
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This is a secure file that must be served only if a valid auth token is present.</p>
|
||||
</body>
|
||||
</html>
|
10
tests/test_root_data/public/index.html
Executable file
10
tests/test_root_data/public/index.html
Executable file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CS3214 - Personal Server
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This is a public document that should be accessible irrespective of authentication.</p>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user