1
0
Fork 0
forked from svrjs/svrjs

Compare commits

...
This repository has been archived on 2024-11-10. You can view files and clone it, but cannot push or open issues or pull requests.

54 commits
main ... stable

Author SHA1 Message Date
317acff5d6 chore: release SVR.JS 4.1.0 2024-10-19 07:39:45 +02:00
f4fc6ba165 chore: release SVR.JS 4.0.2 2024-10-15 18:25:36 +02:00
3bf8ff799e chore: release SVR.JS 4.0.1 2024-09-25 15:51:40 +02:00
9e227bbec6 fix: fix bug with the extraction script 2024-09-20 07:47:15 +02:00
27c613f28e chore: release SVR.JS 4.0.0 2024-09-14 16:23:49 +02:00
215f1fae25 Update to SVR.JS 3.15.7 2024-08-26 08:36:01 +02:00
d44ee67e57 Update to SVR.JS 3.15.6 2024-08-07 06:23:42 +02:00
effc654f05 Update to SVR.JS 3.15.5 2024-06-13 15:26:46 +02:00
997b03c2a2 Update to SVR.JS 3.15.4 2024-05-30 21:09:00 +02:00
45d8b9bcd3 Update to SVR.JS 3.15.3 2024-05-21 17:28:47 +02:00
78e7c8c967 Update to SVR.JS 3.15.2 2024-05-20 17:42:16 +02:00
25280b310c Update to SVR.JS 3.15.1 2024-05-13 18:03:58 +02:00
73b062d306 Update to SVR.JS 3.15.0 2024-05-06 12:30:50 +02:00
2ae73966ec Update to SVR.JS 3.14.15 2024-04-29 20:12:49 +02:00
5e031fe997 Update to SVR.JS 3.14.14 2024-04-27 13:55:21 +02:00
1c6e707f58 Update to SVR.JS 3.14.13 2024-04-24 13:28:20 +02:00
4a1a59f15d Update to SVR.JS 3.14.12 2024-04-13 11:18:02 +02:00
67680fc97f Update to SVR.JS 3.14.11 2024-04-07 15:53:24 +02:00
40f100db94 Update to SVR.JS 3.14.10 2024-04-07 14:24:53 +02:00
7d144c95b6 Update to SVR.JS 3.14.9 2024-04-02 11:24:36 +02:00
3b25b33583 Update to SVR.JS 3.14.8 2024-03-29 11:08:18 +01:00
c70e078b26 Update to SVR.JS 3.14.7 2024-03-19 17:16:13 +01:00
3abc31e2aa Update to SVR.JS 3.14.6 2024-03-17 21:49:23 +01:00
0161b04e1f Update to SVR.JS 3.14.5 2024-03-09 16:37:18 +01:00
d7b0fc463e Update to SVR.JS 3.14.4 2024-03-03 21:20:09 +01:00
3d411c3be1 Update to SVR.JS 3.14.3 2024-02-11 21:37:26 +01:00
9c49df9d87 Update to SVR.JS 3.14.2 2024-02-07 00:57:09 +01:00
06712f35b5 Update to SVR.JS 3.14.1 2024-02-02 20:07:11 +01:00
91f2d3b50f Update to SVR.JS 3.14.0 2024-01-24 21:06:17 +01:00
688c850c50 Update to SVR.JS 3.13.1 2024-01-18 01:21:25 +01:00
26214c9eb8 Update to SVR.JS 3.13.0 2024-01-14 19:03:30 +01:00
4928ac1d2c Update to SVR.JS 3.12.3 2023-12-30 23:50:11 +01:00
27e62da887 Update to SVR.JS 3.12.2 2023-12-16 09:01:30 +01:00
d25f912c06 Update to SVR.JS 3.12.1 2023-12-12 23:28:00 +01:00
19f7345762 Update to SVR.JS 3.12.0 2023-12-07 09:58:43 +01:00
a63e1a893b Update to SVR.JS 3.11.0 2023-11-12 20:18:43 +01:00
a755e32bc7 Update to SVR.JS 3.10.3 2023-09-17 23:40:02 +02:00
c380c469ef Update to SVR.JS 3.10.2 2023-09-12 23:21:54 +02:00
faecaa8b8a Update to SVR.JS 3.10.1 2023-09-12 21:17:24 +02:00
ae3cf033be Update to SVR.JS 3.10.0 2023-09-11 23:23:54 +02:00
9fa9c047d1 Update to SVR.JS 3.9.6 2023-09-10 11:13:23 +02:00
faa043cb99 Update to SVR.JS 3.9.4 2023-09-08 20:20:40 +02:00
7587932250 Update to SVR.JS 3.9.3 2023-09-07 18:07:30 +02:00
9406ffda5f Update to SVR.JS 3.9.2 2023-09-06 20:23:53 +02:00
10ee128136 Update to SVR.JS 3.9.1 2023-09-05 00:13:52 +02:00
Dorian Niemiec
91d8d0df63 Update to SVR.JS 3.9.0 2023-09-03 22:51:02 +02:00
71b5727b6c Update to SVR.JS 3.8.1 2023-09-02 09:39:46 +02:00
c6960061b7 Update to SVR.JS 3.8.0 2023-09-01 11:53:00 +02:00
55262f73c5 Update to SVR.JS 3.7.5 2023-08-29 15:34:17 +02:00
750a312b2f Update to SVR.JS 3.7.4 2023-08-28 04:20:38 +02:00
e0f0cb69d8 Update to SVR.JS 3.7.3 2023-08-25 00:42:38 +02:00
d01064cc17 Update to SVR.JS 3.7.2 2023-08-21 19:44:25 +02:00
c9df74c745 Update to SVR.JS 3.7.1 2023-08-21 02:56:52 +02:00
46a256d31f Update to SVR.JS 3.7.0 2023-08-20 03:14:24 +02:00
563 changed files with 22707 additions and 64784 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

19
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,19 @@
# Sync repo to the Codeberg mirror
name: Repo sync GitHub -> SVR.JS Git server
on:
push:
branches:
- '**'
jobs:
svrjsgit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: spyoungtech/mirror-action@v0.5.1
with:
REMOTE: "https://git.svrjs.org/svrjs/svrjs.git"
GIT_USERNAME: github-mirror
GIT_PASSWORD: ${{ secrets.GIT_PASSWORD }}

26
.gitignore vendored
View file

@ -1 +1,25 @@
commit.sh
# Build output
/dist/
/out/
# Temporary files used by build script
/generatedAssets/
# Dependencies
node_modules/
# Test coverage
/coverage/
# ESLint cache
.eslintcache
# OS-specific files
.DS_Store
Thumbs.db
.Spotlight-V100
.Trashes
# Temporary files used by the editor
*.swp
*.swo

2
.husky/commit-msg Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
npx --no -- commitlint --edit "$1"

2
.husky/pre-commit Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
npx lint-staged

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 DorianTech S.A.
Copyright (c) 2018-2024 SVR.JS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

149
README.md Normal file
View file

