diff --git a/gateway/reverse_proxy.go b/gateway/reverse_proxy.go index 7ca37d36a3e..26c2fa2de6a 100644 --- a/gateway/reverse_proxy.go +++ b/gateway/reverse_proxy.go @@ -726,7 +726,7 @@ func (p *ReverseProxy) WrappedServeHTTP(rw http.ResponseWriter, req *http.Reques begin := time.Now() res, err = roundTripper.RoundTrip(outreq) upstreamLatency = time.Since(begin) - if err != nil || res.StatusCode == http.StatusInternalServerError { + if err != nil || res.StatusCode/100 == 5 { breakerConf.CB.Fail() } else { breakerConf.CB.Success() diff --git a/gateway/reverse_proxy_test.go b/gateway/reverse_proxy_test.go index e50dd0bc973..603b0da6943 100644 --- a/gateway/reverse_proxy_test.go +++ b/gateway/reverse_proxy_test.go @@ -2,6 +2,7 @@ package gateway import ( "bytes" + "encoding/json" "fmt" "io/ioutil" "net/http" @@ -347,6 +348,38 @@ func TestWrappedServeHTTP(t *testing.T) { proxy.WrappedServeHTTP(recorder, req, false) } +func TestCircuitBreaker5xxs(t *testing.T) { + ts := StartTest() + defer ts.Close() + + t.Run("Extended Paths", func(t *testing.T) { + BuildAndLoadAPI(func(spec *APISpec) { + UpdateAPIVersion(spec, "v1", func(v *apidef.VersionInfo) { + json.Unmarshal([]byte(`[ + { + "path": "error", + "method": "GET", + "threshold_percent": 0.1, + "samples": 3, + "return_to_service_after": 6000 + } + ]`), &v.ExtendedPaths.CircuitBreaker) + }) + spec.Proxy.ListenPath = "/" + spec.CircuitBreakerEnabled = true + }) + + ts.Run(t, []test.TestCase{ + {Path: "/errors/500", Code: http.StatusInternalServerError}, + {Path: "/errors/501", Code: http.StatusNotImplemented}, + {Path: "/errors/502", Code: http.StatusBadGateway}, + {Path: "/errors/500", Code: http.StatusServiceUnavailable}, + {Path: "/errors/501", Code: http.StatusServiceUnavailable}, + {Path: "/errors/502", Code: http.StatusServiceUnavailable}, + }...) + }) +} + func TestSingleJoiningSlash(t *testing.T) { testsFalse := []struct { a, b, want string diff --git a/gateway/testutil.go b/gateway/testutil.go index c47daf3f5ff..1ac0e9c2a01 100644 --- a/gateway/testutil.go +++ b/gateway/testutil.go @@ -365,6 +365,7 @@ func testHttpHandler() *mux.Router { // use gorilla's mux as it allows to cancel URI cleaning // (it is not configurable in standard http mux) r := mux.NewRouter() + r.HandleFunc("/get", handleMethod("GET")) r.HandleFunc("/post", handleMethod("POST")) r.HandleFunc("/ws", wsHandler) @@ -379,6 +380,10 @@ func testHttpHandler() *mux.Router { gz.Close() }) r.HandleFunc("/bundles/{rest:.*}", bundleHandleFunc) + r.HandleFunc("/errors/{status}", func(w http.ResponseWriter, r *http.Request) { + statusCode, _ := strconv.Atoi(mux.Vars(r)["status"]) + httpError(w, statusCode) + }) r.HandleFunc("/{rest:.*}", handleMethod("")) return r