diff options
Diffstat (limited to 'std/http')
-rw-r--r-- | std/http/_io.ts | 26 | ||||
-rw-r--r-- | std/http/_io_test.ts | 40 | ||||
-rw-r--r-- | std/http/cookie_test.ts | 20 | ||||
-rwxr-xr-x | std/http/file_server.ts | 20 | ||||
-rw-r--r-- | std/http/file_server_test.ts | 8 | ||||
-rw-r--r-- | std/http/racing_server.ts | 4 | ||||
-rw-r--r-- | std/http/server.ts | 10 | ||||
-rw-r--r-- | std/http/server_test.ts | 60 |
8 files changed, 90 insertions, 98 deletions
diff --git a/std/http/_io.ts b/std/http/_io.ts index 1db0fc292..743f52556 100644 --- a/std/http/_io.ts +++ b/std/http/_io.ts @@ -122,7 +122,7 @@ function isProhibidedForTrailer(key: string): boolean { * field will be deleted. */ export async function readTrailers( headers: Headers, - r: BufReader + r: BufReader, ): Promise<void> { const trailers = parseTrailer(headers.get("trailer")); if (trailers == null) return; @@ -133,11 +133,11 @@ export async function readTrailers( throw new Deno.errors.InvalidData("Missing trailer header."); } const undeclared = [...result.keys()].filter( - (k) => !trailerNames.includes(k) + (k) => !trailerNames.includes(k), ); if (undeclared.length > 0) { throw new Deno.errors.InvalidData( - `Undeclared trailers: ${Deno.inspect(undeclared)}.` + `Undeclared trailers: ${Deno.inspect(undeclared)}.`, ); } for (const [k, v] of result) { @@ -146,7 +146,7 @@ export async function readTrailers( const missingTrailers = trailerNames.filter((k) => !result.has(k)); if (missingTrailers.length > 0) { throw new Deno.errors.InvalidData( - `Missing trailers: ${Deno.inspect(missingTrailers)}.` + `Missing trailers: ${Deno.inspect(missingTrailers)}.`, ); } headers.delete("trailer"); @@ -163,7 +163,7 @@ function parseTrailer(field: string | null): Headers | undefined { const prohibited = trailerNames.filter((k) => isProhibidedForTrailer(k)); if (prohibited.length > 0) { throw new Deno.errors.InvalidData( - `Prohibited trailer names: ${Deno.inspect(prohibited)}.` + `Prohibited trailer names: ${Deno.inspect(prohibited)}.`, ); } return new Headers(trailerNames.map((key) => [key, ""])); @@ -171,7 +171,7 @@ function parseTrailer(field: string | null): Headers | undefined { export async function writeChunkedBody( w: Deno.Writer, - r: Deno.Reader + r: Deno.Reader, ): Promise<void> { const writer = BufWriter.create(w); for await (const chunk of Deno.iter(r)) { @@ -192,7 +192,7 @@ export async function writeChunkedBody( export async function writeTrailers( w: Deno.Writer, headers: Headers, - trailers: Headers + trailers: Headers, ): Promise<void> { const trailer = headers.get("trailer"); if (trailer === null) { @@ -201,7 +201,7 @@ export async function writeTrailers( const transferEncoding = headers.get("transfer-encoding"); if (transferEncoding === null || !transferEncoding.match(/^chunked/)) { throw new TypeError( - `Trailers are only allowed for "transfer-encoding: chunked", got "transfer-encoding: ${transferEncoding}".` + `Trailers are only allowed for "transfer-encoding: chunked", got "transfer-encoding: ${transferEncoding}".`, ); } const writer = BufWriter.create(w); @@ -211,11 +211,11 @@ export async function writeTrailers( ); if (prohibitedTrailers.length > 0) { throw new TypeError( - `Prohibited trailer names: ${Deno.inspect(prohibitedTrailers)}.` + `Prohibited trailer names: ${Deno.inspect(prohibitedTrailers)}.`, ); } const undeclared = [...trailers.keys()].filter( - (k) => !trailerNames.includes(k) + (k) => !trailerNames.includes(k), ); if (undeclared.length > 0) { throw new TypeError(`Undeclared trailers: ${Deno.inspect(undeclared)}.`); @@ -229,7 +229,7 @@ export async function writeTrailers( export async function writeResponse( w: Deno.Writer, - r: Response + r: Response, ): Promise<void> { const protoMajor = 1; const protoMinor = 1; @@ -333,7 +333,7 @@ export function parseHTTPVersion(vers: string): [number, number] { export async function readRequest( conn: Deno.Conn, - bufr: BufReader + bufr: BufReader, ): Promise<ServerRequest | null> { const tp = new TextProtoReader(bufr); const firstLine = await tp.readLine(); // e.g. GET /index.html HTTP/1.0 @@ -372,7 +372,7 @@ function fixLength(req: ServerRequest): void { // that contains a Transfer-Encoding header field. // rfc: https://tools.ietf.org/html/rfc7230#section-3.3.2 throw new Error( - "http: Transfer-Encoding and Content-Length cannot be send together" + "http: Transfer-Encoding and Content-Length cannot be send together", ); } } diff --git a/std/http/_io_test.ts b/std/http/_io_test.ts index 473c40637..77d8288f2 100644 --- a/std/http/_io_test.ts +++ b/std/http/_io_test.ts @@ -23,7 +23,7 @@ Deno.test("bodyReader", async () => { const text = "Hello, Deno"; const r = bodyReader( text.length, - new BufReader(new Deno.Buffer(encode(text))) + new BufReader(new Deno.Buffer(encode(text))), ); assertEquals(decode(await Deno.readAll(r)), text); }); @@ -108,14 +108,14 @@ Deno.test( async () => { await readTrailers( h, - new BufReader(new Deno.Buffer(encode(trailer))) + new BufReader(new Deno.Buffer(encode(trailer))), ); }, Deno.errors.InvalidData, - `Undeclared trailers: [ "` + `Undeclared trailers: [ "`, ); } - } + }, ); Deno.test( @@ -130,10 +130,10 @@ Deno.test( await readTrailers(h, new BufReader(new Deno.Buffer())); }, Deno.errors.InvalidData, - `Prohibited trailer names: [ "` + `Prohibited trailer names: [ "`, ); } - } + }, ); Deno.test("writeTrailer", async () => { @@ -141,11 +141,11 @@ Deno.test("writeTrailer", async () => { await writeTrailers( w, new Headers({ "transfer-encoding": "chunked", trailer: "deno,node" }), - new Headers({ deno: "land", node: "js" }) + new Headers({ deno: "land", node: "js" }), ); assertEquals( new TextDecoder().decode(w.bytes()), - "deno: land\r\nnode: js\r\n\r\n" + "deno: land\r\nnode: js\r\n\r\n", ); }); @@ -156,14 +156,14 @@ Deno.test("writeTrailer should throw", async () => { return writeTrailers(w, new Headers(), new Headers()); }, TypeError, - "Missing trailer header." + "Missing trailer header.", ); await assertThrowsAsync( () => { return writeTrailers(w, new Headers({ trailer: "deno" }), new Headers()); }, TypeError, - `Trailers are only allowed for "transfer-encoding: chunked", got "transfer-encoding: null".` + `Trailers are only allowed for "transfer-encoding: chunked", got "transfer-encoding: null".`, ); for (const f of ["content-length", "trailer", "transfer-encoding"]) { await assertThrowsAsync( @@ -171,11 +171,11 @@ Deno.test("writeTrailer should throw", async () => { return writeTrailers( w, new Headers({ "transfer-encoding": "chunked", trailer: f }), - new Headers({ [f]: "1" }) + new Headers({ [f]: "1" }), ); }, TypeError, - `Prohibited trailer names: [ "` + `Prohibited trailer names: [ "`, ); } await assertThrowsAsync( @@ -183,11 +183,11 @@ Deno.test("writeTrailer should throw", async () => { return writeTrailers( w, new Headers({ "transfer-encoding": "chunked", trailer: "deno" }), - new Headers({ node: "js" }) + new Headers({ node: "js" }), ); }, TypeError, - `Undeclared trailers: [ "node" ].` + `Undeclared trailers: [ "node" ].`, ); }); @@ -419,20 +419,17 @@ Deno.test("testReadRequestError", async function (): Promise<void> { // deduplicated if same or reject otherwise // See Issue 16490. { - in: - "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 0\r\n\r\n" + + in: "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 0\r\n\r\n" + "Gopher hey\r\n", err: "cannot contain multiple Content-Length headers", }, { - in: - "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 6\r\n\r\n" + + in: "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 6\r\n\r\n" + "Gopher\r\n", err: "cannot contain multiple Content-Length headers", }, { - in: - "PUT / HTTP/1.1\r\nContent-Length: 6 \r\nContent-Length: 6\r\n" + + in: "PUT / HTTP/1.1\r\nContent-Length: 6 \r\nContent-Length: 6\r\n" + "Content-Length:6\r\n\r\nGopher\r\n", headers: [{ key: "Content-Length", value: "6" }], }, @@ -451,8 +448,7 @@ Deno.test("testReadRequestError", async function (): Promise<void> { headers: [{ key: "Content-Length", value: "0" }], }, { - in: - "POST / HTTP/1.1\r\nContent-Length:0\r\ntransfer-encoding: " + + in: "POST / HTTP/1.1\r\nContent-Length:0\r\ntransfer-encoding: " + "chunked\r\n\r\n", headers: [], err: "http: Transfer-Encoding and Content-Length cannot be send together", diff --git a/std/http/cookie_test.ts b/std/http/cookie_test.ts index 0b412d8e4..f34f5acae 100644 --- a/std/http/cookie_test.ts +++ b/std/http/cookie_test.ts @@ -38,7 +38,7 @@ Deno.test({ deleteCookie(res, "deno"); assertEquals( res.headers?.get("Set-Cookie"), - "deno=; Expires=Thu, 01 Jan 1970 00:00:00 GMT" + "deno=; Expires=Thu, 01 Jan 1970 00:00:00 GMT", ); }, }); @@ -79,7 +79,7 @@ Deno.test({ }); assertEquals( res.headers.get("Set-Cookie"), - "Space=Cat; Secure; HttpOnly; Max-Age=2" + "Space=Cat; Secure; HttpOnly; Max-Age=2", ); let error = false; @@ -108,7 +108,7 @@ Deno.test({ }); assertEquals( res.headers.get("Set-Cookie"), - "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land" + "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land", ); res.headers = new Headers(); @@ -124,7 +124,7 @@ Deno.test({ assertEquals( res.headers.get("Set-Cookie"), "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; " + - "SameSite=Strict" + "SameSite=Strict", ); res.headers = new Headers(); @@ -139,7 +139,7 @@ Deno.test({ }); assertEquals( res.headers.get("Set-Cookie"), - "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; SameSite=Lax" + "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; SameSite=Lax", ); res.headers = new Headers(); @@ -154,7 +154,7 @@ Deno.test({ }); assertEquals( res.headers.get("Set-Cookie"), - "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; Path=/" + "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; Path=/", ); res.headers = new Headers(); @@ -171,7 +171,7 @@ Deno.test({ assertEquals( res.headers.get("Set-Cookie"), "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; Path=/; " + - "unparsed=keyvalue; batman=Bruce" + "unparsed=keyvalue; batman=Bruce", ); res.headers = new Headers(); @@ -188,7 +188,7 @@ Deno.test({ assertEquals( res.headers.get("Set-Cookie"), "Space=Cat; Secure; HttpOnly; Max-Age=2; Domain=deno.land; Path=/; " + - "Expires=Fri, 07 Jan 1983 15:32:00 GMT" + "Expires=Fri, 07 Jan 1983 15:32:00 GMT", ); res.headers = new Headers(); @@ -203,7 +203,7 @@ Deno.test({ }); assertEquals( res.headers.get("Set-Cookie"), - "__Host-Kitty=Meow; Secure; Path=/" + "__Host-Kitty=Meow; Secure; Path=/", ); res.headers = new Headers(); @@ -211,7 +211,7 @@ Deno.test({ setCookie(res, { name: "cookie-2", value: "value-2", maxAge: 3600 }); assertEquals( res.headers.get("Set-Cookie"), - "cookie-1=value-1; Secure, cookie-2=value-2; Max-Age=3600" + "cookie-1=value-1; Secure, cookie-2=value-2; Max-Age=3600", ); res.headers = new Headers(); diff --git a/std/http/file_server.ts b/std/http/file_server.ts index a66118e74..ffcf31e54 100755 --- a/std/http/file_server.ts +++ b/std/http/file_server.ts @@ -97,7 +97,7 @@ function fileLenToString(len: number): string { export async function serveFile( req: ServerRequest, - filePath: string + filePath: string, ): Promise<Response> { const [file, fileInfo] = await Promise.all([ Deno.open(filePath), @@ -122,7 +122,7 @@ export async function serveFile( // TODO: simplify this after deno.stat and deno.readDir are fixed async function serveDir( req: ServerRequest, - dirPath: string + dirPath: string, ): Promise<Response> { const dirUrl = `/${posix.relative(target, dirPath)}`; const listEntry: EntryInfo[] = []; @@ -192,7 +192,7 @@ function setCORS(res: Response): void { res.headers.append("access-control-allow-origin", "*"); res.headers.append( "access-control-allow-headers", - "Origin, X-Requested-With, Content-Type, Accept, Range" + "Origin, X-Requested-With, Content-Type, Accept, Range", ); } @@ -263,9 +263,10 @@ function dirViewerTemplate(dirname: string, entries: EntryInfo[]): string { <th>Size</th> <th>Name</th> </tr> - ${entries.map( - (entry) => - html` + ${ + entries.map( + (entry) => + html` <tr> <td class="mode"> ${entry.mode} @@ -277,8 +278,9 @@ function dirViewerTemplate(dirname: string, entries: EntryInfo[]): string { <a href="${entry.url}">${entry.name}</a> </td> </tr> - ` - )} + `, + ) + } </table> </main> </body> @@ -359,7 +361,7 @@ function main(): void { console.error(e.message); } } - } + }, ); console.log(`HTTP server listening on http://${addr}/`); diff --git a/std/http/file_server_test.ts b/std/http/file_server_test.ts index 66c1d7d04..486bc514c 100644 --- a/std/http/file_server_test.ts +++ b/std/http/file_server_test.ts @@ -78,13 +78,13 @@ Deno.test( assertEquals(res.headers.get("content-type"), "text/markdown"); const downloadedFile = await res.text(); const localFile = new TextDecoder().decode( - await Deno.readFile("README.md") + await Deno.readFile("README.md"), ); assertEquals(downloadedFile, localFile); } finally { await killFileServer(); } - } + }, ); Deno.test( @@ -98,14 +98,14 @@ Deno.test( assertEquals(res.headers.get("content-type"), "text/markdown"); const downloadedFile = await res.text(); const localFile = new TextDecoder().decode( - await Deno.readFile("./http/README.md") + await Deno.readFile("./http/README.md"), ); console.log(downloadedFile, localFile); assertEquals(downloadedFile, localFile); } finally { await killFileServer(); } - } + }, ); Deno.test("serveDirectory", async function (): Promise<void> { diff --git a/std/http/racing_server.ts b/std/http/racing_server.ts index 67db029e0..1770443af 100644 --- a/std/http/racing_server.ts +++ b/std/http/racing_server.ts @@ -10,7 +10,7 @@ function body(i: number): string { } async function delayedRespond( request: ServerRequest, - step: number + step: number, ): Promise<void> { await delay(3000); await request.respond({ status: 200, body: body(step) }); @@ -24,7 +24,7 @@ async function largeRespond(request: ServerRequest, c: string): Promise<void> { async function ignoreToConsume( request: ServerRequest, - step: number + step: number, ): Promise<void> { await request.respond({ status: 200, body: body(step) }); } diff --git a/std/http/server.ts b/std/http/server.ts index b1ffed96b..93f116fff 100644 --- a/std/http/server.ts +++ b/std/http/server.ts @@ -65,7 +65,7 @@ export class ServerRequest { .map((e): string => e.trim().toLowerCase()); assert( parts.includes("chunked"), - 'transfer-encoding must include "chunked" if content-length is not set' + 'transfer-encoding must include "chunked" if content-length is not set', ); this._body = chunkedBodyReader(this.headers, this.r); } else { @@ -136,7 +136,7 @@ export class Server implements AsyncIterable<ServerRequest> { // Yields all HTTP requests on a single TCP connection. private async *iterateHttpRequests( - conn: Deno.Conn + conn: Deno.Conn, ): AsyncIterableIterator<ServerRequest> { const reader = new BufReader(conn); const writer = new BufWriter(conn); @@ -203,7 +203,7 @@ export class Server implements AsyncIterable<ServerRequest> { // same kind and adds it to the request multiplexer so that another TCP // connection can be accepted. private async *acceptConnAndIterateHttpRequests( - mux: MuxAsyncIterator<ServerRequest> + mux: MuxAsyncIterator<ServerRequest>, ): AsyncIterableIterator<ServerRequest> { if (this.closing) return; // Wait for a new connection. @@ -302,7 +302,7 @@ export function serve(addr: string | HTTPOptions): Server { */ export async function listenAndServe( addr: string | HTTPOptions, - handler: (req: ServerRequest) => void + handler: (req: ServerRequest) => void, ): Promise<void> { const server = serve(addr); @@ -359,7 +359,7 @@ export function serveTLS(options: HTTPSOptions): Server { */ export async function listenAndServeTLS( options: HTTPSOptions, - handler: (req: ServerRequest) => void + handler: (req: ServerRequest) => void, ): Promise<void> { const server = serveTLS(options); diff --git a/std/http/server_test.ts b/std/http/server_test.ts index f6bff1c5f..bc9b52341 100644 --- a/std/http/server_test.ts +++ b/std/http/server_test.ts @@ -51,8 +51,7 @@ const responseTests: ResponseTest[] = [ body: new Deno.Buffer(new TextEncoder().encode("abcdef")), }, - raw: - "HTTP/1.1 200 OK\r\n" + + raw: "HTTP/1.1 200 OK\r\n" + "transfer-encoding: chunked\r\n\r\n" + "6\r\nabcdef\r\n0\r\n\r\n", }, @@ -94,10 +93,9 @@ Deno.test("requestContentLength", function (): void { const maxChunkSize = 70; while (chunkOffset < shortText.length) { const chunkSize = Math.min(maxChunkSize, shortText.length - chunkOffset); - chunksData += `${chunkSize.toString(16)}\r\n${shortText.substr( - chunkOffset, - chunkSize - )}\r\n`; + chunksData += `${chunkSize.toString(16)}\r\n${ + shortText.substr(chunkOffset, chunkSize) + }\r\n`; chunkOffset += chunkSize; } chunksData += "0\r\n\r\n"; @@ -164,7 +162,7 @@ Deno.test( assertEquals(tr.total, 0); await req.finalize(); assertEquals(tr.total, text.length); - } + }, ); Deno.test( "ServerRequest.finalize() should consume unread body / chunked, trailers", @@ -199,7 +197,7 @@ Deno.test( assertEquals(req.headers.has("trailer"), false); assertEquals(req.headers.get("deno"), "land"); assertEquals(req.headers.get("node"), "js"); - } + }, ); Deno.test("requestBodyWithTransferEncoding", async function (): Promise<void> { { @@ -212,10 +210,9 @@ Deno.test("requestBodyWithTransferEncoding", async function (): Promise<void> { const maxChunkSize = 70; while (chunkOffset < shortText.length) { const chunkSize = Math.min(maxChunkSize, shortText.length - chunkOffset); - chunksData += `${chunkSize.toString(16)}\r\n${shortText.substr( - chunkOffset, - chunkSize - )}\r\n`; + chunksData += `${chunkSize.toString(16)}\r\n${ + shortText.substr(chunkOffset, chunkSize) + }\r\n`; chunkOffset += chunkSize; } chunksData += "0\r\n\r\n"; @@ -236,10 +233,9 @@ Deno.test("requestBodyWithTransferEncoding", async function (): Promise<void> { const maxChunkSize = 70; while (chunkOffset < longText.length) { const chunkSize = Math.min(maxChunkSize, longText.length - chunkOffset); - chunksData += `${chunkSize.toString(16)}\r\n${longText.substr( - chunkOffset, - chunkSize - )}\r\n`; + chunksData += `${chunkSize.toString(16)}\r\n${ + longText.substr(chunkOffset, chunkSize) + }\r\n`; chunkOffset += chunkSize; } chunksData += "0\r\n\r\n"; @@ -308,10 +304,9 @@ Deno.test("requestBodyReaderWithTransferEncoding", async function (): Promise< const maxChunkSize = 70; while (chunkOffset < shortText.length) { const chunkSize = Math.min(maxChunkSize, shortText.length - chunkOffset); - chunksData += `${chunkSize.toString(16)}\r\n${shortText.substr( - chunkOffset, - chunkSize - )}\r\n`; + chunksData += `${chunkSize.toString(16)}\r\n${ + shortText.substr(chunkOffset, chunkSize) + }\r\n`; chunkOffset += chunkSize; } chunksData += "0\r\n\r\n"; @@ -341,10 +336,9 @@ Deno.test("requestBodyReaderWithTransferEncoding", async function (): Promise< const maxChunkSize = 70; while (chunkOffset < longText.length) { const chunkSize = Math.min(maxChunkSize, longText.length - chunkOffset); - chunksData += `${chunkSize.toString(16)}\r\n${longText.substr( - chunkOffset, - chunkSize - )}\r\n`; + chunksData += `${chunkSize.toString(16)}\r\n${ + longText.substr(chunkOffset, chunkSize) + }\r\n`; chunkOffset += chunkSize; } chunksData += "0\r\n\r\n"; @@ -436,7 +430,7 @@ Deno.test({ const s = await r.readLine(); assert( s !== null && s.includes("server listening"), - "server must be started" + "server must be started", ); // Requests to the server and immediately closes the connection const conn = await Deno.connectTls({ @@ -446,7 +440,7 @@ Deno.test({ }); await Deno.writeAll( conn, - new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n") + new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n"), ); const res = new Uint8Array(100); const nread = await conn.read(res); @@ -475,7 +469,7 @@ Deno.test( const nextAfterClosing = server[Symbol.asyncIterator]().next(); assertEquals(await nextAfterClosing, { value: undefined, done: true }); - } + }, ); Deno.test({ @@ -492,7 +486,7 @@ Deno.test({ const conn = await Deno.connect({ hostname: "127.0.0.1", port: 8123 }); await Deno.writeAll( conn, - new TextEncoder().encode("GET /hello HTTP/1.1\r\n\r\n") + new TextEncoder().encode("GET /hello HTTP/1.1\r\n\r\n"), ); const res = new Uint8Array(100); const nread = await conn.read(res); @@ -533,7 +527,7 @@ Deno.test({ }); await Deno.writeAll( conn, - new TextEncoder().encode("GET / HTTP/1.1\r\n\r\n") + new TextEncoder().encode("GET / HTTP/1.1\r\n\r\n"), ); conn.close(); await p; @@ -551,12 +545,12 @@ Deno.test({ }); await Deno.writeAll( conn, - encode("GET / HTTP/1.1\r\nmalformedHeader\r\n\r\n\r\n\r\n") + encode("GET / HTTP/1.1\r\nmalformedHeader\r\n\r\n\r\n\r\n"), ); const responseString = decode(await Deno.readAll(conn)); assertMatch( responseString, - /^HTTP\/1\.1 400 Bad Request\r\ncontent-length: \d+\r\n\r\n.*\r\n\r\n$/ms + /^HTTP\/1\.1 400 Bad Request\r\ncontent-length: \d+\r\n\r\n.*\r\n\r\n$/ms, ); conn.close(); server.close(); @@ -592,7 +586,7 @@ Deno.test({ port, // certFile }), - Deno.errors.InvalidData + Deno.errors.InvalidData, ); // Valid request after invalid @@ -604,7 +598,7 @@ Deno.test({ await Deno.writeAll( conn, - new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n") + new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n"), ); const res = new Uint8Array(100); const nread = await conn.read(res); |