Fixed multiple port support and improved it

This commit is contained in:
2022-06-28 07:57:15 -05:00
parent 47cf044858
commit d843ffab93
8 changed files with 119 additions and 23 deletions

View File

@@ -11,15 +11,35 @@ sitefiles also allow comments with #
# Part 2: Commands # 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 * ```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 * ```read [http path] [file path]``` - if the requested path matches
* ```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. ```[http path]```, return the contents of ```[file path]```. If [file path] is
* ```declare [transport] [port]``` - Declares that port ```[port]``` will be used with transport ```[transport]``` where ```[transport]``` is one of ```TCP```, ```TLS``` a directory, then the http path is appended to [file path] and that is read
* ```key [key file] [port]``` - Sets the key file for port ```[port]``` to ```[key file]``` instead.
* ```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 * ```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. ##### 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) * GET (defualt)
* POST * POST
* ```host``` - The hostname to respond to. Case insensitive regex, default: .* * ```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 # Part 4: Global variables

BIN
site/library.so Executable file

Binary file not shown.

1
site/site/shared.html Normal file
View File

@@ -0,0 +1 @@
<p>This page is accessible on ports 8000 and 8001.</p>

View File

@@ -30,15 +30,13 @@ read /blog/.* site/blog/
linked /library linked /library
# The path /library should be dynamically loaded from the library (library.so) # The path /library should be dynamically loaded from the library (library.so)
set host 127.0.0.1:8000 set host .*
# The following pages will respond to the host 127.0.0.1:8000 # The following pages will respond to the host .* (any host)
read / site/easteregg.html read / site/easteregg.html
# The path / should be read from site/easteregg.html # The path / should be read from site/easteregg.html
read /egg.png site/egg.png read /egg.png site/egg.png
# The path /egg.png should be read from 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 read /alldomains site/alldomains.html
# The path /alldomains should be read from /site/alldomains.html # The path /alldomains should be read from /site/alldomains.html
@@ -47,3 +45,7 @@ set port 8001
read / site/8001.html read / site/8001.html
# The path / should be read from site/8001.html # The path / should be read from site/8001.html
set port 8000,8001
read /shared site/shared.html

View File

@@ -168,6 +168,15 @@ int sendResponse(Connection *conn, Sitefile *site) {
continue; continue;
if (fullmatch(&site->content[i].host, host)) if (fullmatch(&site->content[i].host, host))
continue; 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) { if (fullmatch(&site->content[i].path, conn->path.data) == 0) {
switch (site->content[i].command) { switch (site->content[i].command) {
case READ: case READ:

View File

@@ -174,6 +174,45 @@ error:
return 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) { Sitefile *parseSitefile(char *path) {
FILE *file; FILE *file;
RequestType respondto = GET; RequestType respondto = GET;
@@ -182,14 +221,18 @@ Sitefile *parseSitefile(char *path) {
int argc; int argc;
char **argv; char **argv;
Sitefile *ret; Sitefile *ret;
unsigned short currport; unsigned short *ports;
int portcount;
currport = 80;
file = fopen(path, "r"); file = fopen(path, "r");
if (file == NULL) if (file == NULL)
return NULL; return NULL;
ret = xmalloc(sizeof *ret); ret = xmalloc(sizeof *ret);
ports = malloc(sizeof *ports);
ports[0] = 80;
portcount = 1;
ret->size = 0; ret->size = 0;
ret->alloc = 50; ret->alloc = 50;
ret->content = xmalloc(ret->alloc * sizeof *ret->content); ret->content = xmalloc(ret->alloc * sizeof *ret->content);
@@ -205,6 +248,7 @@ Sitefile *parseSitefile(char *path) {
switch (status) { switch (status) {
int i; int i;
case FILE_END: case FILE_END:
free(ports);
for (i = 0; i < ret->portcount; ++i) { for (i = 0; i < ret->portcount; ++i) {
Port *port = ret->ports + i; Port *port = ret->ports + i;
if (port->type == TLS && if (port->type == TLS &&
@@ -232,8 +276,14 @@ Sitefile *parseSitefile(char *path) {
} }
else if (strcmp(argv[1], "host") == 0) else if (strcmp(argv[1], "host") == 0)
host = xstrdup(argv[2]); host = xstrdup(argv[2]);
else if (strcmp(argv[1], "port") == 0) else if (strcmp(argv[1], "port") == 0) {
currport = atoi(argv[2]); free(ports);
if (getports(&ports, &portcount, argv[2])) {
fprintf(stderr, "Invalid port list %s\n",
argv[2]);
goto error;
}
}
else else
goto error; goto error;
continue; continue;
@@ -361,7 +411,12 @@ Sitefile *parseSitefile(char *path) {
regcomp(&ret->content[ret->size].host, ".*", cflags); regcomp(&ret->content[ret->size].host, ".*", cflags);
else else
regcomp(&ret->content[ret->size].host, host, cflags); 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++; ret->size++;
} }
error: error:

View File

@@ -143,22 +143,30 @@ Stream *createStream(Context *context, int flags, int fd) {
case TCP: default: case TCP: default:
break; break;
case TLS: 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; goto error;
}
if (gnutls_priority_set(ret->session, if (gnutls_priority_set(ret->session,
context->priority) < 0) context->priority) < 0) {
createErrorLog("gnutls_priority_set() failed", errno);
goto error; goto error;
}
if (gnutls_credentials_set(ret->session, if (gnutls_credentials_set(ret->session,
GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE,
context->creds) < 0) context->creds) < 0) {
createErrorLog("gnutls_credentials_set() failed", errno);
goto error; goto error;
}
gnutls_certificate_server_set_request(ret->session, gnutls_certificate_server_set_request(ret->session,
GNUTLS_CERT_IGNORE); GNUTLS_CERT_IGNORE);
gnutls_handshake_set_timeout(ret->session, gnutls_handshake_set_timeout(ret->session,
GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
gnutls_transport_set_int(ret->session, ret->fd); 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; goto error;
}
break; break;
} }
return ret; return ret;

View File

@@ -43,7 +43,8 @@ typedef struct {
Command command; Command command;
regex_t path; regex_t path;
char *arg; char *arg;
unsigned short port; unsigned short *ports;
int portcount;
} SiteCommand; } SiteCommand;
typedef struct { typedef struct {