From 8428c5d11a5fa4a2bab73608dd99bf15e79cea12 Mon Sep 17 00:00:00 2001
From: David Merfield <dmerfield@gmail.com>
Date: Fri, 27 Oct 2023 18:34:53 +0100
Subject: [PATCH] Updates init.lua

---
 config/openresty/conf/init.lua | 187 +++++++++++++++++++--------------
 1 file changed, 107 insertions(+), 80 deletions(-)

diff --git a/config/openresty/conf/init.lua b/config/openresty/conf/init.lua
index 092b74a8deb..e58c69520fa 100644
--- a/config/openresty/conf/init.lua
+++ b/config/openresty/conf/init.lua
@@ -1,3 +1,84 @@
+
+local redis = require "resty.redis"
+
+local redis_options = { host = "{{redis.host}}", port = 6379 , prefix = "ssl" }
+
+local function get_redis_instance(redis_options)
+
+  local instance = ngx.ctx.auto_ssl_redis_instance
+
+  if instance then
+    return instance
+  end
+
+  instance = redis:new()
+
+  local ok, err
+
+  if redis_options["socket"] then
+    ok, err = instance:connect(redis_options["socket"])
+  else
+    ok, err = instance:connect(redis_options["host"], redis_options["port"])
+  end
+
+  if not ok then
+    return false, err
+  end
+
+  if redis_options["auth"] then
+    ok, err = instance:auth(redis_options["auth"])
+    if not ok then
+      return false, err
+    end
+  end
+
+  ngx.ctx.auto_ssl_redis_instance = instance
+  return instance
+end
+
+auto_ssl = (require "resty.auto-ssl").new()
+
+auto_ssl:set("redis", redis_options)
+
+-- Certificates are stored in redis
+auto_ssl:set("storage_adapter", "resty.auto-ssl.storage_adapters.redis")
+
+-- This function determines whether the incoming domain
+-- should automatically issue a new SSL certificate.
+-- I need to set domain:blot.im to foo in the database so that
+-- the allow_domain function works as expected even though
+-- it's not technically a user's domain
+auto_ssl:set("allow_domain", function(domain)
+
+  local certstorage = auto_ssl.storage
+  
+  local fullchain_pem, privkey_pem = certstorage:get_cert(domain)
+
+  -- If we have this cert in the memory cache
+  -- then return it without checking redis to save time
+  if fullchain_pem then
+    return true
+  end
+
+  local redis_instance, instance_err = get_redis_instance(redis_options)
+
+  if instance_err then
+    return nil, instance_err
+  end
+
+  local res, err = redis_instance:get('domain:' .. domain)
+
+  if res == ngx.null then
+    return false
+  end
+
+  return true
+end)
+
+auto_ssl:init()
+
+-- now we rehydrate the cache
+
 local cache_directory = "{{{cache_directory}}}"
 
 -- this file will read the contents of the cache directory and store them in 
@@ -42,14 +123,35 @@ local function extractHostFromCacheFile (cache_file_path)
     -- KEY: http://example.com/xyz/abc
     local file = io.open(cache_file_path, "r")
     local first_line = file:read()
+
+    -- keep reading the file until we get a line that starts with KEY
+    while (first_line ~= nil and string.match(first_line, "^KEY:") == nil) do
+        first_line = file:read()
+    end
+
+    if (first_line == nil) then
+        ngx.log(ngx.NOTICE, "uri is nil")
+        return nil
+    end
+
     local uri = string.match(first_line, "KEY: (.*)")
 
+    if (uri == nil) then
+        ngx.log(ngx.NOTICE, "uri is nil")
+        return nil
+    end
+
     -- the protocol is included in the uri so we need to remove it
     local uri_without_protocol = string.match(uri, "://(.*)")
 
     -- the host is the first part of the uri, up to question mark or slash if present
     local host = string.match(uri_without_protocol, "([^/?]+)")
 
+    if (host == nil) then
+        ngx.log(ngx.NOTICE, "host is nil")
+        return nil
+    end
+    
     file:close()
 
     ngx.log(ngx.NOTICE, "found host from cache_file_path: " .. host)
@@ -101,7 +203,8 @@ if ngx ~= nil then
                 local cache_file_path = top_level_directory .. "/" .. second_level_directory .. "/" .. file
                 local host = extractHostFromCacheFile(second_level_directory_path .. "/" .. file)
 
-                -- add the host to the list of hosts
+                if (host ~= nil) then
+                    -- add the host to the list of hosts
                 if (hosts[host] == nil) then
                     ngx.log(ngx.NOTICE, "found host: " .. host)
                     table.insert(hosts, host)
@@ -111,6 +214,9 @@ if ngx ~= nil then
                 ngx.log(ngx.NOTICE, "found cache file path: " .. cache_file_path)
                 proxy_cache_keys_by_host:set(cache_file_path, true)
                 proxy_cache_keys_by_host:rpush(host, cache_file_path)
+                end
+
+                
             end
         end
     end
@@ -119,82 +225,3 @@ if ngx ~= nil then
         deduplicate_key_list_by_host(host, proxy_cache_keys_by_host)
     end
 end
-
-
-local redis = require "resty.redis"
-
-local redis_options = { host = "{{redis.host}}", port = 6379 , prefix = "ssl" }
-
-local function get_redis_instance(redis_options)
-
-  local instance = ngx.ctx.auto_ssl_redis_instance
-
-  if instance then
-    return instance
-  end
-
-  instance = redis:new()
-
-  local ok, err
-
-  if redis_options["socket"] then
-    ok, err = instance:connect(redis_options["socket"])
-  else
-    ok, err = instance:connect(redis_options["host"], redis_options["port"])
-  end
-
-  if not ok then
-    return false, err
-  end
-
-  if redis_options["auth"] then
-    ok, err = instance:auth(redis_options["auth"])
-    if not ok then
-      return false, err
-    end
-  end
-
-  ngx.ctx.auto_ssl_redis_instance = instance
-  return instance
-end
-
-auto_ssl = (require "resty.auto-ssl").new()
-
-auto_ssl:set("redis", redis_options)
-
--- Certificates are stored in redis
-auto_ssl:set("storage_adapter", "resty.auto-ssl.storage_adapters.redis")
-
--- This function determines whether the incoming domain
--- should automatically issue a new SSL certificate.
--- I need to set domain:blot.im to foo in the database so that
--- the allow_domain function works as expected even though
--- it's not technically a user's domain
-auto_ssl:set("allow_domain", function(domain)
-
-  local certstorage = auto_ssl.storage
-  
-  local fullchain_pem, privkey_pem = certstorage:get_cert(domain)
-
-  -- If we have this cert in the memory cache
-  -- then return it without checking redis to save time
-  if fullchain_pem then
-    return true
-  end
-
-  local redis_instance, instance_err = get_redis_instance(redis_options)
-
-  if instance_err then
-    return nil, instance_err
-  end
-
-  local res, err = redis_instance:get('domain:' .. domain)
-
-  if res == ngx.null then
-    return false
-  end
-
-  return true
-end)
-
-auto_ssl:init()
\ No newline at end of file