<commit_before>package config

import (
	"fmt"
	"io"
	"log"
	"net"
	"sync"

	"github.com/mholt/caddy/app"
	"github.com/mholt/caddy/config/parse"
	"github.com/mholt/caddy/config/setup"
	"github.com/mholt/caddy/middleware"
	"github.com/mholt/caddy/server"
)

const (
	DefaultHost = "0.0.0.0"
	DefaultPort = "2015"
	DefaultRoot = "."

	// DefaultConfigFile is the name of the configuration file that is loaded
	// by default if no other file is specified.
	DefaultConfigFile = "Caddyfile"
)

// 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)
					}
				}
			}

			if config.Port == "" {
				config.Port = Port
			}
<commit_msg>Fix ServerBlockStorage so it actually stores stuff<commit_after>package config

import (
	"fmt"
	"io"
	"log"
	"net"
	"sync"

	"github.com/mholt/caddy/app"
	"github.com/mholt/caddy/config/parse"
	"github.com/mholt/caddy/config/setup"
	"github.com/mholt/caddy/middleware"
	"github.com/mholt/caddy/server"
)

const (
	DefaultHost = "0.0.0.0"
	DefaultPort = "2015"
	DefaultRoot = "."

	// DefaultConfigFile is the name of the configuration file that is loaded
	// by default if no other file is specified.
	DefaultConfigFile = "Caddyfile"
)

// 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
			}

{'fraction_non_alphanumeric': 0.11341554559043349, 'fraction_numerical': 0.0037369207772795215, 'mean_word_length': 2.730313588850174, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1627411', 'n_tokens_mistral': 2058, 'n_tokens_neox': 1660, 'n_words': 505}