Skip to content

Commit

Permalink
rules: updated help message, make values optional, fixes tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yusing committed Feb 5, 2025
1 parent c9ddf3d commit 693bf68
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 47 deletions.
28 changes: 14 additions & 14 deletions internal/net/http/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ package http

import "net/http"

var validMethods = map[string]struct{}{
http.MethodGet: {},
http.MethodHead: {},
http.MethodPost: {},
http.MethodPut: {},
http.MethodPatch: {},
http.MethodDelete: {},
http.MethodConnect: {},
http.MethodOptions: {},
http.MethodTrace: {},
}

func IsMethodValid(method string) bool {
_, ok := validMethods[method]
return ok
switch method {
case http.MethodGet,
http.MethodHead,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
http.MethodConnect,
http.MethodOptions,
http.MethodTrace:
return true
default:
return false
}
}
7 changes: 4 additions & 3 deletions internal/route/rules/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ var (
ErrInvalidCommandSequence = E.New("invalid command sequence")
ErrInvalidSetTarget = E.New("invalid `rule.set` target")

ErrExpectNoArg = ErrInvalidArguments.Withf("expect no arg")
ErrExpectOneArg = ErrInvalidArguments.Withf("expect 1 arg")
ErrExpectTwoArgs = ErrInvalidArguments.Withf("expect 2 args")
ErrExpectNoArg = E.New("expect no arg")
ErrExpectOneArg = E.New("expect 1 arg")
ErrExpectTwoArgs = E.New("expect 2 args")
ErrExpectKVOptionalV = E.New("expect 'key' or 'key value'")
)
7 changes: 3 additions & 4 deletions internal/route/rules/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ func (h *Help) String() string {
sb.WriteString(h.command)
sb.WriteString(" ")
for arg := range h.args {
sb.WriteRune('<')
sb.WriteString(arg)
sb.WriteString("> ")
sb.WriteString(strings.ToUpper(arg))
sb.WriteRune(' ')
}
if h.description != "" {
sb.WriteString("\n\t")
Expand All @@ -32,7 +31,7 @@ func (h *Help) String() string {
sb.WriteRune('\n')
for arg, desc := range h.args {
sb.WriteRune('\t')
sb.WriteString(arg)
sb.WriteString(strings.ToUpper(arg))
sb.WriteString(": ")
sb.WriteString(desc)
sb.WriteRune('\n')
Expand Down
68 changes: 52 additions & 16 deletions internal/route/rules/on.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,44 @@ var checkers = map[string]struct {
help: Help{
command: OnHeader,
args: map[string]string{
"key": "the header key",
"value": "the header value",
"key": "the header key",
"[value]": "the header value",
},
},
validate: toStrTuple,
validate: toKVOptionalV,
builder: func(args any) CheckFunc {
k, v := args.(*StrTuple).Unpack()
if v == "" {
return func(cached Cache, r *http.Request) bool {
return len(r.Header[k]) > 0
}
}
return func(cached Cache, r *http.Request) bool {
return r.Header.Get(k) == v
for _, vv := range r.Header[k] {
if v == vv {
return true
}
}
return false
}
},
},
OnQuery: {
help: Help{
command: OnQuery,
args: map[string]string{
"key": "the query key",
"value": "the query value",
"key": "the query key",
"[value]": "the query value",
},
},
validate: toStrTuple,
validate: toKVOptionalV,
builder: func(args any) CheckFunc {
k, v := args.(*StrTuple).Unpack()
if v == "" {
return func(cached Cache, r *http.Request) bool {
return len(cached.GetQueries(r)[k]) > 0
}
}
return func(cached Cache, r *http.Request) bool {
queries := cached.GetQueries(r)[k]
for _, query := range queries {
Expand All @@ -72,13 +87,24 @@ var checkers = map[string]struct {
help: Help{
command: OnCookie,
args: map[string]string{
"key": "the cookie key",
"value": "the cookie value",
"key": "the cookie key",
"[value]": "the cookie value",
},
},
validate: toStrTuple,
validate: toKVOptionalV,
builder: func(args any) CheckFunc {
k, v := args.(*StrTuple).Unpack()
if v == "" {
return func(cached Cache, r *http.Request) bool {
cookies := cached.GetCookies(r)
for _, cookie := range cookies {
if cookie.Name == k {
return true
}
}
return false
}
}
return func(cached Cache, r *http.Request) bool {
cookies := cached.GetCookies(r)
for _, cookie := range cookies {
Expand All @@ -95,13 +121,18 @@ var checkers = map[string]struct {
help: Help{
command: OnForm,
args: map[string]string{
"key": "the form key",
"value": "the form value",
"key": "the form key",
"[value]": "the form value",
},
},
validate: toStrTuple,
validate: toKVOptionalV,
builder: func(args any) CheckFunc {
k, v := args.(*StrTuple).Unpack()
if v == "" {
return func(cached Cache, r *http.Request) bool {
return r.FormValue(k) != ""
}
}
return func(cached Cache, r *http.Request) bool {
return r.FormValue(k) == v
}
Expand All @@ -111,13 +142,18 @@ var checkers = map[string]struct {
help: Help{
command: OnPostForm,
args: map[string]string{
"key": "the form key",
"value": "the form value",
"key": "the form key",
"[value]": "the form value",
},
},
validate: toStrTuple,
validate: toKVOptionalV,
builder: func(args any) CheckFunc {
k, v := args.(*StrTuple).Unpack()
if v == "" {
return func(cached Cache, r *http.Request) bool {
return r.PostFormValue(k) != ""
}
}
return func(cached Cache, r *http.Request) bool {
return r.PostFormValue(k) == v
}
Expand Down
55 changes: 45 additions & 10 deletions internal/route/rules/on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,50 @@ func TestParseOn(t *testing.T) {
}{
// header
{
name: "header_valid",
name: "header_valid_kv",
input: "header Connection Upgrade",
wantErr: nil,
},
{
name: "header_invalid",
name: "header_valid_k",
input: "header Connection",
wantErr: ErrInvalidArguments,
wantErr: nil,
},
{
name: "header_missing_arg",
input: "header",
wantErr: ErrExpectKVOptionalV,
},
// query
{
name: "query_valid",
name: "query_valid_kv",
input: "query key value",
wantErr: nil,
},
{
name: "query_invalid",
name: "query_valid_k",
input: "query key",
wantErr: ErrInvalidArguments,
wantErr: nil,
},
{
name: "query_missing_arg",
input: "query",
wantErr: ErrExpectKVOptionalV,
},
{
name: "cookie_valid_kv",
input: "cookie key value",
wantErr: nil,
},
{
name: "cookie_valid_k",
input: "cookie key",
wantErr: nil,
},
{
name: "cookie_missing_arg",
input: "cookie",
wantErr: ErrExpectKVOptionalV,
},
// method
{
Expand All @@ -43,19 +68,24 @@ func TestParseOn(t *testing.T) {
},
{
name: "method_invalid",
input: "method",
input: "method invalid",
wantErr: ErrInvalidArguments,
},
{
name: "method_missing_arg",
input: "method",
wantErr: ErrExpectOneArg,
},
// path
{
name: "path_valid",
input: "path /home",
wantErr: nil,
},
{
name: "path_invalid",
name: "path_missing_arg",
input: "path",
wantErr: ErrInvalidArguments,
wantErr: ErrExpectOneArg,
},
// remote
{
Expand All @@ -65,9 +95,14 @@ func TestParseOn(t *testing.T) {
},
{
name: "remote_invalid",
input: "remote",
input: "remote abcd",
wantErr: ErrInvalidArguments,
},
{
name: "remote_missing_arg",
input: "remote",
wantErr: ErrExpectOneArg,
},
{
name: "unknown_target",
input: "unknown",
Expand Down
12 changes: 12 additions & 0 deletions internal/route/rules/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ func toStrTuple(args []string) (any, E.Error) {
return &StrTuple{args[0], args[1]}, nil
}

// toKVOptionalV returns *StrTuple that value is optional.
func toKVOptionalV(args []string) (any, E.Error) {
switch len(args) {
case 1:
return &StrTuple{args[0], ""}, nil
case 2:
return &StrTuple{args[0], args[1]}, nil
default:
return nil, ErrExpectKVOptionalV
}
}

// validateURL returns types.URL with the URL validated.
func validateURL(args []string) (any, E.Error) {
if len(args) != 1 {
Expand Down

0 comments on commit 693bf68

Please sign in to comment.