automaticHTTPSPhase1 provisions all route matchers, determines which domain names found in the routes qualify for automatic HTTPS, and sets up HTTP->HTTPS redirects. This phase must occur at the beginning of provisioning, because it may add routes and even servers to the app, which still need to be
(ctx caddy.Context, repl *caddy.Replacer)
| 75 | // even servers to the app, which still need to be set up with the |
| 76 | // rest of them during provisioning. |
| 77 | func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) error { |
| 78 | logger := app.logger.Named("auto_https") |
| 79 | |
| 80 | // this map acts as a set to store the domain names |
| 81 | // for which we will manage certificates automatically |
| 82 | uniqueDomainsForCerts := make(map[string]struct{}) |
| 83 | |
| 84 | // this maps domain names for automatic HTTP->HTTPS |
| 85 | // redirects to their destination server addresses |
| 86 | // (there might be more than 1 if bind is used; see |
| 87 | // https://github.com/caddyserver/caddy/issues/3443) |
| 88 | redirDomains := make(map[string][]caddy.NetworkAddress) |
| 89 | |
| 90 | // the log configuration for an HTTPS enabled server |
| 91 | var logCfg *ServerLogConfig |
| 92 | |
| 93 | // Sort server names to ensure deterministic iteration. |
| 94 | // This prevents race conditions where the order of server processing |
| 95 | // could affect which server gets assigned the HTTP->HTTPS redirect listener. |
| 96 | srvNames := make([]string, 0, len(app.Servers)) |
| 97 | for name := range app.Servers { |
| 98 | srvNames = append(srvNames, name) |
| 99 | } |
| 100 | slices.Sort(srvNames) |
| 101 | for _, srvName := range srvNames { |
| 102 | srv := app.Servers[srvName] |
| 103 | // as a prerequisite, provision route matchers; this is |
| 104 | // required for all routes on all servers, and must be |
| 105 | // done before we attempt to do phase 1 of auto HTTPS, |
| 106 | // since we have to access the decoded host matchers the |
| 107 | // handlers will be provisioned later |
| 108 | if srv.Routes != nil { |
| 109 | err := srv.Routes.ProvisionMatchers(ctx) |
| 110 | if err != nil { |
| 111 | return fmt.Errorf("server %s: setting up route matchers: %v", srvName, err) |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | // prepare for automatic HTTPS |
| 116 | if srv.AutoHTTPS == nil { |
| 117 | srv.AutoHTTPS = new(AutoHTTPSConfig) |
| 118 | } |
| 119 | if srv.AutoHTTPS.Disabled { |
| 120 | logger.Info("automatic HTTPS is completely disabled for server", zap.String("server_name", srvName)) |
| 121 | continue |
| 122 | } |
| 123 | |
| 124 | // skip if all listeners use the HTTP port |
| 125 | if !srv.listenersUseAnyPortOtherThan(app.httpPort()) { |
| 126 | logger.Warn("server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server", |
| 127 | zap.String("server_name", srvName), |
| 128 | zap.Int("http_port", app.httpPort()), |
| 129 | ) |
| 130 | srv.AutoHTTPS.Disabled = true |
| 131 | continue |
| 132 | } |
| 133 | |
| 134 | // if all listeners are on the HTTPS port, make sure |
no test coverage detected