@ -0,0 +1,149 @@
<p align="center">
<a href="https://svrjs.org" target="_blank">
<img src="assets/logo.png" width="384">
</a>
</p>
<p align="center">
<b>SVR.JS</b> - a web server running on Node.JS<br/>
It's free as in freedom, scalable, secure, and configurable.
</p>
<p align="center">
<a href="https://svrjs.org/docs/tentative" target="_blank"><img alt="Static Badge" src="https://img.shields.io/badge/Documentation-green"></a>
<a href="https://svrjs.org" target="_blank"><img alt="Website" src="https://img.shields.io/website?url=https%3A%2F%2Fsvrjs.org"></a>
<a href="https://hub.docker.com/r/svrjs/svrjs" target="_blank"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/svrjs/svrjs"></a>
<a href="https://github.com/svr-js/svrjs/tree/next" target="_blank"><img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/svr-js/svrjs"></a>
<a href="https://x.com/SVR_JS" target="_blank"><img alt="X (formerly Twitter) Follow" src="https://img.shields.io/twitter/follow/SVR_JS"></a>
<a href="https://mastodon.social/@svrjs" target="_blank"><img alt="Mastodon Follow" src="https://img.shields.io/mastodon/follow/111643338718098121"></a>
</p>
* * *
## Features
### Static file handling
* Static file serving (even above 2GB)
* Directory listing serving
* Protection against path traversal
* Content-Range support (for non-HTML static files; also for HTML files from SVR.JS 3.15.1)
* Serving from web root different than SVR.JS installation directory
### Security
* HTTPS support
* HTTP/2 support
* Built-in block list
* Protection against HTTP authentication brute force attacks (from SVR.JS 3.4.8; enabled by default)
* Ability to hide server version
* OCSP stapling support (from SVR.JS 3.4.9)
### Configuration and customization
* Configurability via _config.json_ file
* Expandability via server-side JavaScript and mods
* Ability to serve non-standard error pages
* URL rewriting engine
* Event driven architecture powered by Node.JS, along with clustering.
### Compression and content delivery
* Brotli, gzip and Deflate HTTP compression (Brotli supported since SVR.JS 3.4.11)
* SNI (Server Name Indication) support
* ETag support (from SVR.JS 3.6.1)
* Reverse proxy functionality (requires reverse-proxy-mod SVR.JS mod)
* Forward proxy functionality (requires forward-proxy-mod SVR.JS mod)
### Authentication and access control
* HTTP basic authentication
### Gateway interfaces
* CGI (Common Gateway Interface) support (requires RedBrick mod)
* SCGI (Simple Common Gateway Interface) support (requires OrangeCircle mod)
* JSGI (JavaScript Gateway Interface) support (requires YellowSquare mod)
* PHP support (PHP-CGI with RedBrick mod or PHP-FPM with GreenRhombus mod)
### Additional functionality
* Logging
* Ability to display IP addresses, from which originally request was made (from reverse proxies; via X-Forwarded-For)
## Building SVR.JS
To build SVR.JS, you need Node.JS 18.0.0 or newer.
Before building SVR.JS, install the npm packages using this command:
```bash
npm install
```
After installing the packages, build SVR.JS with this command:
```bash
npm run build
```
After running the command, you will get bundled SVR.JS script, around with built-in utilities and assets in the `dist` directory. You will also get a zip archive in `out` directory, that can be installed using SVR.JS installer
## Installation (built from source)
To install SVR.JS you just built from the source code, you can install it via SVR.JS installer for GNU/Linux or manually.
If you want to install SVR.JS manually, you can read the [server documentation](https://svrjs.org/docs/tentative).
If you want to install via SVR.JS installer for GNU/Linux, run this command:
```bash
curl -fsSL https://downloads.svrjs.org/installer/svr.js.installer.linux.20240509.sh > /tmp/installer.sh && sudo bash /tmp/installer.sh
```
You will be then prompted about the type of installation. Choose option “2” to install SVR.JS from the zip archive, and type in the path to the zip archive (hint: it is in the `out` directory).
After typing the path, you may be prompted to install dependencies via GNU/Linux distributions package manager. Proceed with the installation of dependencies.
After installation, SVR.JS should be listening at http://localhost.
## SVR.JS documentation
You can read the [SVR.JS documentation](https://svrjs.org/docs/tentative) to get information on how to use SVR.JS.
## npm scripts
- To build SVR.JS along with the zip archive, run `npm run build`.
- To check SVR.JS code for errors with ESLint, run `npm run lint`.
- To fix and beautify SVR.JS code with ESLint and Prettier, run `npm run lint:fix`.
- To run SVR.JS from the "dist" folder, run `npm start`.
- To test SVR.JS itself, run `npm run dev`. This removes existing configuration.
- To perform unit tests with Jest, run `npm test`.
## File structure
The file structure for SVR.JS source code looks like this:
- .husky - Git hooks
- assets - files to copy into dist folder and to the archive
- dist - contains SVR.JS, assets, and SVR.JS utiltiies
- generatedAssets - assets generated by the build script
- out - contains SVR.JS zip archive
- src - contains SVR.JS source code
- index.js - entry point
- extraScripts - SVR.JS extra scripts (each script has a single file)
- handlers - handlers for servers
- middleware - built-in middleware for servers
- res - resources
- utils - utility functions
- templates - EJS templates for build script to use
- tests - Jest unit tests
- middleware - tests for middleware
- utils - unit tests for utility functions
- commitlint.config.js - commitlint configuration
- esbuild.config.js - the build script
- eslint.config.js - ESLint configuration
- jest.config.js - Jest configuration
- lint-staged.config.js - lint-staged configuration
- prettier.config.js - Prettier configuration
- svrjs.json - SVR.JS version, name, documentation URL, and statistics server collection endpoint URL
## Contribute
See [SVR.JS contribution page](https://svrjs.org/contribute) for details.
## License
This project is licensed under the MIT/X11 License - see the [LICENSE](LICENSE) file for details.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
assets/.dirimages/audio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
assets/.dirimages/css.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
assets/.dirimages/fifo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

BIN
assets/.dirimages/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
assets/.dirimages/html.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
assets/.dirimages/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

BIN
assets/.dirimages/other.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
assets/.dirimages/php.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
assets/.dirimages/text.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
assets/.dirimages/video.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) [year] [fullname]
Copyright (c) 2018-2024 SVR.JS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

63
assets/config.json Normal file
View file

@ -0,0 +1,63 @@
{
"users": [],
"port": 80,
"pubport": 80,
"page404": "404.html",
"timestamp": 1709477722479,
"blacklist": [],
"nonStandardCodes": [],
"enableCompression": true,
"customHeaders": {},
"enableHTTP2": false,
"enableLogging": true,
"enableDirectoryListing": true,
"enableDirectoryListingWithDefaultHead": false,
"serverAdministratorEmail": "[no contact information]",
"stackHidden": false,
"enableRemoteLogBrowsing": false,
"exposeServerVersion": true,
"disableServerSideScriptExpose": true,
"rewriteMap": [
{
"definingRegex": "/^\\/serverSideScript\\.js(?:$|[#?])/",
"replacements": [
{
"regex": "/^\\/serverSideScript\\.js($|[#?])/",
"replacement": "/NONEXISTENT_PAGE$1"
}
]
},
{
"definingRegex": "/^\\/testdir_rewritten(?:$|[\\/?#])/",
"replacements": [
{
"regex": "/^\\/testdir_rewritten($|[\\/?#])/",
"replacement": "/testdir$1"
}
]
}
],
"allowStatus": true,
"dontCompress": [
"/.*\\.ipxe$/",
"/.*\\.(?:jpe?g|png|bmp|tiff|jfif|gif|webp)$/",
"/.*\\.(?:[id]mg|iso|flp)$/",
"/.*\\.(?:zip|rar|bz2|[gb7x]z|lzma|tar)$/",
"/.*\\.(?:mp[34]|mov|wm[av]|avi|webm|og[gv]|mk[va])$/"
],
"enableIPSpoofing": false,
"secure": false,
"sni": {},
"disableNonEncryptedServer": false,
"disableToHTTPSRedirect": false,
"enableETag": true,
"disableUnusedWorkerTermination": false,
"rewriteDirtyURLs": true,
"errorPages": [],
"useWebRootServerSideScript": true,
"exposeModsInErrorPages": true,
"disableTrailingSlashRedirects": false,
"environmentVariables": {},
"allowDoubleSlashes": false,
"optOutOfStatisticsServer": false
}

BIN
assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
assets/powered.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -9,18 +9,19 @@
// ext - File extension of requested file
// uobject - Request URL object
// search - Request URL queries
// defaultPage - An index page location (deprecated, always returns 'index.json')
// defaultPage - An index page location (deprecated, always returns 'index.html')
// users - A list of users (deprecated)
// page404 - 404 Not Found page location
// head - A head of server response
// foot - A foot of server response
// fd - A response body used by responseEnd method
// fd - Currently unused
// elseCallback - Method summoning SVR.JS internal callbacks
// callServerError - Method to end with server error
// getCustomHeaders - Method to get headers defined in config.json file
// origHref - Original request URL without query (before URL rewriting)
// redirect - Method to redirect.
// parsePostData - Method to parse POST data.
// authUser - Authenticated HTTP user.
//Along with elements added by this implementation:
// disableEndElseCallbackExecute - Determines execution of elseCallback on end
// filterHeaders - Removes invalid HTTP/1.0 headers
@ -62,13 +63,20 @@ if(href == "/hello.svr") {
callServerError(403,"SVR.JS-exampleproxy"); //Server error
serverconsole.errmessage("Client fails to recieve content."); //Log into SVR.JS
} else if(href.indexOf("/proxy.svr/") == 0) {
var hn = href.split("/")[2]; //Hostname
if(hn != "this" && !(req.socket.realRemoteAddress ? req.socket.realRemoteAddress : req.socket.remoteAddress).match(/^(?:localhost$|::1$|f[c-d][0-9a-f]{2}:|(?:::ffff:)?(?:(?:127|10)\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3}|172\.(?:1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3})$)/i) ) {
//Prevent open proxy
callServerError(403,"SVR.JS-exampleproxy"); //Server error
serverconsole.errmessage("Client fails to recieve content."); //Log into SVR.JS
return;
}
var hdrs = req.headers;
hdrs["Host"] = (href.split("/")[2] == "this" ? req.headers.host : href.split("/")[2]);
hdrs["Host"] = (hn == "this" ? req.headers.host : hn);
hdrs["Origin"] = (req.headers.host == undefined ? "" : req.headers.host);
var options = {
hostname: (href.split("/")[2] == "this" ? req.headers.host.split(":")[0] : href.split("/")[2].split(":")[0]),
port: (href.split("/")[2] == "this" ? req.headers.host.split(":")[1] : (href.split("/")[2].split(":")[1] == undefined ? 80 : href.split("/")[2].split(":")[1])),
path: req.url.replace("/proxy.svr/" + href.split("/")[2],""),
hostname: (hn == "this" ? req.headers.host.split(":")[0] : hn.split(":")[0]),
port: (hn == "this" ? req.headers.host.split(":")[1] : (hn.split(":")[1] == undefined ? 80 : hn.split(":")[1])),
path: req.url.replace("/proxy.svr/" + hn,""),
method: req.method,
headers: filterHeaders(hdrs)
};

View file

@ -1,6 +1,6 @@
</div>
<div class="footer">
Copyright &copy; 2020 DorianTech S.A.
Copyright &copy; 2020-2024 SVR.JS
</div>
</body>
</html>

View file

@ -1,6 +1,6 @@
</div>
<div class="footer">
Copyright &copy; 2020 DorianTech S.A.
Copyright &copy; 2020-2024 SVR.JS
</div>
</body>
</html>

3
commitlint.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
extends: ["@commitlint/config-conventional"]
};

View file

@ -1,86 +0,0 @@
{
"users": [],
"port": 80,
"pubport": 80,
"page404": "404.html",
"timestamp": 1680954429282,
"blacklist": [],
"nonStandardCodes": [],
"enableCompression": true,
"customHeaders": {},
"enableHTTP2": false,
"enableLogging": true,
"enableDirectoryListing": true,
"enableDirectoryListingWithDefaultHead": false,
"serverAdministratorEmail": "[no contact information]",
"stackHidden": false,
"enableRemoteLogBrowsing": true,
"exposeServerVersion": true,
"disableServerSideScriptExpose": false,
"rewriteMap": [
{
"definingRegex": "/\\/invoke500\\/\\?/",
"replacements": [
{
"regex": "/\\/invoke500\\/\\?/",
"replacement": "/invoke500.svr?"
}
]
},
{
"definingRegex": "/\\/invoke500\\/.+\\//",
"replacements": [
{
"regex": "/\\/\\?/",
"replacement": "&"
},
{
"regex": "/invoke500\\//",
"replacement": "invoke500.svr?"
},
{
"regex": "/\\/(?!invoke500.svr?)/",
"replacement": ""
}
]
},
{
"definingRegex": "/\\/invoke500\\/.+/",
"replacements": [
{
"regex": "/\\?/",
"replacement": "&"
},
{
"regex": "/invoke500\\//",
"replacement": "invoke500.svr?"
}
]
},
{
"definingRegex": "/\\/invoke500\\//",
"replacements": [
{
"regex": "/\\/invoke500\\//",
"replacement": "/invoke500.svr"
}
]
},
{
"definingRegex": "/\\/invoke500$/",
"replacements": [
{
"regex": "/\\/invoke500/",
"replacement": "/invoke500.svr"
}
]
}
],
"allowStatus": true,
"dontCompress": ["/.*\\.ipxe$/","/.*\\.img$/","/.*\\.iso$/"],
"enableIPSpoofing": false,
"secure": false,
"sni": {},
"disableNonEncryptedServer": false,
"disableToHTTPSRedirect": false
}

251
esbuild.config.js Normal file
View file

@ -0,0 +1,251 @@
const esbuild = require("esbuild");
const esbuildCopyPlugin = require("esbuild-plugin-copy");
const fs = require("fs");
const zlib = require("zlib");
const ejs = require("ejs");
const archiver = require("archiver");
const dependencies =
JSON.parse(fs.readFileSync(__dirname + "/package.json")).dependencies || {};
const requiredDependencyList = Object.keys(dependencies);
let dependencyList = Object.keys(dependencies);
const svrjsInfo = JSON.parse(fs.readFileSync(__dirname + "/svrjs.json"));
const { name, version, documentationURL, changes } = svrjsInfo;
// Function to find and add all dependencies into the dependencyList array.
function findAllDependencies(curList) {
// If no curList parameter is specified, use dependencyList.
if (!curList) curList = dependencyList;
curList.forEach((dependency) => {
const newDeplist = Object.keys(
JSON.parse(
fs
.readFileSync(
__dirname +
"/node_modules/" +
dependency.replace(/\/\.\./g, "") +
"/package.json"
)
.toString()
).dependencies || {}
);
let noDupNewDepList = [];
newDeplist.forEach((dep) => {
// Ignore duplicates
if (dependencyList.indexOf(dep) == -1) {
noDupNewDepList.push(dep);
dependencyList.push(dep);
}
});
// Call findAllDependencies for the dependency list.
findAllDependencies(noDupNewDepList);
});
}
// Get list of all dependencies
findAllDependencies();
dependencyList = dependencyList.sort();
// Create and populate an object, where whenever the dependencies are required are listed.
let dependenciesAreRequired = {};
dependencyList.forEach((dependency) => {
dependenciesAreRequired[dependency] = false;
});
requiredDependencyList.forEach((dependency) => {
dependenciesAreRequired[dependency] = true;
});
// Create the template functions using EJS
const layoutTemplate = ejs.compile(
fs.readFileSync(__dirname + "/templates/layout.ejs").toString()
);
const testsTemplate = ejs.compile(
fs.readFileSync(__dirname + "/templates/tests.ejs").toString()
);
const indexTemplate = ejs.compile(
fs.readFileSync(__dirname + "/templates/index.ejs").toString()
);
const licensesTemplate = ejs.compile(
fs.readFileSync(__dirname + "/templates/licenses.ejs").toString()
);
const licenseElementTemplate = ejs.compile(
fs.readFileSync(__dirname + "/templates/licenseElement.ejs").toString()
);
let licenseElements = "";
// Generate the licenses list in HTML
dependencyList.forEach((dependency) => {
const packageJSON = JSON.parse(
fs
.readFileSync(
__dirname +
"/node_modules/" +
dependency.replace(/\/\.\./g, "") +
"/package.json"
)
.toString()
);
licenseElements += licenseElementTemplate({
moduleName: packageJSON.name,
name: name,
license: packageJSON.license,
description: packageJSON.description || "No description",
author: packageJSON.author ? packageJSON.author.name : packageJSON.author,
required: dependenciesAreRequired[dependency]
});
});
// Generate pages
const licensesPage = layoutTemplate({
title: name + " " + version + " Licenses",
content: licensesTemplate({
name: name,
version: version,
licenses: licenseElements
})
});
const testsPage = layoutTemplate({
title: name + " " + version + " Tests",
content: testsTemplate({
name: name,
version: version
})
});
const indexPage = layoutTemplate({
title: name + " " + version,
content: indexTemplate({
name: name,
version: version,
documentationURL: documentationURL,
changes: changes
})
});
// Remove the generated assets directory if exists, and create a new one.
if (fs.existsSync(__dirname + "/generatedAssets")) {
if (fs.rmSync) fs.rmSync(__dirname + "/generatedAssets", { recursive: true });
else fs.rmdirSync(__dirname + "/generatedAssets", { recursive: true });
}
fs.mkdirSync(__dirname + "/generatedAssets");
// Remove the dist directory if exists, and create a new one.
if (fs.existsSync(__dirname + "/dist")) {
if (fs.rmSync) fs.rmSync(__dirname + "/dist", { recursive: true });
else fs.rmdirSync(__dirname + "/dist", { recursive: true });
}
fs.mkdirSync(__dirname + "/dist");
fs.mkdirSync(__dirname + "/dist/log");
fs.mkdirSync(__dirname + "/dist/mods");
fs.mkdirSync(__dirname + "/dist/temp");
// Remove the out directory if exists, and create a new one.
if (fs.existsSync(__dirname + "/out")) {
if (fs.rmSync) fs.rmSync(__dirname + "/out", { recursive: true });
else fs.rmdirSync(__dirname + "/out", { recursive: true });
}
fs.mkdirSync(__dirname + "/out");
// Create a licenses directory
fs.mkdirSync(__dirname + "/generatedAssets/licenses");
// Write to HTML files
fs.writeFileSync(__dirname + "/generatedAssets/index.html", indexPage);
fs.writeFileSync(__dirname + "/generatedAssets/tests.html", testsPage);
fs.writeFileSync(
__dirname + "/generatedAssets/licenses/index.html",
licensesPage
);
// Bundle the source and copy the assets using esbuild and esbuild-plugin-copy
esbuild
.build({
entryPoints: ["src/index.js"],
bundle: true,
outfile: "dist/svr.js",
platform: "node",
target: "es2017",
plugins: [
esbuildCopyPlugin.copy({
resolveFrom: __dirname,
assets: {
from: ["./assets/**/*"],
to: ["./dist"]
},
globbyOptions: {
dot: true
}
}),
esbuildCopyPlugin.copy({
resolveFrom: __dirname,
assets: {
from: ["./generatedAssets/**/*"],
to: ["./dist"]
}
})
]
})
.then(() => {
const utilFilesAndDirectories = fs.existsSync(
__dirname + "/src/extraScripts"
)
? fs.readdirSync(__dirname + "/src/extraScripts")
: [];
const utilFiles = [];
utilFilesAndDirectories.forEach((entry) => {
if (fs.statSync(__dirname + "/src/extraScripts/" + entry).isFile())
utilFiles.push(entry);
});
// Transpile utilities using esbuild
esbuild
.build({
entryPoints: utilFiles.map(
(filename) => "src/extraScripts/" + filename
),
bundle: true,
outdir: "dist",
platform: "node",
target: "es2017"
})
.then(() => {
const archiveName =
"svr.js." +
version.toLowerCase().replace(/[^0-9a-z]+/g, ".") +
".zip";
const output = fs.createWriteStream(__dirname + "/out/" + archiveName);
const archive = archiver("zip", {
zlib: { level: 9 }
});
archive.pipe(output);
// Add everything in the "dist" directory except for "svr.js" and "svr.compressed"
archive.glob("**/*", {
cwd: __dirname + "/dist",
ignore: ["svr.js", "svr.compressed"],
dot: true
});
// Create a stream for the "svr.compressed" file
const compressedSVRJSFileStream = fs
.createReadStream(__dirname + "/dist/svr.js")
.pipe(
zlib.createGzip({
level: 9
})
);
archive.append(compressedSVRJSFileStream, { name: "svr.compressed" });
archive.append(
'const zlib = require("zlib");\nconst fs = require("fs");\nconsole.log("Deleting SVR.JS stub...");\nfs.unlinkSync("svr.js");\nconsole.log("Decompressing SVR.JS...");\nconst script = zlib.gunzipSync(fs.readFileSync("svr.compressed"));\nfs.unlinkSync("svr.compressed");\nfs.writeFileSync("svr.js",script);\nconsole.log("Restart SVR.JS to get server interface.");',
{ name: "svr.js" }
);
archive.finalize();
})
.catch((err) => {
throw err;
});
})
.catch((err) => {
throw err;
});

30
eslint.config.js Normal file
View file

@ -0,0 +1,30 @@
const globals = require("globals");
const pluginJs = require("@eslint/js");
const eslintPluginPrettierRecommended = require("eslint-plugin-prettier/recommended");
const jest = require("eslint-plugin-jest");
module.exports = [
{
files: ["**/*.js"],
languageOptions: {
sourceType: "commonjs"
}
},
{
files: ["tests/*.test.js", "tests/**/*.test.js"],
...jest.configs['flat/recommended'],
rules: {
...jest.configs['flat/recommended'].rules,
'jest/prefer-expect-assertions': 'off',
}
},
{
languageOptions: {
globals: {
...globals.node
}
}
},
pluginJs.configs.recommended,
eslintPluginPrettierRecommended
];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

View file

@ -1,124 +0,0 @@
//Base64.js for hexstrbase64 library for Node.js
/*
* Copyright (c) 2012 Miles Shang <mail@mshang.ca>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Usage:
* Set your settings:
* base64.settings.char62 = "-";
* base64.settings.char63 = "_";
* etc.
*
* Then:
* base64.encode(str) takes a string and returns the base64 encoding of it.
* base64.decode(str) does the reverse.
*/
/* TODO:
* Add a "padding_mandatory" flag to check for bad padding in the decoder.
* Add test cases that throw errors.
*/
var base64 = new Object();
base64.settings = { // defaults
"char62" : "+",
"char63" : "/",
"pad" : "=",
"ascii" : false
};
/*
* Settings:
* If "pad" is not null or undefined, then it will be used for encoding.
*
* If "ascii" is set to true, then the encoder
* will assume that plaintext is in 8-bit chars (the standard).
* In this case, for every 3 chars in plaintext, you get 4 chars of base64.
* Any non-8-bit chars will cause an error.
* Otherwise, assume that all plaintext can be in the full range
* of Javascript chars, i.e. 16 bits. Get 8 chars of base64 for 3 chars
* of plaintext. Any possible JS string can be encoded.
*/
base64.encode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
for (var i = 0; i < str.length; ++i) {
var c_num = str.charCodeAt(i);
if (this.settings.ascii)
if (c_num >= 256)
throw "Not an 8-bit char.";
var c_bin = c_num.toString(2);
while (c_bin.length < (this.settings.ascii ? 8 : 16))
c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= 6) {
var sextet = buf.slice(0, 6);
buf = buf.slice(6);
output += this.char_set.charAt(parseInt(sextet, 2));
}
}
if (buf) { // not empty
while (buf.length < 6) buf += "0";
output += this.char_set.charAt(parseInt(buf, 2));
}
if (this.settings.pad)
while (output.length % (this.settings.ascii ? 4 : 8) != 0)
output += this.settings.pad;
return output;
}
base64.decode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
var bits = (this.settings.ascii ? 8 : 16);
for (var i = 0; i < str.length; ++i) {
if (str[i] == this.settings.pad) break;
var c_num = this.char_set.indexOf(str.charAt(i));
if (c_num == -1) throw "Not base64.";
var c_bin = c_num.toString(2);
while (c_bin.length < 6) c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= bits) {
var octet = buf.slice(0, bits);
buf = buf.slice(bits);
output += String.fromCharCode(parseInt(octet, 2));
}
}
return output;
}
module.exports = base64;

