Merge branch 'dev'

This commit is contained in:
zefie
2021-08-08 22:27:47 -04:00
12 changed files with 147 additions and 88 deletions

View File

@@ -144,7 +144,7 @@ if (ssid_sessions[socket.ssid].data_store.wtvsec_login) {
headers += getServiceString('wtv-flashrom') + "\n"; headers += getServiceString('wtv-flashrom') + "\n";
if (bf0app_update) headers += "wtv-boot-url: " + gourl + "\n"; if (bf0app_update) headers += "wtv-boot-url: " + gourl + "\n";
else { else {
headers += "wtv-boot-url: wtv-1800:/preregister?relogin=true"; headers += "wtv-boot-url: wtv-head-waiter:/relogin?relogin=true";
if (request_headers.query.guest_login) headers += "&guest_login=true"; if (request_headers.query.guest_login) headers += "&guest_login=true";
headers += "\n"; headers += "\n";
} }

View File

@@ -43,7 +43,7 @@ wtv-ticket: ${wtvsec_login.ticket_b64}
${getServiceString('wtv-register')} ${getServiceString('wtv-register')}
${getServiceString('wtv-head-waiter')} ${getServiceString('wtv-head-waiter')}
${getServiceString('wtv-star')} ${getServiceString('wtv-star')}
wtv-boot-url: wtv-register:/splash? wtv-boot-url: wtv-head-waiter:/relogin?
` `
} }
headers += `wtv-visit: ${gourl} headers += `wtv-visit: ${gourl}
@@ -110,11 +110,11 @@ wtv-connection-timeout: 90
wtv-show-time-enabled: true wtv-show-time-enabled: true
wtv-fader-timeout: 900 wtv-fader-timeout: 900
wtv-tourist-enabled: true` wtv-tourist-enabled: true`
headers += "\nwtv-relogin-url: wtv-1800:/preregister?relogin=true"; headers += "\nwtv-relogin-url: wtv-head-waiter:/relogin?relogin=true";
if (request_headers.query.guest_login) headers += "&guest_login=true"; if (request_headers.query.guest_login) headers += "&guest_login=true";
headers += "\nwtv-reconnect-url: wtv-1800:/preregister?reconnect=true"; headers += "\nwtv-reconnect-url: wtv-head-waiter:/relogin?reconnect=true";
if (request_headers.query.guest_login) headers += "&guest_login=true"; if (request_headers.query.guest_login) headers += "&guest_login=true";
headers += "\nwtv-boot-url: wtv-1800:/preregister?relogin=true"; headers += "\nwtv-boot-url: wtv-head-waiter:/relogin?relogin=true";
if (request_headers.query.guest_login) headers += "&guest_login=true"; if (request_headers.query.guest_login) headers += "&guest_login=true";
headers += "\nwtv-allow-dsc: true"; headers += "\nwtv-allow-dsc: true";
headers += "\nwtv-home-url: wtv-home:/home?"; headers += "\nwtv-home-url: wtv-home:/home?";

View File

@@ -53,8 +53,8 @@ wtv-expire-all: wtv-head-waiter:
wtv-log-url: wtv-log:/log`; wtv-log-url: wtv-log:/log`;
if (challenge_header != "") headers += "\n" + challenge_header; if (challenge_header != "") headers += "\n" + challenge_header;
headers += ` headers += `
wtv-relogin-url: wtv-1800:/preregister?relogin=true wtv-relogin-url: wtv-head-waiter:/relogin?relogin=true
wtv-reconnect-url: wtv-1800:/preregister?reconnect=true wtv-reconnect-url: wwtv-head-waiter:/relogin?reconnect=true
wtv-visit: ${gourl} wtv-visit: ${gourl}
Content-type: text/html`; Content-type: text/html`;
data = ''; data = '';
@@ -66,7 +66,7 @@ Connection: Keep-Alive
Expires: Wed, 09 Oct 1991 22:00:00 GMT Expires: Wed, 09 Oct 1991 22:00:00 GMT
wtv-expire-all: wtv-head-waiter: wtv-expire-all: wtv-head-waiter:
wtv-expire-all: wtv-1800: wtv-expire-all: wtv-1800:
wtv-visit: wtv-1800:/preregister?relogin=true wtv-visit: wtv-head-waiter:/relogin?relogin=true
Content-type: text/html`; Content-type: text/html`;
data = ''; data = '';
} }

