Skip to content

Commit

Permalink
Merge 53f0942 into 9734546
Browse files Browse the repository at this point in the history
  • Loading branch information
Yohan Robert committed Apr 3, 2016
2 parents 9734546 + 53f0942 commit f376f98
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 7 deletions.
29 changes: 22 additions & 7 deletions request.go
Expand Up @@ -18,6 +18,9 @@ type XMLCharDecoder func(charset string, input io.Reader) (io.Reader, error)
// ReqModifierFunc represent the function interface for request modifiers.
type ReqModifierFunc func(*RequestModifier)

// Filter defines whether a RequestModifier should be applied or not.
type Filter func(*http.Request) bool

// RequestModifier implements a convenient abstraction to modify an http.Request,
// including methods to read, decode/encode and define JSON/XML/String/Binary bodies
// and modify HTTP headers.
Expand Down Expand Up @@ -172,22 +175,34 @@ func (s *RequestModifier) Reader(body io.Reader) error {
// RequestInterceptor interceps a given http.Request using a custom request modifier function.
type RequestInterceptor struct {
Modifier ReqModifierFunc
Filters []Filter
}

// Request intercepts an HTTP request and passes it to the given request modifier function.
func Request(h ReqModifierFunc) *RequestInterceptor {
return &RequestInterceptor{Modifier: h}
return &RequestInterceptor{Modifier: h, Filters: []Filter{}}
}

// Filter intercepts an HTTP requests if and only if the given filter returns true.
func (s *RequestInterceptor) Filter(f ...Filter) {
s.Filters = append(s.Filters, f...)
}

// HandleHTTP handles the middleware call chain, intercepting the request data if possible.
// This methods implements the middleware layer compatible interface.
func (s *RequestInterceptor) HandleHTTP(w http.ResponseWriter, r *http.Request, h http.Handler) {
if r.Method == "HEAD" || r.Method == "OPTIONS" {
h.ServeHTTP(w, r)
return
if s.filter(r) {
req := NewRequestModifier(r)
s.Modifier(req)
}
h.ServeHTTP(w, r)
}

req := NewRequestModifier(r)
s.Modifier(req)
h.ServeHTTP(w, req.Request)
func (s RequestInterceptor) filter(req *http.Request) bool {
for _, filter := range s.Filters {
if !filter(req) {
return false
}
}
return true
}
40 changes: 40 additions & 0 deletions request_test.go
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/xml"
"errors"
"github.com/nbio/st"
"gopkg.in/vinci-proxy/utils.v0"
"io"
"io/ioutil"
"net/http"
Expand Down Expand Up @@ -338,3 +339,42 @@ func TestReaderWithStringReaderAsParameter(t *testing.T) {
body, _ := ioutil.ReadAll(req.Body)
st.Expect(t, string(body), "Hello")
}

func TestFilterWithRequestFilteredOut(t *testing.T) {
interceptor := interceptorWithFilters()
stubbedWriter := utils.NewWriterStub()
req := &http.Request{Method: "POST"}
handler := http.HandlerFunc(func(writer http.ResponseWriter, r *http.Request) {
st.Expect(t, r.Header.Get("intercepted"), "")
})
interceptor.HandleHTTP(stubbedWriter, req, handler)
}

func TestFilterWithRequestFilteredIn(t *testing.T) {
interceptor := interceptorWithFilters()
stubbedWriter := utils.NewWriterStub()
req := &http.Request{Method: "POST", Header: http.Header{}}
req.Header.Set("filter2", "true")
req.Header.Set("filter3", "true")
handler := http.HandlerFunc(func(writer http.ResponseWriter, r *http.Request) {
st.Expect(t, r.Header.Get("intercepted"), "true")
})
interceptor.HandleHTTP(stubbedWriter, req, handler)
}

func interceptorWithFilters() *RequestInterceptor {
interceptor := Request(func(m *RequestModifier) {
m.Header.Set("intercepted", "true")
})
filter1 := func(r *http.Request) bool {
return r.Method == "POST"
}
filter2 := func(r *http.Request) bool {
return r.Header.Get("filter2") == "true"
}
interceptor.Filter(filter1, filter2)
interceptor.Filter(func(r *http.Request) bool {
return r.Header.Get("filter3") == "true"
})
return interceptor
}

0 comments on commit f376f98

Please sign in to comment.