View file

@ -1,123 +0,0 @@
//Base64.js for hexstrbase64 library for browser
/*
* Copyright (c) 2012 Miles Shang <mail@mshang.ca>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Usage:
* Set your settings:
* base64.settings.char62 = "-";
* base64.settings.char63 = "_";
* etc.
*
* Then:
* base64.encode(str) takes a string and returns the base64 encoding of it.
* base64.decode(str) does the reverse.
*/
/* TODO:
* Add a "padding_mandatory" flag to check for bad padding in the decoder.
* Add test cases that throw errors.
*/
var base64 = new Object();
base64.settings = { // defaults
"char62" : "+",
"char63" : "/",
"pad" : "=",
"ascii" : false
};
/*
* Settings:
* If "pad" is not null or undefined, then it will be used for encoding.
*
* If "ascii" is set to true, then the encoder
* will assume that plaintext is in 8-bit chars (the standard).
* In this case, for every 3 chars in plaintext, you get 4 chars of base64.
* Any non-8-bit chars will cause an error.
* Otherwise, assume that all plaintext can be in the full range
* of Javascript chars, i.e. 16 bits. Get 8 chars of base64 for 3 chars
* of plaintext. Any possible JS string can be encoded.
*/
base64.encode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
for (var i = 0; i < str.length; ++i) {
var c_num = str.charCodeAt(i);
if (this.settings.ascii)
if (c_num >= 256)
throw "Not an 8-bit char.";
var c_bin = c_num.toString(2);
while (c_bin.length < (this.settings.ascii ? 8 : 16))
c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= 6) {
var sextet = buf.slice(0, 6);
buf = buf.slice(6);
output += this.char_set.charAt(parseInt(sextet, 2));
}
}
if (buf) { // not empty
while (buf.length < 6) buf += "0";
output += this.char_set.charAt(parseInt(buf, 2));
}
if (this.settings.pad)
while (output.length % (this.settings.ascii ? 4 : 8) != 0)
output += this.settings.pad;
return output;
}
base64.decode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
var bits = (this.settings.ascii ? 8 : 16);
for (var i = 0; i < str.length; ++i) {
if (str[i] == this.settings.pad) break;
var c_num = this.char_set.indexOf(str.charAt(i));
if (c_num == -1) throw "Not base64.";
var c_bin = c_num.toString(2);
while (c_bin.length < 6) c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= bits) {
var octet = buf.slice(0, bits);
buf = buf.slice(bits);
output += String.fromCharCode(parseInt(octet, 2));
}
}
return output;
}

