summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--index.js77
1 files changed, 76 insertions, 1 deletions
diff --git a/index.js b/index.js
index eba3ac4..470b21d 100644
--- a/index.js
+++ b/index.js
@@ -1,3 +1,78 @@
'use strict'
-// todo
+const {createServer: createTlsServer} = require('tls')
+const {EventEmitter} = require('events')
+const {createParser} = require('./lib/parser')
+const createResponse = require('./lib/response')
+
+const ALPN_ID = 'gemini' // todo: clarify this
+
+const createGeminiServer = (opt = {}, onRequest) => {
+ if (typeof opt === 'function') {
+ onRequest = opt
+ opt = {}
+ }
+ const {
+ tlsOpt,
+ } = {
+ tlsOpt: {},
+ ...opt,
+ }
+
+ const onConnection = (socket) => {
+ const req = createParser()
+ socket.pipe(req)
+ socket.once('error', (err) => {
+ socket.unpipe(req)
+ req.destroy(err)
+ })
+
+ const close = () => {
+ socket.destroy()
+ req.destroy()
+ }
+ let timeout = setTimeout(close, 20 * 1000)
+
+ req.once('header', (header) => {
+ clearTimeout(timeout)
+
+ // prepare req
+ req.socket = socket
+ req.url = header.url
+ const url = new URL(header.url, 'http://foo/')
+ req.path = url.pathname
+ // todo: req.abort(), req.destroy()
+
+ // prepare res
+ const res = createResponse()
+ res.pipe(socket)
+ res.once('error', (err) => {
+ console.error('error', err)
+ res.unpipe(socket)
+ socket.destroy(err)
+ })
+ Object.defineProperty(res, 'socket', {value: socket})
+
+ onRequest(req, res)
+ server.emit('request', req, res)
+ })
+ }
+
+ const server = createTlsServer({
+ // ALPNProtocols: [ALPN_ID],
+ // https://gemini.circumlunar.space/docs/spec-spec.txt#1.4.1
+ // > Servers MUST use TLS version 1.2 or higher and SHOULD use TLS version
+ // > 1.3 or higher.
+ minVersion: 'TLSv1.2',
+ ...tlsOpt,
+ }, onConnection)
+
+ return server
+}
+
+// https://gemini.circumlunar.space/docs/spec-spec.txt, 1.
+// > When Gemini is served over TCP/IP, servers should listen on port 1965
+// > (the first manned Gemini mission, Gemini 3, flew in March '65).
+createGeminiServer.DEFAULT_PORT = 1965
+
+module.exports = createGeminiServer