diff --git a/src/puter-js/src/index.js b/src/puter-js/src/index.js index 937b177a2..09d4a3f38 100644 --- a/src/puter-js/src/index.js +++ b/src/puter-js/src/index.js @@ -20,6 +20,7 @@ import { XDIncomingService } from './services/XDIncoming.js'; import { NoPuterYetService } from './services/NoPuterYet.js'; import { Debug } from './modules/Debug.js'; import { PSocket, wispInfo } from './modules/networking/PSocket.js'; +import { PTLSSocket } from "./modules/networking/PTLS.js" import { PWispHandler } from './modules/networking/PWispHandler.js'; // TODO: This is for a safe-guard below; we should check if we can @@ -330,7 +331,10 @@ window.puter = (function() { })).json())["token"]; wispInfo.handler = new PWispHandler(wispInfo.server, wispToken); this.net = { - Socket: PSocket + Socket: PSocket, + tls: { + TLSSocket: PTLSSocket + } } })(); diff --git a/src/puter-js/src/modules/networking/PSocket.js b/src/puter-js/src/modules/networking/PSocket.js index 1c0d66c87..1b59eb083 100644 --- a/src/puter-js/src/modules/networking/PSocket.js +++ b/src/puter-js/src/modules/networking/PSocket.js @@ -1,6 +1,5 @@ import EventListener from "../../lib/EventListener.js"; -import {PWispHandler} from "./PWispHandler.js" - +const texten = new TextEncoder(); export let wispInfo = { server: "wss://puter.cafe/", @@ -11,34 +10,35 @@ export class PSocket extends EventListener { _events = new Map(); _streamID; constructor(host, port) { - super(["data", "drain", "open", "close"]); + super(["data", "drain", "open", "close", "tlsdata", "tlsopen"]); const callbacks = { dataCallBack: (data) => { this.emit("data", data); }, closeCallBack: (reason) => { this.emit("close", false); // TODO, report errors - }, - openCallBack: () => { - this.emit("open"); } } this._streamID = wispInfo.handler.register(host, port, callbacks); + setTimeout(() => {this.emit("open", undefined)}, 0); } addListener(...args) { this.on(...args); } write(data, callback) { - if (data.buffer) { // typedArray + if (data.buffer) { // TypedArray wispInfo.handler.write(this._streamID, data); if (callback) callback(); - } else if (data.resize) { + } else if (data.resize) { // ArrayBuffer data.write(this._streamID, new Uint8Array(data)); if (callback) callback(); - } else if (data.arrayBuffer) { // Oh No, a blob, I need to handle this later, maybe with https://gist.github.com/jimmywarting/65c358f878cac8e7f39cfb7d43931f62? - + } else if (typeof(data) === "string") { + wispInfo.handler.write(this._streamID, texten.encode(data)) + if (callback) callback(); + } else { + throw new Error("Invalid data type (not TypedArray, ArrayBuffer or String!!)"); } } close() { diff --git a/src/puter-js/src/modules/networking/PTLS.js b/src/puter-js/src/modules/networking/PTLS.js new file mode 100644 index 000000000..aa48aa4b9 --- /dev/null +++ b/src/puter-js/src/modules/networking/PTLS.js @@ -0,0 +1,72 @@ +/** + * This file uses https://github.com/MercuryWorkshop/rustls-wasm authored by GitHub:@r58Playz under the MIT License + */ + +import { PSocket } from "./PSocket"; + +let rustls = undefined; + +export class PTLSSocket extends PSocket { + constructor(...args) { + super(...args); + (async() => { + if (!rustls) { + rustls = (await import( /* webpackIgnore: true */ "https://puter-net.b-cdn.net/rustls.js")) + // await rustls.default("https://puter-net.b-cdn.net/rustls.wasm") + await rustls.default("https://alicesworld.tech/fun/rustls.wasm") + } + // const socket = new puter.net.Socket("google.com", 443) + const readable = new ReadableStream({ + start: (controller) => { + super.on("data", (data) => { + controller.enqueue(data.buffer) + }) + super.on("close", () => { + controller.close() + }) + } + }) + + const writable = new WritableStream({ + write: (chunk) => { super.write(chunk); }, + abort: () => { super.close(); }, + close: () => { super.close(); }, + }) + + const {read, write} = await rustls.connect_tls(readable, writable, args[0]); + + this.writer = write.getWriter(); + // writer.write("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"); + let reader = read.getReader(); + let done = false; + this.emit("tlsopen", undefined); + + while (!done) { + const {done: readerDone, value} = await reader.read(); + done = readerDone; + if (!done) { + this.emit("tlsdata", value); + } + } + })(); + } + on(event, callback) { + if (event === "data" || event === "open") { + return super.on("tls" + event, callback) + } else { + return super.on(event, callback); + } + } + write(data, callback) { + if (data.buffer) { // TypedArray + this.writer.write(data.slice(0).buffer).then(callback); + } else if (data.resize) { // ArrayBuffer + this.writer.write(data).then(callback); + } else if (typeof(data) === "string"){ + this.writer.write(data).then(callback); + } else { + throw new Error("Invalid data type (not TypedArray, ArrayBuffer or String!!)"); + } + } + +} \ No newline at end of file diff --git a/src/puter-js/src/modules/networking/PWispHandler.js b/src/puter-js/src/modules/networking/PWispHandler.js index f5e3f9d54..1fbd23ae2 100644 --- a/src/puter-js/src/modules/networking/PWispHandler.js +++ b/src/puter-js/src/modules/networking/PWispHandler.js @@ -43,7 +43,7 @@ export class PWispHandler { } register(host, port, callbacks) { const streamID = this._nextStreamID++; - this.streamMap.set(streamID, {queue: [], streamID, buffer: this._bufferMax, dataCallBack: callbacks.dataCallBack, closeCallBack: callbacks.closeCallBack, openCallBack: callbacks.openCallBack}); + this.streamMap.set(streamID, {queue: [], streamID, buffer: this._bufferMax, dataCallBack: callbacks.dataCallBack, closeCallBack: callbacks.closeCallBack}); this._ws.send(createWispPacket({ packetType: CONNECT, streamType: TCP, @@ -51,7 +51,6 @@ export class PWispHandler { hostname: host, port: port })) - return streamID; }