Skip to content

Commit 6352d2a

Browse files
committed
feat: Socket
1 parent 0366525 commit 6352d2a

5 files changed

Lines changed: 122 additions & 2 deletions

File tree

‎deno.json‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@
1515
"command": "deno run -A --check --watch ./src/index.ts"
1616
},
1717
"lint": {
18-
"description": "Run the linting tool.",
18+
"description": "Run linter.",
1919
"command": "deno lint"
2020
},
21+
"format": {
22+
"description": "Run formatter.",
23+
"command": "deno lint --fix"
24+
},
2125
"test": {
2226
"description": "Run the test suite.",
2327
"command": "deno test -A --check --permit-no-files --reload --doc --junit-path=\"./reports/report.xml\""
2428
}
2529
},
2630
"compilerOptions": {
27-
"allowJs": false,
2831
"lib": [
2932
"deno.ns",
3033
"deno.window",
@@ -37,6 +40,11 @@
3740
]
3841
},
3942
"lint": {
43+
"plugins": [
44+
"jsr:@loat-dev/lint-plugins@0.3.6/colon_spacing",
45+
"jsr:@loat-dev/lint-plugins@0.3.6/imports",
46+
"jsr:@loat-dev/lint-plugins@0.3.6/arrays"
47+
],
4048
"rules": {
4149
"tags": [
4250
"recommended"

‎deno.lock‎

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/socket/socket.ts‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { SocketInitOptions } from './socket_init_options.ts';
2+
import { SocketOptions } from './socket_options.ts';
3+
4+
export class Socket {
5+
readonly socketPath : string;
6+
readonly connection : Promise<Deno.UnixConn>;
7+
constructor(
8+
socket : string = '/var/run/docker.sock',
9+
options : SocketOptions = {connect: Deno.connect}
10+
) {
11+
this.socketPath = socket;
12+
this.connection = options.connect({path: socket, transport: 'unix'});
13+
}
14+
15+
public async request(
16+
path : string,
17+
init : SocketInitOptions = {
18+
method: 'GET',
19+
headers: {}
20+
}
21+
) : Promise<unknown> {
22+
const connection = await this.connection;
23+
24+
const headers = {
25+
Host: "docker",
26+
Connection: "close",
27+
...init.headers,
28+
};
29+
30+
const headerLines = [
31+
`${init.method} ${path} HTTP/1.1`,
32+
...Object.entries(headers).map(([k, v]) => `${k}: ${v}`),
33+
'',
34+
'' // closes header section
35+
];
36+
37+
const requestPayload = headerLines.join("\r\n");
38+
39+
await connection.write(new TextEncoder().encode(requestPayload));
40+
41+
let headerParsed = false;
42+
let leftover = '';
43+
44+
const bodyStream = new ReadableStream<Uint8Array>({
45+
async pull(controller) : Promise<void> {
46+
const { value, done } = await connection.readable.getReader().read();
47+
if (done) {
48+
controller.close();
49+
return;
50+
}
51+
52+
const text = new TextDecoder().decode(value, { stream: true });
53+
leftover += text;
54+
55+
if (!headerParsed) {
56+
const headerEnd = leftover.indexOf("\r\n\r\n");
57+
if (headerEnd !== -1) {
58+
headerParsed = true;
59+
60+
const after = leftover.slice(headerEnd + 4);
61+
leftover = "";
62+
63+
controller.enqueue(new TextEncoder().encode(after));
64+
}
65+
} else {
66+
controller.enqueue(value);
67+
}
68+
},
69+
});
70+
71+
return new Response(bodyStream, {
72+
status: 200,
73+
headers: {
74+
"Content-Type": "application/json",
75+
},
76+
});
77+
}
78+
}

‎src/socket/socket_init_options.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface SocketInitOptions {
2+
method? : 'GET' | 'PUT' | 'POST',
3+
headers : Record<string, string>
4+
}

‎src/socket/socket_options.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface SocketOptions {
2+
connect : typeof Deno.connect
3+
}

0 commit comments

Comments
 (0)