Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support path stripping
Browse files Browse the repository at this point in the history
This patch adds support for a 'strip=/path' option which will remove
/path from the front of the outgoing request path. For 'strip=/foo'
a request to '/foo/bar' will be matched on '/foo/bar' but forwarded
as '/bar'.

Fixes: #44, #124, #164
magiconair committed Jan 17, 2017
1 parent 4f99de2 commit 384cf96
Showing 6 changed files with 52 additions and 3 deletions.
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -186,6 +186,7 @@ func watchBackend() {
continue
}
route.SetTable(t)
log.Printf("[INFO] Updated config to\n%s", t)

last = next
}
9 changes: 9 additions & 0 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ package proxy

import (
"net/http"
"strings"
"time"

"github.com/eBay/fabio/config"
@@ -44,6 +45,14 @@ func (p *httpProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

// TODO(fs): The HasPrefix check seems redundant since the lookup function should
// TODO(fs): have found the target based on the prefix but there may be other
// TODO(fs): matchers which may have different rules. I'll keep this for
// TODO(fs): a defensive approach.
if t.StripPath != "" && strings.HasPrefix(r.URL.Path, t.StripPath) {
r.URL.Path = r.URL.Path[len(t.StripPath):]
}

upgrade, accept := r.Header.Get("Upgrade"), r.Header.Get("Accept")

var h http.Handler
26 changes: 26 additions & 0 deletions proxy/proxy_integration_test.go
Original file line number Diff line number Diff line change
@@ -51,6 +51,32 @@ func TestProxyNoRouteStaus(t *testing.T) {
}
}

func TestProxyStripsPath(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI != "/bar" {
w.WriteHeader(404)
return
}
w.Write([]byte("OK"))
}))
parseRoutes("route add mock /foo/bar " + server.URL + ` opts "strip=/foo"`)

tr := http.DefaultTransport
cfg := config.Proxy{}
proxy := NewHTTPProxy(tr, cfg)

req := testReq("/foo/bar")
rec := httptest.NewRecorder()
proxy.ServeHTTP(rec, req)

if got, want := rec.Code, http.StatusOK; got != want {
t.Fatalf("got status %d want %d", got, want)
}
if got, want := rec.Body.String(), "OK"; got != want {
t.Fatalf("got body %q want %q", got, want)
}
}

func TestProxyGzipHandler(t *testing.T) {
tests := []struct {
desc string
14 changes: 12 additions & 2 deletions route/route.go
Original file line number Diff line number Diff line change
@@ -59,9 +59,19 @@ func (r *Route) addTarget(service string, targetURL *url.URL, fixedWeight float6
log.Printf("[ERROR] Invalid metrics name: %s", err)
name = "unknown"
}
timer := ServiceRegistry.GetTimer(name)

t := &Target{Service: service, Tags: tags, URL: targetURL, FixedWeight: fixedWeight, Timer: timer, timerName: name}
t := &Target{
Service: service,
Tags: tags,
URL: targetURL,
FixedWeight: fixedWeight,
Timer: ServiceRegistry.GetTimer(name),
timerName: name,
}
if r.Opts != nil {
t.StripPath = r.Opts["strip"]
}

r.Targets = append(r.Targets, t)
r.weighTargets()
}
1 change: 0 additions & 1 deletion route/table.go
Original file line number Diff line number Diff line change
@@ -51,7 +51,6 @@ func SetTable(t Table) {
table.Store(t)
syncRegistry(t)
mu.Unlock()
log.Printf("[INFO] Updated config to\n%s", t)
}

// syncRegistry unregisters all inactive timers.
4 changes: 4 additions & 0 deletions route/target.go
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ type Target struct {
// Tags are the list of tags for this target
Tags []string

// StripPath will be removed from the front of the outgoing
// request path
StripPath string

// URL is the endpoint the service instance listens on
URL *url.URL

0 comments on commit 384cf96

Please sign in to comment.