Skip to content

Commit

Permalink
fix(http): Skip 0 chunks when writing body (denoland#387)
Browse files Browse the repository at this point in the history
  • Loading branch information
arcatdmz authored and ry committed May 14, 2019
1 parent 07ca4f9 commit 79d5f55
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
3 changes: 2 additions & 1 deletion http/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
const { listen, toAsyncIterator, copy } = Deno;
const { listen, copy, toAsyncIterator } = Deno;
type Conn = Deno.Conn;
type Reader = Deno.Reader;
type Writer = Deno.Writer;
Expand Down Expand Up @@ -79,6 +79,7 @@ async function writeChunkedBody(w: Writer, r: Reader): Promise<void> {
const encoder = new TextEncoder();

for await (const chunk of toAsyncIterator(r)) {
if (chunk.byteLength <= 0) continue;
const start = encoder.encode(`${chunk.byteLength.toString(16)}\r\n`);
const end = encoder.encode("\r\n");
await writer.write(start);
Expand Down
68 changes: 66 additions & 2 deletions http/server_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
// https://github.com/golang/go/blob/master/src/net/http/responsewrite_test.go

const { Buffer } = Deno;
import { test } from "../testing/mod.ts";
import { test, runIfMain } from "../testing/mod.ts";
import { assertEquals } from "../testing/asserts.ts";
import { Response, ServerRequest } from "./server.ts";
import { Response, ServerRequest, writeResponse } from "./server.ts";
import { BufReader, BufWriter } from "../io/bufio.ts";
import { StringReader } from "../io/readers.ts";

interface ResponseTest {
response: Response;
Expand Down Expand Up @@ -261,3 +262,66 @@ test(async function requestBodyStreamWithTransferEncoding(): Promise<void> {
}
}
});

test(async function writeUint8ArrayResponse(): Promise<void> {
const shortText = "Hello";

const body = new TextEncoder().encode(shortText);
const res: Response = { body };

const buf = new Deno.Buffer();
await writeResponse(buf, res);

const decoder = new TextDecoder("utf-8");
const reader = new BufReader(buf);

let line: Uint8Array;
line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), "HTTP/1.1 200 OK");

line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), `content-length: ${shortText.length}`);

line = (await reader.readLine())[0];
assertEquals(line.byteLength, 0);

line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), shortText);

line = (await reader.readLine())[0];
assertEquals(line.byteLength, 0);
});

test(async function writeStringReaderResponse(): Promise<void> {
const shortText = "Hello";

const body = new StringReader(shortText);
const res: Response = { body };

const buf = new Deno.Buffer();
await writeResponse(buf, res);

const decoder = new TextDecoder("utf-8");
const reader = new BufReader(buf);

let line: Uint8Array;
line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), "HTTP/1.1 200 OK");

line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), "transfer-encoding: chunked");

line = (await reader.readLine())[0];
assertEquals(line.byteLength, 0);

line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), shortText.length.toString());

line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), shortText);

line = (await reader.readLine())[0];
assertEquals(decoder.decode(line), "0");
});

runIfMain(import.meta);

0 comments on commit 79d5f55

Please sign in to comment.