View file

@ -1,129 +0,0 @@
//Requires base64
var base64 = require('./base64.js');
var HexStrBase64Buffer = {
from: function(s, e) {
var type = e;
var value = '';
if (e == 'base64') {
value = base64.decode(s);
} else if (e == 'hex') {
try {
var escaped = "";
var hex = "";
if(s.length%4 > 0) {
for(i=0;i<(4-(s.length%4));i++) {
hex += "0";
}
}
hex += s;
for(var i = 0;i<hex.length;i += 4) {
escaped += new String("%u" + hex.charAt(i) + hex.charAt(i + 1) + hex.charAt(i + 2) + hex.charAt(i + 3)).toString().split("undefined").join("");
}
value = unescape(escaped).split(unescape("%00")).join("");
} catch (ex) {
var modex = ex.toString().split('Error: ');
modex[0] = '';
if (typeof modex == 'object') {
throw new Error(
'Invaild hex input: ' + s + '. Reason: ' + modex.join('')
);
} else {
throw new Error('Invaild hex input: ' + s + '. Reason: ' + ex);
}
}
} else {
value = Buffer.from(s, 'utf8').toString(e);
}
function toString(en) {
//function toStringE(en,type) {
if (en == 'base64') {
return base64.encode(value);
} else if (en == 'hex') {
var result = "";
for(var i=0;i<value.length;i++) {
var unicode = escape(value.charAt(i));
var hex = "";
if(value.charAt(i) == "\n") {
hex = "000a";
} else if(value.charAt(i) == "\r") {
hex = "000d";
} else if(value.charAt(i) == " ") {
hex = "0020";
} else if(value.charAt(i) == "\0") {
hex = "";
} else if(unicode == value.charAt(i)) {
var oldhex = value.charCodeAt(i).toString(16);
var newhex = "";
if(oldhex.length < 4) {
for(var j=0;j<4-(oldhex.length%4);j++) {
newhex += "0";
}
newhex += oldhex;
} else {
newhex = oldhex;
}
hex = newhex;
} else {
hex = unicode.split("%u").join("");
}
if(hex.length == 4 || hex === "") {
result += hex;
} else if(hex.length > 4) {
result += hex.substring(hex.length-5,hex.length-1);
} else if(hex.length < 4) {
for(var j=0;j<=4-(hex.length%4);j++) {
result += "0";
}
result += hex;
}
}
return result.split("undefined").join("").split("%").join("");
} else {
//return Buffer.from(value, type).toString(en);
return Buffer.from(value,"utf8").toString(en);
}
}
//}
//function toString(en) {
//return toStringE(en,type);
//}
return { type: type, value: value, toString: toString };
}
};
var hexstrbase64 = {
strtobase64: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('base64');
},
base64tostr: function(b) {
return HexStrBase64Buffer.from(b, 'base64').toString('utf8');
},
strtohex: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('hex');
},
hextostr: function(h) {
return HexStrBase64Buffer.from(h, 'hex').toString('utf8');
},
hextobase64: function(h) {
return hexstrbase64.strtobase64(hexstrbase64.hextostr(h));
},
base64tohex: function(b) {
return hexstrbase64.strtohex(hexstrbase64.base64tostr(b));
},
cipher: function() {
this.strtobase64 = hexstrbase64.strtobase64;
this.base64tostr = hexstrbase64.base64tostr;
this.strtohex = hexstrbase64.strtohex;
this.hextostr = hexstrbase64.hextostr;
this.hextobase64 = hextobase64.hextobase64;
this.base64tohex = hextobase64.base64tohex;
},
native: {
btoa: function(b) {
return hexstrbase64.strtobase64(b);
},
atob: function(a) {
return hexstrbase64.base64tostr(a);
}
}
};
module.exports = hexstrbase64;

View file

@ -1,126 +0,0 @@
//Requires base64_browser.js
var HexStrBase64Buffer = {
from: function(s, e) {
var type = e;
var value = '';
if (e == 'base64') {
value = base64.decode(s);
} else if (e == 'hex') {
try {
var escaped = "";
var hex = "";
if(s.length%4 > 0) {
for(i=0;i<(4-(s.length%4));i++) {
hex += "0";
}
}
hex += s;
for(var i = 0;i<hex.length;i += 4) {
escaped += new String("%u" + hex.charAt(i) + hex.charAt(i + 1) + hex.charAt(i + 2) + hex.charAt(i + 3)).toString().split("undefined").join("");
}
value = unescape(escaped).split(unescape("%00")).join("");
} catch (ex) {
var modex = ex.toString().split('Error: ');
modex[0] = '';
if (typeof modex == 'object') {
throw new Error(
'Invaild hex input: ' + s + '. Reason: ' + modex.join('')
);
} else {
throw new Error('Invaild hex input: ' + s + '. Reason: ' + ex);
}
}
} else {
value = new TextDecoder(e).decode(new TextEncoder('utf8').encode(s));
}
//function toStringE(en,type) {
function toString(en) {
if (en == 'base64') {
return base64.encode(value);
} else if (en == 'hex') {
var result = "";
for(var i=0;i<value.length;i++) {
var unicode = escape(value.charAt(i));
var hex = "";
if(value.charAt(i) == "\n") {
hex = "000a";
} else if(value.charAt(i) == "\r") {
hex = "000d";
} else if(value.charAt(i) == " ") {
hex = "0020";
} else if(value.charAt(i) == "\0") {
hex = "";
} else if(unicode == value.charAt(i)) {
var oldhex = value.charCodeAt(i).toString(16);
var newhex = "";
if(oldhex.length < 4) {
for(var j=0;j<4-(oldhex.length%4);j++) {
newhex += "0";
}
newhex += oldhex;
} else {
newhex = oldhex;
}
hex = newhex;
} else {
hex = unicode.split("%u").join("");
}
if(hex.length == 4 || hex === "") {
result += hex;
} else if(hex.length > 4) {
result += hex.substring(hex.length-5,hex.length-1);
} else if(hex.length < 4) {
for(var j=0;j<=4-(hex.length%4);j++) {
result += "0";
}
result += hex;
}
}
return result.split("undefined").join("").split("%").join("");
} else {
//return new TextDecoder(en).decode(new TextEncoder(type).encode(value));
return new TextDecoder(en).decode(new TextEncoder("utf8").encode(value));
}
}
//function toString(en) {
//return toStringE(en,type);
//}
return { type: type, value: value, toString: toString };
}
};
var hexstrbase64 = {
strtobase64: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('base64');
},
base64tostr: function(b) {
return HexStrBase64Buffer.from(b, 'base64').toString('utf8');
},
strtohex: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('hex');
},
hextostr: function(h) {
return HexStrBase64Buffer.from(h, 'hex').toString('utf8');
},
hextobase64: function(h) {
return hexstrbase64.strtobase64(hexstrbase64.hextostr(h));
},
base64tohex: function(b) {
return hexstrbase64.strtohex(hexstrbase64.base64tostr(b));
},
cipher: function() {
this.strtobase64 = hexstrbase64.strtobase64;
this.base64tostr = hexstrbase64.base64tostr;
this.strtohex = hexstrbase64.strtohex;
this.hextostr = hexstrbase64.hextostr;
this.hextobase64 = hextobase64.hextobase64;
this.base64tohex = hextobase64.base64tohex;
},
native: {
btoa: function(b) {
return hexstrbase64.strtobase64(b);
},
atob: function(a) {
return hexstrbase64.base64tostr(a);
}
}
};

