Skip to content

Commit b0857c3

Browse files
feat: working http server
1 parent 0365bef commit b0857c3

File tree

4 files changed

+126
-51
lines changed

4 files changed

+126
-51
lines changed

src/fileServer/fileServer.ts

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/lib/Log.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class Log {
3131

3232
d(message: any, ...args: any[]): void {
3333
//TODO: Only show debug messages in debug mode
34-
console.debug(
34+
console.log(
3535
`%c${this.format("DEBUG", message)}`,
3636
"color: #999999",
3737
...args,

src/lib/acode.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ import encodings, { decode, encode } from "utils/encodings";
4343
import helpers from "utils/helpers";
4444
import KeyboardEvent from "utils/keyboardEvent";
4545
import Url from "utils/Url";
46-
import { FileServer } from "../fileServer/FileServer";
4746
import { NativeFileWrapper } from "../fileSystem/NativeFileWrapper";
4847
import { SAFDocumentFile } from "../fileSystem/SAFDocumentFile";
4948
import constants from "./constants";
49+
import { FileServer } from "./fileServer";
50+
import { Log } from "./Log";
5051

5152
export default class Acode {
5253
#modules = {};
@@ -125,6 +126,7 @@ export default class Acode {
125126
this.define("nativeFile", NativeFileWrapper);
126127
this.define("SAFDocumentFile", SAFDocumentFile);
127128
this.define("fileServer", FileServer);
129+
this.define("log", Log);
128130
this.define("Url", Url);
129131
this.define("page", Page);
130132
this.define("Color", Color);

src/lib/fileServer.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { FileObject } from "../fileSystem/fileObject";
2+
import { Log } from "./Log";
3+
4+
export class FileServer {
5+
private readonly file: FileObject;
6+
private readonly port: number;
7+
private httpServer: Server | undefined;
8+
private readonly log: Log = new Log("fileServer");
9+
10+
constructor(port: number, file: FileObject) {
11+
this.file = file;
12+
this.port = port;
13+
}
14+
15+
start(onSuccess: (msg: any) => void, onError: (err: any) => void): void {
16+
this.httpServer = CreateServer(this.port, onSuccess, onError);
17+
18+
// @ts-ignore
19+
this.httpServer.setOnRequestHandler(this.handleRequest.bind(this));
20+
}
21+
22+
private async handleRequest(req: {
23+
requestId: string;
24+
path: string;
25+
}): Promise<void> {
26+
this.log.d("Request received:", req);
27+
this.log.d("Received request:", req.requestId);
28+
this.log.d("Request Path", req.path);
29+
30+
if (await this.file.isFile()) {
31+
this.sendText(
32+
(await this.file?.readText()) ?? "null",
33+
req.requestId,
34+
this.getMimeType(await this.file.getName()),
35+
);
36+
return;
37+
}
38+
39+
if (req.path === "/") {
40+
const indexFile = await this.file.getChildByName("index.html");
41+
if ((await indexFile?.exists()) && (await indexFile?.canRead())) {
42+
this.sendText(
43+
(await indexFile?.readText()) ?? "null",
44+
req.requestId,
45+
this.getMimeType(await indexFile!!.getName()),
46+
);
47+
} else {
48+
this.sendText("404 index file not found", req.requestId, "text/plain");
49+
}
50+
return;
51+
}
52+
53+
let targetFile: FileObject | null = null;
54+
55+
for (const name of req.path.split("/")) {
56+
if (!name) continue; // skip empty parts like leading or trailing "/"
57+
58+
if (targetFile === null) {
59+
targetFile = await this.file.getChildByName(name);
60+
} else {
61+
targetFile = await targetFile.getChildByName(name);
62+
}
63+
64+
if (targetFile === null) {
65+
// Stop early if file is missing
66+
break;
67+
}
68+
}
69+
70+
if (targetFile == null || !(await targetFile!!.exists())) {
71+
this.sendText(
72+
"404 file not found: " + req.path,
73+
req.requestId,
74+
"text/plain",
75+
);
76+
return;
77+
}
78+
79+
this.sendText(
80+
(await targetFile?.readText()) ?? "null",
81+
req.requestId,
82+
this.getMimeType(await targetFile.getName()),
83+
);
84+
}
85+
86+
private sendText(
87+
text: string,
88+
id: string,
89+
mimeType: string | null | undefined,
90+
) {
91+
this.httpServer?.send(
92+
id,
93+
{
94+
status: 200,
95+
body: text,
96+
headers: {
97+
"Content-Type": mimeType || "text/html",
98+
},
99+
},
100+
() => {},
101+
this.log.e,
102+
);
103+
}
104+
105+
private getMimeType(filename: string): string {
106+
const ext = filename.split(".").pop()?.toLowerCase();
107+
const map: Record<string, string> = {
108+
html: "text/html",
109+
css: "text/css",
110+
js: "application/javascript",
111+
json: "application/json",
112+
png: "image/png",
113+
jpg: "image/jpeg",
114+
jpeg: "image/jpeg",
115+
gif: "image/gif",
116+
svg: "image/svg+xml",
117+
txt: "text/plain",
118+
xml: "text/xml",
119+
};
120+
return map[ext ?? "text/plain"];
121+
}
122+
}

0 commit comments

Comments
 (0)