changeset 1640:570f3d483a31

host - move https.luan into src
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 21 Dec 2021 16:54:26 -0700
parents 59731f7c24ce
children 48c24eedb8b2
files host/https.luan host/init.luan src/luan/host/https.luan src/luan/host/init.luan
diffstat 4 files changed, 169 insertions(+), 174 deletions(-) [+]
line wrap: on
line diff
diff -r 59731f7c24ce -r 570f3d483a31 host/https.luan
--- a/host/https.luan	Tue Dec 21 16:27:44 2021 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-local Luan = require "luan:Luan.luan"
-local error = Luan.error
-local load_file = Luan.load_file or error()
-local ipairs = Luan.ipairs or error()
-local Boot = require "luan:Boot.luan"
-local Io = require "luan:Io.luan"
-local ip = Io.ip or error()
-local uri = Io.uri or error()
-local output_of = Io.output_of or error()
-local String = require "luan:String.luan"
-local regex_quote = String.regex_quote or error()
-local matches = String.matches or error()
-local Http = require "luan:http/Http.luan"
-local Hosted = require "luan:host/Hosted.luan"
-local Logging = require "luan:logging/Logging.luan"
-local logger = Logging.logger "https"
-
-
-local local_cer = [[
------BEGIN CERTIFICATE-----
-MIIGGDCCBQCgAwIBAgISA2I3DK1t/znI/s4eJX23gWOPMA0GCSqGSIb3DQEBCwUA
-MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
-ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODA2MTEwODQ1MDJaFw0x
-ODA5MDkwODQ1MDJaMCIxIDAeBgNVBAMTF2h0dHBzLnRlc3QubHVhbmhvc3QuY29t
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvlvCVOGcE/79DJFCh45W
-pmqfwljQMYWDNbyNb6zND4QzG80RPHgWNpoDyVUXG8eLn/rDazi0ldwkFH5usrO+
-m3IC5lT/Y/wIr+wT9dQv0l0IJKdkA+cnpOB0z8BU0nBnw6TKhhEcZrPsMRzjbFTJ
-BLeUEf855Y+t/8TeSykBbV9ufiisLnR2/5gvOBW19LHkcxQYzKbmHPVh3sD2wyK8
-gg8B3jgqHJh+m/amOfaxZnOEtEd/TGd6QxCbVvh1jewneBoM9niVOScGUk9JuVol
-tEgToV7vKYpwNRObbN7pitdwudbB3gieK1/BoxHNudjArur4Vapkx/+GSX1aHIsO
-wQIDAQABo4IDHjCCAxowDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
-BwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQhhVC3p8SHDpRt
-GfyT/dPWQ7aSUDAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggr
-BgEFBQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRz
-ZW5jcnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRz
-ZW5jcnlwdC5vcmcvMCIGA1UdEQQbMBmCF2h0dHBzLnRlc3QubHVhbmhvc3QuY29t
-MIH+BgNVHSAEgfYwgfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAmBggr
-BgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUFBwIC
-MIGeDIGbVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBvbiBi
-eSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRoIHRo
-ZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5jcnlw
-dC5vcmcvcmVwb3NpdG9yeS8wggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdQApPFGW
-VMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0eAAAAWPuPA0tAAAEAwBGMEQCIFV8
-xYbsY+O1vubYs0f6KVNlCMMd/d7R5HP76vnNWuGEAiBxlEyVDR4qPf8502v4cqfs
-bG6UGaSqPT4gO8Xp8qOSCQB2ANt0r+7LKeyx/so+cW0s5bmquzb3hHGDx12dTze2
-H79kAAABY+48DR0AAAQDAEcwRQIhAKdDQAa1EquTQzbZaiE88QccvGidohe/AbMB
-Dd1TwQdwAiBGuXo3vKBKZpc1SONmXOz8Oq99JziXcsyLUvkBo99lejANBgkqhkiG
-9w0BAQsFAAOCAQEASyfiSFAjL7nUuFrzhUPlMtWE6sF5JgIoLagHqcGiBZYW8Qzg
-1Xs+zByFmIVl96T6Hgf/7ZRTD81CIinQCEeTPkx4P/S8xLSmyCmYjjxyvje4BHJW
-AkW2eJtPwxQfKfLqaRFzJNE2I2PS1mQC2DyL76UghesujMx+B2uqb1geZ87XRwOu
-iCwQtnLvdqAA3m2JMzahTWXElmW5YbzvbxWc1WLRn3lc3R9a9SFX++LTRxv44/i6
-XiVFekc+IG6oL5bkcLIT70rLa8/vyqUaAicHvnkFp6CbmUX+Pe6nYAfBlYuQzGLM
-e1qixE3bA1Mv6cpyOFIC+beASN/Xj7jbEa7EBA==
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
-SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
-GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
-q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
-SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
-Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
-a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
-/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
-CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
-bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
-c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
-VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
-ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
-MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
-Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
-AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
-uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
-wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
-X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
-PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
-KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
------END CERTIFICATE-----
-]]
-
-local local_key = [[
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAvlvCVOGcE/79DJFCh45WpmqfwljQMYWDNbyNb6zND4QzG80R
-PHgWNpoDyVUXG8eLn/rDazi0ldwkFH5usrO+m3IC5lT/Y/wIr+wT9dQv0l0IJKdk
-A+cnpOB0z8BU0nBnw6TKhhEcZrPsMRzjbFTJBLeUEf855Y+t/8TeSykBbV9ufiis
-LnR2/5gvOBW19LHkcxQYzKbmHPVh3sD2wyK8gg8B3jgqHJh+m/amOfaxZnOEtEd/
-TGd6QxCbVvh1jewneBoM9niVOScGUk9JuVoltEgToV7vKYpwNRObbN7pitdwudbB
-3gieK1/BoxHNudjArur4Vapkx/+GSX1aHIsOwQIDAQABAoIBAFRgJcYr7luqpY2B
-gYTGYcAH+OJTLY0Vye/ysJp0dLxQ87p57g7oh6gSImWGUuTcURZLN316OAlI97Eh
-zX1mULFkGsbvm/g8ibk4oixPrhbHZ8mfbKSSPC9H0l8XuEFC06uTirVcNkOLssCe
-NmwZNLTjjj1f7NDFG/IH2CRme5x3cRdfVDQ1tYiK8lHxoHRj2uN3P1gsJIlDYR1a
-A3TqbLDFYGsvoMPtgkcK/wRpBQCX0FL2IDrigGF33Eb5BiqFHx7KXO9Qjsyb6Y6z
-B/OusjQ6LA//Oq2aizdoDD/op5GRAG7R5wB/8SrjlkME4q8psLRYalcgPwBStQjL
-9tWVHGUCgYEA7xK3xB29TwYoTRY9RwtTILnYXdKM5tY0npC9jDeL96KZeibd0l/S
-2jDqn32O8WUGYHticWYFuUS8evcGtsaBmZPUFT5ndp4DmfahttyS+CoF/NDPlZGq
-cpl92ZDDCQrY68zSY9UhHY/JaslOVv963UfrL30Wok1Bg0A0sqDVgY8CgYEAy9YS
-KjnspIWgC8Fq2kkMAIdBXQVnaRP5l7gyRmVuVwDXS+iG/0DGZfmv1g9S17lUz3R0
-rpKp4iorboJ2A4Wiv0dgar7CmzLMcMSUREX4L7DoRsEXUuxsCOf0F2Vt3baVdo3N
-PtfV8QzpcRAlN4Fap7s0ErNP21OE/ZXocwQ1oq8CgYEA5+1GrVEUiAc3LaF3jOZl
-nIfuaQaLfp0rqvBLki2I8ZGiRqhR5XbkfJub4WHTPEd/ajYIiG4q+1K9bqUatFHb
-BHwu8PT7Nk2QvNpQg690PJ+38003NKh9rHNPbbNMIgeN7SNkr0jhuWX2RkxIXYm3
-TdgpRoaZYJaGCahN90SkG+0CgYBWM1J9Pv+/V68mKYaJh2im9IwEzZs8ybC8o63H
-LW/rJTTnKg+k9HyydVQR/2r2Ra8DCGmrxeRH+7NgSZWkyafYolO48LEVtvbUHZ3h
-/YEGkha4jUHS1J6faZBFMKS0pVkxyKfqkpYsGVzDbqN+hJqU4ksUOXZk9z3/i5zA
-vx/7iwKBgQCELMiakqU/tw3U+VwTRKoWYgCxg9SyG3UWpyuZSguK5k+4C+BvCaXN
-PT7RjA5Gb8oQKUd9kcn1x/ljyTw3mqn5AT7TqfJkG/sMh+Fkl+JMpWFVfmexWihG
-eW2FbldbFg8IUzTPHAOFmO7+9h5oN0pBWwcml2D1YUqfGOyezisuAA==
------END RSA PRIVATE KEY-----
-]]
-
-
-function Hosted.set_https(is_https)
-	local domain = Http.domain
-	local dir = uri("site:").parent()
-	local nginx_file = dir.child("nginx.ssl.conf")
-	local key_file = dir.child(domain..".key")
-	local local_cer_file = dir.child("fullchain.cer")
-	local local_ca_file = dir.child("ca.cer")
-	local top_dir = uri("file:.").canonical().to_string()
-	local changed = false
-	if is_https then  -- https
-		if not key_file.exists() then
-			local is_local = ip(domain) == "127.0.0.1"
-			logger.info("is_local "..is_local)
-			if is_local then
-				key_file.write(local_key)
-				local_cer_file.write(local_cer)
-			else
-				local cmd = [[
-./acme.sh --debug --issue -d "]]..domain..[[" --stateless --cert-home "]]..top_dir..[[/sites" --config-home "]]..top_dir..[[/local/letsencrypt/config";
-]]
-				local s = uri("bash:"..cmd).read_text()
-				logger.info("issue certificate "..s)
-			end
-			if key_file.exists() and local_cer_file.exists() then
-				changed = true
-				local conf = load_file "file:startup/nginx/nginx.ssl.conf.luan"
-				local nginx = output_of( function() conf(top_dir,domain) end )
-				nginx_file.write(nginx)
-			end
-		end
-	else  -- http
-		if key_file.exists() or nginx_file.exists() then
-			changed = true
-			nginx_file.delete()
-			local_cer_file.delete()
-			local_ca_file.delete()
-			local ptn = [[^]]..regex_quote(domain)..[[\.]]
-			for _, file in ipairs(dir.children()) do
-				if matches(file.name(),ptn) then
-					file.delete()
-				end
-			end
-		end
-	end
-	if changed then
-		local cmd = [[
-sudo $(which nginx) -t -c "]]..top_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload;
-]]
-		local s = uri("bash:"..cmd).read_text()
-		logger.info("reload_nginx "..s)
-	end
-	--logger.info "done"
-end
-Hosted.set_https = Boot.no_security(Hosted.set_https)
diff -r 59731f7c24ce -r 570f3d483a31 host/init.luan
--- a/host/init.luan	Tue Dec 21 16:27:44 2021 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
--- run for each site
-
-local Luan = require "luan:Luan.luan"
-Luan.do_file "file:https.luan"
diff -r 59731f7c24ce -r 570f3d483a31 src/luan/host/https.luan
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/host/https.luan	Tue Dec 21 16:54:26 2021 -0700
@@ -0,0 +1,168 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local load_file = Luan.load_file or error()
+local ipairs = Luan.ipairs or error()
+local Boot = require "luan:Boot.luan"
+local Io = require "luan:Io.luan"
+local ip = Io.ip or error()
+local uri = Io.uri or error()
+local output_of = Io.output_of or error()
+local String = require "luan:String.luan"
+local regex_quote = String.regex_quote or error()
+local matches = String.matches or error()
+local Http = require "luan:http/Http.luan"
+local Hosted = require "luan:host/Hosted.luan"
+local Logging = require "luan:logging/Logging.luan"
+local logger = Logging.logger "https"
+
+
+local local_cer = [[
+-----BEGIN CERTIFICATE-----
+MIIGGDCCBQCgAwIBAgISA2I3DK1t/znI/s4eJX23gWOPMA0GCSqGSIb3DQEBCwUA
+MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
+ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODA2MTEwODQ1MDJaFw0x
+ODA5MDkwODQ1MDJaMCIxIDAeBgNVBAMTF2h0dHBzLnRlc3QubHVhbmhvc3QuY29t
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvlvCVOGcE/79DJFCh45W
+pmqfwljQMYWDNbyNb6zND4QzG80RPHgWNpoDyVUXG8eLn/rDazi0ldwkFH5usrO+
+m3IC5lT/Y/wIr+wT9dQv0l0IJKdkA+cnpOB0z8BU0nBnw6TKhhEcZrPsMRzjbFTJ
+BLeUEf855Y+t/8TeSykBbV9ufiisLnR2/5gvOBW19LHkcxQYzKbmHPVh3sD2wyK8
+gg8B3jgqHJh+m/amOfaxZnOEtEd/TGd6QxCbVvh1jewneBoM9niVOScGUk9JuVol
+tEgToV7vKYpwNRObbN7pitdwudbB3gieK1/BoxHNudjArur4Vapkx/+GSX1aHIsO
+wQIDAQABo4IDHjCCAxowDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQhhVC3p8SHDpRt
+GfyT/dPWQ7aSUDAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggr
+BgEFBQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRz
+ZW5jcnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRz
+ZW5jcnlwdC5vcmcvMCIGA1UdEQQbMBmCF2h0dHBzLnRlc3QubHVhbmhvc3QuY29t
+MIH+BgNVHSAEgfYwgfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAmBggr
+BgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUFBwIC
+MIGeDIGbVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBvbiBi
+eSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRoIHRo
+ZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5jcnlw
+dC5vcmcvcmVwb3NpdG9yeS8wggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdQApPFGW
+VMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0eAAAAWPuPA0tAAAEAwBGMEQCIFV8
+xYbsY+O1vubYs0f6KVNlCMMd/d7R5HP76vnNWuGEAiBxlEyVDR4qPf8502v4cqfs
+bG6UGaSqPT4gO8Xp8qOSCQB2ANt0r+7LKeyx/so+cW0s5bmquzb3hHGDx12dTze2
+H79kAAABY+48DR0AAAQDAEcwRQIhAKdDQAa1EquTQzbZaiE88QccvGidohe/AbMB
+Dd1TwQdwAiBGuXo3vKBKZpc1SONmXOz8Oq99JziXcsyLUvkBo99lejANBgkqhkiG
+9w0BAQsFAAOCAQEASyfiSFAjL7nUuFrzhUPlMtWE6sF5JgIoLagHqcGiBZYW8Qzg
+1Xs+zByFmIVl96T6Hgf/7ZRTD81CIinQCEeTPkx4P/S8xLSmyCmYjjxyvje4BHJW
+AkW2eJtPwxQfKfLqaRFzJNE2I2PS1mQC2DyL76UghesujMx+B2uqb1geZ87XRwOu
+iCwQtnLvdqAA3m2JMzahTWXElmW5YbzvbxWc1WLRn3lc3R9a9SFX++LTRxv44/i6
+XiVFekc+IG6oL5bkcLIT70rLa8/vyqUaAicHvnkFp6CbmUX+Pe6nYAfBlYuQzGLM
+e1qixE3bA1Mv6cpyOFIC+beASN/Xj7jbEa7EBA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
+SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
+GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
+q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
+SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
+Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
+a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
+/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
+CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
+bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
+c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
+VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
+ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
+MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
+Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
+AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
+uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
+wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
+X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
+PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
+KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
+-----END CERTIFICATE-----
+]]
+
+local local_key = [[
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAvlvCVOGcE/79DJFCh45WpmqfwljQMYWDNbyNb6zND4QzG80R
+PHgWNpoDyVUXG8eLn/rDazi0ldwkFH5usrO+m3IC5lT/Y/wIr+wT9dQv0l0IJKdk
+A+cnpOB0z8BU0nBnw6TKhhEcZrPsMRzjbFTJBLeUEf855Y+t/8TeSykBbV9ufiis
+LnR2/5gvOBW19LHkcxQYzKbmHPVh3sD2wyK8gg8B3jgqHJh+m/amOfaxZnOEtEd/
+TGd6QxCbVvh1jewneBoM9niVOScGUk9JuVoltEgToV7vKYpwNRObbN7pitdwudbB
+3gieK1/BoxHNudjArur4Vapkx/+GSX1aHIsOwQIDAQABAoIBAFRgJcYr7luqpY2B
+gYTGYcAH+OJTLY0Vye/ysJp0dLxQ87p57g7oh6gSImWGUuTcURZLN316OAlI97Eh
+zX1mULFkGsbvm/g8ibk4oixPrhbHZ8mfbKSSPC9H0l8XuEFC06uTirVcNkOLssCe
+NmwZNLTjjj1f7NDFG/IH2CRme5x3cRdfVDQ1tYiK8lHxoHRj2uN3P1gsJIlDYR1a
+A3TqbLDFYGsvoMPtgkcK/wRpBQCX0FL2IDrigGF33Eb5BiqFHx7KXO9Qjsyb6Y6z
+B/OusjQ6LA//Oq2aizdoDD/op5GRAG7R5wB/8SrjlkME4q8psLRYalcgPwBStQjL
+9tWVHGUCgYEA7xK3xB29TwYoTRY9RwtTILnYXdKM5tY0npC9jDeL96KZeibd0l/S
+2jDqn32O8WUGYHticWYFuUS8evcGtsaBmZPUFT5ndp4DmfahttyS+CoF/NDPlZGq
+cpl92ZDDCQrY68zSY9UhHY/JaslOVv963UfrL30Wok1Bg0A0sqDVgY8CgYEAy9YS
+KjnspIWgC8Fq2kkMAIdBXQVnaRP5l7gyRmVuVwDXS+iG/0DGZfmv1g9S17lUz3R0
+rpKp4iorboJ2A4Wiv0dgar7CmzLMcMSUREX4L7DoRsEXUuxsCOf0F2Vt3baVdo3N
+PtfV8QzpcRAlN4Fap7s0ErNP21OE/ZXocwQ1oq8CgYEA5+1GrVEUiAc3LaF3jOZl
+nIfuaQaLfp0rqvBLki2I8ZGiRqhR5XbkfJub4WHTPEd/ajYIiG4q+1K9bqUatFHb
+BHwu8PT7Nk2QvNpQg690PJ+38003NKh9rHNPbbNMIgeN7SNkr0jhuWX2RkxIXYm3
+TdgpRoaZYJaGCahN90SkG+0CgYBWM1J9Pv+/V68mKYaJh2im9IwEzZs8ybC8o63H
+LW/rJTTnKg+k9HyydVQR/2r2Ra8DCGmrxeRH+7NgSZWkyafYolO48LEVtvbUHZ3h
+/YEGkha4jUHS1J6faZBFMKS0pVkxyKfqkpYsGVzDbqN+hJqU4ksUOXZk9z3/i5zA
+vx/7iwKBgQCELMiakqU/tw3U+VwTRKoWYgCxg9SyG3UWpyuZSguK5k+4C+BvCaXN
+PT7RjA5Gb8oQKUd9kcn1x/ljyTw3mqn5AT7TqfJkG/sMh+Fkl+JMpWFVfmexWihG
+eW2FbldbFg8IUzTPHAOFmO7+9h5oN0pBWwcml2D1YUqfGOyezisuAA==
+-----END RSA PRIVATE KEY-----
+]]
+
+
+function Hosted.set_https(is_https)
+	local domain = Http.domain
+	local dir = uri("site:").parent()
+	local nginx_file = dir.child("nginx.ssl.conf")
+	local key_file = dir.child(domain..".key")
+	local local_cer_file = dir.child("fullchain.cer")
+	local local_ca_file = dir.child("ca.cer")
+	local top_dir = uri("file:.").canonical().to_string()
+	local changed = false
+	if is_https then  -- https
+		if not key_file.exists() then
+			local is_local = ip(domain) == "127.0.0.1"
+			logger.info("is_local "..is_local)
+			if is_local then
+				key_file.write(local_key)
+				local_cer_file.write(local_cer)
+			else
+				local cmd = [[
+./acme.sh --debug --issue -d "]]..domain..[[" --stateless --cert-home "]]..top_dir..[[/sites" --config-home "]]..top_dir..[[/local/letsencrypt/config";
+]]
+				local s = uri("bash:"..cmd).read_text()
+				logger.info("issue certificate "..s)
+			end
+			if key_file.exists() and local_cer_file.exists() then
+				changed = true
+				local conf = load_file "file:startup/nginx/nginx.ssl.conf.luan"
+				local nginx = output_of( function() conf(top_dir,domain) end )
+				nginx_file.write(nginx)
+			end
+		end
+	else  -- http
+		if key_file.exists() or nginx_file.exists() then
+			changed = true
+			nginx_file.delete()
+			local_cer_file.delete()
+			local_ca_file.delete()
+			local ptn = [[^]]..regex_quote(domain)..[[\.]]
+			for _, file in ipairs(dir.children()) do
+				if matches(file.name(),ptn) then
+					file.delete()
+				end
+			end
+		end
+	end
+	if changed then
+		local cmd = [[
+sudo $(which nginx) -t -c "]]..top_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload;
+]]
+		local s = uri("bash:"..cmd).read_text()
+		logger.info("reload_nginx "..s)
+	end
+	--logger.info "done"
+end
+Hosted.set_https = Boot.no_security(Hosted.set_https)
diff -r 59731f7c24ce -r 570f3d483a31 src/luan/host/init.luan
--- a/src/luan/host/init.luan	Tue Dec 21 16:27:44 2021 -0700
+++ b/src/luan/host/init.luan	Tue Dec 21 16:54:26 2021 -0700
@@ -99,8 +99,7 @@
 end
 
 
--- callback to luanhost code
-do_file "file:init.luan"
+do_file "classpath:luan/host/https.luan"
 
 
 local LuanJava = require "java:luan.Luan"