github.com/erda-project/erda-infra@v1.0.9/pkg/transport/http/runtime/parser.go (about) 1 // Copyright (c) 2021 Terminus, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtime 16 17 import ( 18 "strings" 19 20 "github.com/erda-project/erda-infra/pkg/transport/http/httprule" 21 ) 22 23 // Matcher . 24 type Matcher interface { 25 Match(path string) (map[string]string, error) 26 IsStatic() bool 27 Fields() []string 28 Pattern() string 29 } 30 31 // Compile . 32 func Compile(path string) (Matcher, error) { 33 if len(path) <= 1 { 34 return &staticMacher{path}, nil 35 } 36 compiler, err := httprule.Parse(path) 37 if err != nil { 38 return nil, ErrInvalidPattern 39 } 40 temp := compiler.Compile() 41 if len(temp.Fields) <= 0 { 42 return &staticMacher{path}, nil 43 } 44 pattern, err := NewPattern(httprule.SupportPackageIsVersion1, temp.OpCodes, temp.Pool, temp.Verb) 45 if err != nil { 46 return nil, ErrInvalidPattern 47 } 48 return ¶msMatcher{&pattern, path, temp.Fields}, nil 49 } 50 51 type staticMacher struct { 52 path string 53 } 54 55 func (m *staticMacher) Match(path string) (map[string]string, error) { 56 if m.path == path { 57 return nil, nil 58 } 59 return nil, ErrNotMatch 60 } 61 62 func (m *staticMacher) IsStatic() bool { return true } 63 func (m *staticMacher) Fields() []string { return nil } 64 func (m *staticMacher) Pattern() string { return m.path } 65 66 type paramsMatcher struct { 67 p *Pattern 68 path string 69 fields []string 70 } 71 72 func (m *paramsMatcher) Match(path string) (map[string]string, error) { 73 if len(path) > 0 { 74 components := strings.Split(path[1:], "/") 75 last := len(components) - 1 76 var verb string 77 if idx := strings.LastIndex(components[last], ":"); idx >= 0 { 78 c := components[last] 79 components[last], verb = c[:idx], c[idx+1:] 80 } 81 return m.p.Match(components, verb) 82 } 83 return nil, ErrNotMatch 84 } 85 86 func (m *paramsMatcher) IsStatic() bool { return false } 87 func (m *paramsMatcher) Fields() []string { return m.fields } 88 func (m *paramsMatcher) Pattern() string { return m.path }