mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-04 06:43:45 +08:00
a798e0c951
- Server types no longer need to store their own contexts; they are stored on the caddy.Instance, which means each context will be properly GC'ed when the instance is stopped. Server types should use type assertions to convert from caddy.Context to their concrete context type when they need to use it. - Pass the entire context into httpserver.GetConfig instead of only the Key field. - caddy.NewTestController now requires a server type string so it can create a controller with the proper concrete context associated with that server type. Tests still need more attention so that we can test the proper creation of startup functions, etc.
120 lines
2.9 KiB
Go
120 lines
2.9 KiB
Go
package gzip
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/mholt/caddy"
|
|
"github.com/mholt/caddy/caddyhttp/httpserver"
|
|
)
|
|
|
|
// setup configures a new gzip middleware instance.
|
|
func setup(c *caddy.Controller) error {
|
|
configs, err := gzipParse(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
|
|
return Gzip{Next: next, Configs: configs}
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
func gzipParse(c *caddy.Controller) ([]Config, error) {
|
|
var configs []Config
|
|
|
|
for c.Next() {
|
|
config := Config{}
|
|
|
|
// Request Filters
|
|
pathFilter := PathFilter{IgnoredPaths: make(Set)}
|
|
extFilter := ExtFilter{Exts: make(Set)}
|
|
|
|
// Response Filters
|
|
lengthFilter := LengthFilter(0)
|
|
|
|
// No extra args expected
|
|
if len(c.RemainingArgs()) > 0 {
|
|
return configs, c.ArgErr()
|
|
}
|
|
|
|
for c.NextBlock() {
|
|
switch c.Val() {
|
|
case "ext":
|
|
exts := c.RemainingArgs()
|
|
if len(exts) == 0 {
|
|
return configs, c.ArgErr()
|
|
}
|
|
for _, e := range exts {
|
|
if !strings.HasPrefix(e, ".") && e != ExtWildCard && e != "" {
|
|
return configs, fmt.Errorf(`gzip: invalid extension "%v" (must start with dot)`, e)
|
|
}
|
|
extFilter.Exts.Add(e)
|
|
}
|
|
case "not":
|
|
paths := c.RemainingArgs()
|
|
if len(paths) == 0 {
|
|
return configs, c.ArgErr()
|
|
}
|
|
for _, p := range paths {
|
|
if p == "/" {
|
|
return configs, fmt.Errorf(`gzip: cannot exclude path "/" - remove directive entirely instead`)
|
|
}
|
|
if !strings.HasPrefix(p, "/") {
|
|
return configs, fmt.Errorf(`gzip: invalid path "%v" (must start with /)`, p)
|
|
}
|
|
pathFilter.IgnoredPaths.Add(p)
|
|
}
|
|
case "level":
|
|
if !c.NextArg() {
|
|
return configs, c.ArgErr()
|
|
}
|
|
level, _ := strconv.Atoi(c.Val())
|
|
config.Level = level
|
|
case "min_length":
|
|
if !c.NextArg() {
|
|
return configs, c.ArgErr()
|
|
}
|
|
length, err := strconv.ParseInt(c.Val(), 10, 64)
|
|
if err != nil {
|
|
return configs, err
|
|
} else if length == 0 {
|
|
return configs, fmt.Errorf(`gzip: min_length must be greater than 0`)
|
|
}
|
|
lengthFilter = LengthFilter(length)
|
|
default:
|
|
return configs, c.ArgErr()
|
|
}
|
|
}
|
|
|
|
// Request Filters
|
|
config.RequestFilters = []RequestFilter{}
|
|
|
|
// If ignored paths are specified, put in front to filter with path first
|
|
if len(pathFilter.IgnoredPaths) > 0 {
|
|
config.RequestFilters = []RequestFilter{pathFilter}
|
|
}
|
|
|
|
// Then, if extensions are specified, use those to filter.
|
|
// Otherwise, use default extensions filter.
|
|
if len(extFilter.Exts) > 0 {
|
|
config.RequestFilters = append(config.RequestFilters, extFilter)
|
|
} else {
|
|
config.RequestFilters = append(config.RequestFilters, DefaultExtFilter())
|
|
}
|
|
|
|
// Response Filters
|
|
// If min_length is specified, use it.
|
|
if int64(lengthFilter) != 0 {
|
|
config.ResponseFilters = append(config.ResponseFilters, lengthFilter)
|
|
}
|
|
|
|
configs = append(configs, config)
|
|
}
|
|
|
|
return configs, nil
|
|
}
|