code: func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) {
  	// For each address in each server block, make a new config
  	for _, sb := range serverBlocks {
  		for _, key := range sb.Keys {
  			key = strings.ToLower(key)
  			if _, dup := h.keysToSiteConfigs[key]; dup {
  				return serverBlocks, fmt.Errorf("duplicate site address: %s", key)
  			}
  			addr, err := standardizeAddress(key)
  			if err != nil {
  				return serverBlocks, err
  			}
  
  			// Fill in address components from command line so that middleware
  			// have access to the correct information during setup
  			if addr.Host == "" && Host != DefaultHost {
  				addr.Host = Host
  			}
  			if addr.Port == "" && Port != DefaultPort {
  				addr.Port = Port
  			}
  
  			// Save the config to our master list, and key it for lookups
  			cfg := &SiteConfig{
  				Addr:            addr,
  				Root:            Root,
  				TLS:             &caddytls.Config{Hostname: addr.Host},
  				originCaddyfile: sourceFile,
  			}
  			h.saveConfig(key, cfg)
  		}
  	}
  
  	// For sites that have gzip (which gets chained in
  	// before the error handler) we should ensure that the
  	// errors directive also appears so error pages aren't
  	// written after the gzip writer is closed. See #616.
  	for _, sb := range serverBlocks {
  		_, hasGzip := sb.Tokens["gzip"]
  		_, hasErrors := sb.Tokens["errors"]
  		if hasGzip && !hasErrors {
  			sb.Tokens["errors"] = []caddyfile.Token{{Text: "errors"}}
  		}
  	}
  
  	return serverBlocks, nil
  }
docs: // InspectServerBlocks make sure that everything checks out before
  // executing directives and otherwise prepares the directives to
  // be parsed and executed.