diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/current-noflash.js b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/current-noflash.js index 3afc0834..aa7d71b0 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/current-noflash.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/current-noflash.js @@ -1,3 +1,6 @@ +const WTVFlashrom = require("./WTVFlashrom.js"); +request_is_async = true; + // this build can be local or on zefie's server // to get the path from zefie's server, browse // https://archive.midnightchannel.net/zefie/files/wtv-flashrom/content/artemis-webtv-000/ @@ -5,110 +8,23 @@ // example is below var default_build_to_send = minisrv_config.services[service_name].bf0app_default_rom || "content/artemis-webtv-000/build7181/daily-nondebug/bf0app-part000.rom"; -headers = "200 OK\n"; + var request_path = ""; var bf0app_update = true; if (request_headers.query.path) request_path = unescape(request_headers.query.path); else request_path = default_build_to_send; -request_is_async = true; if (ssid_sessions[socket.ssid].get("wtv-client-rom-type") == "bf0app" && ssid_sessions[socket.ssid].get("wtv-client-bootrom-version") == "105") { // assume old classic in flash mode, override user setting and send tellyscript // because it is required to proceed in flash mode bf0app_update = true; ssid_sessions[socket.ssid].set("bf0app_update", bf0app_update); - headers += "minisrv-use-carriage-return: false\n"; } -function doLocalFlashROM(flashrom_file_path) { - // use local flashrom files; - try { - fs.readFile(flashrom_file_path, null, function (err, data) { - if (err) { - errpage = doErrorPage(400) - headers = errpage[0]; - data = err.toString(); - } - sendToClient(socket, headers, data); - }); - } catch (e) { - var errpage = doErrorPage(404, "The service could not find the requested ROM.") - headers = errpage[0]; - data = errpage[1]; - sendToClient(socket, headers, data); - } -} - -function calculatedPath(data, path, numparts = null) { - var data_128 = new Buffer.alloc(128); - data.copy(data_128, 0, 0, 128); - var flashrom_numparts = null; - var flashrom_message = new Buffer.from(data_128.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, ""); - - if (numparts != null) flashrom_numparts = parseInt(numparts); - if (!flashrom_numparts) flashrom_numparts = flashrom_message.substring(flashrom_message.length - 4).replace(/\D/g, ''); - - var ind = new Array(); - ind[0] = (path.indexOf("part") + 4); - ind[1] = (path.indexOf(".", ind[0]) + 1); - var flashrom_part_num = path.substr(ind[0], (path.length - ind[1])); - var flashrom_lastpart = (flashrom_numparts == (parseInt(flashrom_part_num) + 1)) ? true : false; - var flashrom_rompath = 'wtv-flashrom:/get-by-path?path=' + path; - if (flashrom_lastpart) { - flashrom_next_rompath = "wtv-flashrom:/lc2-download-complete?"; - } else { - var flashrom_next_part_num = (parseInt(flashrom_part_num) + 1); - if (flashrom_next_part_num < 10) flashrom_next_part_num = "00" + flashrom_next_part_num; // 1s - else if (flashrom_next_part_num >= 10 && flashrom_next_part_num < 100) flashrom_next_part_num = "0" + flashrom_next_part_num; // 10s - var flashrom_next_rompath = flashrom_rompath.replace("part" + flashrom_part_num, "part" + flashrom_next_part_num) + "&numparts=" + parseInt(flashrom_numparts); - } - return flashrom_next_rompath; -} - -if ((/\.brom$/).test(request_path)) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe? -else headers += "Content-Type: binary/x-wtv-flashblock"; - -var flashrom_file_path = null; -Object.keys(service_vaults).forEach(function (g) { - if (flashrom_file_path != null) return; - flashrom_file_path = service_vaults[g] + "/" + service_name + "/" + request_path; - if (!fs.existsSync(flashrom_file_path)) flashrom_file_path = null; -}); -if (minisrv_config.services[service_name].use_zefie_server && !flashrom_file_path) { - // get flashrom files from archive.midnightchannel.net - var options = { - host: "archive.midnightchannel.net", - path: "/zefie/files/wtv-flashrom/" + request_path, - timeout: 5000, - method: 'GET' - } - const req = https.request(options, function (res) { - var data_hex = ''; - res.setEncoding('hex'); - - res.on('data', d => { - data_hex += d; - }) - - res.on('end', function () { - if (!zquiet) console.log(` * Zefie's FlashROM Server HTTP Status: ${res.statusCode} ${res.statusMessage}`) - if (res.statusCode == 200) { - data = Buffer.from(data_hex, 'hex'); - } else if (res.statusCode == 404) { - var errpage = doErrorPage(404, "The service could not find the requested ROM on zefie's server.") - headers = errpage[0]; - data = errpage[1]; - } else { - var errpage = doErrorPage(400) - headers = errpage[0]; - data = errpage[1]; - } - headers += "\nwtv-visit: " + calculatedPath(data, request_path); - sendToClient(socket, headers, data); - }); - }); - req.end(); -} else { - doLocalFlashROM(flashrom_file_path); +if (!ssid_sessions[socket.ssid].data_store.WTVFlashrom) { + ssid_sessions[socket.ssid].data_store.WTVFlashrom = new WTVFlashrom(service_vaults, service_name, minisrv_config.services[service_name].use_zefie_server, bf0app_update); } +ssid_sessions[socket.ssid].data_store.WTVFlashrom.getFlashRom(request_path, function (data, headers) { + sendToClient(socket, headers, data); +}); \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-by-path.js b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-by-path.js index 00c88d30..ce1de045 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-by-path.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-by-path.js @@ -1,117 +1,26 @@ +const WTVFlashrom = require("./WTVFlashrom.js"); request_is_async = true; - var bf0app_update = false; var request_path = unescape(request_headers.query.path); -headers = "200 OK\n" - -function doLocalFlashROM(flashrom_file_path) { - // use local flashrom files; - try { - fs.readFile(flashrom_file_path, null, function (err, data) { - if (err) { - errpage = doErrorPage(400) - headers = errpage[0]; - data = err.toString(); - } - sendToClient(socket, headers, data); - }); - } catch (e) { - var errpage = doErrorPage(404, "The service could not find the requested ROM.") - headers = errpage[0]; - data = errpage[1]; - sendToClient(socket, headers, data); - } -} if (ssid_sessions[socket.ssid].get("wtv-client-rom-type") == "bf0app" && ssid_sessions[socket.ssid].get("wtv-client-bootrom-version") == "105") { // assume old classic in flash mode, override user setting and send tellyscript // because it is required to proceed in flash mode bf0app_update = true; ssid_sessions[socket.ssid].set("bf0app_update", bf0app_update); - headers += "minisrv-use-carriage-return: false\n"; -} - - -function calculatedPath(data, path, numparts = null) { - var data_128 = new Buffer.alloc(128); - data.copy(data_128, 0, 0, 128); - var flashrom_numparts = null; - var flashrom_message = new Buffer.from(data_128.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, ""); - - if (numparts != null) flashrom_numparts = parseInt(numparts); - if (!flashrom_numparts) flashrom_numparts = flashrom_message.substring(flashrom_message.length - 4).replace(/\D/g, ''); - - var ind = new Array(); - ind[0] = (path.indexOf("part") + 4); - ind[1] = (path.indexOf(".", ind[0]) + 1); - var flashrom_part_num = path.substr(ind[0], (path.length - ind[1])); - var flashrom_lastpart = (flashrom_numparts == (parseInt(flashrom_part_num) + 1)) ? true : false; - var flashrom_rompath = 'wtv-flashrom:/get-by-path?path=' + path; - if (flashrom_lastpart) flashrom_next_rompath = null; - else { - var flashrom_next_part_num = (parseInt(flashrom_part_num) + 1); - if (flashrom_next_part_num < 10) flashrom_next_part_num = "00" + flashrom_next_part_num; // 1s - else if (flashrom_next_part_num >= 10 && flashrom_next_part_num < 100) flashrom_next_part_num = "0" + flashrom_next_part_num; // 10s - var flashrom_next_rompath = flashrom_rompath.replace("part" + flashrom_part_num, "part" + flashrom_next_part_num) + "&numparts=" + parseInt(flashrom_numparts); - } - return flashrom_next_rompath; } if (request_headers.query.raw || bf0app_update) { - if ((/\.brom$/).test(request_path)) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe? - else headers += "Content-Type: binary/x-wtv-flashblock"; - - var flashrom_file_path = null; - Object.keys(service_vaults).forEach(function (g) { - if (flashrom_file_path != null) return; - flashrom_file_path = service_vaults[g] + "/" + service_name + "/" + request_path; - if (!fs.existsSync(flashrom_file_path)) flashrom_file_path = null; - }); - if (minisrv_config.services[service_name].use_zefie_server && !flashrom_file_path) { - // get flashrom files from archive.midnightchannel.net - var options = { - host: "archive.midnightchannel.net", - path: "/zefie/files/wtv-flashrom/" + request_path, - timeout: 5000, - method: 'GET' - } - const req = https.request(options, function (res) { - var data_hex = ''; - res.setEncoding('hex'); - - res.on('data', d => { - data_hex += d; - }) - - res.on('end', function () { - if (!zquiet) console.log(` * Zefie's FlashROM Server HTTP Status: ${res.statusCode} ${res.statusMessage}`) - if (res.statusCode == 200) { - data = Buffer.from(data_hex, 'hex'); - } else if (res.statusCode == 404) { - var errpage = doErrorPage(404, "The service could not find the requested ROM on zefie's server.") - headers = errpage[0]; - data = errpage[1]; - } else { - var errpage = doErrorPage(400) - headers = errpage[0]; - data = errpage[1]; - } - if (bf0app_update) { - var nextpath = calculatedPath(data, request_path, (request_headers.query.numparts || null)); - if (nextpath != null) headers += "\nwtv-visit: " + nextpath; - } - else headers += "\nwtv-connection-close: true"; - sendToClient(socket, headers, data); - }); - }); - req.end(); - } else { - doLocalFlashROM(flashrom_file_path); + if (!ssid_sessions[socket.ssid].data_store.WTVFlashrom) { + ssid_sessions[socket.ssid].data_store.WTVFlashrom = new WTVFlashrom(service_vaults, service_name, minisrv_config.services[service_name].use_zefie_server, bf0app_update); } + + ssid_sessions[socket.ssid].data_store.WTVFlashrom.getFlashRom(request_path, function (data, headers) { + sendToClient(socket, headers, data); + }); } else { - // no support for bf0app yet, but here we send the client to initiate-lc2-download - // to get the rom image + headers = "200 OK\n" if (request_headers.query.path) { headers += "Content-type: text/html\n" headers += "wtv-visit: wtv-flashrom:/initiate-lc2-download?path=" + request_headers.query.path; diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-lc2-page.js b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-lc2-page.js index 2338c10f..fa8cfb8f 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-lc2-page.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/get-lc2-page.js @@ -1,113 +1,32 @@ -// todo, actual file logic -// - ready query param to get flashrom path, check for its existance -// - handle last part to redirect to lc2-download-complete -// - handle failures -request_is_async = true; -function doLocalFlashROM() { - fs.readFile(flashrom_file_path, null, function (err, data) { - try { - var data_128 = new Buffer.alloc(128); - data.copy(data_128, 0, 0, 128); - var flashrom_message = new Buffer.from(data_128.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, ""); - processLC2DownloadPage(request_headers.query.path, flashrom_message, (request_headers.query.numparts || null)); - } catch (e) { - var errpage = doErrorPage(404, "The service could not find the requested ROM.") - headers = errpage[0]; - data = errpage[1]; - sendToClient(socket, headers, data); - } - }); -} +const WTVFlashrom = require("./WTVFlashrom.js"); +var wtvflashrom; +var flashrom_info; +request_is_async = true; if (!request_headers.query.path) { var errpage = doErrorPage(400); headers = errpage[0]; data = errpage[1]; -} else { +} else { + var wtvflashrom = new WTVFlashrom(service_vaults, service_name, minisrv_config.services[service_name].use_zefie_server); var request_path = unescape(request_headers.query.path); - var flashrom_file_path = null; - Object.keys(service_vaults).forEach(function (g) { - if (flashrom_file_path != null) return; - flashrom_file_path = service_vaults[g] + "/" + service_name + "/" + request_path; - if (!fs.existsSync(flashrom_file_path)) flashrom_file_path = null; - }); - - if (minisrv_config.services[service_name].use_zefie_server && !flashrom_file_path) { - // read first 256 bytes of flashrom file from archive.midnightchannel.net - // to get `flashrom_message` and `numparts` if missing - var options = { - host: "archive.midnightchannel.net", - path: "/zefie/files/wtv-flashrom/" + request_path, - method: 'GET', - timeout: 5000, - headers: { - 'Range': 'bytes=0-256' - } - } - var chunk; - - const req = https.request(options, function (res) { - var data = ''; - res.setEncoding('hex'); - - res.on('data', function (d) { - data += d; - }); - - res.on('error', function (e) { - console.log(" * Upstream FlashROM Error:", e); - var errpage = doErrorPage(400) - headers = errpage[0]; - data = errpage[1]; - sendToClient(socket, headers, data); - }); - - res.on('end', function () { - if (res.statusCode == 206) { - var flashrom_message = new Buffer.from(data.substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, ""); - processLC2DownloadPage(request_headers.query.path, flashrom_message, (request_headers.query.numparts || null)); - return; - } else if (res.statusCode == 404) { - var errpage = doErrorPage(404, "The service could not find the requested ROM on zefie's server.") - headers = errpage[0]; - data = errpage[1]; - } else { - var errpage = doErrorPage(400) - headers = errpage[0]; - data = errpage[1]; - } - sendToClient(socket, headers, data); - }); - }); - req.end(); - } else { - // use local flashrom files - doLocalFlashROM(flashrom_file_path); - } + // read 512 bytes of rom + flashrom_info = wtvflashrom.getFlashRom(request_path, function (data, headers = null) { + processLC2DownloadPage(request_headers.query.path, data, (request_headers.query.numparts || null)); + }, 512); } -async function processLC2DownloadPage(path, flashrom_message, numparts = null) { +async function processLC2DownloadPage(path, flashrom_info, numparts = null) { var flashrom_numparts = null; if (numparts != null) flashrom_numparts = parseInt(numparts); - if (!flashrom_numparts) flashrom_numparts = flashrom_message.substring(flashrom_message.length - 4).replace(/\D/g, ''); - var ind = new Array(); - ind[0] = (path.indexOf("part") + 4); - ind[1] = (path.indexOf(".", ind[0]) + 1); - var flashrom_part_num = path.substr(ind[0], (path.length - ind[1])); - var flashrom_lastpart = (flashrom_numparts == (parseInt(flashrom_part_num) + 1)) ? true : false; - var flashrom_rompath = 'wtv-flashrom:/get-by-path?path=' + path + '&raw=true'; - var flashrom_isboot = (/\.brom$/).test(path); - if (flashrom_lastpart) { - flashrom_next_rompath = "wtv-flashrom:/lc2-download-complete?"; - } else { - var flashrom_next_part_num = (parseInt(flashrom_part_num) + 1); - if (flashrom_next_part_num < 10) flashrom_next_part_num = "00" + flashrom_next_part_num; // 1s - else if (flashrom_next_part_num >= 10 && flashrom_next_part_num < 100) flashrom_next_part_num = "0" + flashrom_next_part_num; // 10s - var flashrom_next_rompath = flashrom_rompath.replace("part"+flashrom_part_num, "part"+flashrom_next_part_num).replace('get-by-path', 'get-lc2-page').replace("&raw=true", "&numparts=" + parseInt(flashrom_numparts)); + if (!flashrom_numparts) flashrom_numparts = parseInt(flashrom_info.message.substring(flashrom_info.message.length - 4).replace(/\D/g, '')); + + if (!flashrom_info.is_last_part) { + flashrom_info.next_rompath = flashrom_info.next_rompath.replace("get-by-path", "get-lc2-page").replace("&raw=true", "&numparts=" + parseInt(flashrom_numparts)); } - if (!flashrom_part_num || !flashrom_lastpart || !flashrom_rompath || !flashrom_next_rompath || !flashrom_isboot) { + if (!flashrom_info.part_number || !flashrom_info.is_last_part || !flashrom_info.rompath || !flashrom_info.next_rompath || !flashrom_info.is_bootrom) { headers = `200 OK Content-type: text/html` @@ -163,7 +82,7 @@ Your WebTV Unit is being
updated automatically.

