1
0
Fork 0
forked from svrjs/svrjs

Update to SVR.JS 3.15.0

This commit is contained in:
Dorian Niemiec 2024-05-06 12:30:50 +02:00
parent 2ae73966ec
commit 73b062d306
4 changed files with 1015 additions and 704 deletions

View file

@ -1,25 +1,89 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>SVR.JS 3.14.15</title> <title>SVR.JS 3.15.0</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<style> <style>
body { html {
font-family: FreeSans, Helvetica, Tahoma, Arial, sans-serif; background-color: #dfffdf;
color: #000000;
font-family: FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;
margin: 0.75em;
text-align: center; text-align: center;
} }
body {
background-color: #ffffff;
padding: 0.5em 0.5em 0.1em;
margin: 0.5em auto;
width: 90%;
max-width: 800px;
-webkit-box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15)
}
h1 {
text-align: center;
font-size: 2.25em;
margin: 0.3em 0 0.5em
}
pre,
code {
background-color: #dfffdf;
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
display: block;
padding: 0.2em;
font-family: "DejaVu Sans Mono", "Bitstream Vera Sans Mono", Hack, Menlo, Consolas, Monaco, monospace;
font-size: 0.85em;
margin: auto;
width: 95%;
}
@media screen and (prefers-color-scheme: dark) {
html {
background-color: #002000;
color: #ffffff
}
body {
background-color: #000f00;
-webkit-box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15);
-moz-box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15);
box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15)
}
pre,
code {
background-color: #002000;
-webkit-box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1);
-moz-box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1);
box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1)
}
a {
color: #ffffff
}
a:hover {
color: #00ff00
}
}
</style> </style>
</head> </head>
<body> <body>
<h1>Welcome to SVR.JS 3.14.15</h1> <h1>Welcome to SVR.JS 3.15.0</h1>
<br /> <br />
<img src="/logo.png" style="width: 256px; max-width: 100%;" /> <img src="/logo.png" style="width: 224px; max-width: 100%;" />
<br /> <br />
<p>If you see this page that means that the server is working properly. You can further configure the server and replace <i>index.html</i> and <i>tests.html</i> pages with custom ones.</p> <p>If you see this page that means that the server is working properly. You can further configure the server and replace <i>index.html</i> and <i>tests.html</i> pages with custom ones.</p>
<p>Default <i>config.json</i> looks like this:</p> <p>Default <i>config.json</i> looks like this:</p>
<code style="background-color: #e0e0e0; padding: 5px; text-align: left; display: block; display: inline-block;"> <code style="padding: 5px; text-align: left; display: block; display: inline-block;">
<pre style="margin: 0.2em; white-space: pre-wrap; overflow-wrap: break-word; word-wrap: break-word; word-break: break-all; word-break: break-word">{ <pre style="margin: 0.2em; white-space: pre-wrap; overflow-wrap: break-word; word-wrap: break-word; word-break: break-all; word-break: break-word; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none;">{
"users": [], "users": [],
"port": 80, "port": 80,
"pubport": 80, "pubport": 80,
@ -84,8 +148,11 @@
</code> </code>
<p>Changes:</p> <p>Changes:</p>
<ul style="display: inline-block; margin: 0;"> <ul style="display: inline-block; margin: 0;">
<li>Fixed crashes related to the request ID generation.</li> <li>Changed URL parser from wrapper over WHATWG URL parser to custom regex-based URL parser.</li>
<li>Optimized HTTP compression functionality.</li> <li>Optimized server code.</li>
<li>Redesigned default error pages.</li>
<li>Removed blocking file system calls from the directory listing function.</li>
<li>Replaced <i>path.extname()</i> function with regex-based function.</li>
</ul> </ul>
<p> <p>
<a href="/tests.html">Tests</a><br /> <a href="/tests.html">Tests</a><br />

View file

@ -1,19 +1,83 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>SVR.JS 3.14.15 Licenses</title> <title>SVR.JS 3.15.0 Licenses</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<style> <style>
body { html {
font-family: FreeSans, Helvetica, Tahoma, Arial, sans-serif; background-color: #dfffdf;
color: #000000;
font-family: FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;
margin: 0.75em;
text-align: center; text-align: center;
} }
body {
background-color: #ffffff;
padding: 0.5em 0.5em 0.1em;
margin: 0.5em auto;
width: 90%;
max-width: 800px;
-webkit-box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15)
}
h1 {
text-align: center;
font-size: 2.25em;
margin: 0.3em 0 0.5em
}
pre,
code {
background-color: #dfffdf;
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
display: block;
padding: 0.2em;
font-family: "DejaVu Sans Mono", "Bitstream Vera Sans Mono", Hack, Menlo, Consolas, Monaco, monospace;
font-size: 0.85em;
margin: auto;
width: 95%;
}
@media screen and (prefers-color-scheme: dark) {
html {
background-color: #002000;
color: #ffffff
}
body {
background-color: #000f00;
-webkit-box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15);
-moz-box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15);
box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15)
}
pre,
code {
background-color: #002000;
-webkit-box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1);
-moz-box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1);
box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1)
}
a {
color: #ffffff
}
a:hover {
color: #00ff00
}
}
</style> </style>
</head> </head>
<body> <body>
<h1>SVR.JS 3.14.15 Licenses</h1> <h1>SVR.JS 3.15.0 Licenses</h1>
<h2>SVR.JS 3.14.15</h2> <h2>SVR.JS 3.15.0</h2>
<div style="display: inline-block; text-align: left; border-width: 2px; border-style: solid; border-color: gray; padding: 8px;"> <div style="display: inline-block; text-align: left; border-width: 2px; border-style: solid; border-color: gray; padding: 8px;">
MIT License<br/> MIT License<br/>
<br/> <br/>
@ -37,9 +101,9 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
SOFTWARE.<br/> SOFTWARE.<br/>
</div> </div>
<h2>Packages used by SVR.JS 3.14.15</h2> <h2>Packages used by SVR.JS 3.15.0</h2>
<div style="width: 100%; max-width: 1280px; margin: auto"> <div style="width: 100%; max-width: 1280px; margin: auto">
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/asap.txt"><b>asap</b></a> <a href="/licenses/asap.txt"><b>asap</b></a>
@ -48,7 +112,7 @@
High-priority task queue for Node.js and browsers High-priority task queue for Node.js and browsers
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/asn1.js.txt"><b>asn1.js</b></a> (by Fedor Indutny) <a href="/licenses/asn1.js.txt"><b>asn1.js</b></a> (by Fedor Indutny)
@ -57,7 +121,7 @@
ASN.1 encoder and decoder ASN.1 encoder and decoder
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/asn1.js-rfc2560.txt"><b>asn1.js-rfc2560</b></a> (by Fedor Indutny) <a href="/licenses/asn1.js-rfc2560.txt"><b>asn1.js-rfc2560</b></a> (by Fedor Indutny)
@ -66,7 +130,7 @@
RFC2560 structures for asn1.js RFC2560 structures for asn1.js
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/asn1.js-rfc5280.txt"><b>asn1.js-rfc5280</b></a> (by Felix Hanley) <a href="/licenses/asn1.js-rfc5280.txt"><b>asn1.js-rfc5280</b></a> (by Felix Hanley)
@ -75,7 +139,7 @@
RFC5280 extension structures for asn1.js RFC5280 extension structures for asn1.js
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/async.txt"><b>async</b></a> (by Caolan McMahon) <a href="/licenses/async.txt"><b>async</b></a> (by Caolan McMahon)
@ -84,7 +148,7 @@
Higher-order functions and common patterns for asynchronous code Higher-order functions and common patterns for asynchronous code
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/bn.js.txt"><b>bn.js</b></a> (by Fedor Indutny) <a href="/licenses/bn.js.txt"><b>bn.js</b></a> (by Fedor Indutny)
@ -93,7 +157,7 @@
Big number implementation in pure javascript Big number implementation in pure javascript
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/call-bind.txt"><b>call-bind</b></a> (by Jordan Harband) <a href="/licenses/call-bind.txt"><b>call-bind</b></a> (by Jordan Harband)
@ -102,7 +166,7 @@
Robustly `.call.bind()` a function Robustly `.call.bind()` a function
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/chownr.txt"><b>chownr</b></a> (by Isaac Z. Schlueter) <a href="/licenses/chownr.txt"><b>chownr</b></a> (by Isaac Z. Schlueter)
@ -111,7 +175,7 @@
like `chown -R` like `chown -R`
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/dezalgo.txt"><b>dezalgo</b></a> (by Isaac Z. Schlueter) <a href="/licenses/dezalgo.txt"><b>dezalgo</b></a> (by Isaac Z. Schlueter)
@ -120,7 +184,7 @@
Contain async insanity so that the dark pony lord doesn't eat souls Contain async insanity so that the dark pony lord doesn't eat souls
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/formidable.txt"><b>formidable</b></a> <a href="/licenses/formidable.txt"><b>formidable</b></a>
@ -130,7 +194,7 @@
<b>Required by SVR.JS</b> <b>Required by SVR.JS</b>
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/fs-minipass.txt"><b>fs-minipass</b></a> (by Isaac Z. Schlueter) <a href="/licenses/fs-minipass.txt"><b>fs-minipass</b></a> (by Isaac Z. Schlueter)
@ -140,7 +204,7 @@
<b>Patched to work with Bun</b> <b>Patched to work with Bun</b>
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/function-bind.txt"><b>function-bind</b></a> (by Raynos) <a href="/licenses/function-bind.txt"><b>function-bind</b></a> (by Raynos)
@ -149,7 +213,7 @@
Implementation of Function.prototype.bind Implementation of Function.prototype.bind
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/get-intrinsic.txt"><b>get-intrinsic</b></a> (by Jordan Harband) <a href="/licenses/get-intrinsic.txt"><b>get-intrinsic</b></a> (by Jordan Harband)
@ -158,7 +222,7 @@
Get and robustly cache all JS language-level intrinsics at first require time Get and robustly cache all JS language-level intrinsics at first require time
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/graceful-fs.txt"><b>graceful-fs</b></a> <a href="/licenses/graceful-fs.txt"><b>graceful-fs</b></a>
@ -168,7 +232,7 @@
<b>Required by SVR.JS.</b> <b>Required by SVR.JS.</b>
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/has.txt"><b>has</b></a> (by Thiago de Arruda) <a href="/licenses/has.txt"><b>has</b></a> (by Thiago de Arruda)
@ -177,7 +241,7 @@
Object.prototype.hasOwnProperty.call shortcut Object.prototype.hasOwnProperty.call shortcut
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/has-symbols.txt"><b>has-symbols</b></a> (by Jordan Harband) <a href="/licenses/has-symbols.txt"><b>has-symbols</b></a> (by Jordan Harband)
@ -186,7 +250,7 @@
Determine if the JS environment has Symbol support. Supports spec, or shams. Determine if the JS environment has Symbol support. Supports spec, or shams.
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/hexoid.txt"><b>hexoid</b></a> (by Luke Edwards) <a href="/licenses/hexoid.txt"><b>hexoid</b></a> (by Luke Edwards)
@ -195,7 +259,7 @@
A tiny (190B) and extremely fast utility to generate random IDs of fixed length A tiny (190B) and extremely fast utility to generate random IDs of fixed length
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/inherits.txt"><b>inherits</b></a> <a href="/licenses/inherits.txt"><b>inherits</b></a>
@ -204,7 +268,7 @@
Browser-friendly inheritance fully compatible with standard node.js inherits() Browser-friendly inheritance fully compatible with standard node.js inherits()
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/mime-db.txt"><b>mime-db</b></a> <a href="/licenses/mime-db.txt"><b>mime-db</b></a>
@ -213,7 +277,7 @@
Media Type Database Media Type Database
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/mime-types.txt"><b>mime-types</b></a> <a href="/licenses/mime-types.txt"><b>mime-types</b></a>
@ -223,7 +287,7 @@
<b>Required by SVR.JS.</b> <b>Required by SVR.JS.</b>
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/minimalistic-assert.txt"><b>minimalistic-assert</b></a> <a href="/licenses/minimalistic-assert.txt"><b>minimalistic-assert</b></a>
@ -232,7 +296,7 @@
minimalistic-assert === minimalistic-assert ===
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/minipass.txt"><b>minipass</b></a> (by Isaac Z. Schlueter) <a href="/licenses/minipass.txt"><b>minipass</b></a> (by Isaac Z. Schlueter)
@ -241,7 +305,7 @@
minimal implementation of a PassThrough stream minimal implementation of a PassThrough stream
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/minizlib.txt"><b>minizlib</b></a> (by Isaac Z. Schlueter) <a href="/licenses/minizlib.txt"><b>minizlib</b></a> (by Isaac Z. Schlueter)
@ -250,7 +314,7 @@
A small fast zlib stream built on <a href="http://npm.im/minipass">minipass</a> and Node.js's zlib binding. A small fast zlib stream built on <a href="http://npm.im/minipass">minipass</a> and Node.js's zlib binding.
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/mkdirp.txt"><b>mkdirp</b></a> <a href="/licenses/mkdirp.txt"><b>mkdirp</b></a>
@ -259,7 +323,7 @@
Recursively mkdir, like `mkdir -p` Recursively mkdir, like `mkdir -p`
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/object-inspect.txt"><b>object-inspect</b></a> (by James Halliday) <a href="/licenses/object-inspect.txt"><b>object-inspect</b></a> (by James Halliday)
@ -268,7 +332,7 @@
string representations of objects in node and the browser string representations of objects in node and the browser
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/ocsp.txt"><b>ocsp</b></a> (by Fedor Indutny) <a href="/licenses/ocsp.txt"><b>ocsp</b></a> (by Fedor Indutny)
@ -278,7 +342,7 @@
<b>Required by SVR.JS.</b> <b>Required by SVR.JS.</b>
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/once.txt"><b>once</b></a> (by Isaac Z. Schlueter) <a href="/licenses/once.txt"><b>once</b></a> (by Isaac Z. Schlueter)
@ -287,7 +351,7 @@
Run a function exactly one time Run a function exactly one time
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: BSD-3</div> <div style="float: right;">License: BSD-3</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/qs.txt"><b>qs</b></a> <a href="/licenses/qs.txt"><b>qs</b></a>
@ -296,7 +360,7 @@
A querystring parser that supports nesting and arrays, with a depth limit A querystring parser that supports nesting and arrays, with a depth limit
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/side-channel.txt"><b>side-channel</b></a> (by Jordan Harband) <a href="/licenses/side-channel.txt"><b>side-channel</b></a> (by Jordan Harband)
@ -305,7 +369,7 @@
Store information about any JS value in a side channel. Uses WeakMap if available. Store information about any JS value in a side channel. Uses WeakMap if available.
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: MIT</div> <div style="float: right;">License: MIT</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/simple-lru-cache.txt"><b>simple-lru-cache</b></a> (by Gabriel Eisbruch) <a href="/licenses/simple-lru-cache.txt"><b>simple-lru-cache</b></a> (by Gabriel Eisbruch)
@ -314,7 +378,7 @@
node-simple-lru-cache ===================== node-simple-lru-cache =====================
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/tar.txt"><b>tar</b></a> (by Isaac Z. Schlueter) <a href="/licenses/tar.txt"><b>tar</b></a> (by Isaac Z. Schlueter)
@ -324,7 +388,7 @@
<b>Required by SVR.JS.</b> <b>Required by SVR.JS.</b>
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/wrappy.txt"><b>wrappy</b></a> (by Isaac Z. Schlueter) <a href="/licenses/wrappy.txt"><b>wrappy</b></a> (by Isaac Z. Schlueter)
@ -333,7 +397,7 @@
Callback wrapping utility Callback wrapping utility
</div> </div>
</div> </div>
<div style="width: 100%; background-color: #ccc; border: 1px solid green; text-align: left; margin: 10px 0;"> <div style="width: 100%; background-color: #ccc; background-color: rgba(200, 200, 200, 0.3); border: 1px solid green; text-align: left; margin: 10px 0;">
<div style="float: right;">License: ISC</div> <div style="float: right;">License: ISC</div>
<div style="font-size: 20px;"> <div style="font-size: 20px;">
<a href="/licenses/yallist.txt"><b>yallist</b></a> (by Isaac Z. Schlueter) <a href="/licenses/yallist.txt"><b>yallist</b></a> (by Isaac Z. Schlueter)

