Created
February 15, 2026 19:15
-
-
Save prettydiff/e796ec6c86ce1611110386156fcc323b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {"data":{"algorithm":"sha3-512","base64":false,"digest":"hex","size":0,"time":null,"type":"direct","value":"\n<!doctype html>\n<html lang=\"en\">\n <!-- cspell: words buildx, containerd, dpkg, endianness, EPROTO, healthcheck, internetwork, IRSSI, keyrings, jellyfin, journalctl, kurkle, libcap, NAPTR, PGID, POSIX, ppid, prettydiff, proxied, PUID, setgid, setuid, TLSA, uptimeimages, winget -->\n<head>\n<meta charset=\"utf-8\"/>\n<title>Server Management Dashboard</title>\n<meta content=\"text/html;charset=UTF-8\" http-equiv=\"Content-Type\"/>\n<meta content=\"width=device-width, initial-scale=1\" name=\"viewport\"/>\n<meta content=\"noindex, nofollow\" name=\"robots\"/>\n<meta content=\"#fff\" name=\"theme-color\"/>\n<meta content=\"Global\" name=\"distribution\"/>\n<meta content=\"en\" http-equiv=\"Content-Language\"/>\n<meta content=\"blendTrans(Duration=0)\" http-equiv=\"Page-Enter\"/>\n<meta content=\"blendTrans(Duration=0)\" http-equiv=\"Page-Exit\"/>\n<meta content=\"text/css\" http-equiv=\"content-style-type\"/>\n<meta content=\"application/javascript\" http-equiv=\"content-script-type\"/>\n<meta content=\"#bbbbff\" name=\"msapplication-TileColor\"/>\n<style type=\"text/css\"></style>\n<link rel=\"icon\" type=\"image/png\" href=\"data:image/png;base64,iVBORw0KGgo=\"/>\n</head>\n<body id=\"dashboard\">\n <div class=\"title\">\n <h1>Server Management Dashboard</h1>\n <p><span>Page Load Time:</span><time>0.00000 seconds</time></p>\n <p id=\"clock\"><span>Server Time:</span><time>00:00:00L (00:00:00Z)</time></p>\n </div>\n <p id=\"connection-status\" class=\"connection-offline\">Dashboard Connection: <strong>Offline</strong></p>\n <nav>\n <h2>Navigation</h2>\n <div class=\"first\">\n <h3>Services</h3>\n <ul>\n <li><button class=\"nav-focus\" data-section=\"servers-web\">Web Servers</button></li>\n <li><button data-section=\"compose-containers\">Docker Compose</button></li>\n <li><button data-section=\"udp-socket\">UDP Socket</button></li>\n <li><button data-section=\"statistics\">Statistics</button></li>\n </ul>\n </div>\n <div>\n <h3>Network</h3>\n <ul>\n <li><button data-section=\"interfaces\">Interfaces</button></li>\n <li><button data-section=\"ports-application\">App Ports</button></li>\n <li><button data-section=\"sockets-application-tcp\">App TCP Sockets</button></li>\n <li><button data-section=\"sockets-application-udp\">App UDP Sockets</button></li>\n <li><button data-section=\"sockets-os-tcp\">OS TCP Sockets</button></li>\n <li><button data-section=\"sockets-os-udp\">OS UDP Sockets</button></li>\n </ul>\n </div>\n <div>\n <h3>System</h3>\n <ul>\n <li><button data-section=\"os-machine\">OS/Machine</button></li>\n <li><button data-section=\"devices\">Devices</button></li>\n <li><button data-section=\"disks\">Disks</button></li>\n <li><button data-section=\"processes\">Processes</button></li>\n <li><button data-section=\"services\">Services</button></li>\n <li><button data-section=\"users\">Users</button></li>\n </ul>\n </div>\n <div>\n <h3>Tools</h3>\n <ul>\n <li><button data-section=\"terminal\">Terminal</button></li>\n <li><button data-section=\"file-system\">File System</button></li>\n <li><button data-section=\"dns-query\">DNS Query</button></li>\n <li><button data-section=\"hash\">Hash / Base64</button></li>\n </ul>\n </div>\n <div>\n <h3>Network Tests</h3>\n <ul>\n <li><button data-section=\"test-http\">HTTP Test</button></li>\n <li><button data-section=\"test-websocket\">WebSocket Test</button></li>\n </ul>\n </div>\n <div>\n <h3>Informational</h3>\n <ul>\n <li><button data-section=\"application-logs\">Application Logs</button></li>\n <li><button data-section=\"faq\">FAQ</button></li>\n <li><button data-section=\"help\">Help</button></li>\n </ul>\n </div>\n <span class=\"clear\"></span>\n </nav>\n <main>\n <!-- application-logs start -->\n <div class=\"tab\" id=\"application-logs\">\n <h2>Application Logs</h2>\n <p class=\"tab-description\">At this time logs are not saved outside the application, but do persist for the life of the application runtime.</p>\n <ul></ul>\n </div>\n <!-- application-logs end -->\n <!-- compose-containers start -->\n <div class=\"tab\" id=\"compose-containers\">\n <h2>Docker Compose</h2>\n <p class=\"tab-description\">All containers run under the Docker daemon detached from this application.</p>\n <p class=\"status\"></p>\n <div class=\"compose-body\">\n <div class=\"section\">\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Containers</span> <em></em></p>\n <p><span>Total Variables</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n </div>\n <div class=\"section\">\n <h3>Environmental Variables</h3>\n <p class=\"buttons\"><button class=\"compose-variable-new\">Edit Variables</button></p>\n <ul class=\"compose-variable-list\"></ul>\n </div>\n <div class=\"section\">\n <h3>Status</h3>\n <p class=\"dimensions\">Columns: <em>0</em>, Rows: <em>0</em></p>\n <div class=\"terminal-output\"></div>\n </div>\n <div class=\"section\">\n <h3>Containers</h3>\n <p class=\"buttons\"><button class=\"compose-container-new\">New Container</button></p>\n <ul class=\"compose-container-list\"></ul>\n </div>\n </div>\n </div>\n <!-- compose-containers end -->\n <!-- devices start -->\n <div class=\"tab\" id=\"devices\">\n <h2>Devices</h2>\n <p class=\"tab-description\">A list of hardware devices registered with the OS kernel.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>Device List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Devices</span> <em></em></p>\n <p><span>Filtered Devices</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Name</button></th>\n <th><button data-dir=\"1\">Type</button></th>\n <th><button data-dir=\"1\">Kernel Module</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- devices end -->\n <!-- disks start -->\n <div class=\"tab\" id=\"disks\">\n <h2>Storage Devices</h2>\n <p class=\"tab-description\">A list of storage devices and their partitions. Data automatically refreshes at server's midnight time.</p>\n <div class=\"section\">\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Drives</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <div class=\"item-list\"></div>\n </div>\n </div>\n <!-- disks end -->\n <!-- dns-query start -->\n <div class=\"tab\" id=\"dns-query\">\n <h2>DNS Query</h2>\n <p class=\"tab-description\">Test DNS name resolution from the application's location.</p>\n <div class=\"definitions\">\n <h3>DNS Type Definitions <button class=\"expand\">Expand</button></h3>\n <dl class=\"definition-body\">\n <dt>A</dt>\n <dd>IPv4 addresses</dd>\n <dt>AAAA</dt>\n <dd>IPv6 addresses</dd>\n <dt>CAA</dt>\n <dd>certificate authority authorization records</dd>\n <dt>CNAME</dt>\n <dd>canonical name records</dd>\n <dt>MX</dt>\n <dd>mail exchange records</dd>\n <dt>NAPTR</dt>\n <dd>name authority pointer records</dd>\n <dt>NS</dt>\n <dd>name server records</dd>\n <dt>PTR</dt>\n <dd>pointer records</dd>\n <dt>SOA</dt>\n <dd>start of authority records</dd>\n <dt>SRV</dt>\n <dd>service records</dd>\n <dt>TLSA</dt>\n <dd>certificate associations</dd>\n <dt>TXT</dt>\n <dd>text records</dd>\n </dl>\n </div>\n <div class=\"section\">\n <h3>Input</h3>\n <h4>Query Direction</h4>\n <p><label class=\"radio\">DNS Name Resolve <input checked=\"checked\" name=\"dns_direction\" type=\"radio\" value=\"resolve\"/></label> <label class=\"radio\">Reverse DNS Lookup <input checked=\"checked\" name=\"dns_direction\" type=\"radio\" value=\"reverse\"/></label></p>\n <p><label>Comma separated list of domains and/or hostname entries <input type=\"text\"/></label></p>\n <p><label>Comma separated list of record types. Leave blank for all types. Supported types: A, AAAA, CAA, CNAME, MX, NAPTR, NS, PTR, SOA, SRV, TLSA, TXT <input type=\"text\"/></label></p>\n <p class=\"buttons\"><button>Execute Query</button></p>\n </div>\n <div class=\"section\">\n <h3>Output</h3>\n <p><label>List of DNS resolutions in beautified JSON format <textarea readonly=\"readonly\" spellcheck=\"false\"></textarea></label></p>\n </div>\n </div>\n <!-- dns-query end -->\n <!-- faq start -->\n <div class=\"tab\" id=\"faq\">\n <h2>Frequently Asked Questions</h2>\n <p class=\"tab-description\">Please review these items to help troubleshoot common problems.</p>\n <div class=\"section\">\n <h3>Web Servers</h3>\n <div class=\"section\">\n <h4>The dashboard fails to connect to the terminal, cannot be refreshed, and eventually crashes.</h4>\n <p>\n These are the symptoms of a corrupted network buffer in the operating system kernel.\n Under these conditions some minor network calls, like an HTTP call to a web page or CSS file will succeed soon after web server launch but everything after fails to connect.\n The solution is to reboot the computer.\n </p>\n </div>\n <div class=\"section\">\n <h4>On Windows I can create servers using ports 80 and 443, but it keeps resulting in an error on Linux.</h4>\n <p>\n Linux, by policy, restricts normal users from running services on ports below 1025.\n This can be circumvented by running this application with elevated privilege, as an OS service, or using the package <a href=\"https://archlinux.org/packages/core/x86_64/libcap/\">libcap</a>.\n My preference is to run the application as an OS service using systemd.\n </p>\n </div>\n <div class=\"section\">\n <h4>I created a redirect_asset rule for an absolute path, but it doesn't work.</h4>\n <p>\n For security reasons server paths are absolute to the server's asset location on the machine file system and not the root of the file system.\n If redirection should occur for assets outside the server's asset tree I recommend creating a symbolic link in the server's asset location.\n In Linux this is accomplished with <code>ln -s /desired/path link_name</code> where the first path is where the files actually are and the second is where the link will be in the file system.\n </p>\n </div>\n <div class=\"section\">\n <h4>I am trying to redirect traffic to a vanity domain from one server spawned by this application to another server spawned by this application, but it isn't working.</h4>\n <p>\n The destination server must have the vanity domain listed in its <em>domain_local</em> list.\n For increased security servers will only accept connections to known addresses, which includes IP address and wildcards already supported on local machine interfaces.\n </p>\n </div>\n <div class=\"section\">\n <h4>How can I ensure an end-to-end encrypted tunnel between my users and a proxied destination?</h4>\n <p>\n First, verify the given server is set to <em>encryption</em> values <strong>both</strong> or <strong>secure</strong>.\n If the given server does not have a secure TLS instance running it will not be able to proxy to an encrypted TLS destination.\n </p>\n <p>\n Second, ensure there is a <em>redirect_domain</em> entry for the given server named with a <strong>.secure</strong> suffix, such as my-bank.com.secure as opposed to just my-bank.com.\n That tells this application to only proxy via TLS on incoming TLS connections.\n </p>\n </div>\n <div class=\"section\">\n <h4>On a server entry I specified a <em>redirect_domain</em> entry using <strong>.secure</strong> as a naming suffix to create an end-to-end encrypted connection, but it does not work.</h4>\n <p>\n First, verify the given server is set to <em>encryption</em> values <strong>both</strong> or <strong>secure</strong>.\n If the given server does not have a secure TLS instance running it will not be able to proxy to an encrypted TLS destination.\n </p>\n <p>\n Second, verify the destination is working without using a proxy connection by directly going to the destination address and port in a web browser.\n If the destination fails via direct request then a proxy connection will also expect to fail.\n </p>\n <p>\n Third, if the destination is failing through direct encrypted access via HTTPS but still works through unencrypted HTTP access you can fall back to partial encryption by deleting the <em>redirect_domain</em> entry with the <strong>.secure</strong> suffix.\n Partial encryption still encrypts data between the proxy, your server running from this application, and the users.\n Partial encryption will not encrypt data between the proxy and the destination.\n Typically partial encryption is good enough for privacy, but should not be trusted with sensitive data like passwords or connections to financial institutions.\n </p>\n </div>\n </div>\n <div class=\"section\">\n <h3>Containers</h3>\n <div class=\"section\">\n <h4>None of the Docker commands seem to work, as though they aren't even there. I verified Docker and Docker Compose are installed.</h4>\n <p>\n Most of the docker commands require elevated privilege to run and otherwise pretend to not exist.\n Docker does provide a <a href=\"https://docs.docker.com/engine/install/linux-postinstall/\">guide</a> to run docker commands as a regular user on Linux, but it seems many people (myself included) cannot get this to work.\n </p>\n <p>\n For security reasons I strongly recommend not executing docker commands directly with sudo unless you have no other choice.\n Instead I recommend running docker commands via some interface that is already running as a service.\n My personal solution is to run this application via systemd on Linux and then run Docker command via the terminal provided by the browser dashboard.\n </p>\n </div>\n <div class=\"section\">\n <h4>I saved a Docker Compose file but it does not list in this application when offline.</h4>\n <p>This application reads container information first from <em>docker ps</em> command, which only provides information on running containers. Secondly, this application reads compose files from directory: <em><path to this application>/compose</em> to provide a list of offline containers.</p>\n </div>\n <div class=\"section\">\n <h4>Docker wrote files as user root and now I cannot open them.</h4>\n <p>\n This happens because by default Docker executes with elevated privilege.\n It is <strong>strongly</strong> recommended to specify in each Docker Compose file environmental properties PUID and PGID with values of 1000.\n This allows the container to execute as the OS's default user without elevated privilege access.\n </p>\n </div>\n <div class=\"section\">\n <h4>On regular intervals my container appears to flicker between up and down. Upon further investigation I found the container issues 3 events: <em>exec-create</em>, <em>exec-start</em>, <em>exec-die</em>.</h4>\n <p>This is how containers execute health checks. To stop a service from issuing a health check add the following property to the concerned service in the respective Docker Compose file: <code>\n healthcheck:\n disable: true\n </code></p>\n </div>\n <div class=\"section\">\n <h4>Docker isn't working after computer restart.</h4>\n <p>See if the problem is solved by restarting service <em>containerd</em> first and then service <em>docker</em> second. Then review service logs to determine if service <em>docker</em> started without error.</p>\n </div>\n </div>\n <div class=\"section\">\n <h3>Terminal</h3>\n <div class=\"section\">\n <h4>Why is my preferred choice of shell is not listed in the select list?</h4>\n <p>Linux provides a catalogue of all installed shells in the file <em>/etc/shells</em>. Not all shells may add an entry to file upon their installation.</p>\n <p>Windows provides no such catalogue. Instead I must guess at the default locations for the most commonly used shells on Windows.</p>\n <p>\n To add additional options for the select list scroll to the bottom of the <em>/lib/utilities/vars.ts</em> file of this project looking for the vars.terminal property.\n Please ensure all entries are absolute file system paths to the local executable for any desired shell application.\n </p>\n </div>\n </div>\n <div class=\"section\">\n <h3>HTTP Test</h3>\n <div class=\"section\">\n <h4>What are the common error states demonstrated by this HTTP Test tool?</h4>\n <ul>\n <li>Some domains are very slow to return a response and can take up to 10 minutes.</li>\n <li>Some domains drop the connection or return an erroneous response. This could be due to a misconfiguration at the server, but is more typically an intentional way for servers to abandon traffic they don't want.</li>\n <li>Some domains cause an EPROTO error. This is a TLS protocol negotiation error. It occurs because they server is using unsupported TLS 1.1 certificates, an error in this application, or mostly likely due to an error in Node.js. Examples of domains causing this error: <em>prettydiff.com</em>, <em>www.army.mil</em>, <em>www.treasury.gov</em></li>\n </ul>\n </div>\n <div class=\"section\">\n <h4>What is the fastest observed response from a public domain?</h4>\n <p>The fastest I have seen consistently is <em>www.microsoft.com</em> which completes a roundtrip in about 0.065 seconds.</p>\n </div>\n </div>\n <div class=\"section\">\n <h3>WebSocket Test</h3>\n <div class=\"section\">\n <h4>Why does this not connect if a port number is specified but otherwise connects to the same destination?</h4>\n <p>\n The most likely answer is encryption mismatch, which is to say you are either attempting an encrypted connection to an insecure service or the opposite.\n This will absolutely occur if a port is specified for the destination, but may not occur if the port number is not provided.\n That is because the destination will likely direct your socket to the correct service location either by redirection or by implicit default port number.\n </p>\n </div>\n <div class=\"section\">\n <h4>Why is it that some servers impose strange behaviors on WebSocket headers that don't work anywhere else?</h4>\n <p>\n The conventions specified in RFC 6455 provide the common requirements for interconnection and messaging so that unrelated systems can talk in a commonly agreed upon way.\n When inter-connectivity between different unrelated systems is not necessary, such as one application talking to a different instance of the same application, then the application developer can modify the connection and messaging conventions as they wish.\n </p>\n </div>\n </div>\n <div class=\"section\">\n <h3>Other Sections</h3>\n <div class=\"section\">\n <h4>Why does the process list only associate processes to the local user account?</h4>\n <p>On Windows the application must be run from an administrative shell to see processes associated with additional accounts.</p>\n </div>\n </div>\n </div>\n <!-- faq end -->\n <!-- file-system start -->\n <div class=\"tab\" id=\"file-system\">\n <h2>File System</h2>\n <p class=\"tab-description\">This tool allows navigating the hosting machine's file system.</p>\n <div class=\"definitions\">\n <h3>File System Information <button class=\"expand\">Expand</button></h3>\n <div class=\"definition-body\">\n <h4>File System Objects</h4>\n <dl>\n <dt>block device</dt>\n <dd>A block device refers to an artifact representing a hardware device written to fixed-sized blocks, such as optical disks or flash memory.</dd>\n <dt>character device</dt>\n <dd>A character device is a simulated file that provides written access to hardware via streams, which allows direct access without buffering or fixed-size block segmentation. The typical use provides access to hardware via file system operations where performance is more important than storage integrity such as with serial ports, keyboards, cameras.</dd>\n <dt>directory</dt>\n <dd>A directory serves as a grouping mechanism allowing containing of child file system artifacts, which thereby provides a tree structure with organizational depth.</dd>\n <dt>FIFO device</dt>\n <dd>FIFO, or first in and first out, provides for pipe functionality. A pipe is an inter-process communication stream whereby one process sends its output directly to a different process as streamed input without help from an intermediary, such as a shell or user interaction. A FIFO allows for such inter-process communication via file system operations.</dd>\n <dt>file</dt>\n <dd>Files are the typical storage unit of file systems whereby text or binary is stored directly as opposed to a grouping or communication structure.</dd>\n <dt>socket</dt>\n <dd>File system sockets are similar to network sockets and FIFO devices. File system sockets exist at a low level in the kernel like network sockets and provide streamed inter-process communication like FIFO devices. File system sockets initiate using file system operations, but unlike FIFO devices are not necessarily subject to file system operations for transmitting data. Nonetheless file system sockets respect access and permission limitations inherited from their location on the file system.</dd>\n <dt>symbolic link</dt>\n <dd>A symbolic link is a virtual file that provides redirection within a file system. A symbolic link points to a file system artifact elsewhere on the file system and takes the identity of that artifact so as to function as a shortcut but yet appear exactly as the type of thing it points to. Since a symbolic link looks exactly like the thing it points to in both identity and function it cannot be discerned from a different file system type unless intentionally traversing and scanning for symbolic links.</dd>\n </dl>\n <h4>Permissions</h4>\n <p>File system permission follow a 4 digit model. The digits follow this definition:</p>\n <ol>\n <li>The first digit determines whether to apply one of setuid, setgid, or sticky bit.</li>\n <li>The second digit provides a permission value for artifact owner.</li>\n <li>The third digit provides a permission value for assigned group of the artifact owner.</li>\n <li>The final digit provides a permission value for users that are not owners and not members of the owner's group(s).</li>\n </ol>\n <p>Permission values for the final 3 digits follow a combination of these values:</p>\n <ul>\n <li>4 = read permissions (r)</li>\n <li>2 = write permissions (w)</li>\n <li>1 = execute permissions (x)</li>\n <li>0 = no permissions</li>\n </ul>\n <p>So, for example, a value of 5 means 4 + 1, or read and execute permissions and a value of 7 means read, write, and execute permissions. A complete permission value of <em>0755</em> means owners have complete permissions but users and members of the owner's group(s) can only read and execute to that artifact.</p>\n </div>\n </div>\n <div class=\"table-filters\">\n <h3>Input Controls</h3>\n <p><label>Absolute file system path address. <input spellcheck=\"false\" type=\"text\"/></label> <span>SMB shared paths are not supported.</span></p>\n <p><label>Search token. <input spellcheck=\"false\" type=\"text\"/></label> <span>Executes on press of 'Enter' key or loss of focus. Search values beginning with an exclamation are a negative search. Search values beginning and ending with a forward slash are regular expressions.</span></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"file-list\">\n <h3>File List</h3>\n <p>Status: <em></em></p>\n <table data-column=\"1\"><thead><tr><th><button data-dir=\"1\">object</button></th><th><button data-dir=\"1\">type</button></th><th><button data-dir=\"1\">size</button></th><th><button data-dir=\"1\">modified date</button></th><th><button data-dir=\"1\">modified time</button></th><th><button data-dir=\"1\">permissions</button></th><th><button data-dir=\"1\">children</button></th></tr></thead><tbody></tbody></table>\n </div>\n <div class=\"file-system-content\"></div>\n <div class=\"summary-stats\">\n <h3>Summary of Results</h3>\n <ul class=\"file-system-summary-list\">\n <li><span>Displayed Artifact Size:</span> <strong></strong></li>\n <li><span>Total Items:</span> <strong></strong></li>\n </ul>\n <ul>\n <li><span>Block Devices:</span> <strong></strong></li>\n <li><span>Character Devices:</span> <strong></strong></li>\n <li><span>Directories:</span> <strong></strong></li>\n <li><span>FIFO Pipes:</span> <strong></strong></li>\n <li><span>Files:</span> <strong></strong></li>\n <li><span>Sockets:</span> <strong></strong></li>\n <li><span>Symbolic Links:</span> <strong></strong></li>\n </ul>\n </div>\n <div class=\"section\">\n <h3>Items in current directory that could not be read</h3>\n <ul class=\"file-system-failures\"></ul>\n </div>\n </div>\n <!-- file-system end -->\n <!-- hash start -->\n <div class=\"tab\" id=\"hash\">\n <h2>Hash / Base64</h2>\n <p class=\"tab-description\">Generate a hash tokens from custom input or the file system.</p>\n <div class=\"definitions\">\n <h3>Hash Algorithms Explained <button class=\"expand\">Expand</button></h3>\n <div class=\"definition-body\">\n <p>\n Hash functions allow for generation of a predictable but challenging to reverse string token from a given string or binary input.\n Hashes are typically used as a form of identity or integrity check.\n A hash function provides a means of accepting input, whether string or binary, and returns a short randomly generated string token.\n The same input must always produce the same output, however.\n </p>\n <p>\n The strength of a hash function is the amount of work required to generate a collision.\n A collision occurs when two different forms of input generate the same output.\n MD5 and SHA1 hash algorithms, and all hash algorithms based upon them, are considered broken because there now exists several forms of known collisions and the work to generate new collisions against MD5 is trivial.\n </p>\n <p>\n One of the stronger modern hash algorithms is SHA3-512, which generates a fixed length 512bit token.\n The actual key space of that algorithm, the number of maximum potential values, is not known.\n The maximum possible key space based upon token size, 128 hexadecimal characters or 16^128, is larger than the number of atoms in the observed universe containing billions of galaxies each comprising billions of star systems each comprising billions of objects each comprising billions of atoms and so on.\n </p>\n </div>\n </div>\n <div class=\"form\">\n <h3>Input</h3>\n <h4>Function</h4>\n <p>\n <label class=\"radio\">Generate Hash <input checked=\"checked\" name=\"hash_function\" type=\"radio\" value=\"false\"/></label>\n <label class=\"radio\">Base64 Encode <input name=\"hash_function\" type=\"radio\" value=\"true\"/></label>\n </p>\n <h4>Input Source Type</h4>\n <p>\n <label class=\"radio\">String <input checked=\"checked\" name=\"hash_type\" type=\"radio\" value=\"false\"/></label>\n <label class=\"radio\">File <input name=\"hash_type\" type=\"radio\" value=\"true\"/></label>\n </p>\n <h4>Hash Output Format</h4>\n <p>\n <label class=\"radio\">Hexadecimal <input checked=\"checked\" name=\"hash_digest\" type=\"radio\" value=\"false\"/></label>\n <label class=\"radio\">Base64 <input name=\"hash_digest\" type=\"radio\" value=\"true\"/></label>\n </p>\n <h4>Hash Algorithm</h4>\n <p><label>Choose one of all supported hash algorithms <select></select></label></p>\n <h4>Input Value</h4>\n <p><label>Input must be a local absolute file system path if input type is <em>file</em>, otherwise provide any text value. <textarea spellcheck=\"spellcheck\"></textarea></label></p>\n <p class=\"buttons\"><button>Generate Hash</button></p>\n </div>\n <div class=\"form\">\n <h3>Output</h3>\n <p><label>Generated hash token <textarea class=\"output\" spellcheck=\"false\"></textarea></label></p>\n <p>Input size: <strong>0</strong> bytes. Processing time: <strong>0 days, 00:00:00.000000000</strong>.</p>\n </div>\n </div>\n <!-- hash end -->\n <!-- help start -->\n <div class=\"tab\" id=\"help\">\n <h2>Help</h2>\n <p class=\"tab-description\">Helpful information about this application.</p>\n <div class=\"section\">\n <h3>Conventions</h3>\n <div class=\"section\">\n <h4>General</h4>\n <p>From the command line execute the application with <code class=\"inline\">npm run server</code> or <code class=\"inline\">node lib/index.ts</code>.</p>\n <p>By default the application assigns random ports for the dashboard. I recommend changing these to a port of your preference, such as 3000. Then the dashboard can be repeatedly accessed at <em>http://localhost:3000</em></p>\n <p>When extending the application code perform health checks using <code class=\"inline\">npm run tsc</code> and/or <code class=\"inline\">npm run lint</code>.</p>\n </div>\n <div class=\"section\">\n <h4>Options</h4>\n <p>All options work with or without a double dash prefix, for example both are equally supported: <code class=\"inline\">no-color</code> and <code class=\"inline\">--no-color</code></p>\n <ul>\n <li><em>browser:<file_path></em> - Use this argument to specify a web browser, by file path, to use for testing the dashboard UI.</li>\n <li><em>list:<file_path></em> - Use this argument to specify a single test list, by file path, to execute during test mode.</li>\n <li><em>no-color</em> - If present this option tells the application to never use ANSI formatting in terminal output.</li>\n <li><em>no-exit</em> - If present this option tells the application to continue running at the conclusion of test mode, which is helpful to further interact with and debug the dashboard UI.</li>\n <li><em>test</em> - If present this option instructs the application to execute test automation.</li>\n </ul>\n </div>\n <div class=\"section\">\n <h4>Test Automation</h4>\n <p>Run the test automation with <code class=\"inline\">npm run test</code></p>\n <p>The <em>no-exit</em> option keeps the application running in its last state after the tests complete their evaluations.</p>\n <p>The <em>browser:<file path here></em> option allows specifying a browser by file path for test automation that makes use of a web browser. Spaces in a terminal argument must be escaped, according to the conventions of the given terminal, or the entire option should be quoted.</p>\n <p>The <em>list<test name></em> allows specifying a single test list to execute by test list file name from the project's test directory at <em>/lib/test</em>.</p>\n </div>\n <div class=\"section\">\n <h4>Register the application as a POSIX service</h4>\n <p>First, create a service file for <em>systemd</em> to consume at location: <strong>/etc/systemd/system/<service name here>.service</strong></p>\n <p>My service file looks like:\n<code>[Unit]\nDescription=Aphorio\nAfter=network.target\n\n[Service]\nType=simple\nUser=root\nExecStart=/home/username/.nvm/versions/node/v24.11.1/bin/node /home/username/aphorio/lib/index.ts\nRestart=always\nRestartSec=3\nWorkingDirectory=/home/username/aphorio\n\n[Install]\nWantedBy=multi-user.target</code></p>\n <p>Finally, register and start your service with the following commands:\n<code>sudo systemctl start <service name here>\nsudo systemctl enable <service name here>\nsudo systemctl status <service name here>\n</code> The <em>enable</em> command tells systemd to execute this service on OS boot. The <em>status</em> command prints output to screen indicating status health to confirm the service is executing as a service.</p>\n <p>To inspect output written to the shell by the application use this command: <code>sudo journalctl -u <service name here> --since \"2 minutes ago\"</code></p>\n </div>\n <div class=\"section\">\n <h4>Web Servers</h4>\n <h5>Proxies</h5>\n <p>The servers feature fully capable, though optional, support for proxies. The proxy support is divided between redirection to resources outside the given server and resources within the given server. See the 'Definitions of Server Object Properties' on the Web Servers tab for more information.</p>\n <p>The servers also feature full support for WebSockets and partial support for HTTP. HTTP is served over WebSockets which allows both protocols to coexist on the same port. All HTTP and WebSocket traffic receives full and equivalent proxy support.</p>\n <h5>HTTP Methods</h5>\n <p>HTTP methods <em>DELETE</em>, <em>POST</em>, and <em>PUT</em> are supported by this application but are not handled by this application. If these HTTP methods are to be used a given server must specify a file system path to corresponding libraries executed as child processes. Simply populate the respective properties on a new server's configuration object.</p>\n <h5>Custom WebSocket Message Handling</h5>\n <p>Custom WebSocket messaging handling is supported by supplying a custom function to library <em>/lib/transmit/messageHandler.ts</em>. Simply add a new property to the library object where the key name is the same as the name of the respective server. For example:\n<code>const message_handler:transmit_socket_messageHandler = {\n default: function transmit_messageHandler(bufferData:Buffer):void {\n // default message handling\n },\n \"my_server_name\": function (data:Buffer) {\n // custom message handling\n }\n}</code></p>\n <h5>Deletion</h5>\n <p>Deleting a server will remove the associate file system tree. <strong>Back up files you may wish to preserver before deleting a server.</strong></p>\n </div>\n <div class=\"section\">\n <h4>Logs</h4>\n <p>Logging is fully customizable. Simply call the <em>lib/utilities/log.ts</em> passing an object matching interface <em>config_log</em>. The front-end currently does not display configuration details and error objects, but that support is there awaiting display support from the front-end.</p>\n </div>\n <div class=\"section\">\n <h4>Terminal</h4>\n <p>The terminal makes use of NPM modules <em>@xterm/xterm</em> and <em>@lydell/node-pty</em>. These packages expose a shell to the browser front-end with full support for SSH, VIM, IRSSI, and more. The default supported shells are PowerShell in Windows and /bin/sh elsewhere. To customize that to a different shell, such as Bash, simply modify the appropriate one line of code at <em>/lib/services/terminal.ts</em>.</p>\n <p>Please see this guide for <a href=\"https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797\">ANSI Escape Codes</a> to extend and modify output to the terminal.</p>\n </div>\n </div>\n <div class=\"section\">\n <h3>Dependencies</h3>\n <div class=\"section\">\n <h4>OpenSSL</h4>\n <p>OpenSSL is a Swiss Army knife of cryptographic tools, but is primarily used for certificate creation and analysis.</p>\n <ul>\n <li><p>Windows: <code>winget install --id=ShiningLight.OpenSSL.Dev -e</code></p></li>\n <li><p>Debian: <code>sudo apt install openssl</code></p></li>\n </ul>\n </div>\n <div class=\"section\">\n <h4>Docker Compose</h4>\n <p>Docker Compose is a more convenient way to launch Docker containers by using a tiny YAML file to reference a prebuilt image and map resources from the container to the host machine.</p>\n <ul>\n <li><p>Windows - (Administrative Terminal)\n<code>winget install --id=Docker.DockerCLI -e\nwinget install --id=Docker.DockerCompose -e</code></p></li>\n <li><p>Debian\n<code># Add Docker's official GPG key:\nsudo apt-get update\nsudo apt-get install ca-certificates curl\nsudo install -m 0755 -d /etc/apt/keyrings\nsudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc\nsudo chmod a+r /etc/apt/keyrings/docker.asc\n\n# Add the repository to Apt sources:\necho \"deb \\\n [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \\\n https://download.docker.com/linux/debian \\\n $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable\" | \\\n sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\nsudo apt-get update\nsudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin</code></p></li>\n </ul>\n </div>\n <div class=\"section\">\n <h4>Node Dependencies (included in the repository)</h4>\n <ul class=\"dependencies\">\n <li><a href=\"https://www.npmjs.com/package/@lydell/node-pty\">@lydell/node-pty</a>, <a href=\"https://github.com/lydell/node-pty\">GitHub</a> - (MIT), the binaries powering XTERM emulation for the UI terminal</li>\n <li><a href=\"https://www.npmjs.com/package/@xterm/xterm\">@xterm/xterm</a>, <a href=\"https://github.com/xtermjs/xterm.js\">GitHub</a> - (MIT), the actual browser code for the UI terminal</li>\n <li>\n <a href=\"https://www.npmjs.com/package/chart.js\">chart.js</a>, <a href=\"https://github.com/chartjs/Chart.js\">GitHub</a> - (MIT), the library that creates the statistics charts\n <ul><li><a href=\"https://www.npmjs.com/package/@kurkle/color\">@kurkle/color</a>, <a href=\"https://github.com/kurkle/color\">GitHub</a> - (MIT), a dependency of charts.js library</li></ul>\n </li>\n <li><a href=\"https://gnuwin32.sourceforge.net/packages/file.htm\">file for win32</a>, (BSD 2-2clause), allows execution of the Unix file utility on Windows</li>\n <li><a href=\"https://www.npmjs.com/package/jschardet\">jschardet</a>, <a href=\"https://github.com/aadsm/jschardet\">GitHub</a> - (GPLv2.1), a fall back to discover text encoding of files</li>\n </ul>\n </div>\n </div>\n </div>\n <!-- help end -->\n <!-- interfaces start -->\n <div class=\"tab\" id=\"interfaces\">\n <h2>Network Interfaces</h2>\n <p class=\"tab-description\">A list of network interfaces and their addressing information. Data automatically refreshes at server's midnight time.</p>\n <div class=\"section\">\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Interfaces</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <div class=\"item-list\"></div>\n </div>\n </div>\n <!-- interfaces end -->\n <!-- os-machine start -->\n <div class=\"tab\" id=\"os-machine\">\n <h2>OS/Machine</h2>\n <p class=\"tab-description\">A list of descriptive and statistical data about the application's executing environment. Data automatically refreshes at server's midnight time.</p>\n <div class=\"section\">\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <div class=\"section\">\n <h3>Machine</h3>\n <h4>CPU</h4>\n <ul>\n <li data-name=\"arch\"><strong>Architecture</strong><span></span></li>\n <li data-name=\"cores\"><strong>Logical CPU Cores</strong><span></span></li>\n <li data-name=\"endianness\"><strong>Endianness</strong><span></span></li>\n <li data-name=\"frequency\"><strong>Frequency</strong><span></span></li>\n <li data-name=\"name\"><strong>Name</strong><span></span></li>\n </ul>\n <h4>Memory</h4>\n <ul>\n <li data-name=\"memoryFree\"><strong>Free</strong><span></span></li>\n <li><strong>Used</strong><span></span></li>\n <li data-name=\"memoryFree\"><strong>Total</strong><span></span></li>\n </ul>\n </div>\n <div class=\"section\">\n <h3>Operating System</h3>\n <ul>\n <li data-name=\"hostname\"><strong>Hostname</strong><span></span></li>\n <li data-name=\"name\"><strong>Name</strong><span></span></li>\n <li data-name=\"platform\"><strong>Platform</strong><span></span></li>\n <li data-name=\"release\"><strong>Release</strong><span></span></li>\n <li data-name=\"type\"><strong>Type</strong><span></span></li>\n <li data-name=\"uptime\"><strong>Up Time</strong><span></span></li>\n </ul>\n <div>\n <h4>Path <button class=\"expand\">Expand</button></h4>\n <ul class=\"definition-body\" data-name=\"path\"></ul>\n </div>\n <div>\n <h4>Environmental Variables <button class=\"expand\">Expand</button></h4>\n <ul class=\"definition-body\" data-name=\"env\"></ul>\n </div>\n </div>\n <div class=\"section\">\n <h3>Application Process</h3>\n <ul>\n <li data-name=\"admin\"><strong>Administrative Privilege</strong><span></span></li>\n <li data-name=\"arch\"><strong>Architecture</strong><span></span></li>\n <li data-name=\"argv\"><strong>Arguments</strong><span></span></li>\n <li data-name=\"cpuSystem\"><strong>CPU System Time<sup>1</sup></strong><span></span></li>\n <li data-name=\"cpuUser\"><strong>CPU User Time<sup>1</sup></strong><span></span></li>\n <li data-name=\"cwd\"><strong>Current Working Directory</strong><span></span></li>\n <li data-name=\"memory-process\"><strong>Total Process Memory</strong><span></span></li>\n <li data-name=\"memory-v8\"><strong>V8 Memory</strong><span></span></li>\n <li data-name=\"memory-external\"><strong>Buffers and V8 Helpers Memory</strong><span></span></li>\n <li data-name=\"platform\"><strong>Platform</strong><span></span></li>\n <li data-name=\"pid\"><strong>Process ID</strong><span></span></li>\n <li data-name=\"ppid\"><strong>Parent Process ID</strong><span></span></li>\n <li data-name=\"uptime\"><strong>Up Time</strong><span></span></li>\n </ul>\n <div>\n <h4>Node.js Dependency Versions <button class=\"expand\">Expand</button></h4>\n <ul class=\"definition-body\" data-name=\"versions\"></ul>\n </div>\n <p><strong>[1]</strong> User CPU time and System CPU time measure actual CPU cycle time across all logical CPU instances for this application's process.</p>\n </div>\n <div class=\"section\">\n <h3>User</h3>\n <ul>\n <li data-name=\"gid\"><strong>Group ID</strong><span></span></li>\n <li data-name=\"uid\"><strong>User ID</strong><span></span></li>\n <li data-name=\"homedir\"><strong>Home Directory</strong><span></span></li>\n </ul>\n </div>\n </div>\n </div>\n <!-- os-machine end -->\n <!-- ports-application start -->\n <div class=\"tab\" id=\"ports-application\">\n <h2>App Ports</h2>\n <p class=\"tab-description\">A list of ports listened upon by web servers and docker containers managed from this dashboard.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>Ports List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Sockets</span> <em></em></p>\n <p><span>Filtered Sockets</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-ir=\"1\">Port</button></th>\n <th><button data-ir=\"1\">Type</button></th>\n <th><button data-ir=\"1\">Service</button></th>\n <th><button data-ir=\"1\">Service Name</button></th>\n <th><button data-ir=\"1\">Service Id</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- ports-application end -->\n <!-- processes start -->\n <div class=\"tab\" id=\"processes\">\n <h2>Processes</h2>\n <p class=\"tab-description\">A list of processes running in the local operating system. Data automatically refreshes at server's midnight time.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>Process List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Processes</span> <em></em></p>\n <p><span>Filtered Processes</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Name</button></th>\n <th><button data-dir=\"1\">ID</button></th>\n <th><button data-dir=\"1\">Memory (bytes)</button></th>\n <th><button data-dir=\"1\">CPU Time</button></th>\n <th><button data-dir=\"1\">User</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- processes end -->\n <!-- servers-web start -->\n <div class=\"tab\" id=\"servers-web\">\n <h2>Web Servers</h2>\n <p class=\"tab-description\">A list of configured HTTP/WS servers hosted by this application and their respective status.</p>\n <div class=\"definitions\">\n <h3>Server Information and Configuration <button class=\"expand\">Expand</button></h3>\n <div class=\"definition-body\">\n <div class=\"section\">\n <h4>Server Descriptions</h4>\n <p>These are primitive web servers supporting out of the box HTTP methods: CONNECT, GET, HEAD, OPTIONS, and TRACE. These servers provide no cache control mechanism. These servers also do not report failure responses, aside from 404 status. In the case a connection violates a server's security or connection policies the socket is immediately destroyed.</p>\n <p>For security and efficiency the <em>connect</em> method creates a web socket connection instead a regular HTTP request redirection. If the desired destination does not support the Web Socket protocol the corresponding request will silently fail.</p>\n <p>HTTP methods <em>DELETE</em>, <em>PATCH</em>, <em>POST</em>, and <em>PUT</em> rely upon external services for support. This external support is configured using the <strong>method</strong> property of the server's configuration object. Provided the configuration is present the server will prexy the request to the desired service.</p>\n </div>\n <div class=\"section\">\n <h4>Server Configuration Definitions</h4>\n <dl>\n <dt><em>activate</em> (string)</dt>\n <dd><p>\n Instructs the application to bring the server online automatically at application start and server creation.\n </p></dd>\n <dt><em>block_list</em> (string array)</dt>\n <dd><p>\n The block list contains three optional string arrays of criteria to determine if matching sockets should be instantly destroyed.\n At this time wildcards, CIDR notation, and ranges are not supported.\n </p></dd>\n <dt><em>domain_local</em> (string array)</dt>\n <dd><p>\n Sockets featuring HTTP request host names in this list will be served from this server.\n Sockets featuring HTTP request host names not in this list or in the redirect_domain list will be destroyed.\n </p></dd>\n <dt><em>encryption</em> (string)</dt>\n <dd><p>\n Whether to create an encrypted server for HTTPS and WSS protocols, an unencrypted server for HTTP and WS protocols, or both.\n Accepted values are <em>both</em>, <em>open</em>, or <em>secure</em>.\n </p></dd>\n <dt><em>http</em> (object)</dt>\n <dd><p>\n File system paths to external utilities for handling the supported HTTP methods: <em>delete</em>, <em>post</em>, and <em>put</em>.\n HTTP request bodies are passed into an environmental variable on the respective child process named 'payload'.\n </p></dd>\n <dt><em>id</em> (string)</dt>\n <dd><p>A dynamically assigned identifier. The application creates this value and it cannot be modified.</p></dd>\n <dt><em>method</em> (object)</dt>\n <dd><p>Key names may include any of <em>delete</em>, <em>patch</em>, <em>post</em>, <em>put</em>. These key names are not case sensitive. The value of these method names is a child object containing the properties <em>address</em> (string) and <em>port</em> (number).</p> <code>\"DELETE\": {\"address\": \"localhost\", \"port\": 1234}</code></dd>\n <dt><em>name</em> (string)</dt>\n <dd><p>\n The human readable name of this server.\n </p></dd>\n <dt><em>ports</em> (object)</dt>\n <dd><p>The ports on which the server operates.</p></dd>\n <dt><em>redirect_asset</em> (object)</dt>\n <dd><p>\n Redirects resource paths of HTTP requests within the given server based upon the hostname in the HTTP request header.\n This is useful for dynamic or vanity endpoints on a given server that wish to return something different than a relative file system destination.\n Each instance uses the structure of <code>\"domain\": {\"resource location\": \"new location\"}</code> because each server can represent 0 or more domain names.\n </p><p>\n For example there could be an informational dashboard on some server at address: <em>http://myexample.com/api_services/informational/dashboards/uptime/</em>.\n For the sake of simplicity you want to serve that dashboard from an internal vanity domain like: <em>http://api.dashboard/</em>.\n You would need a rule to redirect from resource <em>/</em> to actual resource at <em>/api_services/informational/dashboards/uptime</em>, and that rule would look like: <code>\"api.dashboard\": {\"/\": \"/api_services/informational/dashboards/uptime/\"}</code>\n </p><p>\n Asset redirection supports use of wildcards by specifying an asterisk at the end of asset locations.\n For example, redirection of request for <em>/api_services/informational/dashboards/uptime/images/interface/title.png</em> to <em>/api/images/interface/title.png</em> would occur with rule: <code>\"api.dashboard\": {\"/api/*\": \"/api_services/informational/dashboards/uptime/\"}</code>\n With wildcards all asset requests matching the address up to the asterisk will be redirected to the specified location.\n </p><p>\n <strong>Please note the terminal slash in the prior examples.</strong>\n Without the terminating slash the redirected address becomes <em>/api_services/informational/dashboards/uptimeimages/interface/title.png</em>.\n </p><p>\n If requests to a given asset of a supported domain should redirect to an existing socket created from this application just supply the socket's id, a 128 hexadecimal: <code>\"jellyfin.x\": {\"/api/\": \"fe37dd66fa849ca98684160d542538b22c1edb576271d76b319ded4965d90143a0806fe1edf29b82b8740ec177880769629bdd1a0fb7cb97d7640e60c44833d3\"}</code>\n The socket must merely exist from the current local instance of this application, which may include sockets associated with other web servers, but the socket must not already exist in a proxy relationship.\n If the specified socket does not exist or is in a proxy relationship the server will drop the request.\n If the given web server is TLS and the specified socket is not TLS the server will drop the request.\n </p></dd>\n <dt><em>redirect_domain</em> (object)</dt>\n <dd><p>\n Redirects traffic to a different server location, such as a vanity domain that may or may not be served from the same server.\n Each instance uses the structure of <code>\"domain\": [\"new domain\", port_number]</code> because each server can represent 0 or more domain names.\n If the 'new domain' is an empty string the requested domain will be used.\n If the port number is not a number or 0 the current server's port number will be used.\n </p><p>\n If TLS connections needs to be directed to a port different than open connections then use the naming convention <strong>myDomain.secure</strong>, for example: <code>\"jellyfin.x.secure\": [\"\", 3003]</code>\n </p><p>\n If the domain specific traffic should be redirected to an existing socket created from this application just supply the socket's id, a 128 hexadecimal, and the port value will be ignored: <code>\"jellyfin.x\": [\"fe37dd66fa849ca98684160d542538b22c1edb576271d76b319ded4965d90143a0806fe1edf29b82b8740ec177880769629bdd1a0fb7cb97d7640e60c44833d3\", 0]</code>\n The socket must merely exist from the current local instance of this application, which may include sockets associated with other web servers, but the socket must not already exist in a proxy relationship.\n If the specified socket does not exist or is in a proxy relationship the server will drop the request.\n If the given web server is TLS and the specified socket is not TLS the server will drop the request.\n </p></dd>\n <dt><em>single_socket</em> (boolean)</dt>\n <dd><p>\n Providing property <em>single_socket</em> with value <em>true</em> will create a server that only accepts a first successful HTTP or WebSocket connection.\n All other connections will be ignored and the server will automatically remove itself once that connection completes.\n This server will never writing configuration data and so it will be forever lost once this application closes.\n </p></dd>\n <dt><em>temporary</em> (boolean)</dt>\n <dd><p>\n Providing property <em>temporary</em> with value <em>true</em> will create a server that never writes configuration data.\n This server will be forever lost once this application closes.\n </p></dd>\n <dt><em>upgrade</em> (boolean)</dt>\n <dd><p>\n Whether the server should upgrade open sockets to secure sockets when the <em>Upgrade-Insecure-Requests</em> HTTP request header is detected.\n This requires the given web server is running both a secure and open web server.\n This works by returning a 301 response to the requesting client for the same resource on the secure server's port with scheme HTTPS.\n </p></dd>\n </dl>\n </div>\n </div>\n </div>\n <div class=\"section\">\n <h3>Web Server List</h3>\n <p class=\"buttons\"><button class=\"server-new\">Create Server</button></p>\n <ul class=\"server-list\"></ul>\n </div>\n </div>\n <!-- servers-web end -->\n <!-- services start -->\n <div class=\"tab\" id=\"services\">\n <h2>Services</h2>\n <p class=\"tab-description\">A list of application services on the local operating system. Data automatically refreshes at server's midnight time.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>Service List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Services</span> <em></em></p>\n <p><span>Filtered Services</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Name</button></th>\n <th><button data-dir=\"1\">Status</button></th>\n <th><button data-dir=\"1\">Description</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- services end -->\n <!-- sockets-application-tcp start -->\n <div class=\"tab\" id=\"sockets-application-tcp\">\n <h2>App TCP Sockets</h2>\n <p class=\"tab-description\">A list of TCP sockets created by this application. Sockets not of 'type' http are WebSocket connections. Proxy identifies the id of the paired socket or null if not piped to another socket. Data automatically refreshes at server's midnight time. Local address and port are from the perspective of the application server. Remote address and port could represent the local web browser.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>TCP Socket List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Sockets</span> <em></em></p>\n <p><span>Filtered Sockets</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Server</button></th>\n <th><button data-dir=\"1\">Server Name</button></th>\n <th><button data-dir=\"1\">Socket ID</button></th>\n <th><button data-dir=\"1\">Type Descriptor</button></th>\n <th><button data-dir=\"1\">Role</button></th>\n <th><button data-dir=\"1\">Proxy</button></th>\n <th><button data-dir=\"1\">Encrypted</button></th>\n <th><button data-dir=\"1\">Local Server IP</button></th>\n <th><button data-dir=\"1\">Local Server Port</button></th>\n <th><button data-dir=\"1\">Remote IP</button></th>\n <th><button data-dir=\"1\">Remote Port</button></th>\n <th><button data-dir=\"1\">User Agent</button></th>\n <th><button data-dir=\"1\">Age</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- sockets-application-tcp end -->\n <!-- sockets-application-udp start -->\n <div class=\"tab\" id=\"sockets-application-udp\">\n <h2>App UDP Sockets</h2>\n <p class=\"tab-description\">A list of UDP sockets created by this application.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>UDP Socket List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Sockets</span> <em></em></p>\n <p><span>Filtered Sockets</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Socket ID</button></th>\n <th><button data-dir=\"1\">Local IP</button></th>\n <th><button data-dir=\"1\">Local Port</button></th>\n <th><button data-dir=\"1\">Remote IP</button></th>\n <th><button data-dir=\"1\">Remote Port</button></th>\n <th><button data-dir=\"1\">Role</button></th>\n <th><button data-dir=\"1\">Multicast Group</button></th>\n <th><button data-dir=\"1\">Multicast Interface</button></th>\n <th><button data-dir=\"1\">Multicast Membership</button></th>\n <th><button data-dir=\"1\">Multicast Source</button></th>\n <th><button data-dir=\"1\">Age</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- sockets-application-udp end -->\n <!-- sockets-os-tcp start -->\n <div class=\"tab\" id=\"sockets-os-tcp\">\n <h2>OS TCP Sockets</h2>\n <p class=\"tab-description\">A list of all connected sockets in the operating system. Data automatically refreshes at server's midnight time.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>Socket List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Sockets</span> <em></em></p>\n <p><span>Filtered Sockets</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Local Address</button></th>\n <th><button data-dir=\"1\">Local Port</button></th>\n <th><button data-dir=\"1\">Remote Address</button></th>\n <th><button data-dir=\"1\">Remote Port</button></th>\n <th><button data-dir=\"1\">Process ID</button></th>\n <th><button data-dir=\"1\">Process Name</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- sockets-os-tcp end -->\n <!-- sockets-os-udp start -->\n <div class=\"tab\" id=\"sockets-os-udp\">\n <h2>OS UDP Sockets</h2>\n <p class=\"tab-description\">A list of all connected sockets in the operating system. Data automatically refreshes at server's midnight time.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>Socket List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Sockets</span> <em></em></p>\n <p><span>Filtered Sockets</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Local Address</button></th>\n <th><button data-dir=\"1\">Local Port</button></th>\n <th><button data-dir=\"1\">Remote Address</button></th>\n <th><button data-dir=\"1\">Remote Port</button></th>\n <th><button data-dir=\"1\">Process ID</button></th>\n <th><button data-dir=\"1\">Process Name</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- sockets-os-udp end -->\n <!-- statistics start -->\n <div class=\"tab\" id=\"statistics\">\n <h2>Statistics</h2>\n <p class=\"tab-description\">Providing a real time metrics for supported services.</p>\n <div class=\"table-filters\">\n <h3>Metric Controls</h3>\n <p><label>Delay between updates in seconds <input spellcheck=\"false\" type=\"number\"/></label></p>\n <p><label>Maximum number of data points <input spellcheck=\"false\" type=\"number\"/></label></p>\n <p><label>Graph Type<select>\n <option value=\"bar\">bar</option>\n <option value=\"line\">line</option>\n </select></label></p>\n <p><label>Display Method<select>\n <option value=\"individual\">individual graphs per service</option>\n <option value=\"composite\">composite graphs per data type</option>\n </select></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>Health Metrics</h3>\n <p>Last updated: <em></em></p>\n <p>Processing duration: <em></em></p>\n <div class=\"graphs\"></div>\n </div>\n </div>\n <!-- statistics end -->\n <!-- terminal start -->\n <div class=\"tab\" id=\"terminal\">\n <h2>Terminal</h2>\n <p class=\"tab-description\">A command terminal to interact with the local operating system. Expect this terminal to mirror the operating system terminal exactly. <em>Text selections in the console are automatically copied to the clipboard.</em></p>\n <div class=\"definitions\">\n <h3>Shells, Terminals, and Pseudo-Terminals <button class=\"expand\">Expand</button></h3>\n <div class=\"definition-body\">\n <div class=\"section\">\n <p>To provide human interaction directly to modern operating systems these modern operating systems include shells, terminals, and pseudo-terminals.</p>\n <p>\n Shells, also called command shells, provide a means for human users to send instructions to operating systems directly without need to interact through other application processes.\n Human users, however, do not typically interact directly with command shells.\n The job of a shell is to provide a means to write commands, and optionally programmable automation, and that the operating system interprets and possibly responds to.\n </p>\n <p>\n All the inputs and outputs through command shells occurs in raw text characters, as in text characters that can be typed directly from a physical keyboard.\n The reason humans do not typically engage with shells directly is because much of this raw text contains formatting and instructions and signals for interaction.\n These control sequences are comprised of raw text that greatly impedes the other raw text meant for humans to read.\n To properly interpret these formatting and control sequences, such as colors and focus movement, humans indirectly interact with shells through terminal applications.\n </p>\n <p>\n A command terminal is an application that interprets shell output and provides a friendlier interface of human input to command shells.\n In other words shells are for computers to achieve human interaction and terminals are for humans to achieve shell interaction.\n Command terminals are sometimes referred to as <em>tty</em> devices, which refers to teletypewriter like an old typewriter for phone lines.\n </p>\n <p>\n If shells are for computers and terminals are for humans then how do other applications interact with command shells?\n That is the job of pseudo-terminals, which are sometimes referred to as <em>pty</em> devices.\n Pseudo-terminals do the same job as terminal applications, but instead of graphically rendering text into pretty colors they send more friendly binary messages to consuming applications.\n For example when a user connects to a remote computer using SSH and sees a command shell they are interacting through pseudo-terminals on each side of the network with one side talking to a shell and the other side talking to a terminal for the human user.\n </p>\n <p>\n Linux provides a functional API to engage with a PTY.\n This requires writing a C language file that makes use of functions <em>open_pty</em> or <em>fork_pty</em> from file pty.h and then compiling these custom instructions to binary.\n Windows provides its own functional API via the ConPTY architecture with functions in C# language.\n That requires writing a C# file that makes use of the Microsoft functions and then compiling to binary.\n </p>\n <p>\n To solve for this in JavaScript world Microsoft maintains a package called <em>node-pty</em> that provides these binaries for both Windows, Linux, and FreeBSD.\n This application makes use of node-pty via package Xterm.js, as does every other application that wishes to provide a terminal interface to a web browser.\n </p>\n </div>\n </div>\n </div>\n <div class=\"section\">\n <h3>Switch Shells</h3>\n <p><label>Available Shells <select></select></label></p>\n </div>\n <div class=\"section\">\n <h3>Terminal Display</h3>\n <p class=\"dimensions\">Columns: <em>0</em>, Rows: <em>0</em></p>\n <span class=\"clear\"></span>\n <div class=\"terminal-output\"></div>\n </div>\n </div>\n <!-- terminal end -->\n <!-- test-http start -->\n <div class=\"tab\" id=\"test-http\">\n <h2>HTTP Test</h2>\n <p class=\"tab-description\">A means to write arbitrary HTTP requests and read the raw response.</p>\n <div class=\"definitions\">\n <h3>HTTP Format (RFC 2616) <button class=\"expand\">Expand</button></h3>\n <div class=\"definition-body\">\n <p>HTTP is a text-based application layer transmission protocol defined as <a href=\"https://datatracker.ietf.org/doc/html/rfc2616\">RFC 2616</a>.</p>\n <p>The first line of an HTTP request a space separated list of method, resource path (also known as <em>end point</em>), and protocol.\n Each following line is separated by a CRLF (x0Dx0A) sequence. This application handles that formatting for you.\n The header portion of the request is separated from a body portion by an empty line, which is two or more consecutive sequences of CRLF.\n A body portion is optional and only used by certain HTTP methods. All lines after the first and before the body portion are headers.\n Each header gets its own line and is a case-insensitive name followed by a colon, zero or more spaces, and a text value.</p>\n <p>A <em>host</em> header is required and is generally the second line of the raw request string.\n The host value is taken from the domain portion of a web address.\n The domain portion of an address includes authentication, domain name, and port.\n The authentication portion is optional and rarely used.</p>\n <p>The port portion of a domain is optional and rarely included if connecting with plain text HTTP over port 80 or encrypted HTTPS over port 443.\n In all other cases the port number is a colon separated suffix to the domain name.\n In the case of an IPv6 address the domain name must be inclosed in square braces before specifying the port number, example: <strong>host: [2600:1700:1234:5678::a]:8081</strong>.</p>\n <ul>\n <li>The method is one of the <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\">HTTP request methods</a>. <strong>GET</strong> is the most common.</li>\n <li>The end point looks like a Unix absolute file path always starting with a forward slash.</li>\n <li>The protocol is HTTP, forward slash, and a version number, such as <em>HTTP/1.1</em>.</li>\n </ul>\n <p>An HTTP request can be either plain text or a TLS encryption. That distinction is not provided in the HTTP header but is inferred by context.</p>\n <p>\n The default behavior of HTTP version 1.1 is to keep a socket open for multiple sequential request/response round trips. HTTP 1.0 does not have this capability, called <em>keep-alive</em>, and it is forbidden in HTTP/2 and HTTP/3.\n As a result, in HTTP/1.1, we must have an indicator different than socket termination to determine when a response completes.\n This following list determines response message completion.\n </p>\n <ul>\n <li>The socket closes.</li>\n <li>The response header is completed with the <em>\"\\r\\n\\r\\n</em> empty line sequence and the response contains no body portion.</li>\n <li>The response header contains a heading <em>transfer-encoding: chunked</em> and the body terminates with a message chunk containing exactly <em>0\\r\\n\\r\\n</em>.</li>\n <li>The response header contains a heading <em>content-length</em> with a numeric value and the byte length, not character length, of the body portion only equals that header value.</li>\n </ul>\n <p>\n Ideally HTTP requests should be sent to HTTP servers which then send an HTTP response and same for HTTPS requests to HTTPS servers.\n Things become more complex when HTTP responses are sent to HTTPS servers or HTTPS requests are sent to HTTP servers.\n All combinations are explained in this list.\n </p>\n <ul>\n <li>Sending an HTTP request to an HTTP server without a <em>Upgrade-Insecure-Requests: 1</em> header should expect a desired HTTP response.</li>\n <li>Sending an HTTP request to an HTTP server with a <em>Upgrade-Insecure-Requests: 1</em> header should expect to receive an HTTP 308 redirection response to a related HTTPS server.</li>\n <li>Sending a HTTPS request to an HTTP server should expect some form of failure, which could include an unexpected HTTP response or dropping the socket resulting in a socket timeout for the requestor.</li>\n <li>It is possible to configure an HTTP server to accept HTTPS requests by checking the first character of the first message on the socket. This application will proxy HTTPS requests to a HTTP server's peer HTTPS server if one is currently running, which silently tunnels HTTPS traffic through the HTTP server. This will appear to the requestor that the HTTP server is actually an HTTPS server while it isn't. This does not violate the cryptography of TLS, but could result in second-order security concerns by setting false expectations upon the server's identity..</li>\n <li>Sending an HTTPS request to an HTTPS server will result in a HTTPS response.</li>\n <li>Sending an HTTP request to an HTTPS server will result in a dropped socket. Secure servers cannot accept insecure connections.</li>\n </ul>\n </div>\n </div>\n <div class=\"form\">\n <h3>Request</h3>\n <h4>Scheme</h4>\n <p><label class=\"radio\">Plain text (http) <input name=\"http_scheme\" type=\"radio\" value=\"false\"/></label> <label class=\"radio\">Encrypted (https) <input checked=\"checked\" name=\"http_scheme\" type=\"radio\" value=\"true\"/></label></p>\n <h4>Timeout</h4>\n <p><label>Request timeout in milliseconds. Value defaults to 0 and a 0 value removes any timeout.<input spellcheck=\"false\" type=\"number\" value=\"0\"/></label></p>\n <h4>Raw Request Text</h4>\n <p><label>Complete raw HTTP request including header <textarea class=\"test-input\" spellcheck=\"false\"></textarea></label></p>\n <p class=\"buttons\"><button class=\"send_request\">Send Request</button></p>\n </div>\n <div class=\"form\">\n <h3>Response</h3>\n <div class=\"http_response\">\n <p><label>URI <textarea readonly=\"readonly\" spellcheck=\"false\"></textarea></label></p>\n <p><label>Response Headers <textarea readonly=\"readonly\" spellcheck=\"false\"></textarea></label></p>\n <p class=\"float-last\"><label>Response Body <textarea readonly=\"readonly\" spellcheck=\"false\"></textarea></label></p>\n <span class=\"clear\"></span>\n </div>\n </div>\n <div class=\"summary-stats\">\n <h3>Statistics</h3>\n <ul>\n <li><span>Response Time:</span> <strong></strong></li>\n <li><span>Response Header Size:</span> <strong></strong></li>\n <li><span>Response Body Size:</span> <strong></strong></li>\n <li><span>Response Chunked:</span> <strong></strong></li>\n <li><span>Response Chunk Count:</span> <strong></strong></li>\n <li><span>Request Header Size:</span> <strong></strong></li>\n <li><span>Request Body Size:</span> <strong></strong></li>\n <li><span>URI Length:</span> <strong></strong></li>\n </ul>\n </div>\n </div>\n <!-- test-http end -->\n <!-- test-websocket start -->\n <div class=\"tab\" id=\"test-websocket\">\n <h2>WebSocket Test</h2>\n <p class=\"tab-description\">A tool to open and experiment with arbitrary WebSocket messaging.</p>\n <div class=\"definitions\">\n <h3>WebSocket Protocol (RFC 6455) <button class=\"expand\">Expand</button></h3>\n <div class=\"definition-body\">\n <p>WebSockets exist in two phases, a handshake phase to establish connection and then a messaging phase.</p>\n <div class=\"section\">\n <h4>Handshake</h4>\n <p>The handshake phase resembles an HTTP GET request, wherein a <a href=\"https://datatracker.ietf.org/doc/html/rfc2616\">RFC 2616</a> compliant request is sent from a client to a server.\n This request includes a vaguely random 32bit key compatible with BASE64 syntax.\n The request also allows for multiple points of identity, such as: a URI path, subprotocol names via comma separated values to the <em>sec-websocket-protocol</em> header, and custom headers.</p>\n <p>Once the server receives the handshake request it responds with an algorithmic transform of the key provided by the request. The client then opens a persistent TCP socket to the server upon confirming the server's key transform.</p>\n </div>\n <div class=\"section\">\n <h4>Messaging</h4>\n <p>Messaging occurs in binary form. A single message may be divided into multiple transmissions called <em>frames</em>. Each frame is composed of a frame header of 2 to 14 bytes immediately followed by the frame message.</p>\n <p>Message in WebSockets is also full-duplex. This means a single socket comprises two separate and fully independent communication channels allowing each side of the socket to send messages without waiting on the other side.</p>\n <p>This application represents frame headers using an object of type name <em>websocket_frame</em> that comprises these properties:</p>\n <dl>\n <dt>extended</dt> <dd>A number value storing the extended frame content length.</dd>\n <dt>fin</dt> <dd>A boolean value indicating whether the given frame is the final frame of a message.</dd>\n <dt>len</dt> <dd>A number value storing the abridged frame content length.</dd>\n <dt>mask</dt> <dd>A boolean value indicating whether the frame applies message masking.</dd>\n <dt>maskKey</dt> <dd>The 32 bit masking key used to unmask the frame body if the frame body were masked.</dd>\n <dt>opcode</dt> <dd>A number value determining frame function or message body format.</dd>\n <dt>rsv1</dt> <dd>A boolean value representing an optional bit flag that can be set for custom application preferences. This is not used by web browsers.</dd>\n <dt>rsv2</dt> <dd>Same as rsv1.</dd>\n <dt>rsv3</dt> <dd>Same as rsv1.</dd>\n <dt>startByte</dt> <dd>A number value only used internally by this application to indicate frame header length, and thus start position of the frame content body.</dd>\n </dl>\n <p>For frame content lengths of less than 126 bytes their lengths are literally represented in the <em>len</em> property of the frame header and then <em>extended</em> property receives a value of 0.\n For frame content lengths greater than 125 bytes but less than 65,536 bytes the <em>len</em> property receives a value of 126 and the <em>extended</em> property stores the actually frame content length occupying exactly 2 bytes of storage.\n For frame content lengths greater than 65,535 bytes the <em>len</em> property receives a value of 127 and the <em>extended</em> property stores the actual frame content length occupying exactly 8 bytes of storage.</p>\n <p>The opcode property stores a 2 byte integer, values of 0 to 15. The first half of values indicate message format and the second half of values indicate control frames. The value definitions are as follows:</p>\n <dl>\n <dt>0</dt> <dd>A continuation frame, which is any frame after the first representing a message divided amongst multiple frames.</dd>\n <dt>1</dt> <dd>A text frame, which stores messages in a text compatible string format of unspecified string encoding.</dd>\n <dt>2</dt> <dd>A binary frame, which means the content comprises a binary buffer.</dd>\n <dt>3-7</dt> <dd>Reserved for future use.</dd>\n <dt>8</dt> <dd>A close control frame. This lets the remote end know the socket will immediately self-destruct.</dd>\n <dt>9</dt> <dd>A ping control frame. This provides heartbeat to the remote end.</dd>\n <dt>10</dt> <dd>A pong control frame, which is just a response to a ping frame.</dd>\n <dt>11-15</dt> <dd>Reserved for future use.</dd>\n </dl>\n <p>Opcode values in the <em>reserved for future use</em> category can be safely repurposed for custom application use so long as both sides of the socket agree on these custom definitions.</p>\n <p>In WebSockets messages cannot be intermingled.\n Each message must be sent serially in the order which the transmission buffer receives them.\n The WebSocket protocol does not specify a message queue, but I strongly recommend always including a message queue on each side of the socket.\n A message queue will ensure messages are not dropped if awaiting a prior message to finish transmission.</p>\n </div>\n </div>\n </div>\n <div class=\"form\">\n <p id=\"websocket-status\" class=\"connection-offline\">WebSocket Test socket: <strong>Offline</strong></p>\n <h3>Socket Connection</h3>\n <h4>Scheme</h4>\n <p><label class=\"radio\">Plain text (ws) <input name=\"socket_scheme\" type=\"radio\" value=\"false\"/></label> <label class=\"radio\">Encrypted (wss) <input checked=\"checked\" name=\"socket_scheme\" type=\"radio\" value=\"true\"/></label> <em class=\"block\">Ensure ports in the handshake message correspond to the scheme choice.</em></p>\n <h4>Handshake Timeout</h4>\n <p><label>Request timeout in milliseconds. Value defaults to 0 and a 0 value removes any timeout.<input spellcheck=\"false\" type=\"number\" value=\"0\"/></label></p>\n <h4>Raw Handshake Message</h4>\n <div class=\"http_response\">\n <p><label>Handshake message. <textarea class=\"test-input\" spellcheck=\"false\"></textarea></label></p>\n <p class=\"float-last\"><label>Handshake error messaging <textarea class=\"test-input\" readonly=\"true\" spellcheck=\"false\">Disconnected.</textarea></label></p>\n <span class=\"clear\"></span>\n </div>\n <p class=\"ports\">Localhost ports: <span></span></p>\n <p class=\"buttons\"><button>Connect</button></p>\n </div>\n <div class=\"form\">\n <h3>Messaging</h3>\n <div class=\"http_response\">\n <div class=\"form\">\n <h4>Send</h4>\n <p><label>Frame Header <textarea spellcheck=\"false\">{\n \"extended\": 0,\n \"fin\": false,\n \"len\": 0,\n \"mask\": false,\n \"maskKey\": \"\",\n \"opcode\": 1,\n \"rsv1\": false,\n \"rsv2\": false,\n \"rsv3\": false,\n \"startByte\": 0,\n}</textarea></label></p>\n <p class=\"float-last\"><label>Message <textarea spellcheck=\"false\"></textarea></label></p>\n <span class=\"clear\"></span>\n <p class=\"buttons\"><button disabled=\"disabled\">Send</button></p>\n </div>\n <div class=\"form\">\n <h4>Receive</h4>\n <p><label>Frame Header <textarea spellcheck=\"false\"></textarea></label></p>\n <p class=\"float-last\"><label>Message <textarea spellcheck=\"false\"></textarea></label></p>\n <span class=\"clear\"></span>\n <p><label><input type=\"checkbox\"/> Halt On Message</label></p>\n </div>\n <span class=\"clear\"></span>\n </div>\n </div>\n </div>\n <!-- test-websocket end -->\n <!-- udp-socket start -->\n <div class=\"tab\" id=\"udp-socket\">\n <h2>UDP Socket</h2>\n <p class=\"tab-description\">Creates a UDP socket and binds it to a specified port.</p>\n <div class=\"definitions\">\n <h3>UDP Reference Information <button class=\"expand\">Expand</button></h3>\n <div class=\"definition-body\">\n <div class=\"section\">\n <h4>Socket Traffic Distribution</h4>\n <p>A UDP socket may send traffic to a single socket end point, multiple socket end points, or all sockets on all interfaces.</p>\n <dl>\n <dt><em>unicast</em></dt>\n <dd>A unicast socket sends data to a single socket end point. This is most similar to TCP.</dd>\n <dt><em>multicast</em></dt>\n <dd>A multicast socket sends data to all socket end points in the socket's given multicast group. Multicast group membership may be designated by a specified IP in the multicast range or by multicast IP and interface identifier.</dd>\n <dt><em>broadcast</em></dt>\n <dd>A broadcast socket attempts to send data across all interfaces using a given network's broadcast address.</dd>\n <dt><em>anycast</em></dt>\n <dd>Anycast is a scheme where multiple destinations share a single address and traffic is routed to the first available of those destinations, such as a load balancer.</dd>\n </dl>\n </div>\n <div class=\"section\">\n <h4>Multicast Address Ranges</h4>\n <p>IPv4 multicast ranges are as follows, per <a href=\"https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml\">IANA definition</a>:</p>\n <ul>\n <li>\n General, Class D - <em>224.0.0.0 - 239.255.255.255</em> (224.0.0.0/4)\n <ul>\n <li>Link Local - <em>224.0.0.0 - 224.0.0.255</em> (224.0.0.0/24)</li>\n <li>\n Globally Scoped - <em>224.0.1.0 - 238.255.255.255</em>\n <ul>\n <li>Internetwork Control Block - <em>224.0.1.0 - 224.0.1.255</em> (224.0.1.0/24)</li>\n <li>AD HOC Block 1 - <em>224.0.2.0 - 224.0.255.255</em></li>\n <li>Reserved - <em>224.1.0.0 - 224.1.255.255</em> (224.1.0.0/16)</li>\n <li>SDP/SAP Block - <em>224.2.0.0 = 224.2.255.255</em> (224.2.0.0/16)</li>\n <li>AD HOC Block 2 - <em>224.3.0.0 - 224.4.255.255</em> (224.3.0.0/24, 224.4.0.0/24)</li>\n <li>Reserved - <em>224.5.0.0 - 224.251.255.255</em></li>\n <li>DIS Transient - <em>224.252.0.0 - 224.255.255.255</em> (224.252.0.0/14)</li>\n <li>Reserved - <em>225.0.0.0 - 231.255.255.255</em> (225.0.0.0/8, 226.0.0.0/7, 228.0.0.0/6)</li>\n <li>\n Source Specific Multicast - <em>232.0.0.0 - 232.255.255.255</em> (232.0.0.0/8)\n <ul>\n <li>Reserved - <em>232.0.0.0</em></li>\n <li>Reserved to IANA - <em>232.0.0.1 - 232.0.0.255</em></li>\n <li>Reserved to Local Host - <em>232.0.1.0 - 232.255.255.255</em></li>\n </ul>\n </li>\n <li>GLOP - <em>233.0.0.0 - 233.251.255.255</em></li>\n <li>AD HOC Block 3 - <em>233.252.0.0 - 233.255.255.255</em> (233.252.0.0/14)</li>\n <li>Unicast-Prefix Based Multicast - <em>234.0.0.0 - 234.255.255.255</em></li>\n <li>Reserved Scoped Multicast - <em>235.0.0.0 - 238.255.255.255</em></li>\n <li>Local-Scoped Multicast - <em>239.0.0.0 - 239.255.255.255</em> (239.0.0.0/8)</li>\n </ul>\n </li>\n <li>Private - <em>239.0.0.0 - 239.255.255.255</em> (239.0.0.0/8)</li>\n </ul>\n </li>\n </ul>\n <p>IPv6 ranges are as follows, per <a href=\"https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml\">IANA definition</a>. Please note that within the ranges below single address exceptions are noted by IANA.</p>\n <ul>\n <li>Node-Local Scope Multicast - <em>ff01::1 - ff01:ffff:ffff:ffff:ffff:ffff:ffff:ffff</em></li>\n <li>\n Link-Local Scope Multicast - <em>ff02::1 - ff02:ffff:ffff:ffff:ffff:ffff:ffff:ffff</em>\n <ul><li>Solicited Node Address - <em>ff02:0:0:0:0:1:ff00:0 - ff02:0:0:0:0:1:ffff:ffff</em></li></ul>\n </li>\n <li>Site-Local Scope Multicast - <em>ff05::1 - ff05::ffff:ffff:ffff:ffff:ffff:ffff:ffff</em></li>\n <li>Variable Scope Multicast - <em>ff0X::1 - ff0X::ffff:ffff:ffff:ffff:ffff:ffff:ffff</em>, where X is any accepted digit and address is not already specified</li>\n <li>Unicast-Based Multicast, IANA allocation - <em>ff3X::4000 - ff3X:0:0:0:0:0:7fff:ffff</em>, where X is any accepted digit and address is not already specified</li>\n <li>Unicase-Based Multicast, dynamic allocation - <em>ff3X::8000 - ff3X:0:0:0:0:0:ffff:ffff</em>, where X is any accepted digit and address is not already specified</li>\n </ul>\n </div>\n </div>\n </div>\n <div class=\"form\">\n <h3>Create UDP Socket</h3>\n <h4>Role</h4>\n <p>\n <label class=\"radio\">Connect (Client) <input name=\"udp-socket-role\" type=\"radio\" value=\"client\"/></label>\n <label class=\"radio\">Bind (Server) <input checked=\"checked\" name=\"udp-socket-role\" type=\"radio\" value=\"server\"/></label>\n </p>\n <h4>Address Type</h4>\n <p>\n <label class=\"radio\">IPv4 <input name=\"udp-socket-type\" type=\"radio\" value=\"ipv4\"/></label>\n <label class=\"radio\">IPv6 <input checked=\"checked\" name=\"udp-socket-type\" type=\"radio\" value=\"ipv6\"/></label>\n </p>\n </div>\n <div class=\"udp-role-server\">\n <h3>Server Side Configurations</h3>\n <p>For UDP sockets that act as a point of connection, like a server, they must be bound to a local port. These sockets can optionally become multicast and a multicast socket can either be configured against a local IP address identity or more restrictively against a remote IP address identity. Multicast identity is specific to one or all physical network interfaces of the local machine.</p>\n <p><label>Local <span></span> Address, <em>optional</em> and limits the socket to a single address identity <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Local Port, defaults to a random port <input spellcheck=\"false\" type=\"number\"/></label></p>\n <h4>Multicast Type</h4>\n <p>\n <label class=\"multicast\">Source Specific Multicast <input name=\"udp-socket-multicast\" type=\"radio\" value=\"source\"/></label>\n <label class=\"multicast\">Multicast Membership <input name=\"udp-socket-multicast\" type=\"radio\" value=\"membership\"/></label>\n <label class=\"multicast\">Not Multicast <input checked=\"checked\" name=\"udp-socket-multicast\" type=\"radio\" value=\"none\"/></label>\n </p>\n <p class=\"udp-socket-multicast-source\"><label>Multicast Source <span></span> Address <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p class=\"udp-socket-multicast-group\"><label>Multicast Group <span></span> Address <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p class=\"udp-socket-multicast-membership\"><label>Multicast Membership <span></span> Address <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p class=\"udp-socket-multicast-interface\"><label>Network Interface <select><option>All Interfaces</option></select></label></p>\n </div>\n <div class=\"udp-role-client\">\n <h3>Connecting Side Configurations</h3>\n <p>A UDP socket that behaves as a client is merely a socket that connects to a remote address/port and all traffic on that socket, sent or received, will be limited to that remote. It will receive a random local port.</p>\n <p><label>Destination <span></span> Address <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Destination Port <input spellcheck=\"false\" type=\"number\"/></label></p>\n </div>\n <div class=\"form\">\n <h3>Socket Creation</h3>\n <p><button>Create Socket</button></p>\n <p>Status: <em class=\"udp-socket-status\">nothing</em></p>\n </div>\n </div>\n <!-- udp-socket end-->\n <!-- users start -->\n <div class=\"tab\" id=\"users\">\n <h2>Users</h2>\n <p class=\"tab-description\">A list of user accounts on the local operating system. Data automatically refreshes at server's midnight time.</p>\n <div class=\"table-filters\">\n <h3>List Controls</h3>\n <p><label>Column(s) To Filter <select></select></label></p>\n <p><label>Filter Value <input spellcheck=\"false\" type=\"text\"/></label></p>\n <p><label>Case Sensitive <input checked=\"checked\" type=\"checkbox\"/></label></p>\n <span class=\"clear\"></span>\n </div>\n <div class=\"section\">\n <h3>User List</h3>\n <div class=\"table-stats\">\n <p class=\"update-button\"><button>Update List</button></p>\n <p><span>Total Users</span> <em></em></p>\n <p><span>Filtered Users</span> <em></em></p>\n <p><span>Last Updated</span> <time></time></p>\n </div>\n <table data-column=\"0\">\n <thead><tr>\n <th><button data-dir=\"1\">Name</button></th>\n <th><button data-dir=\"1\">SID/UID</button></th>\n <th><button data-dir=\"1\">Last Login</button></th>\n <th><button data-dir=\"1\">Process Count</button></th>\n <th><button data-dir=\"1\">Account Type</button></th>\n </tr></thead>\n <tbody></tbody>\n </table>\n </div>\n </div>\n <!-- users end -->\n </main>\n<script type=\"module\">replace_javascript</script></body></html>"},"service":"dashboard-hash"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment