Compare commits
54 commits
Author | SHA1 | Date | |
---|---|---|---|
317acff5d6 | |||
f4fc6ba165 | |||
3bf8ff799e | |||
9e227bbec6 | |||
27c613f28e | |||
215f1fae25 | |||
d44ee67e57 | |||
effc654f05 | |||
997b03c2a2 | |||
45d8b9bcd3 | |||
78e7c8c967 | |||
25280b310c | |||
73b062d306 | |||
2ae73966ec | |||
5e031fe997 | |||
1c6e707f58 | |||
4a1a59f15d | |||
67680fc97f | |||
40f100db94 | |||
7d144c95b6 | |||
3b25b33583 | |||
c70e078b26 | |||
3abc31e2aa | |||
0161b04e1f | |||
d7b0fc463e | |||
3d411c3be1 | |||
9c49df9d87 | |||
06712f35b5 | |||
91f2d3b50f | |||
688c850c50 | |||
26214c9eb8 | |||
4928ac1d2c | |||
27e62da887 | |||
d25f912c06 | |||
19f7345762 | |||
a63e1a893b | |||
a755e32bc7 | |||
c380c469ef | |||
faecaa8b8a | |||
ae3cf033be | |||
9fa9c047d1 | |||
faa043cb99 | |||
7587932250 | |||
9406ffda5f | |||
10ee128136 | |||
|
91d8d0df63 | ||
71b5727b6c | |||
c6960061b7 | |||
55262f73c5 | |||
750a312b2f | |||
e0f0cb69d8 | |||
d01064cc17 | |||
c9df74c745 | |||
46a256d31f |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 7.1 KiB |
19
.github/workflows/main.yml
vendored
Normal 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
|
@ -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
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
npx --no -- commitlint --edit "$1"
|
2
.husky/pre-commit
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
npx lint-staged
|
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
149
README.md
Normal 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 distribution’s 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.
|
BIN
assets/.dirimages/archive.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
assets/.dirimages/audio.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 5.9 KiB |
BIN
assets/.dirimages/css.png
Normal file
After Width: | Height: | Size: 8 KiB |
BIN
assets/.dirimages/directory.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
assets/.dirimages/diskimage.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
assets/.dirimages/fifo.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
assets/.dirimages/font.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
assets/.dirimages/html.png
Normal file
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.6 KiB |
BIN
assets/.dirimages/image.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.3 KiB |
BIN
assets/.dirimages/javascript.png
Normal file
After Width: | Height: | Size: 7 KiB |
BIN
assets/.dirimages/other.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
assets/.dirimages/php.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/.dirimages/return.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
assets/.dirimages/socket.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
assets/.dirimages/text.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
assets/.dirimages/video.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
63
assets/config.json
Normal 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
After Width: | Height: | Size: 15 KiB |
BIN
assets/logo.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
assets/powered.png
Normal file
After Width: | Height: | Size: 19 KiB |
|
@ -9,18 +9,19 @@
|
||||||
// ext - File extension of requested file
|
// ext - File extension of requested file
|
||||||
// uobject - Request URL object
|
// uobject - Request URL object
|
||||||
// search - Request URL queries
|
// 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)
|
// users - A list of users (deprecated)
|
||||||
// page404 - 404 Not Found page location
|
// page404 - 404 Not Found page location
|
||||||
// head - A head of server response
|
// head - A head of server response
|
||||||
// foot - A foot 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
|
// elseCallback - Method summoning SVR.JS internal callbacks
|
||||||
// callServerError - Method to end with server error
|
// callServerError - Method to end with server error
|
||||||
// getCustomHeaders - Method to get headers defined in config.json file
|
// getCustomHeaders - Method to get headers defined in config.json file
|
||||||
// origHref - Original request URL without query (before URL rewriting)
|
// origHref - Original request URL without query (before URL rewriting)
|
||||||
// redirect - Method to redirect.
|
// redirect - Method to redirect.
|
||||||
// parsePostData - Method to parse POST data.
|
// parsePostData - Method to parse POST data.
|
||||||
|
// authUser - Authenticated HTTP user.
|
||||||
//Along with elements added by this implementation:
|
//Along with elements added by this implementation:
|
||||||
// disableEndElseCallbackExecute - Determines execution of elseCallback on end
|
// disableEndElseCallbackExecute - Determines execution of elseCallback on end
|
||||||
// filterHeaders - Removes invalid HTTP/1.0 headers
|
// filterHeaders - Removes invalid HTTP/1.0 headers
|
||||||
|
@ -62,13 +63,20 @@ if(href == "/hello.svr") {
|
||||||
callServerError(403,"SVR.JS-exampleproxy"); //Server error
|
callServerError(403,"SVR.JS-exampleproxy"); //Server error
|
||||||
serverconsole.errmessage("Client fails to recieve content."); //Log into SVR.JS
|
serverconsole.errmessage("Client fails to recieve content."); //Log into SVR.JS
|
||||||
} else if(href.indexOf("/proxy.svr/") == 0) {
|
} 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;
|
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);
|
hdrs["Origin"] = (req.headers.host == undefined ? "" : req.headers.host);
|
||||||
var options = {
|
var options = {
|
||||||
hostname: (href.split("/")[2] == "this" ? req.headers.host.split(":")[0] : href.split("/")[2].split(":")[0]),
|
hostname: (hn == "this" ? req.headers.host.split(":")[0] : hn.split(":")[0]),
|
||||||
port: (href.split("/")[2] == "this" ? req.headers.host.split(":")[1] : (href.split("/")[2].split(":")[1] == undefined ? 80 : href.split("/")[2].split(":")[1])),
|
port: (hn == "this" ? req.headers.host.split(":")[1] : (hn.split(":")[1] == undefined ? 80 : hn.split(":")[1])),
|
||||||
path: req.url.replace("/proxy.svr/" + href.split("/")[2],""),
|
path: req.url.replace("/proxy.svr/" + hn,""),
|
||||||
method: req.method,
|
method: req.method,
|
||||||
headers: filterHeaders(hdrs)
|
headers: filterHeaders(hdrs)
|
||||||
};
|
};
|
|
@ -1,6 +1,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
Copyright © 2020 DorianTech S.A.
|
Copyright © 2020-2024 SVR.JS
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,6 +1,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
Copyright © 2020 DorianTech S.A.
|
Copyright © 2020-2024 SVR.JS
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
3
commitlint.config.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: ["@commitlint/config-conventional"]
|
||||||
|
};
|
86
config.json
|
@ -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
|
@ -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
|
@ -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
|
||||||
|
];
|
BIN
favicon.ico
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 243 B |
|
@ -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;
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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;
|
|
Before Width: | Height: | Size: 252 B |
|
@ -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;
|
|
||||||
}
|
|
|
@ -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 <head> element (replace <b>hexstrbase64/</b> with your path to hexstrbase64 library):</li>
|
|
||||||
<div class="code">
|
|
||||||
<script src="<b>hexstrbase64/</b>hexstrbase64/base64_browser.js"></script><br/>
|
|
||||||
<script src="<b>hexstrbase64/</b>hexstrbase64/main_browser.js"></script>
|
|
||||||
</div>
|
|
||||||
<li>Now hexstrbase64 library added to HTML!</li>
|
|
||||||
</ol>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -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>
|
|
|
@ -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====='
|
|
||||||
)
|
|
||||||
])
|
|
||||||
];
|
|
|
@ -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>
|
|
|
@ -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'
|
|
||||||
)
|
|
||||||
])
|
|
||||||
];
|
|
|
@ -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>
|
|
|
@ -1 +0,0 @@
|
||||||
0
|
|
129
index.html
|
@ -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/>
|
|
||||||
"users": [],<br/>
|
|
||||||
"port": 80,<br/>
|
|
||||||
"pubport": 80,<br/>
|
|
||||||
"page404": "404.html",<br/>
|
|
||||||
"timestamp": 1680954429282,<br/>
|
|
||||||
"blacklist": [],<br/>
|
|
||||||
"nonStandardCodes": [],<br/>
|
|
||||||
"enableCompression": true,<br/>
|
|
||||||
"customHeaders": {},<br/>
|
|
||||||
"enableHTTP2": false,<br/>
|
|
||||||
"enableLogging": true,<br/>
|
|
||||||
"enableDirectoryListing": true,<br/>
|
|
||||||
"enableDirectoryListingWithDefaultHead": false,<br/>
|
|
||||||
"serverAdministratorEmail": "[no contact information]",<br/>
|
|
||||||
"stackHidden": false,<br/>
|
|
||||||
"enableRemoteLogBrowsing": true,<br/>
|
|
||||||
"exposeServerVersion": true,<br/>
|
|
||||||
"disableServerSideScriptExpose": false,<br/>
|
|
||||||
"rewriteMap": [<br/>
|
|
||||||
{<br/>
|
|
||||||
"definingRegex": "/\\/invoke500\\/\\?/",<br/>
|
|
||||||
"replacements": dorians[<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/\\/invoke500\\/\\?/",<br/>
|
|
||||||
"replacement": "/invoke500.svr?"<br/>
|
|
||||||
}<br/>
|
|
||||||
]<br/>
|
|
||||||
},<br/>
|
|
||||||
{<br/>
|
|
||||||
"definingRegex": "/\\/invoke500\\/.+\\//",<br/>
|
|
||||||
"replacements": [<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/\\/\\?/",<br/>
|
|
||||||
"replacement": "&"<br/>
|
|
||||||
},<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/invoke500\\//",<br/>
|
|
||||||
"replacement": "invoke500.svr?"<br/>
|
|
||||||
},<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/\\/(?!invoke500.svr?)/",<br/>
|
|
||||||
"replacement": ""<br/>
|
|
||||||
}<br/>
|
|
||||||
]<br/>
|
|
||||||
},<br/>3.4.13
|
|
||||||
{<br/>
|
|
||||||
"definingRegex": "/\\/invoke500\\/.+/",<br/>
|
|
||||||
"replacements": [<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/\\?/",<br/>
|
|
||||||
"replacement": "&"<br/>
|
|
||||||
},<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/invoke500\\//",<br/>
|
|
||||||
"replacement": "invoke500.svr?"<br/>
|
|
||||||
}<br/>
|
|
||||||
]<br/>
|
|
||||||
},<br/>
|
|
||||||
{<br/>
|
|
||||||
"definingRegex": "/\\/invoke500\\//",<br/>
|
|
||||||
"replacements": [<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/\\/invoke500\\//",<br/>
|
|
||||||
"replacement": "/invoke500.svr"<br/>
|
|
||||||
}<br/>
|
|
||||||
]<br/>
|
|
||||||
},<br/>
|
|
||||||
{<br/>
|
|
||||||
"definingRegex": "/\\/invoke500$/",<br/>
|
|
||||||
"replacements": [<br/>
|
|
||||||
{<br/>
|
|
||||||
"regex": "/\\/invoke500/",<br/>
|
|
||||||
"replacement": "/invoke500.svr"<br/>
|
|
||||||
}<br/>
|
|
||||||
]<br/>
|
|
||||||
}<br/>
|
|
||||||
],<br/>
|
|
||||||
"allowStatus": true,<br/>
|
|
||||||
"dontCompress": ["/.*\\.ipxe$/","/.*\\.img$/","/.*\\.iso$/"],<br/>
|
|
||||||
"enableIPSpoofing": false,<br/>
|
|
||||||
"secure": false,<br/>
|
|
||||||
"sni": {},<br/>
|
|
||||||
"disableNonEncryptedServer": false,<br/>
|
|
||||||
"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
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
testEnvironment: 'node',
|
||||||
|
testMatch: ['**/tests/**/*.test.js'],
|
||||||
|
verbose: true,
|
||||||
|
};
|
Before Width: | Height: | Size: 243 B |
|
@ -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;
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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;
|
|
Before Width: | Height: | Size: 252 B |
|
@ -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;
|
|
||||||
}
|
|
|
@ -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 <head> element (replace <b>hexstrbase64/</b> with your path to hexstrbase64 library):</li>
|
|
||||||
<div class="code">
|
|
||||||
<script src="<b>hexstrbase64/</b>hexstrbase64/base64_browser.js"></script><br/>
|
|
||||||
<script src="<b>hexstrbase64/</b>hexstrbase64/main_browser.js"></script>
|
|
||||||
</div>
|
|
||||||
<li>Now hexstrbase64 library added to HTML!</li>
|
|
||||||
</ol>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -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>
|
|
|
@ -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====='
|
|
||||||
)
|
|
||||||
])
|
|
||||||
];
|
|
|
@ -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>
|
|
|
@ -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'
|
|
||||||
)
|
|
||||||
])
|
|
||||||
];
|
|
|
@ -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>
|
|
|
@ -1,21 +0,0 @@
|
||||||
|
|
||||||
Copyright 2009–2014 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.
|
|
||||||
|
|
|
@ -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.
|
|
|
@ -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.
|
|