View file

@ -1,11 +0,0 @@
let hexstrbase64 = require("./hexstrbase64/main.js");
function decodeBase(b) {
return hexstrbase64.native.atob(b);
}
function encodeStr(s) {
return hexstrbase64.native.btoa(s);
}
var m = Object.create(hexstrbase64);
m.decodeBase = decodeBase;
m.encodeBase = encodeStr;
module.exports = m;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

View file

@ -1,8 +0,0 @@
.code {
border-width: 5px;
border-color: #BEBEBE;
border-style: solid;
color:black;
background-color: #7F7F7F;
font-family: Hack,Consolas,Monaco,monospace;
}

View file

@ -1,31 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>HexStrBase64 Readme</title>
<link rel="stylesheet" href="readme.css">
</head>
<body>
<h1>hexstrbase64</h1>
<h2>How to install?</h2>
<h3>Node.js</h3>
<ol>
<li>Download library from <a href="https://repl.it/@DorianNiemiec/Hex-String-Base64-NodeJS-Library.zip" download>here</a>.</li>
<li>Modify index.js</li>
<li>Write header in program (replace <b>./hexstrbase64</b> with your path to hexstrbase64 library):</li>
<div class="code">
var hexstrbase64 = require("<b>./hexstrbase64</b>/index.js");<br/>
</div>
<li>Now hexstrbase64 library added to program!</li>
</ol>
<h3>Browser Javascript</h3>
<ol>
<li>Download library from <a href="https://repl.it/@DorianNiemiec/Hex-String-Base64-NodeJS-Library.zip" download>here</a>.</li>
<li>Write this code in &lt;head&gt; element (replace <b>hexstrbase64/</b> with your path to hexstrbase64 library):</li>
<div class="code">
&lt;script src="<b>hexstrbase64/</b>hexstrbase64/base64_browser.js"&gt;&lt;/script&gt;<br/>
&lt;script src="<b>hexstrbase64/</b>hexstrbase64/main_browser.js"&gt;&lt;/script&gt;
</div>
<li>Now hexstrbase64 library added to HTML!</li>
</ol>
</body>
</html>

View file

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hexstrbase64 base64 test</title>
<script src="../hexstrbase64/base64_browser.js"></script>
<script src="../hexstrbase64/main_browser.js"></script>
<script src="base64.js"></script>
<script>
testStart();
</script>
</head>
</html>

View file

@ -1,56 +0,0 @@
function nameObj(n, v) {
return {name:n, value:v};
}
function testStart() {
document.write('<meta charset="UTF-8">');
document.write('<title>hexstrbase64 base64 test</title>');
console.log("TESTING STARTED");
for (var i = 0; i < 3; i++) {
document.write('<h1>' + enccases[i].name + '</h1>');
console.log("SWITCH " + enccases[i].name);
for (var j = 0; j < 2; j++) {
document.write('<h2>' + enccases[i].value[j].name + '</h2>');
console.log("CASE " + enccases[i].value[j].name);
console.log("MUST BE: " + enccases[i].value[j].value);
console.log("IS : " + hexstrbase64.strtobase64(enccases[i].value[j].name));
if (hexstrbase64.strtobase64(enccases[i].value[j].name) == enccases[i].value[j].value) {
document.write('<p><img src="../ok.png"></img>Equals</p>');
console.log("EQUALS");
} else {
document.write('<p><img src="../fail.png"></img>Not Equals</p>');
console.log("NOT EQUALS");
}
console.log("CASE " + enccases[i].value[j].name + " ENDED");
}
console.log("SWITCH " + enccases[i].name + " ENDED");
}
console.log("TESTING ENDED");
}
var enccases = [
nameObj('Ascii', [
nameObj('Hello world!', 'AEgAZQBsAGwAbwAgAHcAbwByAGwAZAAh'),
nameObj('Lorem ipsum', 'AEwAbwByAGUAbQAgAGkAcABzAHUAbQ==')
]),
nameObj('Ascii More Than 64 Bytes', [
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum fermentum ac nisl a sollicitudin. Cras interdum dui turpis, non scelerisque.',
'AEwAbwByAGUAbQAgAGkAcABzAHUAbQAgAGQAbwBsAG8AcgAgAHMAaQB0ACAAYQBtAGUAdAAsACAAYwBvAG4AcwBlAGMAdABlAHQAdQByACAAYQBkAGkAcABpAHMAYwBpAG4AZwAgAGUAbABpAHQALgAgAFYAZQBzAHQAaQBiAHUAbAB1AG0AIABmAGUAcgBtAGUAbgB0AHUAbQAgAGEAYwAgAG4AaQBzAGwAIABhACAAcwBvAGwAbABpAGMAaQB0AHUAZABpAG4ALgAgAEMAcgBhAHMAIABpAG4AdABlAHIAZAB1AG0AIABkAHUAaQAgAHQAdQByAHAAaQBzACwAIABuAG8AbgAgAHMAYwBlAGwAZQByAGkAcwBxAHUAZQAu'
),
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dapibus volutpat ligula at pulvinar. Etiam consequat mi fringilla facilisis eleifend.',
'AEwAbwByAGUAbQAgAGkAcABzAHUAbQAgAGQAbwBsAG8AcgAgAHMAaQB0ACAAYQBtAGUAdAAsACAAYwBvAG4AcwBlAGMAdABlAHQAdQByACAAYQBkAGkAcABpAHMAYwBpAG4AZwAgAGUAbABpAHQALgAgAFAAaABhAHMAZQBsAGwAdQBzACAAZABhAHAAaQBiAHUAcwAgAHYAbwBsAHUAdABwAGEAdAAgAGwAaQBnAHUAbABhACAAYQB0ACAAcAB1AGwAdgBpAG4AYQByAC4AIABFAHQAaQBhAG0AIABjAG8AbgBzAGUAcQB1AGEAdAAgAG0AaQAgAGYAcgBpAG4AZwBpAGwAbABhACAAZgBhAGMAaQBsAGkAcwBpAHMAIABlAGwAZQBpAGYAZQBuAGQALg=='
)
]),
nameObj('Unicode UTF8', [
nameObj(
'DorianTech Hex String Base64转换器',
'AEQAbwByAGkAYQBuAFQAZQBjAGgAIABIAGUAeAAgAFMAdAByAGkAbgBnACAAQgBhAHMAZQA2ADSPbGNiVmg====='
),
nameObj(
'DorianTech Hex String Base64转换器用于由DorianTech提供的Node.js',
'AEQAbwByAGkAYQBuAFQAZQBjAGgAIABIAGUAeAAgAFMAdAByAGkAbgBnACAAQgBhAHMAZQA2ADSPbGNiVmj/DHUoTo51MQBEAG8AcgBpAGEAbgBUAGUAYwBoY9BPm3aEAE4AbwBkAGUALgBqAHM====='
)
])
];

View file

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hexstrbase64 hex test</title>
<script src="../hexstrbase64/base64_browser.js"></script>
<script src="../hexstrbase64/main_browser.js"></script>
<script src="hex.js"></script>
<script>
testStart();
</script>
</head>
</html>

View file

