diff --git a/pkg/render/openresty/status_codes.go b/pkg/render/openresty/status_codes.go new file mode 100644 index 00000000..65c4b006 --- /dev/null +++ b/pkg/render/openresty/status_codes.go @@ -0,0 +1,62 @@ +package openresty + +import ( + "fmt" + "sort" + "strconv" + "strings" +) + +const ( + StatusCodeMin = 400 + StatusCodeMax = 599 +) + +func ParseStatusCodeTag(tag string) (lo, hi int, err error) { + tag = strings.TrimSpace(tag) + if tag == "" { + return 0, 0, fmt.Errorf("状态码标签不能为空") + } + if i := strings.IndexByte(tag, '-'); i >= 0 { + lo, err = strconv.Atoi(tag[:i]) + if err != nil { + return 0, 0, fmt.Errorf("无效状态码区间: %s", tag) + } + hi, err = strconv.Atoi(tag[i+1:]) + if err != nil { + return 0, 0, fmt.Errorf("无效状态码区间: %s", tag) + } + } else { + lo, err = strconv.Atoi(tag) + if err != nil { + return 0, 0, fmt.Errorf("无效状态码: %s", tag) + } + hi = lo + } + if lo > hi { + return 0, 0, fmt.Errorf("状态码区间左右端点反序: %s", tag) + } + if lo < StatusCodeMin || hi > StatusCodeMax { + return 0, 0, fmt.Errorf("状态码须在 %d–%d: %s", StatusCodeMin, StatusCodeMax, tag) + } + return lo, hi, nil +} + +func ExpandStatusCodeTags(tags []string) ([]int, error) { + set := map[int]struct{}{} + for _, tag := range tags { + lo, hi, err := ParseStatusCodeTag(tag) + if err != nil { + return nil, err + } + for c := lo; c <= hi; c++ { + set[c] = struct{}{} + } + } + out := make([]int, 0, len(set)) + for c := range set { + out = append(out, c) + } + sort.Ints(out) + return out, nil +} diff --git a/pkg/render/openresty/status_codes_test.go b/pkg/render/openresty/status_codes_test.go new file mode 100644 index 00000000..461672cd --- /dev/null +++ b/pkg/render/openresty/status_codes_test.go @@ -0,0 +1,27 @@ +package openresty + +import "testing" + +func TestExpandStatusCodeTags(t *testing.T) { + t.Parallel() + codes, err := ExpandStatusCodeTags([]string{"500-502", "522", "501"}) + if err != nil { + t.Fatal(err) + } + // want sorted unique: 500,501,502,522 + if len(codes) != 4 || codes[0] != 500 || codes[3] != 522 { + t.Fatalf("got %v", codes) + } + _, err = ExpandStatusCodeTags([]string{"399"}) + if err == nil { + t.Fatal("expected error") + } + _, err = ExpandStatusCodeTags([]string{"503-500"}) + if err == nil { + t.Fatal("expected reverse range error") + } + _, err = ExpandStatusCodeTags([]string{"5xx"}) + if err == nil { + t.Fatal("expected syntax error") + } +}