mirror of
https://github.com/yusing/godoxy.git
synced 2026-01-19 09:57:08 +01:00
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package rules
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
httputils "github.com/yusing/goutils/http"
|
|
)
|
|
|
|
var (
|
|
VarHeader = "header"
|
|
VarResponseHeader = "resp_header"
|
|
VarQuery = "arg"
|
|
VarForm = "form"
|
|
VarPostForm = "postform"
|
|
)
|
|
|
|
type dynamicVarGetter func(args []string, w *httputils.ResponseModifier, req *http.Request) (string, error)
|
|
|
|
var dynamicVarSubsMap = map[string]dynamicVarGetter{
|
|
VarHeader: func(args []string, w *httputils.ResponseModifier, req *http.Request) (string, error) {
|
|
key, index, err := getKeyAndIndex(args)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return getValueByKeyAtIndex(req.Header, key, index)
|
|
},
|
|
VarResponseHeader: func(args []string, w *httputils.ResponseModifier, req *http.Request) (string, error) {
|
|
key, index, err := getKeyAndIndex(args)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return getValueByKeyAtIndex(w.Header(), key, index)
|
|
},
|
|
VarQuery: func(args []string, w *httputils.ResponseModifier, req *http.Request) (string, error) {
|
|
key, index, err := getKeyAndIndex(args)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return getValueByKeyAtIndex(httputils.GetSharedData(w).GetQueries(req), key, index)
|
|
},
|
|
VarForm: func(args []string, w *httputils.ResponseModifier, req *http.Request) (string, error) {
|
|
key, index, err := getKeyAndIndex(args)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if req.Form == nil {
|
|
if err := req.ParseForm(); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
return getValueByKeyAtIndex(req.Form, key, index)
|
|
},
|
|
VarPostForm: func(args []string, w *httputils.ResponseModifier, req *http.Request) (string, error) {
|
|
key, index, err := getKeyAndIndex(args)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if req.Form == nil {
|
|
if err := req.ParseForm(); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
return getValueByKeyAtIndex(req.PostForm, key, index)
|
|
},
|
|
}
|
|
|
|
func getValueByKeyAtIndex[Values http.Header | url.Values](values Values, key string, index int) (string, error) {
|
|
// NOTE: do not use Header.Get or http.CanonicalHeaderKey here, respect to user input
|
|
if values, ok := values[key]; ok && index < len(values) {
|
|
return stripFragment(values[index]), nil
|
|
}
|
|
// ignore unknown header or index out of range
|
|
return "", nil
|
|
}
|
|
|
|
func getKeyAndIndex(args []string) (key string, index int, err error) {
|
|
switch len(args) {
|
|
case 0:
|
|
return "", 0, ErrExpectNoArg
|
|
case 1:
|
|
return args[0], 0, nil
|
|
case 2:
|
|
index, err = strconv.Atoi(args[1])
|
|
if err != nil {
|
|
return "", 0, ErrInvalidArguments.Withf("invalid index %q", args[1])
|
|
}
|
|
return args[0], index, nil
|
|
default:
|
|
return "", 0, ErrExpectOneOrTwoArgs
|
|
}
|
|
}
|