@ -1,56 +0,0 @@
function nameObj(n, v) {
return {name:n, value:v};
}
function testStart() {
document.write('<meta charset="UTF-8">');
document.write('<title>hexstrbase64 hex test</title>');
console.log("TESTING STARTED");
for (var i = 0; i < 3; i++) {
document.write('<h1>' + enccases[i].name + '</h1>');
console.log("SWITCH " + enccases[i].name);
for (var j = 0; j < 2; j++) {
document.write('<h2>' + enccases[i].value[j].name + '</h2>');
console.log("CASE " + enccases[i].value[j].name);
console.log("MUST BE: " + enccases[i].value[j].value);
console.log("IS : " + hexstrbase64.strtohex(enccases[i].value[j].name));
if (hexstrbase64.strtohex(enccases[i].value[j].name) == enccases[i].value[j].value) {
document.write('<p><img src="../ok.png"></img>Equals</p>');
console.log("EQUALS");
} else {
document.write('<p><img src="../fail.png"></img>Not Equals</p>');
console.log("NOT EQUALS");
}
console.log("CASE " + enccases[i].value[j].name + " ENDED");
}
console.log("SWITCH " + enccases[i].name + " ENDED");
}
console.log("TESTING ENDED");
}
var enccases = [
nameObj('Ascii', [
nameObj('Hello world!', '00480065006c006c006f00200077006f0072006c00640021'),
nameObj('Lorem ipsum', '004c006f00720065006d00200069007000730075006d')
]),
nameObj('Ascii More Than 64 Bytes', [
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum fermentum ac nisl a sollicitudin. Cras interdum dui turpis, non scelerisque.',
'004c006f00720065006d00200069007000730075006d00200064006f006c006f0072002000730069007400200061006d00650074002C00200063006f006e00730065006300740065007400750072002000610064006900700069007300630069006e006700200065006c00690074002e00200056006500730074006900620075006c0075006d0020006600650072006d0065006e00740075006d0020006100630020006e00690073006c0020006100200073006f006c006c0069006300690074007500640069006e002e0020004300720061007300200069006e00740065007200640075006d00200064007500690020007400750072007000690073002C0020006e006f006e0020007300630065006c0065007200690073007100750065002e'
),
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dapibus volutpat ligula at pulvinar. Etiam consequat mi fringilla facilisis eleifend.',
'004c006f00720065006d00200069007000730075006d00200064006f006c006f0072002000730069007400200061006d00650074002C00200063006f006e00730065006300740065007400750072002000610064006900700069007300630069006e006700200065006c00690074002e002000500068006100730065006c006c007500730020006400610070006900620075007300200076006f006c007500740070006100740020006c006900670075006c0061002000610074002000700075006c00760069006e00610072002e00200045007400690061006d00200063006f006e0073006500710075006100740020006d00690020006600720069006e00670069006c006c006100200066006100630069006c006900730069007300200065006c0065006900660065006e0064002e'
)
]),
nameObj('Unicode UTF8', [
nameObj(
'DorianTech Hex String Base64转换器',
'0044006f007200690061006e0054006500630068002000480065007800200053007400720069006e006700200042006100730065003600348F6C63625668'
),
nameObj(
'DorianTech Hex String Base64转换器用于由DorianTech提供的Node.js',
'0044006f007200690061006e0054006500630068002000480065007800200053007400720069006e006700200042006100730065003600348F6C63625668FF0C75284E8E75310044006f007200690061006e005400650063006863D04F9B7684004e006f00640065002e006a0073'
)
])
];

View file

@ -1,16 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>hexstrbase64 test</title>
<style>
iframe {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<iframe src="base64.html"></iframe>
<iframe src="hex.html"></iframe>
</body>
</html>

View file

@ -1 +0,0 @@
0

View file

@ -1,129 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>SVR.JS 3.6.4</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8" />
<style>
body {
font-family: FreeSans, Helvetica, Tahoma, Arial, sans-serif;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to SVR.JS 3.6.4</h1>
<br/>
<img src="/logo.png" style="width: 256px;" />
<br/>
<p>If you see this page, that means, that the server is properly working. 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>
<div style="background-color: #e0e0e0; padding: 5px; text-align: left; display: inline-block;">
<code>
{<br/>
&nbsp;&nbsp;"users": [],<br/>
&nbsp;&nbsp;"port": 80,<br/>
&nbsp;&nbsp;"pubport": 80,<br/>
&nbsp;&nbsp;"page404": "404.html",<br/>
&nbsp;&nbsp;"timestamp": 1680954429282,<br/>
&nbsp;&nbsp;"blacklist": [],<br/>
&nbsp;&nbsp;"nonStandardCodes": [],<br/>
&nbsp;&nbsp;"enableCompression": true,<br/>
&nbsp;&nbsp;"customHeaders": {},<br/>
&nbsp;&nbsp;"enableHTTP2": false,<br/>
&nbsp;&nbsp;"enableLogging": true,<br/>
&nbsp;&nbsp;"enableDirectoryListing": true,<br/>
&nbsp;&nbsp;"enableDirectoryListingWithDefaultHead": false,<br/>
&nbsp;&nbsp;"serverAdministratorEmail": "[no contact information]",<br/>
&nbsp;&nbsp;"stackHidden": false,<br/>
&nbsp;&nbsp;"enableRemoteLogBrowsing": true,<br/>
&nbsp;&nbsp;"exposeServerVersion": true,<br/>
&nbsp;&nbsp;"disableServerSideScriptExpose": false,<br/>
&nbsp;&nbsp;"rewriteMap": [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"definingRegex": "/\\/invoke500\\/\\?/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacements": dorians[<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/\\/invoke500\\/\\?/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": "/invoke500.svr?"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"definingRegex": "/\\/invoke500\\/.+\\//",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacements": [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/\\/\\?/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": "&amp;"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/invoke500\\//",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": "invoke500.svr?"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/\\/(?!invoke500.svr?)/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": ""<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;},<br/>3.4.13
&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"definingRegex": "/\\/invoke500\\/.+/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacements": [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/\\?/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": "&amp;"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/invoke500\\//",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": "invoke500.svr?"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"definingRegex": "/\\/invoke500\\//",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacements": [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/\\/invoke500\\//",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": "/invoke500.svr"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"definingRegex": "/\\/invoke500$/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacements": [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"regex": "/\\/invoke500/",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"replacement": "/invoke500.svr"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
&nbsp;&nbsp;],<br/>
&nbsp;&nbsp;"allowStatus": true,<br/>
&nbsp;&nbsp;"dontCompress": ["/.*\\.ipxe$/","/.*\\.img$/","/.*\\.iso$/"],<br/>
&nbsp;&nbsp;"enableIPSpoofing": false,<br/>
&nbsp;&nbsp;"secure": false,<br/>
&nbsp;&nbsp;"sni": {},<br/>
&nbsp;&nbsp;"disableNonEncryptedServer": false,<br/>
&nbsp;&nbsp;"disableToHTTPSRedirect": false<br/>
}
</code>
</div>
<p>Changes:</p>
<ul>
<li>Improved reliability while loading server-side JavaScript.</li>
</ul>
<p>Bugs:</p>
<ul>
<li>Some very old mods requiring hexstrbase64 will fail to load.</li>
<li>On first load server-side JavaScript will fail to load when SVR.JS is running on Bun.</li>
</ul>
<br/>
<a href="/tests.html">Tests</a><br/>
<a href="/licenses">Licenses</a><br/>
<a href="/svrjsstatus.svr">SVR.JS status page</a><br/>
<a href="https://svrjs.org/docs">More Information</a>
<br/>
<br/>
<img src="/powered.png" />
</body>
</html>

5
jest.config.js Normal file
View file

@ -0,0 +1,5 @@
module.exports = {
testEnvironment: 'node',
testMatch: ['**/tests/**/*.test.js'],
verbose: true,
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

View file

@ -1,124 +0,0 @@
//Base64.js for hexstrbase64 library for Node.js
/*
* Copyright (c) 2012 Miles Shang <mail@mshang.ca>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Usage:
* Set your settings:
* base64.settings.char62 = "-";
* base64.settings.char63 = "_";
* etc.
*
* Then:
* base64.encode(str) takes a string and returns the base64 encoding of it.
* base64.decode(str) does the reverse.
*/
/* TODO:
* Add a "padding_mandatory" flag to check for bad padding in the decoder.
* Add test cases that throw errors.
*/
var base64 = new Object();
base64.settings = { // defaults
"char62" : "+",
"char63" : "/",
"pad" : "=",
"ascii" : false
};
/*
* Settings:
* If "pad" is not null or undefined, then it will be used for encoding.
*
* If "ascii" is set to true, then the encoder
* will assume that plaintext is in 8-bit chars (the standard).
* In this case, for every 3 chars in plaintext, you get 4 chars of base64.
* Any non-8-bit chars will cause an error.
* Otherwise, assume that all plaintext can be in the full range
* of Javascript chars, i.e. 16 bits. Get 8 chars of base64 for 3 chars
* of plaintext. Any possible JS string can be encoded.
*/
base64.encode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
for (var i = 0; i < str.length; ++i) {
var c_num = str.charCodeAt(i);
if (this.settings.ascii)
if (c_num >= 256)
throw "Not an 8-bit char.";
var c_bin = c_num.toString(2);
while (c_bin.length < (this.settings.ascii ? 8 : 16))
c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= 6) {
var sextet = buf.slice(0, 6);
buf = buf.slice(6);
output += this.char_set.charAt(parseInt(sextet, 2));
}
}
if (buf) { // not empty
while (buf.length < 6) buf += "0";
output += this.char_set.charAt(parseInt(buf, 2));
}
if (this.settings.pad)
while (output.length % (this.settings.ascii ? 4 : 8) != 0)
output += this.settings.pad;
return output;
}
base64.decode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
var bits = (this.settings.ascii ? 8 : 16);
for (var i = 0; i < str.length; ++i) {
if (str[i] == this.settings.pad) break;
var c_num = this.char_set.indexOf(str.charAt(i));
if (c_num == -1) throw "Not base64.";
var c_bin = c_num.toString(2);
while (c_bin.length < 6) c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= bits) {
var octet = buf.slice(0, bits);
buf = buf.slice(bits);
output += String.fromCharCode(parseInt(octet, 2));
}
}
return output;
}
module.exports = base64;

View file

@ -1,123 +0,0 @@
//Base64.js for hexstrbase64 library for browser
/*
* Copyright (c) 2012 Miles Shang <mail@mshang.ca>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Usage:
* Set your settings:
* base64.settings.char62 = "-";
* base64.settings.char63 = "_";
* etc.
*
* Then:
* base64.encode(str) takes a string and returns the base64 encoding of it.
* base64.decode(str) does the reverse.
*/
/* TODO:
* Add a "padding_mandatory" flag to check for bad padding in the decoder.
* Add test cases that throw errors.
*/
var base64 = new Object();
base64.settings = { // defaults
"char62" : "+",
"char63" : "/",
"pad" : "=",
"ascii" : false
};
/*
* Settings:
* If "pad" is not null or undefined, then it will be used for encoding.
*
* If "ascii" is set to true, then the encoder
* will assume that plaintext is in 8-bit chars (the standard).
* In this case, for every 3 chars in plaintext, you get 4 chars of base64.
* Any non-8-bit chars will cause an error.
* Otherwise, assume that all plaintext can be in the full range
* of Javascript chars, i.e. 16 bits. Get 8 chars of base64 for 3 chars
* of plaintext. Any possible JS string can be encoded.
*/
base64.encode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
for (var i = 0; i < str.length; ++i) {
var c_num = str.charCodeAt(i);
if (this.settings.ascii)
if (c_num >= 256)
throw "Not an 8-bit char.";
var c_bin = c_num.toString(2);
while (c_bin.length < (this.settings.ascii ? 8 : 16))
c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= 6) {
var sextet = buf.slice(0, 6);
buf = buf.slice(6);
output += this.char_set.charAt(parseInt(sextet, 2));
}
}
if (buf) { // not empty
while (buf.length < 6) buf += "0";
output += this.char_set.charAt(parseInt(buf, 2));
}
if (this.settings.pad)
while (output.length % (this.settings.ascii ? 4 : 8) != 0)
output += this.settings.pad;
return output;
}
base64.decode = function (str) {
this.char_set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ this.settings.char62 + this.settings.char63;
var output = ""; // final output
var buf = ""; // binary buffer
var bits = (this.settings.ascii ? 8 : 16);
for (var i = 0; i < str.length; ++i) {
if (str[i] == this.settings.pad) break;
var c_num = this.char_set.indexOf(str.charAt(i));
if (c_num == -1) throw "Not base64.";
var c_bin = c_num.toString(2);
while (c_bin.length < 6) c_bin = "0" + c_bin;
buf += c_bin;
while (buf.length >= bits) {
var octet = buf.slice(0, bits);
buf = buf.slice(bits);
output += String.fromCharCode(parseInt(octet, 2));
}
}
return output;
}

