mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-06 05:28:31 +09:00
more convenient internet accessing using net.mjs
This commit is contained in:
@@ -9,4 +9,4 @@ ProperAuthor:CuriousTorvald
|
||||
ProperDescription:Package manager for TVDOS
|
||||
Licence:MIT
|
||||
SupportMe:https://github.com/sponsors/curioustorvald/
|
||||
PackageFileList:https://raw.githubusercontent.com/curioustorvald/hopper/refs/heads/master/hopper.js;
|
||||
PackageFileList:https://raw.githubusercontent.com/curioustorvald/hopper/refs/heads/master/hopper.js;https://raw.githubusercontent.com/curioustorvald/hopper/refs/heads/master/hop.alias
|
||||
@@ -1,11 +1,13 @@
|
||||
let url="http:localhost/testnet/test.txt"
|
||||
/*let url="https:raw.githubusercontent.com/curioustorvald/hopper-mirror/refs/heads/master/aa.hop.per"
|
||||
|
||||
let file = files.open("B:\\"+url)
|
||||
|
||||
if (!file.exists) {
|
||||
printerrln("No such URL: "+url)
|
||||
return 1
|
||||
}
|
||||
}*/
|
||||
|
||||
let text = file.sread()
|
||||
let net = require("A:/tvdos/include/net.mjs")
|
||||
let text = net.fetchText("https://raw.githubusercontent.com/curioustorvald/hopper-mirror/refs/heads/master/aa.hop.per")
|
||||
if (text === null) { printerrln("No such URL"); return 1 }
|
||||
println(text)
|
||||
|
||||
123
assets/disk0/tvdos/include/net.mjs
Normal file
123
assets/disk0/tvdos/include/net.mjs
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* net.mjs — Internet text-fetch helper for TVDOS
|
||||
*
|
||||
* Wraps the HttpModem peripheral (driven by `_TVDOS.DRV.FS.NET`, see
|
||||
* TVDOS.SYS:1001-1034) behind a small, regular-URL-friendly API. The
|
||||
* helper looks up whichever drive letter the boot probe assigned to the
|
||||
* HTTP modem and translates ordinary URLs (`https://host/path`) into the
|
||||
* scheme-without-double-slash form (`https:host/path`) that the modem
|
||||
* expects on the wire.
|
||||
*
|
||||
* Usage
|
||||
* -----
|
||||
* let net = require("A:/tvdos/include/net.mjs")
|
||||
*
|
||||
* if (!net.isAvailable())
|
||||
* printerrln("No HTTP modem attached")
|
||||
*
|
||||
* let body = net.fetchText("https://example.com/index.html")
|
||||
* if (body === null) printerrln("Fetch failed")
|
||||
* else println(body)
|
||||
*/
|
||||
|
||||
|
||||
let _cachedDrive = null
|
||||
|
||||
/** Scan TVDOS drive table for an HTTP-typed device. Returns the drive
|
||||
* letter (e.g. "B") or null. */
|
||||
function _findHttpDrive() {
|
||||
if (typeof _TVDOS === 'undefined' || !_TVDOS.DRIVEINFO) return null
|
||||
if (_cachedDrive !== null && _TVDOS.DRIVEINFO[_cachedDrive] &&
|
||||
_TVDOS.DRIVEINFO[_cachedDrive].type === 'HTTP')
|
||||
return _cachedDrive
|
||||
|
||||
for (let letter in _TVDOS.DRIVEINFO) {
|
||||
let info = _TVDOS.DRIVEINFO[letter]
|
||||
if (info && info.type === 'HTTP') {
|
||||
_cachedDrive = letter
|
||||
return letter
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Convert a regular URL into the form the HTTP modem accepts:
|
||||
* - strip the `//` between scheme and authority
|
||||
* - drop any URL fragment
|
||||
* - assume `https` when no scheme is provided
|
||||
*/
|
||||
function _normaliseUrl(url) {
|
||||
if (typeof url !== 'string')
|
||||
throw new TypeError("url must be a string")
|
||||
let s = url.trim()
|
||||
if (s.length === 0) throw new Error("url is empty")
|
||||
|
||||
// Drop fragment — the modem speaks to the server, # is client-side.
|
||||
let hash = s.indexOf('#')
|
||||
if (hash >= 0) s = s.substring(0, hash)
|
||||
|
||||
// scheme://host/path → scheme:host/path
|
||||
let m = s.match(/^([a-zA-Z][a-zA-Z0-9+.\-]*):\/\/(.*)$/)
|
||||
if (m) return m[1].toLowerCase() + ':' + m[2]
|
||||
|
||||
// Already in scheme:host/path form (the modem's native shape)
|
||||
if (/^[a-zA-Z][a-zA-Z0-9+.\-]*:[^/]/.test(s)) return s
|
||||
|
||||
// No scheme — default to https
|
||||
if (!/^[a-zA-Z][a-zA-Z0-9+.\-]*:/.test(s))
|
||||
return 'https:' + s.replace(/^\/\//, '')
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
let net = {}
|
||||
|
||||
/** Returns the drive letter currently bound to the HTTP modem, or null
|
||||
* when no such device is attached. */
|
||||
net.getHttpDrive = function () {
|
||||
return _findHttpDrive()
|
||||
}
|
||||
|
||||
/** True iff an HTTP modem is reachable through TVDOS. */
|
||||
net.isAvailable = function () {
|
||||
return _findHttpDrive() !== null
|
||||
}
|
||||
|
||||
/** Translate a URL into the `<drive>:\<modem-url>` form that
|
||||
* `files.open()` would route through `_TVDOS.DRV.FS.NET`. Useful when
|
||||
* another component wants the descriptor directly. Throws if no HTTP
|
||||
* modem is attached. */
|
||||
net.toModemPath = function (url) {
|
||||
let drive = _findHttpDrive()
|
||||
if (drive === null) throw new Error("No HTTP modem device is attached")
|
||||
return drive + ':\\' + _normaliseUrl(url)
|
||||
}
|
||||
|
||||
/** Open a TVDOS file descriptor backed by the HTTP modem for the given
|
||||
* URL. The descriptor's sread()/bread() trigger the actual fetch.
|
||||
* Throws if no HTTP modem is attached. */
|
||||
net.open = function (url) {
|
||||
return files.open(net.toModemPath(url))
|
||||
}
|
||||
|
||||
/** Fetch the body of `url` as a string. Returns the response text on
|
||||
* success, or null when the modem reports a non-zero status (bad URL,
|
||||
* I/O error, etc.). Throws if no HTTP modem is attached. */
|
||||
net.fetchText = function (url) {
|
||||
let fd = net.open(url)
|
||||
let text = fd.sread()
|
||||
try { fd.close() } catch (_) {}
|
||||
return (text === undefined) ? null : text
|
||||
}
|
||||
|
||||
/** Like fetchText, but throws an Error instead of returning null on
|
||||
* fetch failure. */
|
||||
net.fetchTextOrThrow = function (url) {
|
||||
let body = net.fetchText(url)
|
||||
if (body === null) throw new Error("Failed to fetch URL: " + url)
|
||||
return body
|
||||
}
|
||||
|
||||
|
||||
exports = net
|
||||
Reference in New Issue
Block a user