diff options
-rw-r--r-- | std/http/io.ts | 35 | ||||
-rw-r--r-- | std/http/io_test.ts | 18 | ||||
-rw-r--r-- | std/http/mock.ts | 4 | ||||
-rw-r--r-- | std/http/server.ts | 7 |
4 files changed, 14 insertions, 50 deletions
diff --git a/std/http/io.ts b/std/http/io.ts index d16489767..b6bbfa17b 100644 --- a/std/http/io.ts +++ b/std/http/io.ts @@ -342,38 +342,17 @@ export function parseHTTPVersion(vers: string): [number, number] { export async function readRequest( conn: Deno.Conn, - // The reader and writer buffers may be constructed externally so they can be - // shared by requests on the same connection -- see `Server`. - reader?: BufReader, - writer?: BufWriter + bufr: BufReader ): Promise<ServerRequest | Deno.EOF> { - reader = reader ?? new BufReader(conn); - writer = writer ?? new BufWriter(conn); - const tp = new TextProtoReader(reader); - let firstLine: string | Deno.EOF; - let headers: Headers | Deno.EOF; - try { - firstLine = await tp.readLine(); // e.g. GET /index.html HTTP/1.0 - if (firstLine == Deno.EOF) { - return Deno.EOF; - } - headers = await tp.readMIMEHeader(); - if (headers == Deno.EOF) { - throw new Deno.errors.UnexpectedEof(); - } - } catch (error) { - // An error was thrown while parsing request headers. - await writeResponse(writer, { - status: 400, - body: encoder.encode(`${error.message}\r\n\r\n`), - }); - throw error; - } + const tp = new TextProtoReader(bufr); + const firstLine = await tp.readLine(); // e.g. GET /index.html HTTP/1.0 + if (firstLine === Deno.EOF) return Deno.EOF; + const headers = await tp.readMIMEHeader(); + if (headers === Deno.EOF) throw new Deno.errors.UnexpectedEof(); const req = new ServerRequest(); req.conn = conn; - req.r = reader; - req.w = writer; + req.r = bufr; [req.method, req.url, req.proto] = firstLine.split(" ", 3); [req.protoMinor, req.protoMajor] = parseHTTPVersion(req.proto); req.headers = headers; diff --git a/std/http/io_test.ts b/std/http/io_test.ts index aa9c86130..768a4ffe4 100644 --- a/std/http/io_test.ts +++ b/std/http/io_test.ts @@ -5,7 +5,6 @@ import { assert, assertNotEOF, assertNotEquals, - assertMatch, } from "../testing/asserts.ts"; import { bodyReader, @@ -350,28 +349,13 @@ malformedHeader `; const reader = new BufReader(new StringReader(input)); let err; - let responseString: string; try { - // Capture whatever `readRequest()` attempts to write to the connection on - // error. We expect it to be a 400 response. - await readRequest( - mockConn({ - write(p: Uint8Array): Promise<number> { - responseString = decode(p); - return Promise.resolve(p.length); - }, - }), - reader - ); + await readRequest(mockConn(), reader); } catch (e) { err = e; } assert(err instanceof Error); assertEquals(err.message, "malformed MIME header line: malformedHeader"); - assertMatch( - responseString!, - /^HTTP\/1\.1 400 Bad Request\r\ncontent-length: \d+\r\n\r\n.*\r\n\r\n$/ms - ); }); // Ported from Go diff --git a/std/http/mock.ts b/std/http/mock.ts index e84f9ad7b..64bd3fcb9 100644 --- a/std/http/mock.ts +++ b/std/http/mock.ts @@ -17,8 +17,8 @@ export function mockConn(base: Partial<Deno.Conn> = {}): Deno.Conn { read: (): Promise<number | Deno.EOF> => { return Promise.resolve(0); }, - write: (p: Uint8Array): Promise<number> => { - return Promise.resolve(p.length); + write: (): Promise<number> => { + return Promise.resolve(-1); }, close: (): void => {}, ...base, diff --git a/std/http/server.ts b/std/http/server.ts index d8a6d88db..00f401f62 100644 --- a/std/http/server.ts +++ b/std/http/server.ts @@ -146,14 +146,14 @@ export class Server implements AsyncIterable<ServerRequest> { private async *iterateHttpRequests( conn: Conn ): AsyncIterableIterator<ServerRequest> { - const reader = new BufReader(conn); - const writer = new BufWriter(conn); + const bufr = new BufReader(conn); + const w = new BufWriter(conn); let req: ServerRequest | Deno.EOF = Deno.EOF; let err: Error | undefined; while (!this.closing) { try { - req = await readRequest(conn, reader, writer); + req = await readRequest(conn, bufr); } catch (e) { err = e; } @@ -161,6 +161,7 @@ export class Server implements AsyncIterable<ServerRequest> { break; } + req.w = w; yield req; // Wait for the request to be processed before we accept a new request on |