View File

@@ -0,0 +1,20 @@
var gourl = "wtv-1800:/preregister?";
if (request_headers.query.relogin) gourl += "relogin=true";
else if (request_headers.query.reconnect) gourl += "reconnect=true";
if (request_headers.query.guest_login) {
if (request_headers.query.relogin || request_headers.query.reconnect) gourl += "&";
gourl += "guest_login=true";
if (request_headers.query.skip_splash) gourl += "&skip_splash=true";
}
headers = `200 OK
Connection: Keep-Alive
Expires: Wed, 09 Oct 1991 22:00:00 GMT
wtv-expire-all: wtv-head-waiter:
wtv-expire-all: wtv-1800:
wtv-service: reset
${getServiceString('wtv-1800')}
wtv-visit: ${gourl}
Content-type: text/html`;
data = '';

View File

@@ -249,17 +249,17 @@ WARRANTY OF ANY KIND. THE INFORMATION, SOFTWARE, PRODUCTS, AND SERVICES INCLUDED
THROUGH THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE MAY INCLUDE INACCURACIES OR TYPOGRAPHICAL ERRORS. THROUGH THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE MAY INCLUDE INACCURACIES OR TYPOGRAPHICAL ERRORS.
ADVICE RECEIVED VIA THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE SHOULD NOT BE RELIED UPON FOR PERSONAL, ADVICE RECEIVED VIA THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE SHOULD NOT BE RELIED UPON FOR PERSONAL,
MEDICAL, LEGAL OR FINANCIAL DECISIONS AND YOU SHOULD CONSULT AN APPROPRIATE MEDICAL, LEGAL OR FINANCIAL DECISIONS AND YOU SHOULD CONSULT AN APPROPRIATE
PROFESSIONAL FOR SPECIFIC ADVICE TAILORED TO YOUR SITUATION. MICROSOFT, PROFESSIONAL FOR SPECIFIC ADVICE TAILORED TO YOUR SITUATION. ${WTVRegister.getServiceOperator().toUpperCase()},
ITS RESELLERS, DISTRIBUTORS AND/OR SUPPLIERS DO NOT WARRANT THAT ACCESS TO ITS RESELLERS, DISTRIBUTORS AND/OR SUPPLIERS DO NOT WARRANT THAT ACCESS TO
OR USE OF THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE WILL BE UNINTERRUPTED OR ERROR-FREE, THAT MEMBERS OR USE OF THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE WILL BE UNINTERRUPTED OR ERROR-FREE, THAT MEMBERS
WILL BE ABLE TO ACCESS THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE AT ANY TIME OR IN ANY GEOGRAPHIC AREA, WILL BE ABLE TO ACCESS THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE AT ANY TIME OR IN ANY GEOGRAPHIC AREA,
OR THAT THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE OR ${WTVRegister.getServiceOperator().toUpperCase()} SOFTWARE OR SERVICES WILL MEET ANY OR THAT THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE OR ${WTVRegister.getServiceOperator().toUpperCase()} SOFTWARE OR SERVICES WILL MEET ANY
PARTICULAR CRITERIA OF PERFORMANCE OR QUALITY. MICROSOFT, ITS RESELLERS, PARTICULAR CRITERIA OF PERFORMANCE OR QUALITY. ${WTVRegister.getServiceOperator().toUpperCase()}, ITS RESELLERS,
DISTRIBUTORS AND/OR SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS DISTRIBUTORS AND/OR SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS
WITH REGARD TO THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE AND ALL RELATED SOFTWARE, INFORMATION, WITH REGARD TO THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE AND ALL RELATED SOFTWARE, INFORMATION,
PRODUCTS, SERVICES AND GRAPHICS, INCLUDING ALL IMPLIED WARRANTIES AND PRODUCTS, SERVICES AND GRAPHICS, INCLUDING ALL IMPLIED WARRANTIES AND
CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, WORKMANLIKE CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, WORKMANLIKE
EFFORT, TITLE, AND NON-INFRINGEMENT. IN NO EVENT SHALL MICROSOFT, ITS EFFORT, TITLE, AND NON-INFRINGEMENT. IN NO EVENT SHALL ${WTVRegister.getServiceOperator().toUpperCase()}, ITS
RESELLERS, DISTRIBUTORS AND/OR SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, RESELLERS, DISTRIBUTORS AND/OR SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT,
PUNITIVE, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES PUNITIVE, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA, OR WHATSOEVER, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA, OR
@@ -281,7 +281,7 @@ DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR
INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU. IF YOU ARE INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU. IF YOU ARE
DISSATISFIED WITH ANY PORTION OF THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE, OR WITH ANY OF THESE DISSATISFIED WITH ANY PORTION OF THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE, OR WITH ANY OF THESE
TERMS OF USE, YOUR SOLE AND EXCLUSIVE REMEDY IS TO NOT REGISTER FOR A ${minisrv_config.config.service_name.toUpperCase()} TERMS OF USE, YOUR SOLE AND EXCLUSIVE REMEDY IS TO NOT REGISTER FOR A ${minisrv_config.config.service_name.toUpperCase()}
SERVICE ACCOUNT OR TO TERMINATE YOUR ${minisrv_config.config.service_name.toUpperCase()} SERVICE ACCOUNT. MICROSOFT MAY, SERVICE ACCOUNT OR TO TERMINATE YOUR ${minisrv_config.config.service_name.toUpperCase()} SERVICE ACCOUNT. ${WTVRegister.getServiceOperator().toUpperCase()} MAY,
IN ITS SOLE DISCRETION AND WITHOUT PRIOR NOTICE (I) RESTRICT OR LIMIT ACCESS IN ITS SOLE DISCRETION AND WITHOUT PRIOR NOTICE (I) RESTRICT OR LIMIT ACCESS
TO THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE; (II) TERMINATE A USER ACCOUNT OR USER SESSIONS AT ANY TO THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE; (II) TERMINATE A USER ACCOUNT OR USER SESSIONS AT ANY
TIME; OR (III) DISCONTINUE OR MODIFY ANY OR ALL ASPECTS OF THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE OR ITS SERVICES. TIME; OR (III) DISCONTINUE OR MODIFY ANY OR ALL ASPECTS OF THE ${minisrv_config.config.service_name.toUpperCase()} SERVICE OR ITS SERVICES.

