UNPKG

1.95 kBJavaScriptView Raw
1const {promisify} = require('util')
2const {createServer} = require('http')
3const parseUrl = require('parseurl')
4const send = require('send')
5const {untilBefore} = require('until-before')
6const {getHost} = require('./helpers/getHost')
7
8const MOVED_PERMANENTLY = 301
9const PERMANENT_REDIRECT = 308
10const MISDIRECTED_REQUEST = 421
11const INTERNAL_SERVER_ERROR = 500
12
13const ACME_PREFIX = '/.well-known/acme-challenge/'
14
15const DEFAULT_PORT_HTTPS = 443
16
17module.exports.redirect = async (options) => {
18 function requestListener (request, response) {
19 const hostname = untilBefore.call(getHost(request), ':')
20 const {pathname} = parseUrl(request)
21
22 console.log(`HTTP/${request.httpVersion} ${request.method} ${request.url}`)
23
24 if (pathname.startsWith(ACME_PREFIX)) {
25 if (options.acme.redirect.length > 0) {
26 const location = options.acme.redirect + pathname
27 response.writeHead(MOVED_PERMANENTLY, {location})
28 response.end()
29 return
30 } else if (options.acme.webroot.length > 0) {
31 const {pathname} = parseUrl(request)
32 const sendOptions = {
33 root: options.acme.webroot,
34 etag: false,
35 lastModified: false
36 }
37 send(request, pathname, sendOptions)
38 .on('error', (error) => {
39 response.statusCode = error.status || INTERNAL_SERVER_ERROR
40 response.end()
41 })
42 .pipe(response)
43 return
44 }
45 }
46
47 if (hostname === '') {
48 response.writeHead(MISDIRECTED_REQUEST)
49 response.end()
50 } else {
51 const location = options.http.to === DEFAULT_PORT_HTTPS
52 ? `https://${hostname}${request.url}`
53 : `https://${hostname}:${options.http.to}${request.url}`
54 response.writeHead(PERMANENT_REDIRECT, {location})
55 response.end()
56 }
57 }
58 const server = createServer(requestListener)
59 await promisify(server.listen.bind(server))(options.http.from)
60 return server
61}