93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"github.com/gorilla/mux"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// Rules holds rule parsing and configuration
|
||
|
type Rules struct {
|
||
|
route *serverRoute
|
||
|
}
|
||
|
|
||
|
func (r *Rules) host(host string) *mux.Route {
|
||
|
return r.route.route.Host(host)
|
||
|
}
|
||
|
|
||
|
func (r *Rules) path(path string) *mux.Route {
|
||
|
return r.route.route.Path(path)
|
||
|
}
|
||
|
|
||
|
func (r *Rules) pathPrefix(path string) *mux.Route {
|
||
|
return r.route.route.PathPrefix(path)
|
||
|
}
|
||
|
|
||
|
func (r *Rules) pathStrip(path string) *mux.Route {
|
||
|
r.route.stripPrefix = path
|
||
|
return r.route.route.Path(path)
|
||
|
}
|
||
|
|
||
|
func (r *Rules) pathPrefixStrip(path string) *mux.Route {
|
||
|
r.route.stripPrefix = path
|
||
|
return r.route.route.PathPrefix(path)
|
||
|
}
|
||
|
|
||
|
func (r *Rules) methods(methods ...string) *mux.Route {
|
||
|
return r.route.route.Methods(methods...)
|
||
|
}
|
||
|
|
||
|
func (r *Rules) headers(headers ...string) *mux.Route {
|
||
|
return r.route.route.Headers(headers...)
|
||
|
}
|
||
|
|
||
|
func (r *Rules) headersRegexp(headers ...string) *mux.Route {
|
||
|
return r.route.route.HeadersRegexp(headers...)
|
||
|
}
|
||
|
|
||
|
// Parse parses rules expressions
|
||
|
func (r *Rules) Parse(expression string) (*mux.Route, error) {
|
||
|
functions := map[string]interface{}{
|
||
|
"Host": r.host,
|
||
|
"Path": r.path,
|
||
|
"PathStrip": r.pathStrip,
|
||
|
"PathPrefix": r.pathPrefix,
|
||
|
"PathPrefixStrip": r.pathPrefixStrip,
|
||
|
"Methods": r.methods,
|
||
|
"Headers": r.headers,
|
||
|
"HeadersRegexp": r.headersRegexp,
|
||
|
}
|
||
|
f := func(c rune) bool {
|
||
|
return c == ':' || c == '='
|
||
|
}
|
||
|
// get function
|
||
|
parsedFunctions := strings.FieldsFunc(expression, f)
|
||
|
if len(parsedFunctions) != 2 {
|
||
|
return nil, errors.New("Error parsing rule: " + expression)
|
||
|
}
|
||
|
parsedFunction, ok := functions[parsedFunctions[0]]
|
||
|
if !ok {
|
||
|
return nil, errors.New("Error parsing rule: " + expression + ". Unknow function: " + parsedFunctions[0])
|
||
|
}
|
||
|
|
||
|
fargs := func(c rune) bool {
|
||
|
return c == ',' || c == ';'
|
||
|
}
|
||
|
// get function
|
||
|
parsedArgs := strings.FieldsFunc(parsedFunctions[1], fargs)
|
||
|
if len(parsedArgs) == 0 {
|
||
|
return nil, errors.New("Error parsing args from rule: " + expression)
|
||
|
}
|
||
|
|
||
|
inputs := make([]reflect.Value, len(parsedArgs))
|
||
|
for i := range parsedArgs {
|
||
|
inputs[i] = reflect.ValueOf(parsedArgs[i])
|
||
|
}
|
||
|
method := reflect.ValueOf(parsedFunction)
|
||
|
if method.IsValid() {
|
||
|
return method.Call(inputs)[0].Interface().(*mux.Route), nil
|
||
|
}
|
||
|
return nil, errors.New("Method not found: " + parsedFunctions[0])
|
||
|
}
|