Merge pull request #3781 from satnam6502/429

Switch to use Too Many Requests response code
This commit is contained in:
Brian Grant 2015-01-27 16:25:37 -08:00
commit 4096e904eb
4 changed files with 14 additions and 9 deletions

View File

@ -25,6 +25,12 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
) )
// HTTP Status codes not in the golang http package.
const (
StatusUnprocessableEntity = 422
StatusTooManyRequests = 429
)
// StatusError is an error intended for consumption by a REST API server; it can also be // StatusError is an error intended for consumption by a REST API server; it can also be
// reconstructed by clients from a REST response. Public to allow easy type switches. // reconstructed by clients from a REST response. Public to allow easy type switches.
type StatusError struct { type StatusError struct {
@ -134,7 +140,7 @@ func NewInvalid(kind, name string, errs ValidationErrorList) error {
} }
return &StatusError{api.Status{ return &StatusError{api.Status{
Status: api.StatusFailure, Status: api.StatusFailure,
Code: 422, // RFC 4918: StatusUnprocessableEntity Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity
Reason: api.StatusReasonInvalid, Reason: api.StatusReasonInvalid,
Details: &api.StatusDetails{ Details: &api.StatusDetails{
Kind: kind, Kind: kind,

View File

@ -50,10 +50,6 @@ type defaultAPIServer struct {
group *APIGroupVersion group *APIGroupVersion
} }
const (
StatusUnprocessableEntity = 422
)
// Handle returns a Handler function that exposes the provided storage interfaces // Handle returns a Handler function that exposes the provided storage interfaces
// as RESTful resources at prefix, serialized by codec, and also includes the support // as RESTful resources at prefix, serialized by codec, and also includes the support
// http resources. // http resources.

View File

@ -24,6 +24,7 @@ import (
"strings" "strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer"
authhandlers "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/handlers" authhandlers "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/handlers"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog" "github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
@ -71,9 +72,10 @@ func RateLimit(rl util.RateLimiter, handler http.Handler) http.Handler {
handler.ServeHTTP(w, req) handler.ServeHTTP(w, req)
return return
} }
w.WriteHeader(http.StatusServiceUnavailable) // Return a 429 status indicating "Too Many Requests"
w.WriteHeader(errors.StatusTooManyRequests)
w.Header().Set("Retry-After", "1") w.Header().Set("Retry-After", "1")
fmt.Fprintf(w, "Rate limit exceeded.") fmt.Fprintf(w, "Rate limit is 1 QPS or a burst of 20")
}) })
} }
@ -96,7 +98,7 @@ func RecoverPanics(handler http.Handler) http.Handler {
http.StatusTemporaryRedirect, http.StatusTemporaryRedirect,
http.StatusConflict, http.StatusConflict,
http.StatusNotFound, http.StatusNotFound,
StatusUnprocessableEntity, errors.StatusUnprocessableEntity,
), ),
).Log() ).Log()

View File

@ -483,7 +483,8 @@ func (r *Request) Do() Result {
continue continue
} }
if resp.StatusCode == http.StatusServiceUnavailable { // Check to see if we got a 429 Too Many Requests response code.
if resp.StatusCode == errors.StatusTooManyRequests {
if retries < 10 { if retries < 10 {
retries++ retries++
if waitFor := resp.Header.Get("Retry-After"); waitFor != "" { if waitFor := resp.Header.Get("Retry-After"); waitFor != "" {