diff --git a/documentation/sitefiles.md b/documentation/sitefiles.md index 1bc3b20..4d56f9d 100644 --- a/documentation/sitefiles.md +++ b/documentation/sitefiles.md @@ -11,15 +11,35 @@ sitefiles also allow comments with # # Part 2: Commands -* ```set [variable] [value]``` - sets some local variable for the following pages +* ```set [variable] [value]``` - sets some local variable for the following + pages + * ```define [variable] [value]``` - sets some global variable -* ```read [http path] [file path]``` - if the requested path matches ```[http path]```, return the contents of ```[file path]```. If [file path] is a directory, then the http path is appended to [file path] and that is read instead. -* ```linked``` - Run getResponse() from the library loaded from the library global variable -* ```throw [http path] [error code]``` - If the requested path matches ```[http path]```, send back the http error code ```[error code]```. For standardization purposes, these error codes are just the number. -* ```declare [transport] [port]``` - Declares that port ```[port]``` will be used with transport ```[transport]``` where ```[transport]``` is one of ```TCP```, ```TLS``` -* ```key [key file] [port]``` - Sets the key file for port ```[port]``` to ```[key file]``` -* ```cert [cert file] [port]``` - Sets the certificate file for port ```[port]``` to ```[cert file]``` -* ```timeout [timeout] [port]``` - Sets the connection timeout for port ```[port]``` to ```[timeout]``` milliseconds + +* ```read [http path] [file path]``` - if the requested path matches + ```[http path]```, return the contents of ```[file path]```. If [file path] is + a directory, then the http path is appended to [file path] and that is read + instead. + +* ```linked``` - Run getResponse() from the library loaded from the library + global variable + +* ```throw [http path] [error code]``` - If the requested path matches + ```[http path]```, send back the http error code ```[error code]```. For + standardization purposes, these error codes are just the number. + +* ```declare [transport] [port]``` - Declares that port ```[port]``` will be + used with transport ```[transport]``` where ```[transport]``` is one of + ```TCP```, ```TLS```. + +* ```key [key file] [port]``` - Sets the key file for port ```[port]``` to + ```[key file]``` + +* ```cert [cert file] [port]``` - Sets the certificate file for port + ```[port]``` to ```[cert file]``` + +* ```timeout [timeout] [port]``` - Sets the connection timeout for port + ```[port]``` to ```[timeout]``` milliseconds ##### Other than set, commands should take in a regex as argument 1 and operate on a file specified in argument 2. @@ -29,7 +49,7 @@ sitefiles also allow comments with # * GET (defualt) * POST * ```host``` - The hostname to respond to. Case insensitive regex, default: .* -* ```port``` - The port to respond to, default: 80 +* ```port``` - The ports to respond to in a comma separated list. Default: 80 # Part 4: Global variables diff --git a/site/library.so b/site/library.so new file mode 100755 index 0000000..2afe267 Binary files /dev/null and b/site/library.so differ diff --git a/site/site/shared.html b/site/site/shared.html new file mode 100644 index 0000000..8570c59 --- /dev/null +++ b/site/site/shared.html @@ -0,0 +1 @@ +
This page is accessible on ports 8000 and 8001.
diff --git a/site/sitefile b/site/sitefile index 6bfd67b..8a73adb 100644 --- a/site/sitefile +++ b/site/sitefile @@ -30,15 +30,13 @@ read /blog/.* site/blog/ linked /library # The path /library should be dynamically loaded from the library (library.so) -set host 127.0.0.1:8000 -# The following pages will respond to the host 127.0.0.1:8000 +set host .* +# The following pages will respond to the host .* (any host) read / site/easteregg.html # The path / should be read from site/easteregg.html read /egg.png site/egg.png # The path /egg.png should be read from site/egg.png -set host .* -# The following pages will respond to all hosts (regex) read /alldomains site/alldomains.html # The path /alldomains should be read from /site/alldomains.html @@ -47,3 +45,7 @@ set port 8001 read / site/8001.html # The path / should be read from site/8001.html + +set port 8000,8001 + +read /shared site/shared.html diff --git a/src/responses.c b/src/responses.c index fb365a7..1fa5b62 100644 --- a/src/responses.c +++ b/src/responses.c @@ -168,6 +168,15 @@ int sendResponse(Connection *conn, Sitefile *site) { continue; if (fullmatch(&site->content[i].host, host)) continue; + { + int j; + const unsigned short currport = site->ports[conn->portind].num; + for (j = 0; j < site->content[i].portcount; ++j) + if (site->content[i].ports[j] == currport) + goto foundport; + continue; + } +foundport: if (fullmatch(&site->content[i].path, conn->path.data) == 0) { switch (site->content[i].command) { case READ: diff --git a/src/sitefile.c b/src/sitefile.c index f02712c..00649bb 100644 --- a/src/sitefile.c +++ b/src/sitefile.c @@ -174,6 +174,45 @@ error: return ERROR; } +static char *getport(char *data, unsigned short *ret) { + *ret = 0; + while (isdigit(data[0])) { + *ret *= 10; + *ret += data[0] - '0'; + ++data; + } + if (data[0] == ',') + return data + 1; + if (data[0] != '\0') + return NULL; + return data; +} + +static int getports(unsigned short **ports, int *portcount, char *data) { + int alloc; + alloc = 10; + *portcount = 0; + *ports = xmalloc(alloc * sizeof **ports); + for (;;) { + if (data[0] == '\0') + return 0; + if (*portcount >= alloc) { + alloc *= 2; + *ports = xrealloc(*ports, alloc * sizeof **ports); + } + { + unsigned short newport; + data = getport(data, &newport); + (*ports)[*portcount] = newport; + ++*portcount; + } + if (data == NULL) { + free(*ports); + return 1; + } + } +} + Sitefile *parseSitefile(char *path) { FILE *file; RequestType respondto = GET; @@ -182,14 +221,18 @@ Sitefile *parseSitefile(char *path) { int argc; char **argv; Sitefile *ret; - unsigned short currport; + unsigned short *ports; + int portcount; - currport = 80; file = fopen(path, "r"); if (file == NULL) return NULL; ret = xmalloc(sizeof *ret); + ports = malloc(sizeof *ports); + ports[0] = 80; + portcount = 1; + ret->size = 0; ret->alloc = 50; ret->content = xmalloc(ret->alloc * sizeof *ret->content); @@ -205,6 +248,7 @@ Sitefile *parseSitefile(char *path) { switch (status) { int i; case FILE_END: + free(ports); for (i = 0; i < ret->portcount; ++i) { Port *port = ret->ports + i; if (port->type == TLS && @@ -232,8 +276,14 @@ Sitefile *parseSitefile(char *path) { } else if (strcmp(argv[1], "host") == 0) host = xstrdup(argv[2]); - else if (strcmp(argv[1], "port") == 0) - currport = atoi(argv[2]); + else if (strcmp(argv[1], "port") == 0) { + free(ports); + if (getports(&ports, &portcount, argv[2])) { + fprintf(stderr, "Invalid port list %s\n", + argv[2]); + goto error; + } + } else goto error; continue; @@ -361,7 +411,12 @@ Sitefile *parseSitefile(char *path) { regcomp(&ret->content[ret->size].host, ".*", cflags); else regcomp(&ret->content[ret->size].host, host, cflags); - ret->content[ret->size].port = currport; + + ret->content[ret->size].ports = xmalloc(portcount * + sizeof *ret->content[ret->size].ports); + memcpy(ret->content[ret->size].ports, ports, portcount * sizeof *ports); + ret->content[ret->size].portcount = portcount; + ret->size++; } error: diff --git a/src/sockets.c b/src/sockets.c index f113389..6729f0f 100644 --- a/src/sockets.c +++ b/src/sockets.c @@ -143,22 +143,30 @@ Stream *createStream(Context *context, int flags, int fd) { case TCP: default: break; case TLS: - if (gnutls_init(&ret->session, GNUTLS_SERVER) < 0) + if (gnutls_init(&ret->session, GNUTLS_SERVER) < 0) { + createErrorLog("gnutls_init() failed", errno); goto error; + } if (gnutls_priority_set(ret->session, - context->priority) < 0) + context->priority) < 0) { + createErrorLog("gnutls_priority_set() failed", errno); goto error; + } if (gnutls_credentials_set(ret->session, GNUTLS_CRD_CERTIFICATE, - context->creds) < 0) + context->creds) < 0) { + createErrorLog("gnutls_credentials_set() failed", errno); goto error; + } gnutls_certificate_server_set_request(ret->session, GNUTLS_CERT_IGNORE); gnutls_handshake_set_timeout(ret->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); gnutls_transport_set_int(ret->session, ret->fd); - if (gnutls_handshake(ret->session) < 0) + if (gnutls_handshake(ret->session) < 0) { + createErrorLog("gnutls_handshake() failed", errno); goto error; + } break; } return ret; diff --git a/src/swebs/sitefile.h b/src/swebs/sitefile.h index 0030f0b..c8cef22 100644 --- a/src/swebs/sitefile.h +++ b/src/swebs/sitefile.h @@ -43,7 +43,8 @@ typedef struct { Command command; regex_t path; char *arg; - unsigned short port; + unsigned short *ports; + int portcount; } SiteCommand; typedef struct {