View file

@ -1,129 +0,0 @@
//Requires base64
var base64 = require('./base64.js');
var HexStrBase64Buffer = {
from: function(s, e) {
var type = e;
var value = '';
if (e == 'base64') {
value = base64.decode(s);
} else if (e == 'hex') {
try {
var escaped = "";
var hex = "";
if(s.length%4 > 0) {
for(i=0;i<(4-(s.length%4));i++) {
hex += "0";
}
}
hex += s;
for(var i = 0;i<hex.length;i += 4) {
escaped += new String("%u" + hex.charAt(i) + hex.charAt(i + 1) + hex.charAt(i + 2) + hex.charAt(i + 3)).toString().split("undefined").join("");
}
value = unescape(escaped).split(unescape("%00")).join("");
} catch (ex) {
var modex = ex.toString().split('Error: ');
modex[0] = '';
if (typeof modex == 'object') {
throw new Error(
'Invaild hex input: ' + s + '. Reason: ' + modex.join('')
);
} else {
throw new Error('Invaild hex input: ' + s + '. Reason: ' + ex);
}
}
} else {
value = Buffer.from(s, 'utf8').toString(e);
}
function toString(en) {
//function toStringE(en,type) {
if (en == 'base64') {
return base64.encode(value);
} else if (en == 'hex') {
var result = "";
for(var i=0;i<value.length;i++) {
var unicode = escape(value.charAt(i));
var hex = "";
if(value.charAt(i) == "\n") {
hex = "000a";
} else if(value.charAt(i) == "\r") {
hex = "000d";
} else if(value.charAt(i) == " ") {
hex = "0020";
} else if(value.charAt(i) == "\0") {
hex = "";
} else if(unicode == value.charAt(i)) {
var oldhex = value.charCodeAt(i).toString(16);
var newhex = "";
if(oldhex.length < 4) {
for(var j=0;j<4-(oldhex.length%4);j++) {
newhex += "0";
}
newhex += oldhex;
} else {
newhex = oldhex;
}
hex = newhex;
} else {
hex = unicode.split("%u").join("");
}
if(hex.length == 4 || hex === "") {
result += hex;
} else if(hex.length > 4) {
result += hex.substring(hex.length-5,hex.length-1);
} else if(hex.length < 4) {
for(var j=0;j<=4-(hex.length%4);j++) {
result += "0";
}
result += hex;
}
}
return result.split("undefined").join("").split("%").join("");
} else {
//return Buffer.from(value, type).toString(en);
return Buffer.from(value,"utf8").toString(en);
}
}
//}
//function toString(en) {
//return toStringE(en,type);
//}
return { type: type, value: value, toString: toString };
}
};
var hexstrbase64 = {
strtobase64: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('base64');
},
base64tostr: function(b) {
return HexStrBase64Buffer.from(b, 'base64').toString('utf8');
},
strtohex: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('hex');
},
hextostr: function(h) {
return HexStrBase64Buffer.from(h, 'hex').toString('utf8');
},
hextobase64: function(h) {
return hexstrbase64.strtobase64(hexstrbase64.hextostr(h));
},
base64tohex: function(b) {
return hexstrbase64.strtohex(hexstrbase64.base64tostr(b));
},
cipher: function() {
this.strtobase64 = hexstrbase64.strtobase64;
this.base64tostr = hexstrbase64.base64tostr;
this.strtohex = hexstrbase64.strtohex;
this.hextostr = hexstrbase64.hextostr;
this.hextobase64 = hextobase64.hextobase64;
this.base64tohex = hextobase64.base64tohex;
},
native: {
btoa: function(b) {
return hexstrbase64.strtobase64(b);
},
atob: function(a) {
return hexstrbase64.base64tostr(a);
}
}
};
module.exports = hexstrbase64;

View file

@ -1,126 +0,0 @@
//Requires base64_browser.js
var HexStrBase64Buffer = {
from: function(s, e) {
var type = e;
var value = '';
if (e == 'base64') {
value = base64.decode(s);
} else if (e == 'hex') {
try {
var escaped = "";
var hex = "";
if(s.length%4 > 0) {
for(i=0;i<(4-(s.length%4));i++) {
hex += "0";
}
}
hex += s;
for(var i = 0;i<hex.length;i += 4) {
escaped += new String("%u" + hex.charAt(i) + hex.charAt(i + 1) + hex.charAt(i + 2) + hex.charAt(i + 3)).toString().split("undefined").join("");
}
value = unescape(escaped).split(unescape("%00")).join("");
} catch (ex) {
var modex = ex.toString().split('Error: ');
modex[0] = '';
if (typeof modex == 'object') {
throw new Error(
'Invaild hex input: ' + s + '. Reason: ' + modex.join('')
);
} else {
throw new Error('Invaild hex input: ' + s + '. Reason: ' + ex);
}
}
} else {
value = new TextDecoder(e).decode(new TextEncoder('utf8').encode(s));
}
//function toStringE(en,type) {
function toString(en) {
if (en == 'base64') {
return base64.encode(value);
} else if (en == 'hex') {
var result = "";
for(var i=0;i<value.length;i++) {
var unicode = escape(value.charAt(i));
var hex = "";
if(value.charAt(i) == "\n") {
hex = "000a";
} else if(value.charAt(i) == "\r") {
hex = "000d";
} else if(value.charAt(i) == " ") {
hex = "0020";
} else if(value.charAt(i) == "\0") {
hex = "";
} else if(unicode == value.charAt(i)) {
var oldhex = value.charCodeAt(i).toString(16);
var newhex = "";
if(oldhex.length < 4) {
for(var j=0;j<4-(oldhex.length%4);j++) {
newhex += "0";
}
newhex += oldhex;
} else {
newhex = oldhex;
}
hex = newhex;
} else {
hex = unicode.split("%u").join("");
}
if(hex.length == 4 || hex === "") {
result += hex;
} else if(hex.length > 4) {
result += hex.substring(hex.length-5,hex.length-1);
} else if(hex.length < 4) {
for(var j=0;j<=4-(hex.length%4);j++) {
result += "0";
}
result += hex;
}
}
return result.split("undefined").join("").split("%").join("");
} else {
//return new TextDecoder(en).decode(new TextEncoder(type).encode(value));
return new TextDecoder(en).decode(new TextEncoder("utf8").encode(value));
}
}
//function toString(en) {
//return toStringE(en,type);
//}
return { type: type, value: value, toString: toString };
}
};
var hexstrbase64 = {
strtobase64: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('base64');
},
base64tostr: function(b) {
return HexStrBase64Buffer.from(b, 'base64').toString('utf8');
},
strtohex: function(s) {
return HexStrBase64Buffer.from(s, 'utf8').toString('hex');
},
hextostr: function(h) {
return HexStrBase64Buffer.from(h, 'hex').toString('utf8');
},
hextobase64: function(h) {
return hexstrbase64.strtobase64(hexstrbase64.hextostr(h));
},
base64tohex: function(b) {
return hexstrbase64.strtohex(hexstrbase64.base64tostr(b));
},
cipher: function() {
this.strtobase64 = hexstrbase64.strtobase64;
this.base64tostr = hexstrbase64.base64tostr;
this.strtohex = hexstrbase64.strtohex;
this.hextostr = hexstrbase64.hextostr;
this.hextobase64 = hextobase64.hextobase64;
this.base64tohex = hextobase64.base64tohex;
},
native: {
btoa: function(b) {
return hexstrbase64.strtobase64(b);
},
atob: function(a) {
return hexstrbase64.base64tostr(a);
}
}
};

View file

@ -1,11 +0,0 @@
let hexstrbase64 = require("./hexstrbase64/main.js");
function decodeBase(b) {
return hexstrbase64.native.atob(b);
}
function encodeStr(s) {
return hexstrbase64.native.btoa(s);
}
var m = Object.create(hexstrbase64);
m.decodeBase = decodeBase;
m.encodeBase = encodeStr;
module.exports = m;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

View file

@ -1,8 +0,0 @@
.code {
border-width: 5px;
border-color: #BEBEBE;
border-style: solid;
color:black;
background-color: #7F7F7F;
font-family: Hack,Consolas,Monaco,monospace;
}

View file

