Separate version and challenge parsing from ping

Replace ping logic with individual functions to extract API version and authorization challenges. The response from a ping operation can be passed into these function. If an error occurs in parsing, the version or challenge will not be used. Sending the ping request is the responsibility of the caller.
APIVersion has been converted from a string to a structure type. A parse function was added to convert from string to the structure type.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
Derek McGowan 2015-06-15 16:10:48 -07:00
parent b66ee14e62
commit 5a3a9c6a77
3 changed files with 104 additions and 35 deletions

View file

@ -1,14 +1,10 @@
package auth
import (
"fmt"
"net/http"
"strings"
)
// Octet types from RFC 2616.
type octetType byte
// Challenge carries information from a WWW-Authenticate response header.
// See RFC 2617.
type Challenge struct {
@ -19,6 +15,9 @@ type Challenge struct {
Parameters map[string]string
}
// Octet types from RFC 2616.
type octetType byte
var octetTypes [256]octetType
const (
@ -58,36 +57,17 @@ func init() {
}
}
// Ping pings the provided endpoint to determine its required authorization challenges.
// If a version header is provided, the versions will be returned.
func Ping(client *http.Client, endpoint, versionHeader string) ([]Challenge, []string, error) {
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
return nil, nil, err
}
resp, err := client.Do(req)
if err != nil {
return nil, nil, err
}
defer resp.Body.Close()
versions := []string{}
if versionHeader != "" {
for _, supportedVersions := range resp.Header[http.CanonicalHeaderKey(versionHeader)] {
versions = append(versions, strings.Fields(supportedVersions)...)
}
}
// ResponseChallenges returns a list of authorization challenges
// for the given http Response. Challenges are only checked if
// the response status code was a 401.
func ResponseChallenges(resp *http.Response) []Challenge {
if resp.StatusCode == http.StatusUnauthorized {
// Parse the WWW-Authenticate Header and store the challenges
// on this endpoint object.
return parseAuthHeader(resp.Header), versions, nil
} else if resp.StatusCode != http.StatusOK {
return nil, versions, fmt.Errorf("unable to get valid ping response: %d", resp.StatusCode)
return parseAuthHeader(resp.Header)
}
return nil, versions, nil
return nil
}
func parseAuthHeader(header http.Header) []Challenge {