pixl-server-web 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +251 -40
- package/lib/http.js +1 -1
- package/lib/https.js +1 -1
- package/lib/response.js +6 -0
- package/package.json +1 -1
- package/web_server.js +92 -1
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ This module is a component for use in [pixl-server](https://www.github.com/jhuck
|
|
|
36
36
|
* [brotli_opts](#brotli_opts)
|
|
37
37
|
* [default_acl](#default_acl)
|
|
38
38
|
* [blacklist](#blacklist)
|
|
39
|
+
* [whitelist](#whitelist)
|
|
39
40
|
* [allow_hosts](#allow_hosts)
|
|
40
41
|
* [rewrites](#rewrites)
|
|
41
42
|
* [redirects](#redirects)
|
|
@@ -64,6 +65,7 @@ This module is a component for use in [pixl-server](https://www.github.com/jhuck
|
|
|
64
65
|
* [startup_message](#startup_message)
|
|
65
66
|
* [debug_ttl](#debug_ttl)
|
|
66
67
|
* [debug_bind_local](#debug_bind_local)
|
|
68
|
+
* [chaos](#chaos)
|
|
67
69
|
* [https](#https)
|
|
68
70
|
* [https_port](#https_port)
|
|
69
71
|
* [https_alt_ports](#https_alt_ports)
|
|
@@ -118,7 +120,23 @@ This module is a component for use in [pixl-server](https://www.github.com/jhuck
|
|
|
118
120
|
* [Determining HTTP or HTTPS](#determining-http-or-https)
|
|
119
121
|
* [Self-Referencing URLs](#self-referencing-urls)
|
|
120
122
|
* [Custom Method Handlers](#custom-method-handlers)
|
|
121
|
-
* [Let's Encrypt
|
|
123
|
+
* [Let's Encrypt / ACME TLS Certificates](#lets-encrypt--acme-tls-certificates)
|
|
124
|
+
+ [ACME clients](#acme-clients)
|
|
125
|
+
+ [Point your domain at your server](#point-your-domain-at-your-server)
|
|
126
|
+
+ [Install Certbot](#install-certbot)
|
|
127
|
+
- [Ubuntu / Debian](#ubuntu--debian)
|
|
128
|
+
- [RHEL / CentOS / Fedora](#rhel--centos--fedora)
|
|
129
|
+
+ [Option A: HTTP-01 (webroot)](#option-a-http-01-webroot)
|
|
130
|
+
- [Ensure HTTP is working on port 80](#ensure-http-is-working-on-port-80)
|
|
131
|
+
- [Issue a certificate using webroot](#issue-a-certificate-using-webroot)
|
|
132
|
+
+ [Configure pixl-server-web for HTTPS](#configure-pixl-server-web-for-https)
|
|
133
|
+
+ [Automatic renewal](#automatic-renewal)
|
|
134
|
+
- [Check that renewal timers are installed](#check-that-renewal-timers-are-installed)
|
|
135
|
+
+ [Option B: DNS-01 with DNS API (wildcards, advanced)](#option-b-dns-01-with-dns-api-wildcards-advanced)
|
|
136
|
+
- [Using Certbot DNS plugins](#using-certbot-dns-plugins)
|
|
137
|
+
- [Using acme.sh](#using-acmesh)
|
|
138
|
+
+ [Where your certificates live](#where-your-certificates-live)
|
|
139
|
+
+ [Troubleshooting](#troubleshooting)
|
|
122
140
|
* [Request Max Dump](#request-max-dump)
|
|
123
141
|
- [License](#license)
|
|
124
142
|
|
|
@@ -822,6 +840,29 @@ When set to `true` and running in debug mode (i.e. `--debug` CLI flag on startup
|
|
|
822
840
|
|
|
823
841
|
This feature defaults to `false` (disabled).
|
|
824
842
|
|
|
843
|
+
## chaos
|
|
844
|
+
|
|
845
|
+
Use the `chaos` feature to introduce optional and random fault injection into your web requests. Used for testing purposes, this feature can introduce a random delay on every request, and also hijack requests and inject random error responses based on probabilities you specify. Here is how to use it:
|
|
846
|
+
|
|
847
|
+
```json
|
|
848
|
+
"chaos": {
|
|
849
|
+
"enabled": true,
|
|
850
|
+
"uri": ".+",
|
|
851
|
+
"delay": {
|
|
852
|
+
"min":0,
|
|
853
|
+
"max":2000
|
|
854
|
+
},
|
|
855
|
+
"errors": {
|
|
856
|
+
"503 Service Unavailable": 0.1
|
|
857
|
+
},
|
|
858
|
+
"headers": {
|
|
859
|
+
"Retry-After": 10
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
Set the `chaos.enabled` flag to `true` to enable fault injection. By default, all URIs will be affected, unless you specify a `chaos.uri` (regular expression) to limit the requests. Set `chaos.delay.min` and `chaos.delay.max` to the range you want to delay requests (in milliseconds). Fill the `chaos.errors` object the HTTP repsonse codes (and status messages) you want to see, and how often. The values are interpreted as probabilities from `0.0` (never) to `1.0` (always). In the above example, the `HTTP 503` error code will be injected approximately 10% of the time. When errors are injected, you can include additional response headers in the `chaos.headers` object.
|
|
865
|
+
|
|
825
866
|
## https
|
|
826
867
|
|
|
827
868
|
This boolean allows you to enable HTTPS (SSL) support in the web server. It defaults to `false`. Note that you must also set `https_port`, and possibly `https_cert_file` and `https_key_file` for this to work.
|
|
@@ -1017,6 +1058,8 @@ callback(
|
|
|
1017
1058
|
|
|
1018
1059
|
The content body can be a string, a [Buffer](https://nodejs.org/api/buffer.html) object, or a [readable stream](https://nodejs.org/api/stream.html#class-streamreadable).
|
|
1019
1060
|
|
|
1061
|
+
Note that you can omit the status text and just return a code, e.g. `"200"`, and the web server will fill in the text.
|
|
1062
|
+
|
|
1020
1063
|
### Custom Response
|
|
1021
1064
|
|
|
1022
1065
|
The second type of response is to send content directly to the underlying Node.js server by yourself, using `args.response` (see below). If you do this, you can pass `true` to the callback function, indicating to the web server that you "handled" the response, and it shouldn't do anything else. Example:
|
|
@@ -1895,78 +1938,246 @@ server.WebServer.addMethodHandler( "OPTIONS", "CORS Preflight", function(args, c
|
|
|
1895
1938
|
} );
|
|
1896
1939
|
```
|
|
1897
1940
|
|
|
1898
|
-
## Let's Encrypt
|
|
1941
|
+
## Let's Encrypt / ACME TLS Certificates
|
|
1942
|
+
|
|
1943
|
+
These are instructions for using [Let's Encrypt](https://letsencrypt.org/) TLS certificates with **pixl-server-web**: how to get your certificate issued and how to keep it renewed automatically.
|
|
1944
|
+
|
|
1945
|
+
The examples below use the domain `mydomain.com`. Replace this with your own real domain.
|
|
1946
|
+
|
|
1947
|
+
### ACME clients
|
|
1948
|
+
|
|
1949
|
+
Let's Encrypt issues certificates using the **ACME protocol**. To talk ACME, you need an ACME *client*.
|
|
1899
1950
|
|
|
1900
|
-
|
|
1951
|
+
For most people, Let's Encrypt recommends **Certbot** as the default ACME client:
|
|
1901
1952
|
|
|
1902
|
-
|
|
1953
|
+
https://letsencrypt.org/docs/client-options/
|
|
1903
1954
|
|
|
1904
|
-
|
|
1955
|
+
Other popular clients include:
|
|
1956
|
+
|
|
1957
|
+
* **acme.sh** – pure shell, great DNS-API support.
|
|
1958
|
+
* Various language-specific clients (Go, Rust, Node, etc.) – see the Let's Encrypt “ACME clients” list for a full catalog.
|
|
1959
|
+
|
|
1960
|
+
These docs focus on **Certbot**, with a short note about acme.sh for DNS-based / wildcard setups.
|
|
1961
|
+
|
|
1962
|
+
### Point your domain at your server
|
|
1963
|
+
|
|
1964
|
+
Before you can get a certificate:
|
|
1965
|
+
|
|
1966
|
+
1. Make sure your server has a **public IPv4 (and/or IPv6) address**.
|
|
1967
|
+
2. In your DNS provider’s control panel, create an **A record** for your domain:
|
|
1968
|
+
- Name: `@` (or `mydomain.com`, provider-specific)
|
|
1969
|
+
- Type: `A`
|
|
1970
|
+
- Value: your server’s IPv4 address
|
|
1971
|
+
- Optionally create an **AAAA record** for IPv6.
|
|
1972
|
+
3. Wait for DNS to propagate.
|
|
1973
|
+
|
|
1974
|
+
You should be able to open http://mydomain.com/ in a browser and hit your server.
|
|
1975
|
+
|
|
1976
|
+
### Install Certbot
|
|
1977
|
+
|
|
1978
|
+
1. Go to: https://certbot.eff.org/
|
|
1979
|
+
2. Select:
|
|
1980
|
+
- Your OS (e.g. “Ubuntu 24.04” or “Debian 12”)
|
|
1981
|
+
- Web server: **“None of the above (or other)”**
|
|
1982
|
+
3. Follow the instructions shown there.
|
|
1983
|
+
|
|
1984
|
+
Typical examples:
|
|
1985
|
+
|
|
1986
|
+
#### Ubuntu / Debian
|
|
1987
|
+
|
|
1988
|
+
Certbot’s maintainers (EFF) now publish current builds only through Snap:
|
|
1905
1989
|
|
|
1906
1990
|
```sh
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
chmod a+x /usr/local/bin/certbot-auto
|
|
1991
|
+
sudo snap install --classic certbot
|
|
1992
|
+
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
|
|
1910
1993
|
```
|
|
1911
1994
|
|
|
1912
|
-
|
|
1995
|
+
#### RHEL / CentOS / Fedora
|
|
1996
|
+
|
|
1997
|
+
DNF is the correct command to use on RedHat and family:
|
|
1913
1998
|
|
|
1914
1999
|
```sh
|
|
1915
|
-
|
|
2000
|
+
sudo dnf install certbot
|
|
1916
2001
|
```
|
|
1917
2002
|
|
|
1918
|
-
|
|
2003
|
+
Verify installation:
|
|
1919
2004
|
|
|
1920
|
-
|
|
2005
|
+
```sh
|
|
2006
|
+
certbot --version
|
|
2007
|
+
```
|
|
2008
|
+
|
|
2009
|
+
### Option A: HTTP-01 (webroot)
|
|
2010
|
+
|
|
2011
|
+
HTTP-01 requires port **80** open and a web root directory that pixl-server-web (or another HTTP server) uses.
|
|
2012
|
+
|
|
2013
|
+
#### Ensure HTTP is working on port 80
|
|
2014
|
+
|
|
2015
|
+
Configure pixl-server-web (or any HTTP server) to:
|
|
2016
|
+
|
|
2017
|
+
- Listen on **port 80**.
|
|
2018
|
+
- Serve static content from a directory, for example `/var/www/html`.
|
|
2019
|
+
|
|
2020
|
+
Then visit: http://mydomain.com/
|
|
1921
2021
|
|
|
2022
|
+
#### Issue a certificate using webroot
|
|
2023
|
+
|
|
2024
|
+
```sh
|
|
2025
|
+
sudo certbot certonly --webroot -w /var/www/html -d mydomain.com
|
|
1922
2026
|
```
|
|
1923
|
-
IMPORTANT NOTES:
|
|
1924
|
-
- Congratulations! Your certificate and chain have been saved at:
|
|
1925
|
-
/etc/letsencrypt/live/mydomain.com/fullchain.pem
|
|
1926
|
-
Your key file has been saved at:
|
|
1927
|
-
/etc/letsencrypt/live/mydomain.com/privkey.pem
|
|
1928
|
-
Your cert will expire on 2019-06-19. To obtain a new or tweaked
|
|
1929
|
-
version of this certificate in the future, simply run certbot-auto
|
|
1930
|
-
again. To non-interactively renew *all* of your certificates, run
|
|
1931
|
-
"certbot-auto renew"
|
|
1932
|
-
- Your account credentials have been saved in your Certbot
|
|
1933
|
-
configuration directory at /etc/letsencrypt. You should make a
|
|
1934
|
-
secure backup of this folder now. This configuration directory will
|
|
1935
|
-
also contain certificates and private keys obtained by Certbot so
|
|
1936
|
-
making regular backups of this folder is ideal.
|
|
1937
|
-
- If you like Certbot, please consider supporting our work by:
|
|
1938
2027
|
|
|
1939
|
-
|
|
1940
|
-
|
|
2028
|
+
Add more hostnames if needed:
|
|
2029
|
+
|
|
2030
|
+
```sh
|
|
2031
|
+
sudo certbot certonly --webroot -w /var/www/html -d mydomain.com -d www.mydomain.com
|
|
1941
2032
|
```
|
|
1942
2033
|
|
|
1943
|
-
|
|
2034
|
+
Certbot will create:
|
|
2035
|
+
|
|
2036
|
+
```
|
|
2037
|
+
/etc/letsencrypt/live/mydomain.com/fullchain.pem
|
|
2038
|
+
/etc/letsencrypt/live/mydomain.com/privkey.pem
|
|
2039
|
+
/etc/letsencrypt/live/mydomain.com/cert.pem
|
|
2040
|
+
/etc/letsencrypt/live/mydomain.com/chain.pem
|
|
2041
|
+
```
|
|
2042
|
+
|
|
2043
|
+
### Configure pixl-server-web for HTTPS
|
|
2044
|
+
|
|
2045
|
+
In your pixl-server-web config:
|
|
1944
2046
|
|
|
1945
2047
|
```js
|
|
1946
2048
|
"https": true,
|
|
1947
2049
|
"https_port": 443,
|
|
1948
|
-
"https_cert_file":
|
|
1949
|
-
"https_key_file":
|
|
1950
|
-
"https_ca_file":
|
|
2050
|
+
"https_cert_file": "/etc/letsencrypt/live/mydomain.com/cert.pem",
|
|
2051
|
+
"https_key_file": "/etc/letsencrypt/live/mydomain.com/privkey.pem",
|
|
2052
|
+
"https_ca_file": "/etc/letsencrypt/live/mydomain.com/chain.pem"
|
|
2053
|
+
```
|
|
2054
|
+
|
|
2055
|
+
Then restart pixl-server-web so it can bind to port 443.
|
|
2056
|
+
|
|
2057
|
+
Visit: https://mydomain.com/
|
|
2058
|
+
|
|
2059
|
+
### Automatic renewal
|
|
2060
|
+
|
|
2061
|
+
Let's Encrypt certificates are valid for **90 days**.
|
|
2062
|
+
|
|
2063
|
+
Certbot automatically installs:
|
|
2064
|
+
|
|
2065
|
+
- A **systemd timer**, or
|
|
2066
|
+
- A **cron job**
|
|
2067
|
+
|
|
2068
|
+
that runs `certbot renew` twice a day.
|
|
2069
|
+
|
|
2070
|
+
pixl-server-web will automatically reload certs when they change on disk. There is no need to trigger a restart.
|
|
2071
|
+
|
|
2072
|
+
#### Check that renewal timers are installed
|
|
2073
|
+
|
|
2074
|
+
```sh
|
|
2075
|
+
systemctl list-timers | grep certbot
|
|
2076
|
+
```
|
|
2077
|
+
|
|
2078
|
+
Test renewal:
|
|
2079
|
+
|
|
2080
|
+
```sh
|
|
2081
|
+
sudo certbot renew --dry-run
|
|
2082
|
+
```
|
|
2083
|
+
|
|
2084
|
+
### Option B: DNS-01 with DNS API (wildcards, advanced)
|
|
2085
|
+
|
|
2086
|
+
Use DNS-01 if:
|
|
2087
|
+
|
|
2088
|
+
* You want a **wildcard cert** (`*.mydomain.com`).
|
|
2089
|
+
* Port 80 is blocked or server is not exposed to the internet.
|
|
2090
|
+
* You want a central ACME box managing certs.
|
|
2091
|
+
|
|
2092
|
+
DNS-01 works by creating a TXT record:
|
|
2093
|
+
|
|
1951
2094
|
```
|
|
2095
|
+
_acme-challenge.mydomain.com
|
|
2096
|
+
```
|
|
2097
|
+
|
|
2098
|
+
#### Using Certbot DNS plugins
|
|
1952
2099
|
|
|
1953
|
-
|
|
2100
|
+
Example: Cloudflare
|
|
1954
2101
|
|
|
1955
|
-
|
|
2102
|
+
Install plugin (package varies by distro):
|
|
1956
2103
|
|
|
1957
|
-
|
|
2104
|
+
```
|
|
2105
|
+
sudo apt install python3-certbot-dns-cloudflare
|
|
2106
|
+
```
|
|
2107
|
+
|
|
2108
|
+
Create credentials file:
|
|
2109
|
+
|
|
2110
|
+
`~/.secrets/certbot/cloudflare.ini`
|
|
2111
|
+
|
|
2112
|
+
```ini
|
|
2113
|
+
dns_cloudflare_api_token = YOUR_TOKEN
|
|
2114
|
+
```
|
|
2115
|
+
|
|
2116
|
+
Lock permissions:
|
|
1958
2117
|
|
|
1959
2118
|
```sh
|
|
1960
|
-
|
|
2119
|
+
chmod 600 ~/.secrets/certbot/cloudflare.ini
|
|
1961
2120
|
```
|
|
1962
2121
|
|
|
1963
|
-
|
|
2122
|
+
Issue wildcard cert:
|
|
1964
2123
|
|
|
1965
2124
|
```sh
|
|
1966
|
-
|
|
2125
|
+
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -d mydomain.com -d '*.mydomain.com'
|
|
1967
2126
|
```
|
|
1968
2127
|
|
|
1969
|
-
|
|
2128
|
+
#### Using acme.sh
|
|
2129
|
+
|
|
2130
|
+
Install:
|
|
2131
|
+
|
|
2132
|
+
```sh
|
|
2133
|
+
curl https://get.acme.sh | sh
|
|
2134
|
+
```
|
|
2135
|
+
|
|
2136
|
+
Issue DNS-based cert:
|
|
2137
|
+
|
|
2138
|
+
```sh
|
|
2139
|
+
~/.acme.sh/acme.sh --issue --dns dns_cf -d mydomain.com -d '*.mydomain.com'
|
|
2140
|
+
```
|
|
2141
|
+
|
|
2142
|
+
Install certs into your preferred paths:
|
|
2143
|
+
|
|
2144
|
+
```sh
|
|
2145
|
+
~/.acme.sh/acme.sh --install-cert -d mydomain.com --key-file /etc/letsencrypt/live/mydomain.com/privkey.pem --fullchain-file /etc/letsencrypt/live/mydomain.com/fullchain.pem
|
|
2146
|
+
```
|
|
2147
|
+
|
|
2148
|
+
### Where your certificates live
|
|
2149
|
+
|
|
2150
|
+
Default Certbot paths:
|
|
2151
|
+
|
|
2152
|
+
```
|
|
2153
|
+
/etc/letsencrypt/live/mydomain.com/privkey.pem
|
|
2154
|
+
/etc/letsencrypt/live/mydomain.com/fullchain.pem
|
|
2155
|
+
/etc/letsencrypt/live/mydomain.com/cert.pem
|
|
2156
|
+
/etc/letsencrypt/live/mydomain.com/chain.pem
|
|
2157
|
+
```
|
|
2158
|
+
|
|
2159
|
+
### Troubleshooting
|
|
2160
|
+
|
|
2161
|
+
Test renewal:
|
|
2162
|
+
|
|
2163
|
+
```sh
|
|
2164
|
+
sudo certbot renew --dry-run
|
|
2165
|
+
```
|
|
2166
|
+
|
|
2167
|
+
Logs:
|
|
2168
|
+
|
|
2169
|
+
```
|
|
2170
|
+
/var/log/letsencrypt/letsencrypt.log
|
|
2171
|
+
```
|
|
2172
|
+
|
|
2173
|
+
- DNS-01 issues:
|
|
2174
|
+
- Verify TXT record exists using `dig` or `nslookup`.
|
|
2175
|
+
- Ensure your API credentials have minimum DNS permissions.
|
|
2176
|
+
|
|
2177
|
+
For more information:
|
|
2178
|
+
|
|
2179
|
+
- https://letsencrypt.org/docs/
|
|
2180
|
+
- https://certbot.eff.org/docs/
|
|
1970
2181
|
|
|
1971
2182
|
## Request Max Dump
|
|
1972
2183
|
|
package/lib/http.js
CHANGED
|
@@ -209,7 +209,7 @@ module.exports = class HTTP {
|
|
|
209
209
|
if (self.config.get('log_socket_errors')) {
|
|
210
210
|
self.logError(err.code || 'socket', "Client error: " + socket._pixl_data.id + ": " + msg, err_args);
|
|
211
211
|
}
|
|
212
|
-
else {
|
|
212
|
+
else if (err.code != 'ECONNRESET') {
|
|
213
213
|
self.logDebug(5, "Client error: " + socket._pixl_data.id + ": " + msg, err_args);
|
|
214
214
|
}
|
|
215
215
|
|
package/lib/https.js
CHANGED
|
@@ -300,7 +300,7 @@ module.exports = class HTTP2 {
|
|
|
300
300
|
if (self.config.get('log_socket_errors')) {
|
|
301
301
|
self.logError(err.code || 'socket', "Client error: " + socket._pixl_data.id + ": " + msg, err_args);
|
|
302
302
|
}
|
|
303
|
-
else {
|
|
303
|
+
else if (err.code != 'ECONNRESET') {
|
|
304
304
|
self.logDebug(5, "Client error: " + socket._pixl_data.id + ": " + msg, err_args);
|
|
305
305
|
}
|
|
306
306
|
|
package/lib/response.js
CHANGED
|
@@ -72,10 +72,16 @@ module.exports = class Response {
|
|
|
72
72
|
// parse code and status
|
|
73
73
|
var http_code = 200;
|
|
74
74
|
var http_status = "OK";
|
|
75
|
+
|
|
75
76
|
if (status.match(/^(\d+)\s+(.+)$/)) {
|
|
76
77
|
http_code = parseInt( RegExp.$1 );
|
|
77
78
|
http_status = RegExp.$2;
|
|
78
79
|
}
|
|
80
|
+
else if (this.responseCodes[status]) {
|
|
81
|
+
http_code = parseInt(status);
|
|
82
|
+
http_status = this.responseCodes[status];
|
|
83
|
+
}
|
|
84
|
+
|
|
79
85
|
args.http_code = http_code;
|
|
80
86
|
args.http_status = http_status;
|
|
81
87
|
|
package/package.json
CHANGED
package/web_server.js
CHANGED
|
@@ -85,7 +85,68 @@ module.exports = Class({
|
|
|
85
85
|
stats: null,
|
|
86
86
|
recent: null,
|
|
87
87
|
|
|
88
|
-
badHeaderCharPattern: /([\x7F-\xFF\x00-\x1F\u00FF-\uFFFF])/g
|
|
88
|
+
badHeaderCharPattern: /([\x7F-\xFF\x00-\x1F\u00FF-\uFFFF])/g,
|
|
89
|
+
|
|
90
|
+
responseCodes: {
|
|
91
|
+
"100": "Continue",
|
|
92
|
+
"101": "Switching Protocols",
|
|
93
|
+
"102": "Processing",
|
|
94
|
+
"103": "Early Hints",
|
|
95
|
+
"200": "OK",
|
|
96
|
+
"201": "Created",
|
|
97
|
+
"202": "Accepted",
|
|
98
|
+
"203": "Non Authoritative Information",
|
|
99
|
+
"204": "No Content",
|
|
100
|
+
"205": "Reset Content",
|
|
101
|
+
"206": "Partial Content",
|
|
102
|
+
"207": "Multi-Status",
|
|
103
|
+
"300": "Multiple Choices",
|
|
104
|
+
"301": "Moved Permanently",
|
|
105
|
+
"302": "Moved Temporarily",
|
|
106
|
+
"303": "See Other",
|
|
107
|
+
"304": "Not Modified",
|
|
108
|
+
"305": "Use Proxy",
|
|
109
|
+
"307": "Temporary Redirect",
|
|
110
|
+
"308": "Permanent Redirect",
|
|
111
|
+
"400": "Bad Request",
|
|
112
|
+
"401": "Unauthorized",
|
|
113
|
+
"402": "Payment Required",
|
|
114
|
+
"403": "Forbidden",
|
|
115
|
+
"404": "Not Found",
|
|
116
|
+
"405": "Method Not Allowed",
|
|
117
|
+
"406": "Not Acceptable",
|
|
118
|
+
"407": "Proxy Authentication Required",
|
|
119
|
+
"408": "Request Timeout",
|
|
120
|
+
"409": "Conflict",
|
|
121
|
+
"410": "Gone",
|
|
122
|
+
"411": "Length Required",
|
|
123
|
+
"412": "Precondition Failed",
|
|
124
|
+
"413": "Request Entity Too Large",
|
|
125
|
+
"414": "Request-URI Too Long",
|
|
126
|
+
"415": "Unsupported Media Type",
|
|
127
|
+
"416": "Requested Range Not Satisfiable",
|
|
128
|
+
"417": "Expectation Failed",
|
|
129
|
+
"418": "I'm a teapot",
|
|
130
|
+
"419": "Insufficient Space on Resource",
|
|
131
|
+
"420": "Method Failure",
|
|
132
|
+
"421": "Misdirected Request",
|
|
133
|
+
"422": "Unprocessable Entity",
|
|
134
|
+
"423": "Locked",
|
|
135
|
+
"424": "Failed Dependency",
|
|
136
|
+
"426": "Upgrade Required",
|
|
137
|
+
"428": "Precondition Required",
|
|
138
|
+
"429": "Too Many Requests",
|
|
139
|
+
"431": "Request Header Fields Too Large",
|
|
140
|
+
"451": "Unavailable For Legal Reasons",
|
|
141
|
+
"500": "Internal Server Error",
|
|
142
|
+
"501": "Not Implemented",
|
|
143
|
+
"502": "Bad Gateway",
|
|
144
|
+
"503": "Service Unavailable",
|
|
145
|
+
"504": "Gateway Timeout",
|
|
146
|
+
"505": "HTTP Version Not Supported",
|
|
147
|
+
"507": "Insufficient Storage",
|
|
148
|
+
"511": "Network Authentication Required"
|
|
149
|
+
}
|
|
89
150
|
|
|
90
151
|
},
|
|
91
152
|
class WebServer extends Component {
|
|
@@ -122,10 +183,40 @@ class WebServer extends Component {
|
|
|
122
183
|
this.server.on('ready', function() { setTimeout( self.postStartupMessage.bind(self), 250 ); } );
|
|
123
184
|
}
|
|
124
185
|
|
|
186
|
+
// optional chaos (fault injection)
|
|
187
|
+
if (this.config.getPath('chaos.enabled')) this.setupChaos();
|
|
188
|
+
|
|
125
189
|
// start listeners
|
|
126
190
|
this.startAll(callback);
|
|
127
191
|
}
|
|
128
192
|
|
|
193
|
+
setupChaos() {
|
|
194
|
+
// setup chaos system (random delays, errors, etc.)
|
|
195
|
+
// chaos: { enabled, uri?, delay?: { min:0, max:250 }, errors?: { "503 Service Unavailable": 0.1 }, headers? }
|
|
196
|
+
var self = this;
|
|
197
|
+
var chaos = this.config.get('chaos');
|
|
198
|
+
|
|
199
|
+
this.addURIFilter( new RegExp(chaos.uri || '.+'), "Chaos", function(args, callback) {
|
|
200
|
+
var ms = chaos.delay ? Math.round( chaos.delay.min + (Math.random() * (chaos.delay.max - chaos.delay.min)) ) : 0;
|
|
201
|
+
if (ms) self.logDebug(9, `Chaos: Delaying request for ${ms}ms`);
|
|
202
|
+
|
|
203
|
+
setTimeout( function() {
|
|
204
|
+
if (!chaos.errors) return callback(false); // passthru
|
|
205
|
+
var chosen = false;
|
|
206
|
+
|
|
207
|
+
for (var status in chaos.errors) {
|
|
208
|
+
if (Math.random() <= chaos.errors[status]) { chosen = status; break; }
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (chosen) {
|
|
212
|
+
self.logDebug(9, `Chaos: Injecting fault: $(chosen)`);
|
|
213
|
+
callback( chosen, chaos.headers || {}, "Simulated Error: " + chosen );
|
|
214
|
+
}
|
|
215
|
+
else callback(false);
|
|
216
|
+
}, ms); // setTimeout
|
|
217
|
+
}); // addURIFilter
|
|
218
|
+
}
|
|
219
|
+
|
|
129
220
|
prepConfig() {
|
|
130
221
|
// prep config at startup, and when config is hot reloaded
|
|
131
222
|
|