github.com/google/martian/v3@v3.3.3/filter/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 filter provides a modifier that executes a given set of child 16 // modifiers based on the evaluated value of the provided conditional. 17 package filter 18 19 import ( 20 "fmt" 21 "net/http" 22 23 "github.com/google/martian/v3" 24 "github.com/google/martian/v3/log" 25 "github.com/google/martian/v3/verify" 26 ) 27 28 var noop = martian.Noop("Filter") 29 30 // Filter is a modifer that contains conditions to evaluate on request and 31 // response as well as a set of modifiers to execute based on the value of 32 // the provided RequestCondition or ResponseCondition. 33 type Filter struct { 34 reqcond RequestCondition 35 rescond ResponseCondition 36 37 treqmod martian.RequestModifier 38 tresmod martian.ResponseModifier 39 freqmod martian.RequestModifier 40 fresmod martian.ResponseModifier 41 } 42 43 // New returns a pointer to a Filter with all child modifiers initialized to 44 // the noop modifier. 45 func New() *Filter { 46 return &Filter{ 47 treqmod: noop, 48 tresmod: noop, 49 fresmod: noop, 50 freqmod: noop, 51 } 52 } 53 54 // SetRequestCondition sets the condition to evaluate on requests. 55 func (f *Filter) SetRequestCondition(reqcond RequestCondition) { 56 f.reqcond = reqcond 57 } 58 59 // SetResponseCondition sets the condition to evaluate on responses. 60 func (f *Filter) SetResponseCondition(rescond ResponseCondition) { 61 f.rescond = rescond 62 } 63 64 // SetRequestModifier sets the martian.RequestModifier that is executed 65 // when the RequestCondition evaluates to True. This function is provided 66 // to maintain backwards compatability with filtering prior to filter.Filter. 67 func (f *Filter) SetRequestModifier(reqmod martian.RequestModifier) { 68 f.RequestWhenTrue(reqmod) 69 } 70 71 // RequestWhenTrue sets the martian.RequestModifier that is executed 72 // when the RequestCondition evaluates to True. 73 func (f *Filter) RequestWhenTrue(mod martian.RequestModifier) { 74 if mod == nil { 75 f.treqmod = noop 76 return 77 } 78 79 f.treqmod = mod 80 } 81 82 // SetResponseModifier sets the martian.ResponseModifier that is executed 83 // when the ResponseCondition evaluates to True. This function is provided 84 // to maintain backwards compatability with filtering prior to filter.Filter. 85 func (f *Filter) SetResponseModifier(resmod martian.ResponseModifier) { 86 f.ResponseWhenTrue(resmod) 87 } 88 89 // RequestWhenFalse sets the martian.RequestModifier that is executed 90 // when the RequestCondition evaluates to False. 91 func (f *Filter) RequestWhenFalse(mod martian.RequestModifier) { 92 if mod == nil { 93 f.freqmod = noop 94 return 95 } 96 97 f.freqmod = mod 98 } 99 100 // ResponseWhenTrue sets the martian.ResponseModifier that is executed 101 // when the ResponseCondition evaluates to True. 102 func (f *Filter) ResponseWhenTrue(mod martian.ResponseModifier) { 103 if mod == nil { 104 f.tresmod = noop 105 return 106 } 107 108 f.tresmod = mod 109 } 110 111 // ResponseWhenFalse sets the martian.ResponseModifier that is executed 112 // when the ResponseCondition evaluates to False. 113 func (f *Filter) ResponseWhenFalse(mod martian.ResponseModifier) { 114 if mod == nil { 115 f.fresmod = noop 116 return 117 } 118 119 f.fresmod = mod 120 } 121 122 // ModifyRequest evaluates reqcond and executes treqmod iff reqcond evaluates 123 // to true; otherwise, freqmod is executed. 124 func (f *Filter) ModifyRequest(req *http.Request) error { 125 if f.reqcond == nil { 126 return fmt.Errorf("filter.ModifyRequest: no request condition set. Set condition with SetRequestCondition") 127 } 128 129 match := f.reqcond.MatchRequest(req) 130 if match { 131 log.Debugf("filter.ModifyRequest: matched %s", req.URL) 132 return f.treqmod.ModifyRequest(req) 133 } 134 135 return f.freqmod.ModifyRequest(req) 136 } 137 138 // ModifyResponse evaluates rescond and executes tresmod iff rescond evaluates 139 // to true; otherwise, fresmod is executed. 140 func (f *Filter) ModifyResponse(res *http.Response) error { 141 if f.rescond == nil { 142 return fmt.Errorf("filter.ModifyResponse: no response condition set. Set condition with SetResponseCondition") 143 } 144 145 match := f.rescond.MatchResponse(res) 146 if match { 147 requ := "" 148 if res.Request != nil { 149 requ = res.Request.URL.String() 150 } 151 log.Debugf("filter.ModifyResponse: %s", requ) 152 return f.tresmod.ModifyResponse(res) 153 } 154 155 return f.fresmod.ModifyResponse(res) 156 } 157 158 // VerifyRequests returns an error containing all the verification errors 159 // returned by request verifiers. 160 func (f *Filter) VerifyRequests() error { 161 merr := martian.NewMultiError() 162 163 freqv, ok := f.freqmod.(verify.RequestVerifier) 164 if ok { 165 if ve := freqv.VerifyRequests(); ve != nil { 166 merr.Add(ve) 167 } 168 } 169 170 treqv, ok := f.treqmod.(verify.RequestVerifier) 171 if ok { 172 if ve := treqv.VerifyRequests(); ve != nil { 173 merr.Add(ve) 174 } 175 } 176 177 if merr.Empty() { 178 return nil 179 } 180 181 return merr 182 } 183 184 // VerifyResponses returns an error containing all the verification errors 185 // returned by response verifiers. 186 func (f *Filter) VerifyResponses() error { 187 merr := martian.NewMultiError() 188 189 tresv, ok := f.tresmod.(verify.ResponseVerifier) 190 if ok { 191 if ve := tresv.VerifyResponses(); ve != nil { 192 merr.Add(ve) 193 } 194 } 195 196 fresv, ok := f.fresmod.(verify.ResponseVerifier) 197 if ok { 198 if ve := fresv.VerifyResponses(); ve != nil { 199 merr.Add(ve) 200 } 201 } 202 203 if merr.Empty() { 204 return nil 205 } 206 207 return merr 208 } 209 210 // ResetRequestVerifications resets the state of the contained request verifiers. 211 func (f *Filter) ResetRequestVerifications() { 212 if treqv, ok := f.treqmod.(verify.RequestVerifier); ok { 213 treqv.ResetRequestVerifications() 214 } 215 if freqv, ok := f.freqmod.(verify.RequestVerifier); ok { 216 freqv.ResetRequestVerifications() 217 } 218 } 219 220 // ResetResponseVerifications resets the state of the contained request verifiers. 221 func (f *Filter) ResetResponseVerifications() { 222 if tresv, ok := f.tresmod.(verify.ResponseVerifier); ok { 223 tresv.ResetResponseVerifications() 224 } 225 }