forked from svrjs/svrjs
Update to SVR.JS 3.15.0
This commit is contained in:
parent
2ae73966ec
commit
73b062d306
4 changed files with 1015 additions and 704 deletions
95
index.html
95
index.html
|
@ -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,13 +148,16 @@
|
||||||
</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 />
|
||||||
<a href="/licenses/">Licenses</a><br/>
|
<a href="/licenses/">Licenses</a><br />
|
||||||
<a href="/svrjsstatus.svr">SVR.JS status page</a><br/>
|
<a href="/svrjsstatus.svr">SVR.JS status page</a><br />
|
||||||
<a href="https://svrjs.org/docs">SVR.JS documentation</a>
|
<a href="https://svrjs.org/docs">SVR.JS documentation</a>
|
||||||
</p>
|
</p>
|
||||||
<img src="/powered.png" />
|
<img src="/powered.png" />
|
||||||
|
|
|
@ -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
374
svr.js
|
@ -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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{contact}/g, serverAdmin.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).replace(/{path}/g, req.url.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")).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, "&").replace(/</g, "<").replace(/>/g, ">") + ((req.headers.host == undefined || isProxy) ? "" : " on " + String(req.headers.host).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"))).replace(/{contact}/g, serverAdmin.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").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, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/{errorDesc}/g, serverHTTPErrorDescs[errorCode]).replace(/{stack}/g, stack.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ {2}/g, " ")).replace(/{path}/g, req.url.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")).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, "&").replace(/</g, "<").replace(/>/g, ">") + ((req.headers.host == undefined || isProxy) ? "" : " on " + String(req.headers.host).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"))).replace(/{contact}/g, serverAdmin.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").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, "&").replace(/</g, "<").replace(/>/g, ">") + "</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, "&").replace(/</g, "<").replace(/>/g, ">") + "</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, "&").replace(/</g, "<").replace(/>/g, ">")) + "</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, "&").replace(/</g, "<").replace(/>/g, ">")) + "</title>")) + "<h1>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")) + "</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, "&").replace(/</g, "<").replace(/>/g, ">")) + "</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, "&").replace(/</g, "<").replace(/>/g, ">")) + "</title>")) + "<h1>SVR.JS status" + (req.headers.host == undefined ? "" : " for " + String(req.headers.host).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")) + "</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, "&").replace(/</g, "<").replace(/>/g, ">") + "</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, "&").replace(/</g, "<").replace(/>/g, ">") + "</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, "&").replace(/</g, "<").replace(/>/g, ">") + "</title>")) :
|
customDirListingHeader.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</title>")) :
|
||||||
head.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</title>")) +
|
head.replace(/<head>/i, "<head><title>Directory: " + decodeURIComponent(origHref).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
86
tests.html
86
tests.html
|
@ -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" />
|
||||||
|
|
Reference in a new issue