Merge pull request #638 from duglin/MoveHTTPRC

Move challenge http status code logic
This commit is contained in:
Stephen Day 2015-06-18 12:03:29 -07:00
commit 92e2636de0
8 changed files with 9 additions and 19 deletions

View file

@ -24,7 +24,7 @@ var (
Description: `The access controller denied access for the operation on Description: `The access controller denied access for the operation on
a resource. Often this will be accompanied by a 401 Unauthorized a resource. Often this will be accompanied by a 401 Unauthorized
response status.`, response status.`,
HTTPStatusCode: http.StatusForbidden, HTTPStatusCode: http.StatusUnauthorized,
}) })
// ErrorCodeDigestInvalid is returned when uploading a blob if the // ErrorCodeDigestInvalid is returned when uploading a blob if the

View file

@ -62,10 +62,10 @@ type Access struct {
type Challenge interface { type Challenge interface {
error error
// ServeHTTP prepares the request to conduct the appropriate challenge // ServeHTTP prepares the request to conduct the appropriate challenge
// response. For most implementations, simply calling ServeHTTP should be // response by adding the appropriate HTTP challenge header on the response
// sufficient. Because no body is written, users may write a custom body after // message. Callers are expected to set the appropriate HTTP status code
// calling ServeHTTP, but any headers must be written before the call and may // (e.g. 401) themselves. Because no body is written, users may write a
// be overwritten. // custom body after calling ServeHTTP.
ServeHTTP(w http.ResponseWriter, r *http.Request) ServeHTTP(w http.ResponseWriter, r *http.Request)
} }

View file

@ -90,7 +90,6 @@ type challenge struct {
func (ch *challenge) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (ch *challenge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
header := fmt.Sprintf("Basic realm=%q", ch.realm) header := fmt.Sprintf("Basic realm=%q", ch.realm)
w.Header().Set("WWW-Authenticate", header) w.Header().Set("WWW-Authenticate", header)
w.WriteHeader(http.StatusUnauthorized)
} }
func (ch *challenge) Error() string { func (ch *challenge) Error() string {

View file

@ -49,6 +49,7 @@ func TestBasicAccessController(t *testing.T) {
switch err := err.(type) { switch err := err.(type) {
case auth.Challenge: case auth.Challenge:
err.ServeHTTP(w, r) err.ServeHTTP(w, r)
w.WriteHeader(http.StatusUnauthorized)
return return
default: default:
t.Fatalf("unexpected error authorizing request: %v", err) t.Fatalf("unexpected error authorizing request: %v", err)

View file

@ -83,7 +83,6 @@ func (ch *challenge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
w.Header().Set("WWW-Authenticate", header) w.Header().Set("WWW-Authenticate", header)
w.WriteHeader(http.StatusUnauthorized)
} }
func (ch *challenge) Error() string { func (ch *challenge) Error() string {

View file

@ -22,6 +22,7 @@ func TestSillyAccessController(t *testing.T) {
switch err := err.(type) { switch err := err.(type) {
case auth.Challenge: case auth.Challenge:
err.ServeHTTP(w, r) err.ServeHTTP(w, r)
w.WriteHeader(http.StatusUnauthorized)
return return
default: default:
t.Fatalf("unexpected error authorizing request: %v", err) t.Fatalf("unexpected error authorizing request: %v", err)

View file

@ -117,10 +117,9 @@ func (ac *authChallenge) SetHeader(header http.Header) {
} }
// ServeHttp handles writing the challenge response // ServeHttp handles writing the challenge response
// by setting the challenge header and status code. // by setting the challenge header.
func (ac *authChallenge) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (ac *authChallenge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ac.SetHeader(w.Header()) ac.SetHeader(w.Header())
w.WriteHeader(ac.Status())
} }
// accessController implements the auth.AccessController interface. // accessController implements the auth.AccessController interface.

View file

@ -495,16 +495,7 @@ func (app *App) authorized(w http.ResponseWriter, r *http.Request, context *Cont
if err != nil { if err != nil {
switch err := err.(type) { switch err := err.(type) {
case auth.Challenge: case auth.Challenge:
// NOTE(duglin): // Add the appropriate WWW-Auth header
// Since err.ServeHTTP will set the HTTP status code for us
// we need to set the content-type here. The serveJSON
// func will try to do it but it'll be too late at that point.
// I would have have preferred to just have the auth.Challenge
// ServerHTTP func just add the WWW-Authenticate header and let
// serveJSON set the HTTP status code and content-type but I wasn't
// sure if that's an ok design change. STEVVOOE ?
w.Header().Set("Content-Type", "application/json; charset=utf-8")
err.ServeHTTP(w, r) err.ServeHTTP(w, r)
var errs errcode.Errors var errs errcode.Errors