本文整理匯總了Golang中github.com/mholt/caddy.Controller.Err方法的典型用法代碼示例。如果您正苦於以下問題:Golang Controller.Err方法的具體用法?Golang Controller.Err怎麽用?Golang Controller.Err使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類github.com/mholt/caddy.Controller
的用法示例。
在下文中一共展示了Controller.Err方法的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: ipfilterParse
// ipfilterParse parses all ipfilter {} blocks to an IPFConfig
func ipfilterParse(c *caddy.Controller) (IPFConfig, error) {
var config IPFConfig
var hasCountryCodes, hasRanges bool
for c.Next() {
path, err := ipfilterParseSingle(&config, c)
if err != nil {
return config, err
}
if len(path.CountryCodes) != 0 {
hasCountryCodes = true
}
if len(path.Nets) != 0 {
hasRanges = true
}
config.Paths = append(config.Paths, path)
}
// having a database is mandatory if you are blocking by country codes.
if hasCountryCodes && config.DBHandler == nil {
return config, c.Err("ipfilter: Database is required to block/allow by country")
}
// needs atleast one of the three.
if !hasCountryCodes && !hasRanges {
return config, c.Err("ipfilter: No IPs or Country codes has been provided")
}
return config, nil
}
示例2: parse
func parse(m *module, c *caddy.Controller) (err error) {
args := c.RemainingArgs()
if len(args) == 1 && args[0] == "cloudflare" {
addCloudflareIps(m)
if c.NextBlock() {
return c.Err("No realip subblocks allowed if using preset.")
}
} else if len(args) != 0 {
return c.ArgErr()
}
for c.NextBlock() {
var err error
switch c.Val() {
case "header":
m.Header, err = StringArg(c)
case "from":
var cidr *net.IPNet
cidr, err = CidrArg(c)
m.From = append(m.From, cidr)
case "strict":
m.Strict, err = BoolArg(c)
default:
return c.Errf("Unknown realip arg: %s", c.Val())
}
if err != nil {
return err
}
}
return nil
}
示例3: loadParams
func loadParams(c *caddy.Controller, mdc *Config) error {
cfg := httpserver.GetConfig(c.Key)
switch c.Val() {
case "ext":
for _, ext := range c.RemainingArgs() {
mdc.Extensions[ext] = struct{}{}
}
return nil
case "css":
if !c.NextArg() {
return c.ArgErr()
}
mdc.Styles = append(mdc.Styles, c.Val())
return nil
case "js":
if !c.NextArg() {
return c.ArgErr()
}
mdc.Scripts = append(mdc.Scripts, c.Val())
return nil
case "template":
tArgs := c.RemainingArgs()
switch len(tArgs) {
default:
return c.ArgErr()
case 1:
fpath := filepath.ToSlash(filepath.Clean(cfg.Root + string(filepath.Separator) + tArgs[0]))
if err := SetTemplate(mdc.Template, "", fpath); err != nil {
c.Errf("default template parse error: %v", err)
}
return nil
case 2:
fpath := filepath.ToSlash(filepath.Clean(cfg.Root + string(filepath.Separator) + tArgs[1]))
if err := SetTemplate(mdc.Template, tArgs[0], fpath); err != nil {
c.Errf("template parse error: %v", err)
}
return nil
}
case "templatedir":
if !c.NextArg() {
return c.ArgErr()
}
_, err := mdc.Template.ParseGlob(c.Val())
if err != nil {
c.Errf("template load error: %v", err)
}
if c.NextArg() {
return c.ArgErr()
}
return nil
default:
return c.Err("Expected valid markdown configuration property")
}
}
示例4: registerCallback
// registerCallback registers a callback function to execute by
// using c to parse the directive. It registers the callback
// to be executed using registerFunc.
func registerCallback(c *caddy.Controller, registerFunc func(func() error)) error {
var funcs []func() error
for c.Next() {
args := c.RemainingArgs()
if len(args) == 0 {
return c.ArgErr()
}
nonblock := false
if len(args) > 1 && args[len(args)-1] == "&" {
// Run command in background; non-blocking
nonblock = true
args = args[:len(args)-1]
}
command, args, err := caddy.SplitCommandAndArgs(strings.Join(args, " "))
if err != nil {
return c.Err(err.Error())
}
fn := func() error {
cmd := exec.Command(command, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if nonblock {
log.Printf("[INFO] Nonblocking Command:\"%s %s\"", command, strings.Join(args, " "))
return cmd.Start()
}
log.Printf("[INFO] Blocking Command:\"%s %s\"", command, strings.Join(args, " "))
return cmd.Run()
}
funcs = append(funcs, fn)
}
return c.OncePerServerBlock(func() error {
for _, fn := range funcs {
registerFunc(fn)
}
return nil
})
}
示例5: Setup
func Setup(c *caddy.Controller) error {
var m *module
for c.Next() {
if m != nil {
return c.Err("cannot specify realip more than once")
}
m = &module{
Header: "X-Forwarded-For",
}
if err := parse(m, c); err != nil {
return err
}
}
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
m.next = next
return m
})
return nil
}
示例6: setup
// setup returns a new instance of a pprof handler. It accepts no arguments or options.
func setup(c *caddy.Controller) error {
found := false
for c.Next() {
if found {
return c.Err("pprof can only be specified once")
}
if len(c.RemainingArgs()) != 0 {
return c.ArgErr()
}
if c.NextBlock() {
return c.ArgErr()
}
found = true
}
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return &Handler{Next: next, Mux: NewMux()}
})
return nil
}
示例7: setupTLS
// setupTLS sets up the TLS configuration and installs certificates that
// are specified by the user in the config file. All the automatic HTTPS
// stuff comes later outside of this function.
func setupTLS(c *caddy.Controller) error {
configGetter, ok := configGetters[c.ServerType()]
if !ok {
return fmt.Errorf("no caddytls.ConfigGetter for %s server type; must call RegisterConfigGetter", c.ServerType())
}
config := configGetter(c)
if config == nil {
return fmt.Errorf("no caddytls.Config to set up for %s", c.Key)
}
config.Enabled = true
for c.Next() {
var certificateFile, keyFile, loadDir, maxCerts string
args := c.RemainingArgs()
switch len(args) {
case 1:
// even if the email is one of the special values below,
// it is still necessary for future analysis that we store
// that value in the ACMEEmail field.
config.ACMEEmail = args[0]
// user can force-disable managed TLS this way
if args[0] == "off" {
config.Enabled = false
return nil
}
// user might want a temporary, in-memory, self-signed cert
if args[0] == "self_signed" {
config.SelfSigned = true
}
case 2:
certificateFile = args[0]
keyFile = args[1]
config.Manual = true
}
// Optional block with extra parameters
var hadBlock bool
for c.NextBlock() {
hadBlock = true
switch c.Val() {
case "key_type":
arg := c.RemainingArgs()
value, ok := supportedKeyTypes[strings.ToUpper(arg[0])]
if !ok {
return c.Errf("Wrong key type name or key type not supported: '%s'", c.Val())
}
config.KeyType = value
case "protocols":
args := c.RemainingArgs()
if len(args) == 1 {
value, ok := supportedProtocols[strings.ToLower(args[0])]
if !ok {
return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[0])
}
config.ProtocolMinVersion, config.ProtocolMaxVersion = value, value
} else {
value, ok := supportedProtocols[strings.ToLower(args[0])]
if !ok {
return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[0])
}
config.ProtocolMinVersion = value
value, ok = supportedProtocols[strings.ToLower(args[1])]
if !ok {
return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[1])
}
config.ProtocolMaxVersion = value
if config.ProtocolMinVersion > config.ProtocolMaxVersion {
return c.Errf("Minimum protocol version cannot be higher than maximum (reverse the order)")
}
}
case "ciphers":
for c.NextArg() {
value, ok := supportedCiphersMap[strings.ToUpper(c.Val())]
if !ok {
return c.Errf("Wrong cipher name or cipher not supported: '%s'", c.Val())
}
config.Ciphers = append(config.Ciphers, value)
}
case "clients":
clientCertList := c.RemainingArgs()
if len(clientCertList) == 0 {
return c.ArgErr()
}
listStart, mustProvideCA := 1, true
switch clientCertList[0] {
case "request":
config.ClientAuth = tls.RequestClientCert
mustProvideCA = false
case "require":
config.ClientAuth = tls.RequireAnyClientCert
mustProvideCA = false
//.........這裏部分代碼省略.........
示例8: webSocketParse
func webSocketParse(c *caddy.Controller) ([]Config, error) {
var websocks []Config
var respawn bool
optionalBlock := func() (hadBlock bool, err error) {
for c.NextBlock() {
hadBlock = true
if c.Val() == "respawn" {
respawn = true
} else {
return true, c.Err("Expected websocket configuration parameter in block")
}
}
return
}
for c.Next() {
var val, path, command string
// Path or command; not sure which yet
if !c.NextArg() {
return nil, c.ArgErr()
}
val = c.Val()
// Extra configuration may be in a block
hadBlock, err := optionalBlock()
if err != nil {
return nil, err
}
if !hadBlock {
// The next argument on this line will be the command or an open curly brace
if c.NextArg() {
path = val
command = c.Val()
} else {
path = "/"
command = val
}
// Okay, check again for optional block
_, err = optionalBlock()
if err != nil {
return nil, err
}
}
// Split command into the actual command and its arguments
cmd, args, err := caddy.SplitCommandAndArgs(command)
if err != nil {
return nil, err
}
websocks = append(websocks, Config{
Path: path,
Command: cmd,
Arguments: args,
Respawn: respawn, // TODO: This isn't used currently
})
}
return websocks, nil
}
示例9: redirParse
func redirParse(c *caddy.Controller) ([]Rule, error) {
var redirects []Rule
cfg := httpserver.GetConfig(c.Key)
// setRedirCode sets the redirect code for rule if it can, or returns an error
setRedirCode := func(code string, rule *Rule) error {
if code == "meta" {
rule.Meta = true
} else if codeNumber, ok := httpRedirs[code]; ok {
rule.Code = codeNumber
} else {
return c.Errf("Invalid redirect code '%v'", code)
}
return nil
}
// checkAndSaveRule checks the rule for validity (except the redir code)
// and saves it if it's valid, or returns an error.
checkAndSaveRule := func(rule Rule) error {
if rule.FromPath == rule.To {
return c.Err("'from' and 'to' values of redirect rule cannot be the same")
}
for _, otherRule := range redirects {
if otherRule.FromPath == rule.FromPath {
return c.Errf("rule with duplicate 'from' value: %s -> %s", otherRule.FromPath, otherRule.To)
}
}
redirects = append(redirects, rule)
return nil
}
for c.Next() {
args := c.RemainingArgs()
var hadOptionalBlock bool
for c.NextBlock() {
hadOptionalBlock = true
var rule Rule
if cfg.TLS.Enabled {
rule.FromScheme = "https"
} else {
rule.FromScheme = "http"
}
// Set initial redirect code
// BUG: If the code is specified for a whole block and that code is invalid,
// the line number will appear on the first line inside the block, even if that
// line overwrites the block-level code with a valid redirect code. The program
// still functions correctly, but the line number in the error reporting is
// misleading to the user.
if len(args) == 1 {
err := setRedirCode(args[0], &rule)
if err != nil {
return redirects, err
}
} else {
rule.Code = http.StatusMovedPermanently // default code
}
// RemainingArgs only gets the values after the current token, but in our
// case we want to include the current token to get an accurate count.
insideArgs := append([]string{c.Val()}, c.RemainingArgs()...)
switch len(insideArgs) {
case 1:
// To specified (catch-all redirect)
// Not sure why user is doing this in a table, as it causes all other redirects to be ignored.
// As such, this feature remains undocumented.
rule.FromPath = "/"
rule.To = insideArgs[0]
case 2:
// From and To specified
rule.FromPath = insideArgs[0]
rule.To = insideArgs[1]
case 3:
// From, To, and Code specified
rule.FromPath = insideArgs[0]
rule.To = insideArgs[1]
err := setRedirCode(insideArgs[2], &rule)
if err != nil {
return redirects, err
}
default:
return redirects, c.ArgErr()
}
err := checkAndSaveRule(rule)
if err != nil {
return redirects, err
}
}
if !hadOptionalBlock {
var rule Rule
//.........這裏部分代碼省略.........
示例10: parseRules
func parseRules(c *caddy.Controller) ([]*corsRule, error) {
rules := []*corsRule{}
for c.Next() {
rule := &corsRule{Path: "/", Conf: cors.Default()}
args := c.RemainingArgs()
anyOrigins := false
if len(args) > 0 {
rule.Path = args[0]
}
for i := 1; i < len(args); i++ {
if !anyOrigins {
rule.Conf.AllowedOrigins = nil
}
rule.Conf.AllowedOrigins = append(rule.Conf.AllowedOrigins, strings.Split(args[i], ",")...)
anyOrigins = true
}
for c.NextBlock() {
switch c.Val() {
case "origin":
if !anyOrigins {
rule.Conf.AllowedOrigins = nil
}
args := c.RemainingArgs()
for _, domain := range args {
rule.Conf.AllowedOrigins = append(rule.Conf.AllowedOrigins, strings.Split(domain, ",")...)
}
anyOrigins = true
case "methods":
if arg, err := singleArg(c, "methods"); err != nil {
return nil, err
} else {
rule.Conf.AllowedMethods = arg
}
case "allow_credentials":
if arg, err := singleArg(c, "allow_credentials"); err != nil {
return nil, err
} else {
var b bool
if arg == "true" {
b = true
} else if arg != "false" {
return nil, c.Errf("allow_credentials must be true or false.")
}
rule.Conf.AllowCredentials = &b
}
case "max_age":
if arg, err := singleArg(c, "max_age"); err != nil {
return nil, err
} else {
i, err := strconv.Atoi(arg)
if err != nil {
return nil, c.Err("max_age must be valid int")
}
rule.Conf.MaxAge = i
}
case "allowed_headers":
if arg, err := singleArg(c, "allowed_headers"); err != nil {
return nil, err
} else {
rule.Conf.AllowedHeaders = arg
}
case "exposed_headers":
if arg, err := singleArg(c, "exposed_headers"); err != nil {
return nil, err
} else {
rule.Conf.ExposedHeaders = arg
}
default:
return nil, c.Errf("Unknown cors config item: %s", c.Val())
}
}
rules = append(rules, rule)
}
return rules, nil
}
示例11: rewriteParse
func rewriteParse(c *caddy.Controller) ([]httpserver.HandlerConfig, error) {
var rules []httpserver.HandlerConfig
for c.Next() {
var rule Rule
var err error
var base = "/"
var pattern, to string
var status int
var ext []string
args := c.RemainingArgs()
var matcher httpserver.RequestMatcher
switch len(args) {
case 1:
base = args[0]
fallthrough
case 0:
// Integrate request matcher for 'if' conditions.
matcher, err = httpserver.SetupIfMatcher(c)
if err != nil {
return nil, err
}
for c.NextBlock() {
if httpserver.IfMatcherKeyword(c) {
continue
}
switch c.Val() {
case "r", "regexp":
if !c.NextArg() {
return nil, c.ArgErr()
}
pattern = c.Val()
case "to":
args1 := c.RemainingArgs()
if len(args1) == 0 {
return nil, c.ArgErr()
}
to = strings.Join(args1, " ")
case "ext":
args1 := c.RemainingArgs()
if len(args1) == 0 {
return nil, c.ArgErr()
}
ext = args1
case "status":
if !c.NextArg() {
return nil, c.ArgErr()
}
status, _ = strconv.Atoi(c.Val())
if status < 200 || (status > 299 && status < 400) || status > 499 {
return nil, c.Err("status must be 2xx or 4xx")
}
default:
return nil, c.ArgErr()
}
}
// ensure to or status is specified
if to == "" && status == 0 {
return nil, c.ArgErr()
}
if rule, err = NewComplexRule(base, pattern, to, status, ext, matcher); err != nil {
return nil, err
}
rules = append(rules, rule)
// the only unhandled case is 2 and above
default:
rule = NewSimpleRule(args[0], strings.Join(args[1:], " "))
rules = append(rules, rule)
}
}
return rules, nil
}
示例12: fastcgiParse
func fastcgiParse(c *caddy.Controller) ([]Rule, error) {
var rules []Rule
for c.Next() {
var rule Rule
args := c.RemainingArgs()
switch len(args) {
case 0:
return rules, c.ArgErr()
case 1:
rule.Path = "/"
rule.Address = args[0]
case 2:
rule.Path = args[0]
rule.Address = args[1]
case 3:
rule.Path = args[0]
rule.Address = args[1]
err := fastcgiPreset(args[2], &rule)
if err != nil {
return rules, c.Err("Invalid fastcgi rule preset '" + args[2] + "'")
}
}
for c.NextBlock() {
switch c.Val() {
case "ext":
if !c.NextArg() {
return rules, c.ArgErr()
}
rule.Ext = c.Val()
case "split":
if !c.NextArg() {
return rules, c.ArgErr()
}
rule.SplitPath = c.Val()
case "index":
args := c.RemainingArgs()
if len(args) == 0 {
return rules, c.ArgErr()
}
rule.IndexFiles = args
case "env":
envArgs := c.RemainingArgs()
if len(envArgs) < 2 {
return rules, c.ArgErr()
}
rule.EnvVars = append(rule.EnvVars, [2]string{envArgs[0], envArgs[1]})
case "except":
ignoredPaths := c.RemainingArgs()
if len(ignoredPaths) == 0 {
return rules, c.ArgErr()
}
rule.IgnoredSubPaths = ignoredPaths
}
}
rules = append(rules, rule)
}
return rules, nil
}
示例13: ParseSearchConfig
// ParseSearchConfig controller information to create a IndexSearch config
func ParseSearchConfig(c *caddy.Controller, cnf *httpserver.SiteConfig) (*Config, error) {
hosthash := md5.New()
hosthash.Write([]byte(cnf.Host()))
conf := &Config{
HostName: hex.EncodeToString(hosthash.Sum(nil)),
Engine: `bleve`,
IndexDirectory: `/tmp/caddyIndex`,
IncludePaths: []*regexp.Regexp{},
ExcludePaths: []*regexp.Regexp{},
Endpoint: `/search`,
SiteRoot: cnf.Root,
Expire: 60 * time.Second,
Template: nil,
}
_, err := os.Stat(conf.SiteRoot)
if err != nil {
return nil, c.Err("[search]: `invalid root directory`")
}
incPaths := []string{}
excPaths := []string{}
for c.Next() {
args := c.RemainingArgs()
switch len(args) {
case 2:
conf.Endpoint = args[1]
fallthrough
case 1:
incPaths = append(incPaths, args[0])
}
for c.NextBlock() {
switch c.Val() {
case "engine":
if !c.NextArg() {
return nil, c.ArgErr()
}
conf.Engine = c.Val()
case "+path":
if !c.NextArg() {
return nil, c.ArgErr()
}
incPaths = append(incPaths, c.Val())
incPaths = append(incPaths, c.RemainingArgs()...)
case "-path":
if !c.NextArg() {
return nil, c.ArgErr()
}
excPaths = append(excPaths, c.Val())
excPaths = append(excPaths, c.RemainingArgs()...)
case "endpoint":
if !c.NextArg() {
return nil, c.ArgErr()
}
conf.Endpoint = c.Val()
case "expire":
if !c.NextArg() {
return nil, c.ArgErr()
}
exp, err := strconv.Atoi(c.Val())
if err != nil {
return nil, err
}
conf.Expire = time.Duration(exp) * time.Second
case "datadir":
if !c.NextArg() {
return nil, c.ArgErr()
}
conf.IndexDirectory = c.Val()
case "template":
var err error
if c.NextArg() {
conf.Template, err = template.ParseFiles(filepath.Join(conf.SiteRoot, c.Val()))
if err != nil {
return nil, err
}
}
}
}
}
if len(incPaths) == 0 {
incPaths = append(incPaths, "^/")
}
conf.IncludePaths = ConvertToRegExp(incPaths)
conf.ExcludePaths = ConvertToRegExp(excPaths)
dir := conf.IndexDirectory
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return nil, c.Err("[search] Given 'datadir' not a valid path.")
}
}
//.........這裏部分代碼省略.........
示例14: ipfilterParseSingle
// ipfilterParseSingle parses a single ipfilter {} block from the caddy config.
func ipfilterParseSingle(config *IPFConfig, c *caddy.Controller) (IPPath, error) {
var cPath IPPath
// Get PathScopes
cPath.PathScopes = c.RemainingArgs()
if len(cPath.PathScopes) == 0 {
return cPath, c.ArgErr()
}
// Sort PathScopes by length (the longest is always the most specific so should be tested first)
sort.Sort(sort.Reverse(ByLength(cPath.PathScopes)))
for c.NextBlock() {
value := c.Val()
switch value {
case "rule":
if !c.NextArg() {
return cPath, c.ArgErr()
}
rule := c.Val()
if rule == "block" {
cPath.IsBlock = true
} else if rule != "allow" {
return cPath, c.Err("ipfilter: Rule should be 'block' or 'allow'")
}
case "database":
if !c.NextArg() {
return cPath, c.ArgErr()
}
// Check if a database has already been opened
if config.DBHandler != nil {
return cPath, c.Err("ipfilter: A database is already opened")
}
database := c.Val()
// Open the database.
var err error
config.DBHandler, err = maxminddb.Open(database)
if err != nil {
return cPath, c.Err("ipfilter: Can't open database: " + database)
}
case "blockpage":
if !c.NextArg() {
return cPath, c.ArgErr()
}
// check if blockpage exists.
blockpage := c.Val()
if _, err := os.Stat(blockpage); os.IsNotExist(err) {
return cPath, c.Err("ipfilter: No such file: " + blockpage)
}
cPath.BlockPage = blockpage
case "country":
cPath.CountryCodes = c.RemainingArgs()
if len(cPath.CountryCodes) == 0 {
return cPath, c.ArgErr()
}
case "ip":
ips := c.RemainingArgs()
if len(ips) == 0 {
return cPath, c.ArgErr()
}
for _, ip := range ips {
ipRange, err := parseIP(ip)
if err != nil {
return cPath, c.Err("ipfilter: " + err.Error())
}
cPath.Nets = append(cPath.Nets, ipRange...)
}
case "strict":
cPath.Strict = true
}
}
return cPath, nil
}
示例15: redirParse
func redirParse(c *caddy.Controller) ([]Rule, error) {
var redirects []Rule
cfg := httpserver.GetConfig(c)
initRule := func(rule *Rule, defaultCode string, args []string) error {
if cfg.TLS.Enabled {
rule.FromScheme = "https"
} else {
rule.FromScheme = "http"
}
var (
from = "/"
to string
code = defaultCode
)
switch len(args) {
case 1:
// To specified (catch-all redirect)
// Not sure why user is doing this in a table, as it causes all other redirects to be ignored.
// As such, this feature remains undocumented.
to = args[0]
case 2:
// From and To specified
from = args[0]
to = args[1]
case 3:
// From, To, and Code specified
from = args[0]
to = args[1]
code = args[2]
default:
return c.ArgErr()
}
rule.FromPath = from
rule.To = to
if code == "meta" {
rule.Meta = true
code = defaultCode
}
if codeNumber, ok := httpRedirs[code]; ok {
rule.Code = codeNumber
} else {
return c.Errf("Invalid redirect code '%v'", code)
}
return nil
}
// checkAndSaveRule checks the rule for validity (except the redir code)
// and saves it if it's valid, or returns an error.
checkAndSaveRule := func(rule Rule) error {
if rule.FromPath == rule.To {
return c.Err("'from' and 'to' values of redirect rule cannot be the same")
}
for _, otherRule := range redirects {
if otherRule.FromPath == rule.FromPath {
return c.Errf("rule with duplicate 'from' value: %s -> %s", otherRule.FromPath, otherRule.To)
}
}
redirects = append(redirects, rule)
return nil
}
const initDefaultCode = "301"
for c.Next() {
args := c.RemainingArgs()
matcher, err := httpserver.SetupIfMatcher(c)
if err != nil {
return nil, err
}
var hadOptionalBlock bool
for c.NextBlock() {
if httpserver.IfMatcherKeyword(c) {
continue
}
hadOptionalBlock = true
rule := Rule{
RequestMatcher: matcher,
}
defaultCode := initDefaultCode
// Set initial redirect code
if len(args) == 1 {
defaultCode = args[0]
}
// RemainingArgs only gets the values after the current token, but in our
// case we want to include the current token to get an accurate count.
insideArgs := append([]string{c.Val()}, c.RemainingArgs()...)
err := initRule(&rule, defaultCode, insideArgs)
if err != nil {
//.........這裏部分代碼省略.........