This will take a while, and
then you can use your WebTV again. `; - if (flashrom_isboot && parseInt(flashrom_part_num) == 16) { + if (flashrom_info.is_bootrom && flashrom_info.part_number == 16) { data += `

The system will pause for about 30 seconds at the end of this update. Please do not interrupt the system @@ -174,16 +93,20 @@ data += `




+blockurl="${flashrom_info.rompath}" +lastblock="${flashrom_info.is_last_part}" +curblock="` + (flashrom_info.part_number + 1) + `" +` + if (flashrom_numparts) { + data += `totalblocks="${flashrom_numparts}"`; + } + data += `>

-${flashrom_message} +${flashrom_info.message}

diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/noflash.js b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/noflash.js index 3afc0834..440a6e64 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/noflash.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-flashrom/noflash.js @@ -1,3 +1,6 @@ +const WTVFlashrom = require("./WTVFlashrom.js"); +request_is_async = true; + // this build can be local or on zefie's server // to get the path from zefie's server, browse // https://archive.midnightchannel.net/zefie/files/wtv-flashrom/content/artemis-webtv-000/ @@ -5,110 +8,23 @@ // example is below var default_build_to_send = minisrv_config.services[service_name].bf0app_default_rom || "content/artemis-webtv-000/build7181/daily-nondebug/bf0app-part000.rom"; -headers = "200 OK\n"; + var request_path = ""; var bf0app_update = true; if (request_headers.query.path) request_path = unescape(request_headers.query.path); else request_path = default_build_to_send; -request_is_async = true; if (ssid_sessions[socket.ssid].get("wtv-client-rom-type") == "bf0app" && ssid_sessions[socket.ssid].get("wtv-client-bootrom-version") == "105") { // assume old classic in flash mode, override user setting and send tellyscript // because it is required to proceed in flash mode bf0app_update = true; ssid_sessions[socket.ssid].set("bf0app_update", bf0app_update); - headers += "minisrv-use-carriage-return: false\n"; } -function doLocalFlashROM(flashrom_file_path) { - // use local flashrom files; - try { - fs.readFile(flashrom_file_path, null, function (err, data) { - if (err) { - errpage = doErrorPage(400) - headers = errpage[0]; - data = err.toString(); - } - sendToClient(socket, headers, data); - }); - } catch (e) { - var errpage = doErrorPage(404, "The service could not find the requested ROM.") - headers = errpage[0]; - data = errpage[1]; - sendToClient(socket, headers, data); - } +if (!ssid_sessions[socket.ssid].data_store.WTVFlashrom) { + ssid_sessions[socket.ssid].data_store.WTVFlashrom = new WTVFlashrom(service_vaults, service_name, 0, minisrv_config.services[service_name].use_zefie_server, bf0app_update); } -function calculatedPath(data, path, numparts = null) { - var data_128 = new Buffer.alloc(128); - data.copy(data_128, 0, 0, 128); - var flashrom_numparts = null; - var flashrom_message = new Buffer.from(data_128.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, ""); - - if (numparts != null) flashrom_numparts = parseInt(numparts); - if (!flashrom_numparts) flashrom_numparts = flashrom_message.substring(flashrom_message.length - 4).replace(/\D/g, ''); - - var ind = new Array(); - ind[0] = (path.indexOf("part") + 4); - ind[1] = (path.indexOf(".", ind[0]) + 1); - var flashrom_part_num = path.substr(ind[0], (path.length - ind[1])); - var flashrom_lastpart = (flashrom_numparts == (parseInt(flashrom_part_num) + 1)) ? true : false; - var flashrom_rompath = 'wtv-flashrom:/get-by-path?path=' + path; - if (flashrom_lastpart) { - flashrom_next_rompath = "wtv-flashrom:/lc2-download-complete?"; - } else { - var flashrom_next_part_num = (parseInt(flashrom_part_num) + 1); - if (flashrom_next_part_num < 10) flashrom_next_part_num = "00" + flashrom_next_part_num; // 1s - else if (flashrom_next_part_num >= 10 && flashrom_next_part_num < 100) flashrom_next_part_num = "0" + flashrom_next_part_num; // 10s - var flashrom_next_rompath = flashrom_rompath.replace("part" + flashrom_part_num, "part" + flashrom_next_part_num) + "&numparts=" + parseInt(flashrom_numparts); - } - return flashrom_next_rompath; -} - -if ((/\.brom$/).test(request_path)) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe? -else headers += "Content-Type: binary/x-wtv-flashblock"; - -var flashrom_file_path = null; -Object.keys(service_vaults).forEach(function (g) { - if (flashrom_file_path != null) return; - flashrom_file_path = service_vaults[g] + "/" + service_name + "/" + request_path; - if (!fs.existsSync(flashrom_file_path)) flashrom_file_path = null; +ssid_sessions[socket.ssid].data_store.WTVFlashrom.getFlashRom(request_path, function (data, headers) { + sendToClient(socket, headers, data); }); -if (minisrv_config.services[service_name].use_zefie_server && !flashrom_file_path) { - // get flashrom files from archive.midnightchannel.net - var options = { - host: "archive.midnightchannel.net", - path: "/zefie/files/wtv-flashrom/" + request_path, - timeout: 5000, - method: 'GET' - } - const req = https.request(options, function (res) { - var data_hex = ''; - res.setEncoding('hex'); - - res.on('data', d => { - data_hex += d; - }) - - res.on('end', function () { - if (!zquiet) console.log(` * Zefie's FlashROM Server HTTP Status: ${res.statusCode} ${res.statusMessage}`) - if (res.statusCode == 200) { - data = Buffer.from(data_hex, 'hex'); - } else if (res.statusCode == 404) { - var errpage = doErrorPage(404, "The service could not find the requested ROM on zefie's server.") - headers = errpage[0]; - data = errpage[1]; - } else { - var errpage = doErrorPage(400) - headers = errpage[0]; - data = errpage[1]; - } - headers += "\nwtv-visit: " + calculatedPath(data, request_path); - sendToClient(socket, headers, data); - }); - }); - req.end(); -} else { - doLocalFlashROM(flashrom_file_path); -} - diff --git a/zefie_wtvp_minisrv/WTVFlashrom.js b/zefie_wtvp_minisrv/WTVFlashrom.js new file mode 100644 index 00000000..fa37ed32 --- /dev/null +++ b/zefie_wtvp_minisrv/WTVFlashrom.js @@ -0,0 +1,179 @@ +class WTVFlashrom { + + fs = require('fs'); + https = require('https'); + use_zefie_server = true; + bf0app_update = false; + service_vaults = new Array(); + service_name = ""; + zdebug = false; + + + constructor(service_vaults, service_name, use_zefie_server = true, bf0app_update = false, debug = false) { + this.service_vaults = service_vaults; + this.service_name = service_name; + this.use_zefie_server = use_zefie_server; + this.bf0app_update = bf0app_update; + this.zdebug = debug; + } + + async doLocalFlashROM(flashrom_file_path, callback, info_only = false) { + // use local flashrom files; + console.log(info_only); + var self = this; + try { + this.fs.readFile(flashrom_file_path, null, function (err, data) { + if (err) { + errpage = doErrorPage(400) + var headers = errpage[0]; + data = err.toString(); + callback(data, headers); + } else { + if (info_only) { + callback(self.getFlashromData(data, flashrom_file_path)); + } else { + self.sendToClient(data, flashrom_file_path, callback); + } + } + }); + } catch (e) { + var errpage = doErrorPage(404, "The service could not find the requested ROM.") + var headers = errpage[0]; + var data = errpage[1]; + callback(data, headers); + } + } + + formatPartNum(partnum) { + if (partnum < 10) return "00" + partnum; // 1s + else if (partnum >= 10 && partnum < 100) return "0" + partnum; // 10s + else return partnum; // 100s + } + + + getFlashromData(data, path) { + var flashrom_info = new Array(); + var flashrom_magic = "96031889"; + var part_header = new Buffer.alloc(32); + data.copy(part_header, 0, 0, 32); + flashrom_info.header_length = data.readUInt16BE(26); + + flashrom_info.is_bootrom = (/\.brom$/).test(path); + + // re-read entire header + var part_header = new Buffer.alloc(flashrom_info.header_length); + data.copy(part_header, 0, 0, flashrom_info.header_length); + + flashrom_info.magic = part_header.toString('hex', 0, 4); + flashrom_info.valid_flashrom = false; + if (flashrom_info.magic == flashrom_magic) flashrom_info.valid_flashrom = true; + if (!flashrom_info.valid_flashrom) console.error(" * Warning! FlashROM File Magic (" + flashrom_info.magic + ") did not match expected magic (" + flashrom_magic + ")..."); + + if (this.zdebug) console.log(" # FlashROM File Magic (" + flashrom_info.magic + "), expected magic (" + flashrom_magic + "), OK = " + flashrom_info.valid_flashrom + "..."); + flashrom_info.byte_progress = data.readUInt32BE(68); + if (this.zdebug) console.log(" # Flashrom Part Bytes Sent:", flashrom_info.byte_progress); + flashrom_info.compression_type = parseInt(part_header[16], 16); + if (this.zdebug) console.log(" # Flashrom Part Compression Type:", flashrom_info.compression_type); + flashrom_info.part_data_size = data.readUInt32BE(4); + if (this.zdebug) console.log(" # Flashrom Part Data Size:", flashrom_info.part_data_size); + flashrom_info.part_total_size = flashrom_info.part_data_size + flashrom_info.header_length; + if (this.zdebug) console.log(" # Flashrom Part Total Size:", flashrom_info.part_total_size); + + flashrom_info.total_parts_size = data.readUInt32BE(32); + if (this.zdebug) console.log(" # Flashrom All Parts Total Size:", flashrom_info.total_parts_size); + + // read current part number bit from part header + flashrom_info.part_number = data.readUInt16BE(28); + + if (this.zdebug) console.log(" # Flashrom Current Part Number:", flashrom_info.part_number); + + // read current part display message from part header + flashrom_info.message = new Buffer.from(part_header.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, ""); + + flashrom_info.is_last_part = ((flashrom_info.byte_progress + flashrom_info.part_total_size) == flashrom_info.total_parts_size) ? true : false; + flashrom_info.rompath = 'wtv-flashrom:/get-by-path?path=' + path + '&raw=true'; + if (this.zdebug) console.log(" # Flashrom Part Bytes Sent (after this part):", flashrom_info.byte_progress + flashrom_info.part_total_size); + if (this.zdebug) console.log(" # Flashrom Part is Last Part", flashrom_info.is_last_part); + + if (flashrom_info.is_last_part && this.bf0app_update) { + flashrom_info.next_rompath = null; + } else if (flashrom_info.is_last_part && !this.bf0app_update) { + flashrom_info.next_rompath = "wtv-flashrom:/lc2-download-complete?"; + } else { + flashrom_info.next_part_number = this.formatPartNum(flashrom_info.part_number + 1); + flashrom_info.next_rompath = flashrom_info.rompath.replace("part" + this.formatPartNum(flashrom_info.part_number), "part" + flashrom_info.next_part_number); + } + return flashrom_info; + } + + async sendToClient(data, request_path, callback) { + var headers = "200 OK\n"; + if (this.bf0app_update) headers += "minisrv-use-carriage-return: false\n"; + var flashrom_info = this.getFlashromData(data, request_path) + if (flashrom_info.is_bootrom) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe? + else headers += "Content-Type: binary/x-wtv-flashblock"; + if (flashrom_info.next_rompath != null) headers += "\nwtv-visit: " + flashrom_info.next_rompath; + callback(data, headers); + } + + async getFlashRom(request_path, callback, length = 0) { + var flashrom_file_path = null; + var self = this; + Object.keys(self.service_vaults).forEach(function (g) { + if (flashrom_file_path != null) return; + flashrom_file_path = self.service_vaults[g] + "/" + self.service_name + "/" + request_path; + if (!self.fs.existsSync(flashrom_file_path)) flashrom_file_path = null; + }); + if (this.use_zefie_server && !flashrom_file_path) { + // get flashrom files from archive.midnightchannel.net + var options = { + host: "archive.midnightchannel.net", + path: "/zefie/files/wtv-flashrom/" + request_path, + timeout: 5000, + method: 'GET' + } + if (length > 0) { + options.headers = { + 'Range': 'bytes=0-' + length + } + } + + const req = this.https.request(options, function (res) { + var data_hex = ''; + res.setEncoding('hex'); + + res.on('data', d => { + data_hex += d; + }) + + res.on('end', function () { + console.log(` * Zefie's FlashROM Server HTTP Status: ${res.statusCode} ${res.statusMessage}`) + if (res.statusCode == 200) { + var data = Buffer.from(data_hex, 'hex'); + } else if (res.statusCode == 206) { + headers = ""; + var data = self.getFlashromData(Buffer.from(data_hex, 'hex'), request_path); + } else if (res.statusCode == 404) { + var errpage = doErrorPage(404, "The service could not find the requested ROM on zefie's server.") + var headers = errpage[0]; + var data = errpage[1]; + } else { + var errpage = doErrorPage(400) + var headers = errpage[0]; + var data = errpage[1]; + } + if (res.statusCode == "206") { + self.sendToClient(data, request_path, callback); + } else { + callback(data); + } + }); + }); + req.end(); + } else { + this.doLocalFlashROM(flashrom_file_path, callback, ((length != 0) ? true : false)); + } + } +} + +module.exports = WTVFlashrom; \ No newline at end of file diff --git a/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj b/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj index 6b73bcde..ef2322c7 100644 --- a/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj +++ b/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj @@ -221,6 +221,9 @@ Code + + Code + Code