374
svr.js
View file

@ -69,7 +69,7 @@ function deleteFolderRecursive(path) {
} }
var os = require("os"); var os = require("os");
var version = "3.14.15"; var version = "3.15.0";
var singlethreaded = false; var singlethreaded = false;
if (process.versions) process.versions.svrjs = version; // Inject SVR.JS into process.versions if (process.versions) process.versions.svrjs = version; // Inject SVR.JS into process.versions
@ -1347,6 +1347,81 @@ function sanitizeURL(resource, allowDoubleSlashes) {
else return sanitizedResource; else return sanitizedResource;
} }
// SVR.JS URL parser function
function parseURL(uri, prepend) {
// Replace newline characters with its respective URL encodings
uri = uri.replace(/\r/g, "%0D").replace(/\n/g, "%0A");
// If URL begins with a slash, prepend a string if available
if (prepend && uri[0] == "/") uri = prepend.replace(/\/+$/,"") + uri;
// Determine if URL has slashes
var hasSlashes = (uri.indexOf("/") != -1);
// Parse the URL using regular expression
var parsedURI = uri.match(/^(?:([^:]+:)(\/\/)?)?(?:([^@]+)@)?([^:\/?#\*]+|\[[^\*]\/]\])?(?::([0-9]+))?(\*|\/[^?#]*)?(\?[^#]*)?(#[\S\s]*)?/);
// Match 1: protocol
// Match 2: slashes after protocol
// Match 3: authentication credentials
// Match 4: host name
// Match 5: port
// Match 6: path name
// Match 7: query string
// Match 8: hash
// If regular expression didn't match the entire URL, throw an error
if (parsedURI[0].length != uri.length) throw new Error("Invalid URL: " + uri);
// If match 1 is not empty, set the slash variable based on state of match 2
if (parsedURI[1]) hasSlashes = (parsedURI[2] == "//");
// If match 6 is empty and URL has slashes, set it to a slash.
if (hasSlashes && !parsedURI[6]) parsedURI[6] = "/";
// If match 4 contains Unicode characters, convert it to Punycode. If the result is an empty string, throw an error
if (parsedURI[4] && !parsedURI[4].match(/^[a-zA-Z0-9\.\-]+$/)) {
parsedURI[4] = url.domainToASCII(parsedURI[4]);
if (!parsedURI[4]) throw new Error("Invalid URL: " + uri);
}
// Create a new URL object
var uobject = new url.Url();
// Populate a URL object
if (hasSlashes) uobject.slashes = true;
if (parsedURI[1]) uobject.protocol = parsedURI[1];
if (parsedURI[3]) uobject.auth = parsedURI[3];
if (parsedURI[4]) {
uobject.host = parsedURI[4] + (parsedURI[5] ? (":" + parsedURI[5]) : "");
if (parsedURI[4][0] == "[") uobject.hostname = parsedURI[4].substring(1, parsedURI[4].length-1);
else uobject.hostname = parsedURI[4];
}
if (parsedURI[5]) uobject.port = parsedURI[5];
if (parsedURI[6]) uobject.pathname = parsedURI[6];
if (parsedURI[7]) {
uobject.search = parsedURI[7];
// Parse query strings
var qobject = Object.create(null);
var parsedQuery = parsedURI[7].substring(1).match(/([^&=]*)(?:=([^&]*))?/g);
parsedQuery.forEach(function (qp) {
if (qp.length > 0) {
var parsedQP = qp.match(/([^&=]*)(?:=([^&]*))?/);
if (parsedQP) {
qobject[parsedQP[1]] = parsedQP[2] ? parsedQP[2] : "";
}
}
});
uobject.query = qobject;
} else {
uobject.query = Object.create(null);
}
if (parsedURI[8]) uobject.hash = parsedURI[8];
if (uobject.pathname) uobject.path = uobject.pathname + (uobject.search ? uobject.search : "");
uobject.href = (uobject.protocol ? (uobject.protocol + (uobject.slashes ? "//" : "")) : "") + (uobject.auth ? (uobject.auth + "@") : "") + (uobject.hostname ? uobject.hostname : "") + (uobject.path ? uobject.path : "") + (uobject.hash ? uobject.hash : "");
return uobject;
}
// Node.JS mojibake URL fixing function // Node.JS mojibake URL fixing function
function fixNodeMojibakeURL(string) { function fixNodeMojibakeURL(string) {
var encoded = ""; var encoded = "";
@ -2548,7 +2623,7 @@ if (!cluster.isPrimary) {
if (err.code == "ERR_SSL_HTTP_REQUEST" && process.version && parseInt(process.version.split(".")[0].substring(1)) >= 16) { if (err.code == "ERR_SSL_HTTP_REQUEST" && process.version && parseInt(process.version.split(".")[0].substring(1)) >= 16) {
// Disable custom error page for HTTP SSL error // Disable custom error page for HTTP SSL error
res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders); res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders);
res.write(("<html><head><title>{errorMessage}</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body><h1>{errorMessage}</h1><p>{errorDesc}</p><p><i>{server}</i></p></body></html>").replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode].replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{server}/g, "" + ((exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\./g, "[dot]").replace(/@/g, "[at]"))); res.write(("<!DOCTYPE html><html><head><title>{errorMessage}</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><style>html{background-color:#dfffdf;color:#000000;font-family:FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;margin:0.75em}body{background-color:#ffffff;padding:0.5em 0.5em 0.1em;margin:0.5em auto;width:90%;max-width:800px;-webkit-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15)}h1{text-align:center;font-size:2.25em;margin:0.3em 0 0.5em}code{background-color:#dfffdf;-webkit-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);display:block;padding:0.2em;font-family:\"DejaVu Sans Mono\", \"Bitstream Vera Sans Mono\", Hack, Menlo, Consolas, Monaco, monospace;font-size:0.85em;margin:auto;width:95%;max-width:600px}table{width:95%;border-collapse:collapse;margin:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-all;word-break:break-word;position:relative;z-index:0}table tbody{background-color:#ffffff;color:#000000}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);content:' ';position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}table img{margin:0;display:inline}th,tr{padding:0.15em;text-align:center}th{background-color:#007000;color:#ffffff}th a{color:#ffffff}td,th{padding:0.225em}td{text-align:left}tr:nth-child(odd){background-color:#dfffdf}hr{color:#ffffff}@media screen and (prefers-color-scheme: dark){html{background-color:#002000;color:#ffffff}body{background-color:#000f00;-webkit-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15)}code{background-color:#002000;-webkit-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1)}a{color:#ffffff}a:hover{color:#00ff00}table tbody{background-color:#000f00;color:#ffffff}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175)}tr:nth-child(odd){background-color:#002000}}</style></head><body><h1>{errorMessage}</h1><p>{errorDesc}</p><p><i>{server}</i></p></body></html>").replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode].replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{server}/g, "" + ((exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\./g, "[dot]").replace(/@/g, "[at]")));
res.end(); res.end();
} else { } else {
fs.readFile(errorFile, function (err, data) { fs.readFile(errorFile, function (err, data) {
@ -2572,7 +2647,7 @@ if (!cluster.isPrimary) {
additionalError = 508; additionalError = 508;
} }
res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders); res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders);
res.write(("<html><head><title>{errorMessage}</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body><h1>{errorMessage}</h1><p>{errorDesc}</p>" + ((additionalError == 404) ? "" : "<p>Additionally, a {additionalError} error occurred while loading an error page.</p>") + "<p><i>{server}</i></p></body></html>").replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode].replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{server}/g, "" + ((exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\./g, "[dot]").replace(/@/g, "[at]")).replace(/{additionalError}/g, additionalError.toString())); res.write(("<!DOCTYPE html><html><head><title>{errorMessage}</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><style>html{background-color:#dfffdf;color:#000000;font-family:FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;margin:0.75em}body{background-color:#ffffff;padding:0.5em 0.5em 0.1em;margin:0.5em auto;width:90%;max-width:800px;-webkit-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15)}h1{text-align:center;font-size:2.25em;margin:0.3em 0 0.5em}code{background-color:#dfffdf;-webkit-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);display:block;padding:0.2em;font-family:\"DejaVu Sans Mono\", \"Bitstream Vera Sans Mono\", Hack, Menlo, Consolas, Monaco, monospace;font-size:0.85em;margin:auto;width:95%;max-width:600px}table{width:95%;border-collapse:collapse;margin:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-all;word-break:break-word;position:relative;z-index:0}table tbody{background-color:#ffffff;color:#000000}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);content:' ';position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}table img{margin:0;display:inline}th,tr{padding:0.15em;text-align:center}th{background-color:#007000;color:#ffffff}th a{color:#ffffff}td,th{padding:0.225em}td{text-align:left}tr:nth-child(odd){background-color:#dfffdf}hr{color:#ffffff}@media screen and (prefers-color-scheme: dark){html{background-color:#002000;color:#ffffff}body{background-color:#000f00;-webkit-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15)}code{background-color:#002000;-webkit-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1)}a{color:#ffffff}a:hover{color:#00ff00}table tbody{background-color:#000f00;color:#ffffff}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175)}tr:nth-child(odd){background-color:#002000}}</style></head><body><h1>{errorMessage}</h1><p>{errorDesc}</p>" + ((additionalError == 404) ? "" : "<p>Additionally, a {additionalError} error occurred while loading an error page.</p>") + "<p><i>{server}</i></p></body></html>").replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode].replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{server}/g, "" + ((exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\./g, "[dot]").replace(/@/g, "[at]")).replace(/{additionalError}/g, additionalError.toString()));
res.end(); res.end();
} }
}); });
@ -2790,13 +2865,11 @@ if (!cluster.isPrimary) {
modFunction(); modFunction();
} }
function vres(req, socket, head, serverconsole) { function vres() {
return function () {
serverconsole.errmessage("SVR.JS doesn't support proxy without proxy mod."); serverconsole.errmessage("SVR.JS doesn't support proxy without proxy mod.");
if (!socket.destroyed) socket.end("HTTP/1.1 501 Not Implemented\n\n"); if (!socket.destroyed) socket.end("HTTP/1.1 501 Not Implemented\n\n");
};
} }
modExecute(mods, vres(req, socket, head, serverconsole)); modExecute(mods, vres);
} }
function reqhandler(req, res, fromMain) { function reqhandler(req, res, fromMain) {
@ -3232,7 +3305,7 @@ if (!cluster.isPrimary) {
} }
res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders); res.writeHead(errorCode, http.STATUS_CODES[errorCode], cheaders);
res.write(("<html><head><title>{errorMessage}</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body><h1>{errorMessage}</h1><p>{errorDesc}</p>" + ((additionalError == 404) ? "" : "<p>Additionally, a {additionalError} error occurred while loading an error page.</p>") + "<p><i>{server}</i></p></body></html>").replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode].replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{path}/g, req.url.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{server}/g, "" + ((exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + ((req.headers.host == undefined || isProxy) ? "" : " on " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"))).replace(/{contact}/g, serverAdmin.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\./g, "[dot]").replace(/@/g, "[at]")).replace(/{additionalError}/g, additionalError.toString())); // Replace placeholders in error response res.write(("<!DOCTYPE html><html><head><title>{errorMessage}</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><style>html{background-color:#dfffdf;color:#000000;font-family:FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;margin:0.75em}body{background-color:#ffffff;padding:0.5em 0.5em 0.1em;margin:0.5em auto;width:90%;max-width:800px;-webkit-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15)}h1{text-align:center;font-size:2.25em;margin:0.3em 0 0.5em}code{background-color:#dfffdf;-webkit-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);display:block;padding:0.2em;font-family:\"DejaVu Sans Mono\", \"Bitstream Vera Sans Mono\", Hack, Menlo, Consolas, Monaco, monospace;font-size:0.85em;margin:auto;width:95%;max-width:600px}table{width:95%;border-collapse:collapse;margin:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-all;word-break:break-word;position:relative;z-index:0}table tbody{background-color:#ffffff;color:#000000}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);content:' ';position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}table img{margin:0;display:inline}th,tr{padding:0.15em;text-align:center}th{background-color:#007000;color:#ffffff}th a{color:#ffffff}td,th{padding:0.225em}td{text-align:left}tr:nth-child(odd){background-color:#dfffdf}hr{color:#ffffff}@media screen and (prefers-color-scheme: dark){html{background-color:#002000;color:#ffffff}body{background-color:#000f00;-webkit-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15)}code{background-color:#002000;-webkit-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1)}a{color:#ffffff}a:hover{color:#00ff00}table tbody{background-color:#000f00;color:#ffffff}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175)}tr:nth-child(odd){background-color:#002000}}</style></head><body><h1>{errorMessage}</h1><p>{errorDesc}</p>" + ((additionalError == 404) ? "" : "<p>Additionally, a {additionalError} error occurred while loading an error page.</p>") + "<p><i>{server}</i></p></body></html>").replace(/{errorMessage}/g, errorCode.toString() + " " + http.STATUS_CODES[errorCode].replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, "&nbsp;&nbsp;")).replace(/{path}/g, req.url.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")).replace(/{server}/g, "" + ((exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS") + ((!exposeModsInErrorPages || extName == undefined) ? "" : " " + extName)).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + ((req.headers.host == undefined || isProxy) ? "" : " on " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"))).replace(/{contact}/g, serverAdmin.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\./g, "[dot]").replace(/@/g, "[at]")).replace(/{additionalError}/g, additionalError.toString())); // Replace placeholders in error response
res.end(); res.end();
} }
}); });
@ -3247,6 +3320,7 @@ if (!cluster.isPrimary) {
callServerError(500, err); callServerError(500, err);
} }
// Function to perform HTTP redirection to a specified destination URL // Function to perform HTTP redirection to a specified destination URL
function redirect(destination, isTemporary, keepMethod, customHeaders) { function redirect(destination, isTemporary, keepMethod, customHeaders) {
// If keepMethod is a object, then save it to customHeaders // If keepMethod is a object, then save it to customHeaders
@ -3318,72 +3392,24 @@ if (!cluster.isPrimary) {
}); });
} }
// Function to parse a URL string into a URL object
function parseURL(uri) {
// Prepare the path (remove multiple slashes)
var preparedURI = uri.replace(/^\/{2,}/,"/");
// Check if the URL API is available (Node.js version >= 10)
if (typeof URL !== "undefined" && url.Url) {
try {
// Create a new URL object using the provided URI and base URL
var uobject = new URL(preparedURI, "http" + (req.socket.encrypted ? "s" : "") + "://" + (req.headers.host ? req.headers.host : (domain ? domain : "unknown.invalid")));
// Create a new URL object (similar to deprecated url.Url)
var nuobject = new url.Url();
// Set properties of the new URL object from the provided URL
if (preparedURI.indexOf("/") != -1) nuobject.slashes = true;
if (uobject.protocol != "") nuobject.protocol = uobject.protocol;
if (uobject.username != "" && uobject.password != "") nuobject.auth = uobject.username + ":" + uobject.password;
if (uobject.host != "") nuobject.host = uobject.host;
if (uobject.hostname != "") nuobject.hostname = uobject.hostname;
if (uobject.port != "") nuobject.port = uobject.port;
if (uobject.pathname != "") nuobject.pathname = uobject.pathname;
if (uobject.search != "") nuobject.search = uobject.search;
if (uobject.hash != "") nuobject.hash = uobject.hash;
if (uobject.href != "") nuobject.href = uobject.href;
// Adjust the pathname and href properties if the URI doesn't start with "/"
if (preparedURI[0] != "/") {
if (nuobject.pathname) {
nuobject.pathname = nuobject.pathname.substring(1);
nuobject.href = nuobject.pathname + (nuobject.search ? nuobject.search : "");
}
}
// Set the path property as a combination of pathname and search
if (nuobject.pathname) {
nuobject.path = nuobject.pathname + (nuobject.search ? nuobject.search : "");
}
// Initialize the query object and copy URL search parameters to it
nuobject.query = {};
uobject.searchParams.forEach(function (value, key) {
nuobject.query[key] = value;
});
// Return the created URL object
return nuobject;
} catch (err) {
// If there was an error using the URL API, fall back to deprecated url.parse
return url.parse(preparedURI, true);
}
} else {
// If the URL API is not available, fall back to deprecated url.parse
return url.parse(preparedURI, true);
}
}
// Authenticated user variable // Authenticated user variable
var authUser = null; var authUser = null;
// URL-related objects. // URL-related objects.
var uobject = parseURL(req.url); var uobject = {};
try {
uobject = parseURL(req.url, "http" + (req.socket.encrypted ? "s" : "") + "://" + (req.headers.host ? req.headers.host : (domain ? domain : "unknown.invalid")));
} catch (err) {
// Return an 400 error
callServerError(400);
serverconsole.errmessage("Bad request!");
return;
}
var search = uobject.search; var search = uobject.search;
var href = uobject.pathname; var href = uobject.pathname;
var ext = path.extname(href).toLowerCase(); var ext = href.match(/[^\/]\.([^.]+)$/);
ext = ext.substring(1, ext.length + 1); if(!ext) ext = "";
else ext = ext[1].toLowerCase();
var decodedHref = ""; var decodedHref = "";
try { try {
decodedHref = decodeURIComponent(href); decodedHref = decodeURIComponent(href);
@ -3393,6 +3419,7 @@ if (!cluster.isPrimary) {
serverconsole.errmessage("Bad request!"); serverconsole.errmessage("Bad request!");
return; return;
} }
var origHref = href; // Placeholder origHref
if (req.headers["expect"] && req.headers["expect"] != "100-continue") { if (req.headers["expect"] && req.headers["expect"] != "100-continue") {
// Expectations not met. // Expectations not met.
@ -3424,8 +3451,7 @@ if (!cluster.isPrimary) {
var vresCalled = false; var vresCalled = false;
function vres(req, res, serverconsole, responseEnd, href, ext, uobject, search, defaultpage, users, page404, head, foot, fd, callServerError, getCustomHeaders, origHref, redirect, parsePostData, authUser) { function vres() {
return function () {
if (vresCalled) { if (vresCalled) {
process.emitWarning("elseCallback() invoked multiple times.", { process.emitWarning("elseCallback() invoked multiple times.", {
code: "WARN_SVRJS_MULTIPLE_ELSECALLBACK" code: "WARN_SVRJS_MULTIPLE_ELSECALLBACK"
@ -3468,7 +3494,7 @@ if (!cluster.isPrimary) {
var eheaders = getCustomHeaders(); var eheaders = getCustomHeaders();
eheaders["Content-Type"] = "text/html; charset=utf-8"; eheaders["Content-Type"] = "text/html; charset=utf-8";
res.writeHead(501, http.STATUS_CODES[501], eheaders); res.writeHead(501, http.STATUS_CODES[501], eheaders);
res.write("<html><head><title>Proxy not implemented</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body><h1>Proxy not implemented</h1><p>SVR.JS doesn't support proxy without proxy mod. If you're administator of this server, then install this mod in order to use SVR.JS as a proxy.</p><p><i>" + (exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</i></p></body></html>"); res.write("<!DOCTYPE html><html><head><title>Proxy not implemented</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><style>html{background-color:#dfffdf;color:#000000;font-family:FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;margin:0.75em}body{background-color:#ffffff;padding:0.5em 0.5em 0.1em;margin:0.5em auto;width:90%;max-width:800px;-webkit-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15)}h1{text-align:center;font-size:2.25em;margin:0.3em 0 0.5em}code{background-color:#dfffdf;-webkit-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);display:block;padding:0.2em;font-family:\"DejaVu Sans Mono\", \"Bitstream Vera Sans Mono\", Hack, Menlo, Consolas, Monaco, monospace;font-size:0.85em;margin:auto;width:95%;max-width:600px}table{width:95%;border-collapse:collapse;margin:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-all;word-break:break-word;position:relative;z-index:0}table tbody{background-color:#ffffff;color:#000000}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);content:' ';position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}table img{margin:0;display:inline}th,tr{padding:0.15em;text-align:center}th{background-color:#007000;color:#ffffff}th a{color:#ffffff}td,th{padding:0.225em}td{text-align:left}tr:nth-child(odd){background-color:#dfffdf}hr{color:#ffffff}@media screen and (prefers-color-scheme: dark){html{background-color:#002000;color:#ffffff}body{background-color:#000f00;-webkit-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15)}code{background-color:#002000;-webkit-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1)}a{color:#ffffff}a:hover{color:#00ff00}table tbody{background-color:#000f00;color:#ffffff}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175)}tr:nth-child(odd){background-color:#002000}}</style></head><body><h1>Proxy not implemented</h1><p>SVR.JS doesn't support proxy without proxy mod. If you're administator of this server, then install this mod in order to use SVR.JS as a proxy.</p><p><i>" + (exposeServerVersion ? "SVR.JS/" + version + " (" + getOS() + "; " + (process.isBun ? ("Bun/v" + process.versions.bun + "; like Node.JS/" + process.version) : ("Node.JS/" + process.version)) + ")" : "SVR.JS").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</i></p></body></html>");
res.end(); res.end();
serverconsole.errmessage("SVR.JS doesn't support proxy without proxy mod."); serverconsole.errmessage("SVR.JS doesn't support proxy without proxy mod.");
return; return;
@ -3508,22 +3534,22 @@ if (!cluster.isPrimary) {
if (process.cpuUsage) statusBody += "<br/>Total CPU usage by thread: u" + (process.cpuUsage().user / 1000) + "ms s" + (process.cpuUsage().system / 1000) + "ms - " + (Math.round((((process.cpuUsage().user + process.cpuUsage().system) / 1000000) / process.uptime()) * 1000) / 1000) + "%"; if (process.cpuUsage) statusBody += "<br/>Total CPU usage by thread: u" + (process.cpuUsage().user / 1000) + "ms s" + (process.cpuUsage().system / 1000) + "ms - " + (Math.round((((process.cpuUsage().user + process.cpuUsage().system) / 1000000) / process.uptime()) * 1000) / 1000) + "%";
statusBody += "<br/>Thread PID: " + process.pid + "<br/>"; statusBody += "<br/>Thread PID: " + process.pid + "<br/>";
var hdhds = getCustomHeaders(); res.writeHead(200, http.STATUS_CODES[200], {
hdhds["Content-Type"] = "text/html; charset=utf-8"; "Content-Type": "text/html; charset=utf-8"
res.writeHead(200, http.STATUS_CODES[200], hdhds); });
res.end((head == "" ? "<html><head><title>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) + "</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body>" : head.replace(/<head>/i, "<head><title>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) + "</title>")) + "<h1>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) + "</h1>" + statusBody + (foot == "" ? "</body></html>" : foot)); res.end((head == "" ? "<!DOCTYPE html><html><head><title>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) + "</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><style>html{background-color:#dfffdf;color:#000000;font-family:FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;margin:0.75em}body{background-color:#ffffff;padding:0.5em 0.5em 0.1em;margin:0.5em auto;width:90%;max-width:800px;-webkit-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15)}h1{text-align:center;font-size:2.25em;margin:0.3em 0 0.5em}code{background-color:#dfffdf;-webkit-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);display:block;padding:0.2em;font-family:\"DejaVu Sans Mono\", \"Bitstream Vera Sans Mono\", Hack, Menlo, Consolas, Monaco, monospace;font-size:0.85em;margin:auto;width:95%;max-width:600px}table{width:95%;border-collapse:collapse;margin:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-all;word-break:break-word;position:relative;z-index:0}table tbody{background-color:#ffffff;color:#000000}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);content:' ';position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}table img{margin:0;display:inline}th,tr{padding:0.15em;text-align:center}th{background-color:#007000;color:#ffffff}th a{color:#ffffff}td,th{padding:0.225em}td{text-align:left}tr:nth-child(odd){background-color:#dfffdf}hr{color:#ffffff}@media screen and (prefers-color-scheme: dark){html{background-color:#002000;color:#ffffff}body{background-color:#000f00;-webkit-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15)}code{background-color:#002000;-webkit-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1)}a{color:#ffffff}a:hover{color:#00ff00}table tbody{background-color:#000f00;color:#ffffff}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175)}tr:nth-child(odd){background-color:#002000}}</style></head><body>" : head.replace(/<head>/i, "<head><title>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) + "</title>")) + "<h1>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) + "</h1>" + statusBody + (foot == "" ? "</body></html>" : foot));
return; return;
} }
var pth = decodeURIComponent(href).replace(/\/+/g, "/").substring(1); var dHref = decodeURIComponent(href);
var readFrom = "./" + pth; var readFrom = "." + dHref;
var dirImagesMissing = false; var dirImagesMissing = false;
fs.stat(readFrom, function (err, stats) { fs.stat(readFrom, function (err, stats) {
if (err) { if (err) {
if (err.code == "ENOENT") { if (err.code == "ENOENT") {
if (__dirname != process.cwd() && pth.match(/^\.dirimages\/(?:(?!\.png$).)+\.png$/)) { if (__dirname != process.cwd() && dHref.match(/^\/\.dirimages\/(?:(?!\.png$).)+\.png$/)) {
dirImagesMissing = true; dirImagesMissing = true;
readFrom = __dirname + "/" + pth; readFrom = __dirname + dHref;
} else { } else {
callServerError(404); callServerError(404);
serverconsole.errmessage("Resource not found."); serverconsole.errmessage("Resource not found.");
@ -3564,25 +3590,22 @@ if (!cluster.isPrimary) {
properDirectoryListingAndStaticFileServe(); properDirectoryListingAndStaticFileServe();
} else { } else {
stats = s; stats = s;
pth = (pth + "/index.xhtml").replace(/\/+/g, "/");
ext = "xhtml"; ext = "xhtml";
readFrom = "./" + pth; readFrom = (readFrom + "/index.xhtml").replace(/\/+/g, "/");
properDirectoryListingAndStaticFileServe(); properDirectoryListingAndStaticFileServe();
} }
}); });
} else { } else {
stats = s; stats = s;
pth = (pth + "/index.htm").replace(/\/+/g, "/");
ext = "htm"; ext = "htm";
readFrom = "./" + pth; readFrom = (readFrom + "/index.htm").replace(/\/+/g, "/");
properDirectoryListingAndStaticFileServe(); properDirectoryListingAndStaticFileServe();
} }
}); });
} else { } else {
stats = s; stats = s;
pth = (pth + "/index.html").replace(/\/+/g, "/");
ext = "html"; ext = "html";
readFrom = "./" + pth; readFrom = (readFrom + "/index.html").replace(/\/+/g, "/");
properDirectoryListingAndStaticFileServe(); properDirectoryListingAndStaticFileServe();
} }
}); });
@ -3613,9 +3636,9 @@ if (!cluster.isPrimary) {
// Check if the client's request matches the ETag value (If-None-Match) // Check if the client's request matches the ETag value (If-None-Match)
var clientETag = req.headers["if-none-match"]; var clientETag = req.headers["if-none-match"];
if (clientETag === fileETag) { if (clientETag === fileETag) {
var headers = getCustomHeaders(); res.writeHead(304, http.STATUS_CODES[304], {
headers.ETag = clientETag; "ETag": clientETag
res.writeHead(304, http.STATUS_CODES[304], headers); });
res.end(); res.end();
return; return;
} }
@ -3623,9 +3646,9 @@ if (!cluster.isPrimary) {
// Check if the client's request doesn't match the ETag value (If-Match) // Check if the client's request doesn't match the ETag value (If-Match)
var ifMatchETag = req.headers["if-match"]; var ifMatchETag = req.headers["if-match"];
if (ifMatchETag && ifMatchETag !== "*" && ifMatchETag !== fileETag) { if (ifMatchETag && ifMatchETag !== "*" && ifMatchETag !== fileETag) {
var headers = getCustomHeaders(); callServerError(412, {
headers.ETag = clientETag; "ETag": clientETag
callServerError(412, headers); });
return; return;
} }
} }
@ -3754,7 +3777,7 @@ if (!cluster.isPrimary) {
} }
try { try {
var hdhds = getCustomHeaders(); var hdhds = {};
if (useBrotli && isCompressable) { if (useBrotli && isCompressable) {
hdhds["Content-Encoding"] = "br"; hdhds["Content-Encoding"] = "br";
} else if (useDeflate && isCompressable) { } else if (useDeflate && isCompressable) {
@ -3846,29 +3869,79 @@ if (!cluster.isPrimary) {
} else if (stats.isDirectory()) { } else if (stats.isDirectory()) {
// Check if directory listing is enabled in the configuration // Check if directory listing is enabled in the configuration
if (checkForEnabledDirectoryListing(req.headers.host, req.socket ? req.socket.localAddress : undefined)) { if (checkForEnabledDirectoryListing(req.headers.host, req.socket ? req.socket.localAddress : undefined)) {
var customHeaders = getCustomHeaders(); var customDirListingHeader = "";
customHeaders["Content-Type"] = "text/html; charset=utf-8"; var customDirListingFooter = "";
res.writeHead(200, http.STATUS_CODES[200], customHeaders);
function getCustomDirListingHeader(callback) {
fs.readFile(("." + dHref + "/.dirhead").replace(/\/+/g, "/"), function (err, data) {
if (err) {
if (err.code == "ENOENT" || err.code == "EISDIR") {
if (os.platform != "win32" || href != "/") {
fs.readFile(("." + dHref + "/HEAD.html").replace(/\/+/g, "/"), function (err, data) {
if (err) {
if (err.code == "ENOENT" || err.code == "EISDIR") {
callback();
} else {
callServerError(500, err);
}
} else {
customDirListingHeader = data.toString();
callback();
}
});
} else {
callback();
}
} else {
callServerError(500, err);
}
} else {
customDirListingHeader = data.toString();
callback();
}
});
}
function getCustomDirListingFooter(callback) {
fs.readFile(("." + dHref + "/.dirfoot").replace(/\/+/g, "/"), function (err, data) {
if (err) {
if (err.code == "ENOENT" || err.code == "EISDIR") {
if (os.platform != "win32" || href != "/") {
fs.readFile(("." + dHref + "/FOOT.html").replace(/\/+/g, "/"), function (err, data) {
if (err) {
if (err.code == "ENOENT" || err.code == "EISDIR") {
callback();
} else {
callServerError(500, err);
}
} else {
customDirListingFooter = data.toString();
callback();
}
});
} else {
callback();
}
} else {
callServerError(500, err);
}
} else {
customDirListingFooter = data.toString();
callback();
}
});
}
// Read custom header and footer content (if available) // Read custom header and footer content (if available)
var customDirListingHeader = fs.existsSync(("." + decodeURIComponent(href) + "/.dirhead").replace(/\/+/g, "/")) ? getCustomDirListingHeader(function () {
fs.readFileSync(("." + decodeURIComponent(href) + "/.dirhead").replace(/\/+/g, "/")).toString() : getCustomDirListingFooter(function () {
(fs.existsSync(("." + decodeURIComponent(href) + "/HEAD.html").replace(/\/+/g, "/")) && (os.platform != "win32" || href != "/")) ?
fs.readFileSync(("." + decodeURIComponent(href) + "/HEAD.html").replace(/\/+/g, "/")).toString() :
"";
var customDirListingFooter = fs.existsSync(("." + decodeURIComponent(href) + "/.dirfoot").replace(/\/+/g, "/")) ?
fs.readFileSync(("." + decodeURIComponent(href) + "/.dirfoot").replace(/\/+/g, "/")).toString() :
(fs.existsSync(("." + decodeURIComponent(href) + "/FOOT.html").replace(/\/+/g, "/")) && (os.platform != "win32" || href != "/")) ?
fs.readFileSync(("." + decodeURIComponent(href) + "/FOOT.html").replace(/\/+/g, "/")).toString() :
"";
// Check if custom header has HTML tag // Check if custom header has HTML tag
var headerHasHTMLTag = customDirListingHeader.replace(/<!--(?:(?:(?!--\>)[\s\S])*|)(?:-->|$)/g, "").match(/<html(?![a-zA-Z0-9])(?:"(?:\\(?:[\s\S]|$)|[^\\"])*(?:"|$)|'(?:\\(?:[\s\S]|$)|[^\\'])*(?:'|$)|[^'">])*(?:>|$)/i); var headerHasHTMLTag = customDirListingHeader.replace(/<!--(?:(?:(?!--\>)[\s\S])*|)(?:-->|$)/g, "").match(/<html(?![a-zA-Z0-9])(?:"(?:\\(?:[\s\S]|$)|[^\\"])*(?:"|$)|'(?:\\(?:[\s\S]|$)|[^\\'])*(?:'|$)|[^'">])*(?:>|$)/i);
// Generate HTML head and footer based on configuration and custom content // Generate HTML head and footer based on configuration and custom content
var htmlHead = (!configJSON.enableDirectoryListingWithDefaultHead || head == "" ? var htmlHead = (!configJSON.enableDirectoryListingWithDefaultHead || head == "" ?
(!headerHasHTMLTag ? (!headerHasHTMLTag ?
"<!DOCTYPE html><html><head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /></head><body>" : "<!DOCTYPE html><html><head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><style>html{background-color:#dfffdf;color:#000000;font-family:FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;margin:0.75em}body{background-color:#ffffff;padding:0.5em 0.5em 0.1em;margin:0.5em auto;width:90%;max-width:800px;-webkit-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15);box-shadow:0 5px 10px 0 rgba(0, 0, 0, 0.15)}h1{text-align:center;font-size:2.25em;margin:0.3em 0 0.5em}code{background-color:#dfffdf;-webkit-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);box-shadow:0 2px 4px 0 rgba(0, 0, 0, 0.1);display:block;padding:0.2em;font-family:\"DejaVu Sans Mono\", \"Bitstream Vera Sans Mono\", Hack, Menlo, Consolas, Monaco, monospace;font-size:0.85em;margin:auto;width:95%;max-width:600px}table{width:95%;border-collapse:collapse;margin:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-all;word-break:break-word;position:relative;z-index:0}table tbody{background-color:#ffffff;color:#000000}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.175);content:' ';position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}table img{margin:0;display:inline}th,tr{padding:0.15em;text-align:center}th{background-color:#007000;color:#ffffff}th a{color:#ffffff}td,th{padding:0.225em}td{text-align:left}tr:nth-child(odd){background-color:#dfffdf}hr{color:#ffffff}@media screen and (prefers-color-scheme: dark){html{background-color:#002000;color:#ffffff}body{background-color:#000f00;-webkit-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);-moz-box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15);box-shadow:0 5px 10px 0 rgba(127, 127, 127, 0.15)}code{background-color:#002000;-webkit-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);-moz-box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1);box-shadow:0 2px 4px 0 rgba(127, 127, 127, 0.1)}a{color:#ffffff}a:hover{color:#00ff00}table tbody{background-color:#000f00;color:#ffffff}table tbody:after{-webkit-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);-moz-box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175);box-shadow:0 4px 8px 0 rgba(127, 127, 127, 0.175)}tr:nth-child(odd){background-color:#002000}}</style></head><body>" :
customDirListingHeader.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) : customDirListingHeader.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) :
head.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) + head.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</title>")) +
(!headerHasHTMLTag ? customDirListingHeader : "") + (!headerHasHTMLTag ? customDirListingHeader : "") +
@ -3880,7 +3953,7 @@ if (!cluster.isPrimary) {
htmlFoot = "</table><hr/>" + fs.readFileSync("." + decodeURIComponent(href) + "/.maindesc".replace(/\/+/g, "/")) + htmlFoot; htmlFoot = "</table><hr/>" + fs.readFileSync("." + decodeURIComponent(href) + "/.maindesc".replace(/\/+/g, "/")) + htmlFoot;
} }
fs.readdir("." + decodeURIComponent(href), function (err, list) { fs.readdir(readFrom, function (err, list) {
try { try {
if (err) throw err; if (err) throw err;
list = list.sort(); list = list.sort();
@ -3928,7 +4001,7 @@ if (!cluster.isPrimary) {
} }
// Get stats for all files in the directory and generate the listing // Get stats for all files in the directory and generate the listing
getStatsForAllFiles(list, "." + decodeURIComponent(href), function (filelist) { getStatsForAllFiles(list, readFrom, function (filelist) {
var directoryListingRows = []; var directoryListingRows = [];
for (var i = 0; i < filelist.length; i++) { for (var i = 0; i < filelist.length; i++) {
if (filelist[i].name[0] !== ".") { if (filelist[i].name[0] !== ".") {
@ -4019,6 +4092,9 @@ if (!cluster.isPrimary) {
} }
// Send the directory listing response // Send the directory listing response
res.writeHead(200, http.STATUS_CODES[200], {
"Content-Type": "text/html; charset=utf-8"
});
res.end(htmlHead + directoryListingRows.join("") + htmlFoot); res.end(htmlHead + directoryListingRows.join("") + htmlFoot);
serverconsole.resmessage("Client successfully received content."); serverconsole.resmessage("Client successfully received content.");
}); });
@ -4045,6 +4121,8 @@ if (!cluster.isPrimary) {
} }
} }
}); });
});
});
} else { } else {
// Directory listing is disabled, call 403 Forbidden error // Directory listing is disabled, call 403 Forbidden error
callServerError(403); callServerError(403);
@ -4057,7 +4135,6 @@ if (!cluster.isPrimary) {
} }
} }
}); });
};
} }
try { try {
@ -4118,11 +4195,19 @@ if (!cluster.isPrimary) {
serverconsole.resmessage("URL sanitized: " + req.url + " => " + sanitizedURL); serverconsole.resmessage("URL sanitized: " + req.url + " => " + sanitizedURL);
if (rewriteDirtyURLs) { if (rewriteDirtyURLs) {
req.url = sanitizedURL; req.url = sanitizedURL;
uobject = parseURL(req.url); try {
uobject = parseURL(req.url, "http" + (req.socket.encrypted ? "s" : "") + "://" + (req.headers.host ? req.headers.host : (domain ? domain : "unknown.invalid")));
} catch (err) {
// Return an 400 error
callServerError(400);
serverconsole.errmessage("Bad request!");
return;
}
search = uobject.search; search = uobject.search;
href = uobject.pathname; href = uobject.pathname;
ext = path.extname(href).toLowerCase(); ext = href.match(/[^\/]\.([^.]+)$/);
ext = ext.substring(1, ext.length + 1); if(!ext) ext = "";
else ext = ext[1].toLowerCase();
try { try {
decodedHref = decodeURIComponent(href); decodedHref = decodeURIComponent(href);
} catch (err) { } catch (err) {
@ -4267,7 +4352,7 @@ if (!cluster.isPrimary) {
} }
} }
var origHref = href; origHref = href;
// Add web root postfixes // Add web root postfixes
if (!isProxy) { if (!isProxy) {
@ -4296,11 +4381,19 @@ if (!cluster.isPrimary) {
if (urlWithPostfix != preparedReqUrl3) { if (urlWithPostfix != preparedReqUrl3) {
serverconsole.resmessage("Added web root postfix: " + req.url + " => " + urlWithPostfix); serverconsole.resmessage("Added web root postfix: " + req.url + " => " + urlWithPostfix);
req.url = urlWithPostfix; req.url = urlWithPostfix;
uobject = parseURL(req.url); try {
uobject = parseURL(req.url, "http" + (req.socket.encrypted ? "s" : "") + "://" + (req.headers.host ? req.headers.host : (domain ? domain : "unknown.invalid")));
} catch (err) {
// Return an 400 error
callServerError(400);
serverconsole.errmessage("Bad request!");
return;
}
search = uobject.search; search = uobject.search;
href = uobject.pathname; href = uobject.pathname;
ext = path.extname(href).toLowerCase(); ext = href.match(/[^\/]\.([^.]+)$/);
ext = ext.substring(1, ext.length + 1); if(!ext) ext = "";
else ext = ext[1].toLowerCase();
try { try {
decodedHref = decodeURIComponent(href); decodedHref = decodeURIComponent(href);
@ -4331,11 +4424,19 @@ if (!cluster.isPrimary) {
rewrittenAgainURL = url.format(rewrittenAgainURL); rewrittenAgainURL = url.format(rewrittenAgainURL);
serverconsole.resmessage("URL sanitized: " + req.url + " => " + rewrittenAgainURL); serverconsole.resmessage("URL sanitized: " + req.url + " => " + rewrittenAgainURL);
req.url = rewrittenAgainURL; req.url = rewrittenAgainURL;
uobject = parseURL(req.url); try {
uobject = parseURL(req.url, "http" + (req.socket.encrypted ? "s" : "") + "://" + (req.headers.host ? req.headers.host : (domain ? domain : "unknown.invalid")));
} catch (err) {
// Return an 400 error
callServerError(400);
serverconsole.errmessage("Bad request!");
return;
}
search = uobject.search; search = uobject.search;
href = uobject.pathname; href = uobject.pathname;
ext = path.extname(href).toLowerCase(); ext = href.match(/[^\/]\.([^.]+)$/);
ext = ext.substring(1, ext.length + 1); if(!ext) ext = "";
else ext = ext[1].toLowerCase();
try { try {
decodedHref = decodeURIComponent(href); decodedHref = decodeURIComponent(href);
} catch (err) { } catch (err) {
@ -4357,12 +4458,19 @@ if (!cluster.isPrimary) {
if (rewrittenURL != req.url) { if (rewrittenURL != req.url) {
serverconsole.resmessage("URL rewritten: " + req.url + " => " + rewrittenURL); serverconsole.resmessage("URL rewritten: " + req.url + " => " + rewrittenURL);
req.url = rewrittenURL; req.url = rewrittenURL;
uobject = parseURL(req.url); try {
uobject = parseURL(req.url, "http" + (req.socket.encrypted ? "s" : "") + "://" + (req.headers.host ? req.headers.host : (domain ? domain : "unknown.invalid")));
} catch (err) {
// Return an 400 error
callServerError(400);
serverconsole.errmessage("Bad request!");
return;
}
search = uobject.search; search = uobject.search;
href = uobject.pathname; href = uobject.pathname;
ext = path.extname(href).toLowerCase(); ext = href.match(/[^\/]\.([^.]+)$/);
ext = ext.substring(1, ext.length + 1); if(!ext) ext = "";
else ext = ext[1].toLowerCase();
try { try {
decodedHref = decodeURIComponent(href); decodedHref = decodeURIComponent(href);
} catch (err) { } catch (err) {
@ -4392,11 +4500,19 @@ if (!cluster.isPrimary) {
rewrittenAgainURL = url.format(rewrittenAgainURL); rewrittenAgainURL = url.format(rewrittenAgainURL);
serverconsole.resmessage("URL sanitized: " + req.url + " => " + rewrittenAgainURL); serverconsole.resmessage("URL sanitized: " + req.url + " => " + rewrittenAgainURL);
req.url = rewrittenAgainURL; req.url = rewrittenAgainURL;
uobject = parseURL(req.url); try {
uobject = parseURL(req.url, "http" + (req.socket.encrypted ? "s" : "") + "://" + (req.headers.host ? req.headers.host : (domain ? domain : "unknown.invalid")));
} catch (err) {
// Return an 400 error
callServerError(400);
serverconsole.errmessage("Bad request!");
return;
}
search = uobject.search; search = uobject.search;
href = uobject.pathname; href = uobject.pathname;
ext = path.extname(href).toLowerCase(); ext = href.match(/[^\/]\.([^.]+)$/);
ext = ext.substring(1, ext.length + 1); if(!ext) ext = "";
else ext = ext[1].toLowerCase();
try { try {
decodedHref = decodeURIComponent(href); decodedHref = decodeURIComponent(href);
} catch (err) { } catch (err) {
@ -4681,7 +4797,7 @@ if (!cluster.isPrimary) {
serverconsole.reqmessage("Client is logged in as \"" + String(username).replace(/[\r\n]/g, "") + "\"."); serverconsole.reqmessage("Client is logged in as \"" + String(username).replace(/[\r\n]/g, "") + "\".");
authUser = username; authUser = username;
redirectTrailingSlashes(function () { redirectTrailingSlashes(function () {
modExecute(mods, vres(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, "", callServerError, getCustomHeaders, origHref, redirect, parsePostData, authUser)); modExecute(mods, vres);
}); });
} }
} catch (err) { } catch (err) {
@ -4730,7 +4846,7 @@ if (!cluster.isPrimary) {
} }
} else { } else {
redirectTrailingSlashes(function () { redirectTrailingSlashes(function () {
modExecute(mods, vres(req, res, serverconsole, responseEnd, href, ext, uobject, search, "index.html", users, page404, head, foot, "", callServerError, getCustomHeaders, origHref, redirect, parsePostData, authUser)); modExecute(mods, vres);
}); });
} }
} }

View file

@ -1,32 +1,96 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>SVR.JS 3.14.15 Tests</title> <title>SVR.JS 3.15.0 Tests</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<style> <style>
body { html {
font-family: FreeSans, Helvetica, Tahoma, Arial, sans-serif; background-color: #dfffdf;
color: #000000;
font-family: FreeSans, Helvetica, Tahoma, Verdana, Arial, sans-serif;
margin: 0.75em;
text-align: center; text-align: center;
} }
body {
background-color: #ffffff;
padding: 0.5em 0.5em 0.1em;
margin: 0.5em auto;
width: 90%;
max-width: 800px;
-webkit-box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15)
}
h1 {
text-align: center;
font-size: 2.25em;
margin: 0.3em 0 0.5em
}
pre,
code {
background-color: #dfffdf;
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
display: block;
padding: 0.2em;
font-family: "DejaVu Sans Mono", "Bitstream Vera Sans Mono", Hack, Menlo, Consolas, Monaco, monospace;
font-size: 0.85em;
margin: auto;
width: 95%;
}
@media screen and (prefers-color-scheme: dark) {
html {
background-color: #002000;
color: #ffffff
}
body {
background-color: #000f00;
-webkit-box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15);
-moz-box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15);
box-shadow: 0 5px 10px 0 rgba(127, 127, 127, 0.15)
}
pre,
code {
background-color: #002000;
-webkit-box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1);
-moz-box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1);
box-shadow: 0 2px 4px 0 rgba(127, 127, 127, 0.1)
}
a {
color: #ffffff
}
a:hover {
color: #00ff00
}
}
</style> </style>
</head> </head>
<body> <body>
<h1>SVR.JS 3.14.15 Tests</h1> <h1>SVR.JS 3.15.0 Tests</h1>
<h2>Directory (without trailing slash)</h2> <h2>Directory (without trailing slash)</h2>
<iframe src="/testdir" width="50%" height="300px"></iframe> <iframe src="/testdir" width="75%" height="300px"></iframe>
<h2>Directory (with query)</h2> <h2>Directory (with query)</h2>
<iframe src="/testdir/?query=value" width="50%" height="300px"></iframe> <iframe src="/testdir/?query=value" width="75%" height="300px"></iframe>
<h2>Directory (personalized)</h2> <h2>Directory (personalized)</h2>
<iframe src="/testdir/.personalized" width="50%" height="300px"></iframe> <iframe src="/testdir/.personalized" width="75%" height="300px"></iframe>
<h2>404 Error</h2> <h2>404 Error</h2>
<iframe src="/tfhgfhggf" width="50%" height="300px"></iframe> <iframe src="/tfhgfhggf" width="75%" height="300px"></iframe>
<h2>Server Side Javascript</h2> <h2>Server Side Javascript</h2>
<iframe src="/hello.svr" width="50%" height="300px"></iframe> <iframe src="/hello.svr" width="75%" height="300px"></iframe>
<h2>Proxy test</h2> <h2>Proxy test</h2>
<iframe src="/proxy.svr/this/hello.svr" width="50%" height="300px" id="proxy"></iframe> <iframe src="/proxy.svr/this/hello.svr" width="75%" height="300px" id="proxy"></iframe>
<h2>URL rewriting test (/testdir_rewritten => /testdir)</h2> <h2>URL rewriting test (/testdir_rewritten => /testdir)</h2>
<iframe src="/testdir_rewritten" width="50%" height="300px"></iframe> <iframe src="/testdir_rewritten" width="75%" height="300px"></iframe>
<br/> <br/>
<br/> <br/>
<img src="/powered.png" /> <img src="/powered.png" />