1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-14 01:50:19 -05:00

std/http: add serveTLS and listenAndServeTLS (#3257)

This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2019-11-04 13:45:29 -05:00 committed by Ry Dahl
parent 0049d4e50c
commit 0644f9c1a6
4 changed files with 124 additions and 1 deletions

View file

@ -1,5 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
const { listen, copy, toAsyncIterator } = Deno;
const { listen, listenTLS, copy, toAsyncIterator } = Deno;
type Listener = Deno.Listener;
type Conn = Deno.Conn;
type Reader = Deno.Reader;
@ -401,6 +401,61 @@ export async function listenAndServe(
}
}
/** Options for creating an HTTPS server. */
export type HTTPSOptions = Omit<Deno.ListenTLSOptions, "transport">;
/**
* Create an HTTPS server with given options
* @param options Server configuration
* @return Async iterable server instance for incoming requests
*
* const body = new TextEncoder().encode("Hello HTTPS");
* const options = {
* hostname: "localhost",
* port: 443,
* certFile: "./path/to/localhost.crt",
* keyFile: "./path/to/localhost.key",
* };
* for await (const req of serveTLS(options)) {
* req.respond({ body });
* }
*/
export function serveTLS(options: HTTPSOptions): Server {
const tlsOptions: Deno.ListenTLSOptions = {
...options,
transport: "tcp"
};
const listener = listenTLS(tlsOptions);
return new Server(listener);
}
/**
* Create an HTTPS server with given options and request handler
* @param options Server configuration
* @param handler Request handler
*
* const body = new TextEncoder().encode("Hello HTTPS");
* const options = {
* hostname: "localhost",
* port: 443,
* certFile: "./path/to/localhost.crt",
* keyFile: "./path/to/localhost.key",
* };
* listenAndServeTLS(options, (req) => {
* req.respond({ body });
* });
*/
export async function listenAndServeTLS(
options: HTTPSOptions,
handler: (req: ServerRequest) => void
): Promise<void> {
const server = serveTLS(options);
for await (const request of server) {
handler(request);
}
}
export interface Response {
status?: number;
headers?: Headers;

View file

@ -529,4 +529,55 @@ test({
}
});
test({
name: "[http] serveTLS",
async fn(): Promise<void> {
// Runs a simple server as another process
const p = Deno.run({
args: [
Deno.execPath(),
"http/testdata/simple_https_server.ts",
"--allow-net",
"--allow-read"
],
stdout: "piped"
});
try {
const r = new TextProtoReader(new BufReader(p.stdout!));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("server listening"));
let serverIsRunning = true;
p.status()
.then(
(): void => {
serverIsRunning = false;
}
)
.catch((_): void => {}); // Ignores the error when closing the process.
// Requests to the server and immediately closes the connection
const conn = await Deno.dialTLS({
hostname: "localhost",
port: 4503,
certFile: "http/testdata/tls/RootCA.pem"
});
await Deno.writeAll(
conn,
new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n")
);
const res = new Uint8Array(100);
const nread = assertNotEOF(await conn.read(res));
conn.close();
const resStr = new TextDecoder().decode(res.subarray(0, nread));
assert(resStr.includes("Hello HTTPS"));
assert(serverIsRunning);
} finally {
// Stops the sever.
p.close();
}
}
});
runIfMain(import.meta);

View file

@ -0,0 +1,16 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// This is an example of a https server
import { serveTLS } from "../server.ts";
const tlsOptions = {
hostname: "localhost",
port: 4503,
certFile: "./http/testdata/tls/localhost.crt",
keyFile: "./http/testdata/tls/localhost.key",
};
const s = serveTLS(tlsOptions);
console.log(`Simple HTTPS server listening on ${tlsOptions.hostname}:${tlsOptions.port}`);
const body = new TextEncoder().encode("Hello HTTPS");
for await (const req of s) {
req.respond({ body });
}

1
std/http/testdata/tls vendored Symbolic link
View file

@ -0,0 +1 @@
../../../cli/tests/tls