View File

@@ -40,7 +40,7 @@ Welcome
ENCTYPE="x-www-form-encoded" METHOD="POST"> ENCTYPE="x-www-form-encoded" METHOD="POST">
<input type=hidden name=registering value="true"> <input type=hidden name=registering value="true">
<td height=230 width= 300 bgcolor="#171726" colspan=5 valign=top align=left> <td height=230 width= 300 bgcolor="#171726" colspan=5 valign=top align=left>
Welcome to the ${minisrv_config.config.service_name} Mini Service, operated by ${minisrv_config.config.service_owner} Welcome to the ${minisrv_config.config.service_name} Mini Service, operated by ${minisrv_config.config.service_owner}.
The next screens will lead you through a quick setup process for using this service.<p> Press the "Continue" button below to begin setup.<p> The next screens will lead you through a quick setup process for using this service.<p> Press the "Continue" button below to begin setup.<p>
<td abswidth=20 bgcolor=#171726 > <td abswidth=20 bgcolor=#171726 >
</tr> </tr>

View File

@@ -202,7 +202,7 @@ class WTVClientSessionData {
try { try {
// only save if file has changed // only save if file has changed
var json_save_data = JSON.stringify(this.session_store); var json_save_data = JSON.stringify(this.session_store);
var json_load_data = loadSessionData(true); var json_load_data = this.loadSessionData(true);
if (json_save_data != json_load_data) this.fs.writeFileSync(this.session_storage + this.path.sep + this.ssid + ".json", JSON.stringify(this.session_store), "Utf8"); if (json_save_data != json_load_data) this.fs.writeFileSync(this.session_storage + this.path.sep + this.ssid + ".json", JSON.stringify(this.session_store), "Utf8");
return true; return true;
} catch (e) { } catch (e) {

View File

@@ -15,12 +15,12 @@ class WTVLzpf {
current_length = 0; current_length = 0;
current_literal = 0; current_literal = 0;
flag = 0xFFFF; flag = 0xFFFFFFFF;
working_data = 0; working_data = 0;
match_index = 0; match_index = 0;
type_index = 0; type_index = 0;
checksum = 0; checksum = 0;
flag_table = new Uint16Array(0x1000) flag_table = new Uint32Array(0x1000)
ring_buffer = new Uint8Array(0x2000) ring_buffer = new Uint8Array(0x2000)
encoded_data = []; encoded_data = [];
@@ -283,13 +283,13 @@ class WTVLzpf {
clear() { clear() {
this.current_length = 0; this.current_length = 0;
this.current_literal = 0; this.current_literal = 0;
this.flag = 0xFFFF; this.flag = 0xFFFFFFFF;
this.working_data = 0; this.working_data = 0;
this.match_index = 0; this.match_index = 0;
this.type_index = 0; this.type_index = 0;
this.checksum = 0; this.checksum = 0;
this.ring_buffer.fill(0x00, 0, 0x2000) this.ring_buffer.fill(0x00, 0, 0x2000)
this.flag_table.fill(0xFFFF, 0, 0x1000); this.flag_table.fill(0xFFFFFFFF, 0, 0x1000);
this.encoded_data = []; this.encoded_data = [];
} }
@@ -364,28 +364,28 @@ class WTVLzpf {
this.type_index = 3; this.type_index = 3;
} else { } else {
this.match_index = (this.match_index + 1) & 0x1FFF; this.match_index = (this.match_index + 1) & 0x1FFF;
this.flag = (this.flag + 1) & 0x1FFF; this.flag = (this.flag + 1) & 0x1FFFFFFF;
this.checksum = (this.checksum + byte) & 0xFFFF; this.checksum = (this.checksum + byte) & 0xFFFF;
this.working_data = ((this.working_data * 0x0100) + byte) & 0xFFFFFFFF; this.working_data = ((this.working_data * 0x0100) + byte) & 0xFFFFFFFF;
i++; i++;
} }
} else { } else {
this.flag = 0xFFFF; this.flag = 0xFFFFFFFF;
if (i >= 3) { if (i >= 3) {
flags_index = (this.working_data >>> 0x0B ^ this.working_data) & 0x0FFF; flags_index = (this.working_data >>> 0x0B ^ this.working_data) & 0x0FFF;
this.flag = this.flag_table[flags_index]; this.flag = this.flag_table[flags_index];
this.flag_table[flags_index] = i & 0x1FFF; this.flag_table[flags_index] = i & 0x1FFFFFFF;
} else { } else {
this.type_index++; this.type_index++;
} }
if (this.flag == 0xFFFF) { if (this.flag == 0xFFFFFFFF) {
code_length = this.nomatchEncode[byte][1]; code_length = this.nomatchEncode[byte][1];
code = this.nomatchEncode[byte][0] << 0x10; code = this.nomatchEncode[byte][0] << 0x10;
} else if (byte == this.ring_buffer[this.flag] && compress_data) { } else if (byte == this.ring_buffer[this.flag] && compress_data) {
this.match_index = 1; this.match_index = 1;
this.flag = (this.flag + 1) & 0x1FFF; this.flag = (this.flag + 1) & 0x1FFFFFFF;
this.type_index = 4; this.type_index = 4;
} else { } else {
code_length = this.nomatchEncode[byte][1] + 1; code_length = this.nomatchEncode[byte][1] + 1;
@@ -427,7 +427,7 @@ class WTVLzpf {
var flags_index = (this.working_data >>> 0x0B ^ this.working_data) & 0x0FFF; var flags_index = (this.working_data >>> 0x0B ^ this.working_data) & 0x0FFF;
var flag = this.flag_table[flags_index]; var flag = this.flag_table[flags_index];
if (flag == 0xFFFF) { if (flag == 0xFFFFFFFF) {
this.EncodeLiteral(0x10, 0x00990000); this.EncodeLiteral(0x10, 0x00990000);
} else { } else {
this.EncodeLiteral(0x11, 0x004c8000); this.EncodeLiteral(0x11, 0x004c8000);

View File

@@ -2,6 +2,7 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const zlib = require('zlib');
const http = require('http'); const http = require('http');
const https = require('https'); const https = require('https');
const strftime = require('strftime'); // used externally by service scripts const strftime = require('strftime'); // used externally by service scripts
@@ -100,68 +101,70 @@ function doErrorPage(code, data = null) {
function getConType(path) { function getConType(path) {
var file_ext = getFileExt(path).toLowerCase(); var file_ext = getFileExt(path).toLowerCase();
var wtv_mime_type = "";
var modern_mime_type = "";
// process WebTV overrides, fall back to generic mime lookup // process WebTV overrides, fall back to generic mime lookup
switch (file_ext) { switch (file_ext) {
case "aif": case "aif":
return "audio/x-aif"; wtv_mime_type = "audio/x-aif";
case "aifc": case "aifc":
return "audio/x-aifc"; wtv_mime_type = "audio/x-aifc";
case "aiff": case "aiff":
return "audio/x-aiff"; wtv_mime_type = "audio/x-aiff";
case "ani": case "ani":
return "x-wtv-animation"; wtv_mime_type = "x-wtv-animation";
case "brom": case "brom":
return "binary/x-wtv-bootrom"; wtv_mime_type = "binary/x-wtv-bootrom";
case "cdf": case "cdf":
return "application/netcdf"; wtv_mime_type = "application/netcdf";
case "dat": case "dat":
return "binary/cache-data"; wtv_mime_type = "binary/cache-data";
case "dl": case "dl":
return "wtv/download-list"; wtv_mime_type = "wtv/download-list";
case "gsm": case "gsm":
return "audio/x-gsm"; wtv_mime_type = "audio/x-gsm";
case "gz": case "gz":
return "application/gzip"; wtv_mime_type = "application/gzip";
case "ini": case "ini":
return "wtv/jack-configuration"; wtv_mime_type = "wtv/jack-configuration";
case "mips-code": case "mips-code":
return "code/x-wtv-code-mips"; wtv_mime_type = "code/x-wtv-code-mips";
case "o": case "o":
return "binary/x-wtv-approm"; wtv_mime_type = "binary/x-wtv-approm";
case "ram": case "ram":
return "audio/x-pn-realaudio"; wtv_mime_type = "audio/x-pn-realaudio";
case "rom": case "rom":
return "binary/x-wtv-flashblock"; wtv_mime_type = "binary/x-wtv-flashblock";
case "rsp": case "rsp":
return "wtv/jack-response"; wtv_mime_type = "wtv/jack-response";
case "swa": case "swa":
case "swf": case "swf":
return "application/x-shockwave-flash"; wtv_mime_type = "application/x-shockwave-flash";
case "srf": case "srf":
case "spl": case "spl":
return "wtv/jack-data"; wtv_mime_type = "wtv/jack-data";
case "ttf": case "ttf":
return "wtv/jack-fonts"; wtv_mime_type = "wtv/jack-fonts";
case "tvch": case "tvch":
return "wtv/tv-channels"; wtv_mime_type = "wtv/tv-channels";
case "tvl": case "tvl":
return "wtv/tv-listings"; wtv_mime_type = "wtv/tv-listings";
case "tvsl": case "tvsl":
return "wtv/tv-smartlinks"; wtv_mime_type = "wtv/tv-smartlinks";
case "wad": case "wad":
return "binary/doom-data"; wtv_mime_type = "binary/doom-data";
case "mp2": case "mp2":
case "hsb": case "hsb":
case "rmf": case "rmf":
case "s3m": case "s3m":
case "mod": case "mod":
case "xm": case "xm":
return "application/Music"; wtv_mime_type = "application/Music";
} }
// if we reach here, its not a WebTV specific override modern_mime_type = mime.lookup(path);
// or we are not yet aware of said override if (wtv_mime_type == "") wtv_mime_type = modern_mime_type;
return mime.lookup(path); return new Array(wtv_mime_type, modern_mime_type);
} }
async function processPath(socket, service_vault_file_path, request_headers = new Array(), service_name) { async function processPath(socket, service_vault_file_path, request_headers = new Array(), service_name) {
@@ -180,9 +183,10 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
service_vault_found = true; service_vault_found = true;
request_is_async = true; request_is_async = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + " to handle request (Direct File Mode) [Socket " + socket.id + "]"); if (!zquiet) console.log(" * Found " + service_vault_file_path + " to handle request (Direct File Mode) [Socket " + socket.id + "]");
var contype = getConType(service_vault_file_path); var contypes = getConType(service_vault_file_path);
headers = "200 OK\n" headers = "200 OK\n"
headers += "Content-Type: " + contype; headers += "Content-Type: " + contypes[0] + "\n";
headers += "wtv-modern-content-type" + contypes[1];
fs.readFile(service_vault_file_path, null, function (err, data) { fs.readFile(service_vault_file_path, null, function (err, data) {
sendToClient(socket, headers, data); sendToClient(socket, headers, data);
}); });
@@ -585,11 +589,11 @@ async function sendToClient(socket, headers_obj, data) {
headers_obj = moveObjectElement('Connection', 'http_response', headers_obj); headers_obj = moveObjectElement('Connection', 'http_response', headers_obj);
} }
var clen = 0; var content_length = 0;
if (typeof data.length !== 'undefined') { if (typeof data.length !== 'undefined') {
clen = data.length; content_length = data.length;
} else if (typeof data.byteLength !== 'undefined') { } else if (typeof data.byteLength !== 'undefined') {
clen = data.byteLength; content_length = data.byteLength;
} }
// fix captialization // fix captialization
@@ -601,28 +605,80 @@ async function sendToClient(socket, headers_obj, data) {
// if box can do compression, see if its worth enabling // if box can do compression, see if its worth enabling
if (ssid_sessions[socket.ssid].capabilities) { if (ssid_sessions[socket.ssid].capabilities) {
if (ssid_sessions[socket.ssid].capabilities['client-can-receive-compressed-data'] && minisrv_config.config.enable_lzpf_compression) { if (ssid_sessions[socket.ssid].capabilities['client-can-receive-compressed-data']) {
compress_data = shouldWeCompress(headers_obj["Content-Type"]); var compression_type = 1; // lzpf
if (ssid_sessions[socket.ssid].get("wtv-client-rom-type") != "bf0app") {
var compression_type = 2; // gzip
}
// mostly for debugging
if (minisrv_config.config.force_compression_type == "lzpf") compression_type = 1;
if (minisrv_config.config.force_compression_type == "gzip") compression_type = 2;
// should we bother to compress?
if (!headers_obj["Content-Encoding"]) {
if (typeof (headers_obj["Content-Type"]) != 'undefined') {
var content_type = (typeof (headers_obj["wtv-modern-content-type"]) != 'undefined') ? headers_obj["wtv-modern-content-type"] : headers_obj["Content-Type"];
// both lzpf and gzip
if (content_type.match(/^text\//) && headers_obj["Content-Type"] != "text/tellyscript") compress_data = true;
else if (content_type.match(/^application\/(x-?)javascript$/)) compress_data = true;
else if (content_type == "application/json") compress_data = true;
if (compression_type == 2) {
// gzip only
if (content_type.match(/^audio\/(x-)?[midi|wav]/)) compress_data = true; // midi & wav
if (content_type.match(/^audio\/(x-)?[s3m|mod|xm]/)) compress_data = true; // s3m, mod, xm
if (content_type.match(/^audio\/(x-)?[midi|wav]/)) compress_data = true; // midi & wav
}
}
}
if (headers_obj["wtv-modern-content-type"]) delete headers_obj["wtv-modern-content-type"];
} }
} }
// compress if needed // compress if needed
if (compress_data && clen > 0) { if (compress_data && compression_type && content_length > 0) {
content_length = clen; var uncompressed_content_length = content_length;
switch (compression_type) {
case 1:
// wtv-lzpf implementation
if (minisrv_config.config.enable_lzpf_compression || minisrv_config.config.force_compression_type) {
headers_obj["wtv-lzpf"] = 0;
var wtvcomp = new WTVLzpf();
data = wtvcomp.Compress(data);
wtvcomp = null; // Makes the garbage gods happy so it cleans up our mess
}
break;
headers_obj["wtv-lzpf"] = 0; case 2:
// zlib gzip implementation
if (minisrv_config.config.enable_gzip_compression || minisrv_config.config.force_compression_type) {
headers_obj['Content-Encoding'] = 'gzip';
data = zlib.gzipSync(data, {
'level': 9
});
}
break;
}
var wtvcomp = new WTVLzpf(); var compressed_content_length = 0;
data = wtvcomp.Compress(data); if (content_length == 0 || compression_type != 1) {
// ultimately send compressed content length
wtvcomp = null; // Makes the garbage gods happy so it cleans up our mess compressed_content_length = data.byteLength;
content_length = compressed_content_length;
} else {
// ultimately send original content length if lzpf
compressed_content_length = data.byteLength;
}
var compression_percentage = ((compressed_content_length / uncompressed_content_length) * 100).toFixed(1).toString() + "%";
if (uncompressed_content_length != compressed_content_length) if (zdebug) console.log(" # Compression stats: Orig Size:", uncompressed_content_length, "~ Comp Size:", compressed_content_length, "~ Ratio:", compression_percentage);
} }
// encrypt if needed // encrypt if needed
if (socket_sessions[socket.id].secure == true) { if (socket_sessions[socket.id].secure == true) {
headers_obj["wtv-encrypted"] = 'true'; headers_obj["wtv-encrypted"] = 'true';
headers_obj = moveObjectElement('wtv-encrypted', 'Connection', headers_obj); headers_obj = moveObjectElement('wtv-encrypted', 'Connection', headers_obj);
if (clen > 0 && socket_sessions[socket.id].wtvsec) { if (content_length > 0 && socket_sessions[socket.id].wtvsec) {
if (!zquiet) console.log(" * Encrypting response to client ...") if (!zquiet) console.log(" * Encrypting response to client ...")
var enc_data = socket_sessions[socket.id].wtvsec.Encrypt(1, data); var enc_data = socket_sessions[socket.id].wtvsec.Encrypt(1, data);
data = enc_data; data = enc_data;
@@ -634,14 +690,6 @@ async function sendToClient(socket, headers_obj, data) {
if (headers_obj["Content-Length"]) delete headers_obj["Content-Length"]; if (headers_obj["Content-Length"]) delete headers_obj["Content-Length"];
if (headers_obj["Content-length"]) delete headers_obj["Content-length"]; if (headers_obj["Content-length"]) delete headers_obj["Content-length"];
if (content_length == 0) {
if (typeof data.length !== 'undefined') {
content_length = data.length;
} else if (typeof data.byteLength !== 'undefined') {
content_length = data.byteLength;
}
}
headers_obj["Content-length"] = content_length; headers_obj["Content-length"] = content_length;
if (ssid_sessions[socket.ssid]) { if (ssid_sessions[socket.ssid]) {
@@ -713,19 +761,6 @@ async function sendToClient(socket, headers_obj, data) {
} }
} }
function shouldWeCompress(content_type) {
if (typeof (content_type) != 'undefined') {
if ((content_type.match(/^text\//) && content_type != "text/tellyscript") ||
content_type.match(/^application\/(x-?)javascript$/) ||
content_type.match(/^audio\/(x-)?midi/) ||
content_type.match(/^audio\/(x-)?wav/) ||
content_type == "application/json") {
return true;
}
}
return false;
}
function concatArrayBuffer(buffer1, buffer2) { function concatArrayBuffer(buffer1, buffer2) {
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(new Uint8Array(buffer1), 0); tmp.set(new Uint8Array(buffer1), 0);

View File

@@ -15,6 +15,7 @@
"verbosity": 2, "verbosity": 2,
"error_log_file": "errors.log", "error_log_file": "errors.log",
"enable_lzpf_compression": false, "enable_lzpf_compression": false,
"enable_gzip_compression": true,
"allow_guests": true "allow_guests": true
}, },
"services": { "services": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "zefie_wtvp_minisrv", "name": "zefie_wtvp_minisrv",
"version": "0.9.13", "version": "0.9.14",
"description": "WebTV Service (WTVP) Emulation Server", "description": "WebTV Service (WTVP) Emulation Server",
"main": "app.js", "main": "app.js",
"homepage": "https://github.com/zefie/zefie_wtvp_minisrv", "homepage": "https://github.com/zefie/zefie_wtvp_minisrv",

View File

@@ -71,6 +71,9 @@
<Content Include="ServiceVault\wtv-flashrom\ROMCache\up-arrows.swf" /> <Content Include="ServiceVault\wtv-flashrom\ROMCache\up-arrows.swf" />
<Content Include="ServiceVault\wtv-flashrom\ROMCache\WebTVLogoJewel.gif" /> <Content Include="ServiceVault\wtv-flashrom\ROMCache\WebTVLogoJewel.gif" />
<Content Include="ServiceVault\wtv-flashrom\willie.js" /> <Content Include="ServiceVault\wtv-flashrom\willie.js" />
<Content Include="ServiceVault\wtv-head-waiter\relogin.js">
<SubType>Code</SubType>
</Content>
<Content Include="ServiceVault\wtv-music\demo\hacktv4.gif" /> <Content Include="ServiceVault\wtv-music\demo\hacktv4.gif" />
<Content Include="ServiceVault\wtv-music\demo\index.html" /> <Content Include="ServiceVault\wtv-music\demo\index.html" />
<Content Include="ServiceVault\wtv-music\demo\midi\acey.mid" /> <Content Include="ServiceVault\wtv-music\demo\midi\acey.mid" />