github.com/google/martian/v3@v3.3.3/method/method_filter.go (about) 1 // Copyright 2015 Google Inc. All rights reserved. 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 method 16 17 import ( 18 "encoding/json" 19 "net/http" 20 "strings" 21 22 "github.com/google/martian/v3" 23 "github.com/google/martian/v3/filter" 24 "github.com/google/martian/v3/log" 25 "github.com/google/martian/v3/parse" 26 ) 27 28 var noop = martian.Noop("method.Filter") 29 30 func init() { 31 parse.Register("method.Filter", filterFromJSON) 32 } 33 34 // Filter runs modifier iff the request method matches the specified method. 35 type Filter struct { 36 *filter.Filter 37 } 38 39 type filterJSON struct { 40 Method string `json:"method"` 41 Modifier json.RawMessage `json:"modifier"` 42 ElseModifier json.RawMessage `json:"else"` 43 Scope []parse.ModifierType `json:"scope"` 44 } 45 46 func filterFromJSON(b []byte) (*parse.Result, error) { 47 msg := &filterJSON{} 48 if err := json.Unmarshal(b, msg); err != nil { 49 return nil, err 50 } 51 52 filter := NewFilter(msg.Method) 53 54 m, err := parse.FromJSON(msg.Modifier) 55 if err != nil { 56 return nil, err 57 } 58 59 filter.RequestWhenTrue(m.RequestModifier()) 60 filter.ResponseWhenTrue(m.ResponseModifier()) 61 62 if len(msg.ElseModifier) > 0 { 63 em, err := parse.FromJSON(msg.ElseModifier) 64 if err != nil { 65 return nil, err 66 } 67 68 if em != nil { 69 filter.RequestWhenFalse(em.RequestModifier()) 70 filter.ResponseWhenFalse(em.ResponseModifier()) 71 } 72 } 73 74 return parse.NewResult(filter, msg.Scope) 75 } 76 77 // NewFilter constructs a filter that applies the modifer when the 78 // request method matches meth. 79 func NewFilter(meth string) *Filter { 80 log.Debugf("method.NewFilter(%q)", meth) 81 m := NewMatcher(meth) 82 f := filter.New() 83 f.SetRequestCondition(m) 84 f.SetResponseCondition(m) 85 return &Filter{f} 86 } 87 88 // Matcher is a conditional evaluator of request methods to be used in 89 // filters that take conditionals. 90 type Matcher struct { 91 method string 92 } 93 94 // NewMatcher builds a new method matcher. 95 func NewMatcher(method string) *Matcher { 96 return &Matcher{ 97 method: method, 98 } 99 } 100 101 // MatchRequest retuns true if m.method matches the request method. 102 func (m *Matcher) MatchRequest(req *http.Request) bool { 103 matched := m.matches(req.Method) 104 if matched { 105 log.Debugf("method.MatchRequest: matched %s request: %s", req.Method, req.URL) 106 } 107 return matched 108 } 109 110 // MatchResponse retuns true if m.method matches res.Request.Method. 111 func (m *Matcher) MatchResponse(res *http.Response) bool { 112 matched := m.matches(res.Request.Method) 113 if matched { 114 log.Debugf("method.MatchResponse: matched %s request: %s", res.Request.Method, res.Request.URL) 115 } 116 return matched 117 } 118 119 func (m *Matcher) matches(method string) bool { 120 return strings.EqualFold(method, m.method) 121 }