|
- // Copyright 2015 Google Inc. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- // Package filter provides a modifier that executes a given set of child
- // modifiers based on the evaluated value of the provided conditional.
- package filter
-
- import (
- "net/http"
-
- "github.com/google/martian"
- "github.com/google/martian/log"
- "github.com/google/martian/verify"
- )
-
- var noop = martian.Noop("Filter")
-
- // Filter is a modifer that contains conditions to evaluate on request and
- // response as well as a set of modifiers to execute based on the value of
- // the provided RequestCondition or ResponseCondition.
- type Filter struct {
- reqcond RequestCondition
- rescond ResponseCondition
-
- treqmod martian.RequestModifier
- tresmod martian.ResponseModifier
- freqmod martian.RequestModifier
- fresmod martian.ResponseModifier
- }
-
- // New returns a pointer to a Filter with all child modifiers initialized to
- // the noop modifier.
- func New() *Filter {
- return &Filter{
- treqmod: noop,
- tresmod: noop,
- fresmod: noop,
- freqmod: noop,
- }
- }
-
- // SetRequestCondition sets the condition to evaluate on requests.
- func (f *Filter) SetRequestCondition(reqcond RequestCondition) {
- f.reqcond = reqcond
- }
-
- // SetResponseCondition sets the condition to evaluate on responses.
- func (f *Filter) SetResponseCondition(rescond ResponseCondition) {
- f.rescond = rescond
- }
-
- // SetRequestModifier sets the martian.RequestModifier that is executed
- // when the RequestCondition evaluates to True. This function is provided
- // to maintain backwards compatability with filtering prior to filter.Filter.
- func (f *Filter) SetRequestModifier(reqmod martian.RequestModifier) {
- f.RequestWhenTrue(reqmod)
- }
-
- // RequestWhenTrue sets the martian.RequestModifier that is executed
- // when the RequestCondition evaluates to True.
- func (f *Filter) RequestWhenTrue(mod martian.RequestModifier) {
- if mod == nil {
- f.treqmod = noop
- return
- }
-
- f.treqmod = mod
- }
-
- // SetResponseModifier sets the martian.ResponseModifier that is executed
- // when the ResponseCondition evaluates to True. This function is provided
- // to maintain backwards compatability with filtering prior to filter.Filter.
- func (f *Filter) SetResponseModifier(resmod martian.ResponseModifier) {
- f.ResponseWhenTrue(resmod)
- }
-
- // RequestWhenFalse sets the martian.RequestModifier that is executed
- // when the RequestCondition evaluates to False.
- func (f *Filter) RequestWhenFalse(mod martian.RequestModifier) {
- if mod == nil {
- f.freqmod = noop
- return
- }
-
- f.freqmod = mod
- }
-
- // ResponseWhenTrue sets the martian.ResponseModifier that is executed
- // when the ResponseCondition evaluates to True.
- func (f *Filter) ResponseWhenTrue(mod martian.ResponseModifier) {
- if mod == nil {
- f.tresmod = noop
- return
- }
-
- f.tresmod = mod
- }
-
- // ResponseWhenFalse sets the martian.ResponseModifier that is executed
- // when the ResponseCondition evaluates to False.
- func (f *Filter) ResponseWhenFalse(mod martian.ResponseModifier) {
- if mod == nil {
- f.fresmod = noop
- return
- }
-
- f.fresmod = mod
- }
-
- // ModifyRequest evaluates reqcond and executes treqmod iff reqcond evaluates
- // to true; otherwise, freqmod is executed.
- func (f *Filter) ModifyRequest(req *http.Request) error {
- match := f.reqcond.MatchRequest(req)
- if match {
- log.Debugf("filter.ModifyRequest: matched %s", req.URL)
- return f.treqmod.ModifyRequest(req)
- }
-
- return f.freqmod.ModifyRequest(req)
- }
-
- // ModifyResponse evaluates rescond and executes tresmod iff rescond evaluates
- // to true; otherwise, fresmod is executed.
- func (f *Filter) ModifyResponse(res *http.Response) error {
- match := f.rescond.MatchResponse(res)
- if match {
- requ := ""
- if res.Request != nil {
- requ = res.Request.URL.String()
- }
- log.Debugf("filter.ModifyResponse: %s", requ)
- return f.tresmod.ModifyResponse(res)
- }
-
- return f.fresmod.ModifyResponse(res)
- }
-
- // VerifyRequests returns an error containing all the verification errors
- // returned by request verifiers.
- func (f *Filter) VerifyRequests() error {
- merr := martian.NewMultiError()
-
- freqv, ok := f.freqmod.(verify.RequestVerifier)
- if ok {
- if ve := freqv.VerifyRequests(); ve != nil {
- merr.Add(ve)
- }
- }
-
- treqv, ok := f.treqmod.(verify.RequestVerifier)
- if ok {
- if ve := treqv.VerifyRequests(); ve != nil {
- merr.Add(ve)
- }
- }
-
- if merr.Empty() {
- return nil
- }
-
- return merr
- }
-
- // VerifyResponses returns an error containing all the verification errors
- // returned by response verifiers.
- func (f *Filter) VerifyResponses() error {
- merr := martian.NewMultiError()
-
- tresv, ok := f.tresmod.(verify.ResponseVerifier)
- if ok {
- if ve := tresv.VerifyResponses(); ve != nil {
- merr.Add(ve)
- }
- }
-
- fresv, ok := f.fresmod.(verify.ResponseVerifier)
- if ok {
- if ve := fresv.VerifyResponses(); ve != nil {
- merr.Add(ve)
- }
- }
-
- if merr.Empty() {
- return nil
- }
-
- return merr
- }
-
- // ResetRequestVerifications resets the state of the contained request verifiers.
- func (f *Filter) ResetRequestVerifications() {
- if treqv, ok := f.treqmod.(verify.RequestVerifier); ok {
- treqv.ResetRequestVerifications()
- }
- if freqv, ok := f.freqmod.(verify.RequestVerifier); ok {
- freqv.ResetRequestVerifications()
- }
- }
-
- // ResetResponseVerifications resets the state of the contained request verifiers.
- func (f *Filter) ResetResponseVerifications() {
- if tresv, ok := f.tresmod.(verify.ResponseVerifier); ok {
- tresv.ResetResponseVerifications()
- }
- }
|