14

I am looking for an example of creating a https server in Deno. I have seen examples of Deno http server but not https.

I have tried searching in google but found no results

jayKumar
  • 141
  • 1
  • 4
  • 1
    Deno currently does not have SSL bindings yet. There is ongoing work adding such bindings so you could expect it to land in the coming 2 months. – Kevin Qian Apr 30 '19 at 06:58
  • 2
    As above, there's currently no way to do so in Deno. A good alternative is to setup a reverse proxy like nginx which will forward https requests to your http server. – JD Byrnes Aug 05 '19 at 17:51
  • 1
    Small update: we just implemented `Deno.listenTLS()`. We will be introducing `serveTLS` or similar for https very soon in Deno standard modules. – Kevin Qian Nov 03 '19 at 20:04

7 Answers7

9

serveTLS has landed along with Deno 0.23.0:

Sample usage:

import { serveTLS } from "https://deno.land/std/http/server.ts";

const body = new TextEncoder().encode("Hello HTTPS");
const options = {
  hostname: "localhost",
  port: 443,
  certFile: "./path/to/localhost.crt",
  keyFile: "./path/to/localhost.key",
};
// Top-level await supported
for await (const req of serveTLS(options)) {
  req.respond({ body });
}
Kevin Qian
  • 2,532
  • 1
  • 16
  • 26
1

With Deno 1.9+ you could use the native server. It provides the ability to use HTTPS.

It is a good bit faster faster than older implementations of std/http. However, as of version 0.107.0 the native server is used for std/http as well.

Example:

const server = Deno.listenTls({
  port: 443,
  certFile: "./my-ca-certificate.pem",
  keyFile: "./my-key.pem"
});

for await (const conn of server) {
  handle(conn);
}

async function handle(conn: Deno.Conn) {
  const httpConn = Deno.serveHttp(conn);
  
  for await (const requestEvent of httpConn) {
    try {
      const response = new Response("Hello World!");
      await requestEvent.respondWith(response);
    } 
    catch (error) {
      console.error(error);
    }
  }
}
Zwiers
  • 3,040
  • 2
  • 12
  • 18
0

Now TLS binding is supported by Dano. Below are ways to create https server:

import { serveTLS } from "https://deno.land/std/http/server.ts";

    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 });
}

serveTLS

Arguments options: any

return :Server

With listenAndServeTLS

listenAndServeTLS(options, (req) => {
   req.respond({ body });
 });

listenAndServeTLS

Arguments

  • options: any

  • handler: (req: ServerRequest) => void

return:any

For more details see official docs:

Sandeep Patel
  • 4,815
  • 3
  • 21
  • 37
  • 2
    do you know how to make it work with self signed certificates, it does not seems to be working with it! – user3769778 Mar 04 '20 at 11:04
  • 2
    Yes, I am getting this error: `Uncaught InvalidData: received fatal alert: BadCertificate`, same cert-key works on node express setup! – user3769778 Mar 06 '20 at 02:19
0

How about using deno oak framework?

https://github.com/oakserver/oak

I think the project is the most stable web framework in Deno. And you also get the much information from that you want to learn about it.

Songwon Park
  • 125
  • 1
  • 11
0

First of all, it is possible to create an HTTPS server with DENO std library. But in my case, I used the OAK library for my app. More about the oak library can be found here. Step-1: Have the certificate file and key file ready(assuming they are produced for whatever domain name you like. It could just be localhost). If you have no idea what this means, read this article.. Step-2: It's time to configure your app's listening options. You can copy the below line of code and change the paths to the certFile and keyFile options as necessary. More explanation given below.

await app.listen({ port: port, secure: true, certFile: "<path-to-file>/<file-name>.pem", keyFile: "<path-to-file>/<file-name>-key.pem" });

In case you want to know what's happening in the above line:

  1. Oak's Application's listen method accepts options to be configured and these options is of type ListenOptions which can either be ListenOptionsBase or ListenOptionsTls which are inherited from Deno.ListenOptions and Deno.ListenTlsOptions respectively. If you check the Deno.ListenTlsOptions there are two options which are certFile and keyFile which accepts paths to your certificate and key for the certificate respectively, which are both .pem files.
0

bro, I run into some situations when I code like as follow:

/** @format */
const cert = Deno.readTextFileSync('./cert.pem')
const key = Deno.readTextFileSync('./private.pem')

const listener = Deno.listenTls({
  cert,
  key,
  hostname: 'localhost',
  port: 8080,
})

console.log('Server running on https://localhost:8080/')

for await (const conn of listener) {
  handleConn(conn)
}

async function handleConn(conn: Deno.TlsConn) {
  const httpConn = Deno.serveHttp(conn)

  for await (const req of httpConn) {
    const url = new URL(req.request.url)
    if (url.pathname === '/favicon.ico') continue
    const path = url.pathname === '/' ? '/welcome.html' : url.pathname
    const ext = path.split('.').pop()

    const file = (await Deno.open(`./http/example${path}`)).readable
    let res: Response | null = null
    switch (ext) {
      case 'html' || 'css':
        res = resBuilder(file, `text/${ext}`)
        break
      case 'js':
        res = resBuilder(file, 'text/javascript')
        break
      case 'png' || 'jpg' || 'ico':
        res = resBuilder(file, `image/${ext}`)
        break
      default:
        res = resBuilder(file, '*/*')
    }
    req.respondWith(res!)
  }
}

function resBuilder(data: ReadableStream<Uint8Array>, contentType: string) {
  return new Response(data, {
    headers: new Headers({ 'content-type': contentType }),
  })
}

When I opened it in the browser, an error occurred:

error: Uncaught (in promise) Http: error writing a body to connection: tls handshake eof: tls handshake eof
  for await (const req of httpConn) {
                   ^
    at async HttpConn.nextRequest (ext:deno_http/01_http.js:101:21)
    at async Object.next (ext:deno_http/01_http.js:184:24)
    at async handleConn (file:///Users/feiwu/Project/node/coding_and_nas/http/example/http.ts:24:20)
fwqaaq
  • 1
-2

Have you checked DENO ABC? It is better framework to create web applications. Read more at https://deno.land/x/abc/README.md.

import { abc } from "https://deno.sh/abc/mod.ts";
const app = abc();
app
  .get("/hello", c => {
    return "Hello, Abc!";
  })
  .start("0.0.0.0:8080");
David Medinets
  • 5,160
  • 3
  • 29
  • 42
Speedyankur
  • 152
  • 6