// Load reads input (named filename) and parses it, returning server // configurations grouped by listening address. func Load(filename string, input io.Reader) (Group, error) { var configs []server.Config // turn off timestamp for parsing flags := log.Flags() log.SetFlags(0) serverBlocks, err := parse.ServerBlocks(filename, input) if err != nil { return nil, err } if len(serverBlocks) == 0 { return Default() } // Each server block represents one or more servers/addresses. // Iterate each server block and make a config for each one, // executing the directives that were parsed. for _, sb := range serverBlocks { sharedConfig, err := serverBlockToConfig(filename, sb) if err != nil { return nil, err } // Now share the config with as many hosts as share the server block for i, addr := range sb.Addresses { config := sharedConfig config.Host = addr.Host config.Port = addr.Port if config.Port == "" { config.Port = Port } if config.Port == "http" { config.TLS.Enabled = false log.Printf("Warning: TLS disabled for %s://%s. To force TLS over the plaintext HTTP port, "+ "specify port 80 explicitly (https://%s:80).", config.Port, config.Host, config.Host) } if i == 0 { sharedConfig.Startup = []func() error{} sharedConfig.Shutdown = []func() error{} } configs = append(configs, config) } } // restore logging settings log.SetFlags(flags) // Group by address/virtualhosts return arrangeBindings(configs) }
// Load reads input (named filename) and parses it, returning server // configurations grouped by listening address. func Load(filename string, input io.Reader) (Group, error) { var configs []server.Config // turn off timestamp for parsing flags := log.Flags() log.SetFlags(0) serverBlocks, err := parse.ServerBlocks(filename, input) if err != nil { return nil, err } // Each server block represents one or more servers/addresses. // Iterate each server block and make a config for each one, // executing the directives that were parsed. for _, sb := range serverBlocks { sharedConfig, err := serverBlockToConfig(filename, sb) if err != nil { return nil, err } // Now share the config with as many hosts as share the server block for i, addr := range sb.Addresses { config := sharedConfig config.Host = addr.Host config.Port = addr.Port if config.Port == "" { config.Port = Port } if i == 0 { sharedConfig.Startup = []func() error{} sharedConfig.Shutdown = []func() error{} } configs = append(configs, config) } } // restore logging settings log.SetFlags(flags) // Group by address/virtualhosts return arrangeBindings(configs) }
// Load reads input (named filename) and parses it, returning server // configurations grouped by listening address. func Load(filename string, input io.Reader) (Group, error) { var configs []server.Config // turn off timestamp for parsing flags := log.Flags() log.SetFlags(0) serverBlocks, err := parse.ServerBlocks(filename, input) if err != nil { return nil, err } if len(serverBlocks) == 0 { return Default() } // Each server block represents similar hosts/addresses. // Iterate each server block and make a config for each one, // executing the directives that were parsed. for i, sb := range serverBlocks { onces := makeOnces() storages := makeStorages() for j, addr := range sb.Addresses { config := server.Config{ Host: addr.Host, Port: addr.Port, Root: Root, Middleware: make(map[string][]middleware.Middleware), ConfigFile: filename, AppName: app.Name, AppVersion: app.Version, } // It is crucial that directives are executed in the proper order. for _, dir := range directiveOrder { // Execute directive if it is in the server block if tokens, ok := sb.Tokens[dir.name]; ok { // Each setup function gets a controller, which is the // server config and the dispenser containing only // this directive's tokens. controller := &setup.Controller{ Config: &config, Dispenser: parse.NewDispenserTokens(filename, tokens), OncePerServerBlock: func(f func() error) error { var err error onces[dir.name].Do(func() { err = f() }) return err }, ServerBlockIndex: i, ServerBlockHostIndex: j, ServerBlockHosts: sb.HostList(), ServerBlockStorage: storages[dir.name], } midware, err := dir.setup(controller) if err != nil { return nil, err } if midware != nil { // TODO: For now, we only support the default path scope / config.Middleware["/"] = append(config.Middleware["/"], midware) } storages[dir.name] = controller.ServerBlockStorage // persist for this server block } } if config.Port == "" { config.Port = Port } configs = append(configs, config) } } // restore logging settings log.SetFlags(flags) return arrangeBindings(configs) }
func Load(filename string, input io.Reader) ([]server.Config, error) { var configs []server.Config // turn off timestamp for parsing flags := log.Flags() log.SetFlags(0) serverBlocks, err := parse.ServerBlocks(filename, input) if err != nil { return configs, err } // Each server block represents a single server/address. // Iterate each server block and make a config for each one, // executing the directives that were parsed. for _, sb := range serverBlocks { config := server.Config{ Host: sb.Host, Port: sb.Port, Root: Root, Middleware: make(map[string][]middleware.Middleware), ConfigFile: filename, AppName: app.Name, AppVersion: app.Version, } // It is crucial that directives are executed in the proper order. for _, dir := range directiveOrder { // Execute directive if it is in the server block if tokens, ok := sb.Tokens[dir.name]; ok { // Each setup function gets a controller, which is the // server config and the dispenser containing only // this directive's tokens. controller := &setup.Controller{ Config: &config, Dispenser: parse.NewDispenserTokens(filename, tokens), } midware, err := dir.setup(controller) if err != nil { return configs, err } if midware != nil { // TODO: For now, we only support the default path scope / config.Middleware["/"] = append(config.Middleware["/"], midware) } } } if config.Port == "" { config.Port = Port } configs = append(configs, config) } // restore logging settings log.SetFlags(flags) return configs, nil }