diff options
| author | Ryan Dahl <ry@tinyclouds.org> | 2018-11-08 15:03:45 -0500 |
|---|---|---|
| committer | Ryan Dahl <ry@tinyclouds.org> | 2018-11-08 15:07:37 -0500 |
| commit | 80b2067030abdf9f51b1d0eb9ceaaf76c2d09bfb (patch) | |
| tree | 28ac74d66c66bbf9e418e926dfed978919b81fb8 | |
| parent | fb0b99408b1ce0c8061d654e9dae3fd8221efa6f (diff) | |
Use async iterators for http server.
Original: https://github.com/denoland/deno_std/commit/9377d154c5079a732d76a36a6ec5892d8da43087
| -rw-r--r-- | http.ts | 98 | ||||
| -rw-r--r-- | http_test.ts | 19 |
2 files changed, 64 insertions, 53 deletions
@@ -1,71 +1,67 @@ -import * as deno from "deno"; -import * as bufio from "./bufio.ts"; +import { listen, Conn } from "deno"; +import { BufReader, BufState } from "./bufio.ts"; import { TextProtoReader } from "./textproto.ts"; +import { Headers } from "./headers.ts"; -type Handler = (req: ServerRequest) => Promise<void>; - -class Server { - _closing = false; - - constructor(readonly listener: deno.Listener) {} - - async serve(handler: Handler) { - while (!this._closing) { - const c = await this.listener.accept(); - const sc = new ServerConn(c); - sc.serve(handler); - } +export async function* serve(addr: string) { + const listener = listen("tcp", addr); + while (true) { + const c = await listener.accept(); + yield* serveConn(c); } + listener.close(); +} - close() { - this._closing = true; - this.listener.close(); +export async function* serveConn(c: Conn) { + let bufr = new BufReader(c); + try { + while (true) { + const req = await readRequest(bufr); + yield req; + } + } finally { + c.close(); } } -class ServerConn { - constructor(readonly c: deno.Conn) { - // TODO Use memory pool to obtain bufr and bufw. - this.bufr = new bufio.Reader(c); - this.bufw = new bufio.Writer(c); - } +interface Response { + status?: number; + body: string; +} - async serve(handler: Handler): Promise<void> { - const buffer = new Uint8Array(1024); - try { - while (true) { - const req = readRequest(this.bufr); +class ServerRequest { + url: string; + method: string; + proto: string; - /* - const response = new TextEncoder().encode( - "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World\n" - ); - await this.c.write(response); - */ - } - } finally { - this.c.close(); - } + respond(r: Response = { status: 200 }): Promise<void> { + throw Error("not implemented"); } } -function readRequest(b: bufio.Reader): ServerRequest { +async function readRequest(b: BufReader): Promise<ServerRequest> { const tp = new TextProtoReader(b); const req = new ServerRequest(); // First line: GET /index.html HTTP/1.0 - const s = await tp.readLine(); - const [method, url, proto] = parseRequestLine(s); - console.log("readRequest", method, url); -} + let s: string; + let err: BufState; + [s, err] = await tp.readLine(); + const { method, url, proto } = parseRequestLine(s); + req.method = method; + req.url = url; + req.proto = proto; -// Returns [method, url, proto] -function parseRequestLine(line: string): [string, string, string] { - return line.split(" ", 3); + let headers: Headers; + [headers, err] = await tp.readMIMEHeader(); + + return req; } -export function listen(addr: string): Server { - const listener = deno.listen("tcp", addr); - const s = new Server(listener); - return s; +// Returns [method, url, proto] +function parseRequestLine( + line: string +): { method: string; url: string; proto: string } { + let [method, url, proto] = line.split(" ", 3); + return { method, url, proto }; } diff --git a/http_test.ts b/http_test.ts index 4a8867aba..1b16b0f0a 100644 --- a/http_test.ts +++ b/http_test.ts @@ -1,6 +1,21 @@ -//import { listen } from "./server.ts"; -import { test } from "https://deno.land/x/testing/testing.ts"; +import { serve } from "./http.ts"; +//import { test } from "https://deno.land/x/testing/testing.ts"; +const addr = "0.0.0.0:8000"; +const s = serve(addr); +console.log(`listening on http://${addr}/`); + +async function main() { + for await (const req of s) { + console.log("Req", req); + req.respond({ body: "Hello World\n" }); + } +} + +main(); + +/* test(function basic() { console.log("ok"); }); + */ |