@ -1,31 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>HexStrBase64 Readme</title>
<link rel="stylesheet" href="readme.css">
</head>
<body>
<h1>hexstrbase64</h1>
<h2>How to install?</h2>
<h3>Node.js</h3>
<ol>
<li>Download library from <a href="https://repl.it/@DorianNiemiec/Hex-String-Base64-NodeJS-Library.zip" download>here</a>.</li>
<li>Modify index.js</li>
<li>Write header in program (replace <b>./hexstrbase64</b> with your path to hexstrbase64 library):</li>
<div class="code">
var hexstrbase64 = require("<b>./hexstrbase64</b>/index.js");<br/>
</div>
<li>Now hexstrbase64 library added to program!</li>
</ol>
<h3>Browser Javascript</h3>
<ol>
<li>Download library from <a href="https://repl.it/@DorianNiemiec/Hex-String-Base64-NodeJS-Library.zip" download>here</a>.</li>
<li>Write this code in &lt;head&gt; element (replace <b>hexstrbase64/</b> with your path to hexstrbase64 library):</li>
<div class="code">
&lt;script src="<b>hexstrbase64/</b>hexstrbase64/base64_browser.js"&gt;&lt;/script&gt;<br/>
&lt;script src="<b>hexstrbase64/</b>hexstrbase64/main_browser.js"&gt;&lt;/script&gt;
</div>
<li>Now hexstrbase64 library added to HTML!</li>
</ol>
</body>
</html>

View file

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hexstrbase64 base64 test</title>
<script src="../hexstrbase64/base64_browser.js"></script>
<script src="../hexstrbase64/main_browser.js"></script>
<script src="base64.js"></script>
<script>
testStart();
</script>
</head>
</html>

View file

@ -1,56 +0,0 @@
function nameObj(n, v) {
return {name:n, value:v};
}
function testStart() {
document.write('<meta charset="UTF-8">');
document.write('<title>hexstrbase64 base64 test</title>');
console.log("TESTING STARTED");
for (var i = 0; i < 3; i++) {
document.write('<h1>' + enccases[i].name + '</h1>');
console.log("SWITCH " + enccases[i].name);
for (var j = 0; j < 2; j++) {
document.write('<h2>' + enccases[i].value[j].name + '</h2>');
console.log("CASE " + enccases[i].value[j].name);
console.log("MUST BE: " + enccases[i].value[j].value);
console.log("IS : " + hexstrbase64.strtobase64(enccases[i].value[j].name));
if (hexstrbase64.strtobase64(enccases[i].value[j].name) == enccases[i].value[j].value) {
document.write('<p><img src="../ok.png"></img>Equals</p>');
console.log("EQUALS");
} else {
document.write('<p><img src="../fail.png"></img>Not Equals</p>');
console.log("NOT EQUALS");
}
console.log("CASE " + enccases[i].value[j].name + " ENDED");
}
console.log("SWITCH " + enccases[i].name + " ENDED");
}
console.log("TESTING ENDED");
}
var enccases = [
nameObj('Ascii', [
nameObj('Hello world!', 'AEgAZQBsAGwAbwAgAHcAbwByAGwAZAAh'),
nameObj('Lorem ipsum', 'AEwAbwByAGUAbQAgAGkAcABzAHUAbQ==')
]),
nameObj('Ascii More Than 64 Bytes', [
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum fermentum ac nisl a sollicitudin. Cras interdum dui turpis, non scelerisque.',
'AEwAbwByAGUAbQAgAGkAcABzAHUAbQAgAGQAbwBsAG8AcgAgAHMAaQB0ACAAYQBtAGUAdAAsACAAYwBvAG4AcwBlAGMAdABlAHQAdQByACAAYQBkAGkAcABpAHMAYwBpAG4AZwAgAGUAbABpAHQALgAgAFYAZQBzAHQAaQBiAHUAbAB1AG0AIABmAGUAcgBtAGUAbgB0AHUAbQAgAGEAYwAgAG4AaQBzAGwAIABhACAAcwBvAGwAbABpAGMAaQB0AHUAZABpAG4ALgAgAEMAcgBhAHMAIABpAG4AdABlAHIAZAB1AG0AIABkAHUAaQAgAHQAdQByAHAAaQBzACwAIABuAG8AbgAgAHMAYwBlAGwAZQByAGkAcwBxAHUAZQAu'
),
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dapibus volutpat ligula at pulvinar. Etiam consequat mi fringilla facilisis eleifend.',
'AEwAbwByAGUAbQAgAGkAcABzAHUAbQAgAGQAbwBsAG8AcgAgAHMAaQB0ACAAYQBtAGUAdAAsACAAYwBvAG4AcwBlAGMAdABlAHQAdQByACAAYQBkAGkAcABpAHMAYwBpAG4AZwAgAGUAbABpAHQALgAgAFAAaABhAHMAZQBsAGwAdQBzACAAZABhAHAAaQBiAHUAcwAgAHYAbwBsAHUAdABwAGEAdAAgAGwAaQBnAHUAbABhACAAYQB0ACAAcAB1AGwAdgBpAG4AYQByAC4AIABFAHQAaQBhAG0AIABjAG8AbgBzAGUAcQB1AGEAdAAgAG0AaQAgAGYAcgBpAG4AZwBpAGwAbABhACAAZgBhAGMAaQBsAGkAcwBpAHMAIABlAGwAZQBpAGYAZQBuAGQALg=='
)
]),
nameObj('Unicode UTF8', [
nameObj(
'DorianTech Hex String Base64转换器',
'AEQAbwByAGkAYQBuAFQAZQBjAGgAIABIAGUAeAAgAFMAdAByAGkAbgBnACAAQgBhAHMAZQA2ADSPbGNiVmg====='
),
nameObj(
'DorianTech Hex String Base64转换器用于由DorianTech提供的Node.js',
'AEQAbwByAGkAYQBuAFQAZQBjAGgAIABIAGUAeAAgAFMAdAByAGkAbgBnACAAQgBhAHMAZQA2ADSPbGNiVmj/DHUoTo51MQBEAG8AcgBpAGEAbgBUAGUAYwBoY9BPm3aEAE4AbwBkAGUALgBqAHM====='
)
])
];

View file

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hexstrbase64 hex test</title>
<script src="../hexstrbase64/base64_browser.js"></script>
<script src="../hexstrbase64/main_browser.js"></script>
<script src="hex.js"></script>
<script>
testStart();
</script>
</head>
</html>

View file

@ -1,56 +0,0 @@
function nameObj(n, v) {
return {name:n, value:v};
}
function testStart() {
document.write('<meta charset="UTF-8">');
document.write('<title>hexstrbase64 hex test</title>');
console.log("TESTING STARTED");
for (var i = 0; i < 3; i++) {
document.write('<h1>' + enccases[i].name + '</h1>');
console.log("SWITCH " + enccases[i].name);
for (var j = 0; j < 2; j++) {
document.write('<h2>' + enccases[i].value[j].name + '</h2>');
console.log("CASE " + enccases[i].value[j].name);
console.log("MUST BE: " + enccases[i].value[j].value);
console.log("IS : " + hexstrbase64.strtohex(enccases[i].value[j].name));
if (hexstrbase64.strtohex(enccases[i].value[j].name) == enccases[i].value[j].value) {
document.write('<p><img src="../ok.png"></img>Equals</p>');
console.log("EQUALS");
} else {
document.write('<p><img src="../fail.png"></img>Not Equals</p>');
console.log("NOT EQUALS");
}
console.log("CASE " + enccases[i].value[j].name + " ENDED");
}
console.log("SWITCH " + enccases[i].name + " ENDED");
}
console.log("TESTING ENDED");
}
var enccases = [
nameObj('Ascii', [
nameObj('Hello world!', '00480065006c006c006f00200077006f0072006c00640021'),
nameObj('Lorem ipsum', '004c006f00720065006d00200069007000730075006d')
]),
nameObj('Ascii More Than 64 Bytes', [
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum fermentum ac nisl a sollicitudin. Cras interdum dui turpis, non scelerisque.',
'004c006f00720065006d00200069007000730075006d00200064006f006c006f0072002000730069007400200061006d00650074002C00200063006f006e00730065006300740065007400750072002000610064006900700069007300630069006e006700200065006c00690074002e00200056006500730074006900620075006c0075006d0020006600650072006d0065006e00740075006d0020006100630020006e00690073006c0020006100200073006f006c006c0069006300690074007500640069006e002e0020004300720061007300200069006e00740065007200640075006d00200064007500690020007400750072007000690073002C0020006e006f006e0020007300630065006c0065007200690073007100750065002e'
),
nameObj(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dapibus volutpat ligula at pulvinar. Etiam consequat mi fringilla facilisis eleifend.',
'004c006f00720065006d00200069007000730075006d00200064006f006c006f0072002000730069007400200061006d00650074002C00200063006f006e00730065006300740065007400750072002000610064006900700069007300630069006e006700200065006c00690074002e002000500068006100730065006c006c007500730020006400610070006900620075007300200076006f006c007500740070006100740020006c006900670075006c0061002000610074002000700075006c00760069006e00610072002e00200045007400690061006d00200063006f006e0073006500710075006100740020006d00690020006600720069006e00670069006c006c006100200066006100630069006c006900730069007300200065006c0065006900660065006e0064002e'
)
]),
nameObj('Unicode UTF8', [
nameObj(
'DorianTech Hex String Base64转换器',
'0044006f007200690061006e0054006500630068002000480065007800200053007400720069006e006700200042006100730065003600348F6C63625668'
),
nameObj(
'DorianTech Hex String Base64转换器用于由DorianTech提供的Node.js',
'0044006f007200690061006e0054006500630068002000480065007800200053007400720069006e006700200042006100730065003600348F6C63625668FF0C75284E8E75310044006f007200690061006e005400650063006863D04F9B7684004e006f00640065002e006a0073'
)
])
];

View file

@ -1,16 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>hexstrbase64 test</title>
<style>
iframe {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<iframe src="base64.html"></iframe>
<iframe src="hex.html"></iframe>
</body>
</html>

Binary file not shown.

View file

@ -1,21 +0,0 @@
Copyright 20092014 Contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View file

View file

@ -1,19 +0,0 @@
Copyright (c) 2010-2014 Caolan McMahon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,19 +0,0 @@
Copyright Fedor Indutny, 2015.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Some files were not shown because too many files have changed in this diff Show more