a little bit more structure
diff --git a/digest_auth_client.go b/digest_auth_client.go
index 474b3e4..a66668f 100644
--- a/digest_auth_client.go
+++ b/digest_auth_client.go
@@ -1,63 +1,61 @@
package digest_auth_client
import (
- "crypto/md5"
- "crypto/sha256"
+ "bytes"
"fmt"
- "hash"
- "io"
+ "net/http"
"strings"
+ "time"
)
-type AuthorizationHeader struct {
- Algorithm string // unquoted
- Body string // request value
- Cnonce string // quoted
- Method string // request value
- Nc string // unquoted
- Opaque string // quoted
- Qop string // unquoted
- Realm string // quoted
- Resposne string // quoted
- Uri string // quoted
- Userhash string // quoted
- Username string // quoted
- Username_ string // quoted
+type DigestRequest struct {
+ Body string
+ Method string
+ Password string
+ Uri string
+ Username string
}
-func (ah *AuthorizationHeader) ComputeResponse() AuthorizationHeader {
- return *ah
+func (dr *DigestRequest) NewRequest(
+ username string, password string, method string, uri string, body string) DigestRequest {
+
+ dr.Body = body
+ dr.Method = method
+ dr.Password = password
+ dr.Uri = uri
+ dr.Body = body
+
+ return *dr
}
-func (ah *AuthorizationHeader) ComputeA1() AuthorizationHeader {
- return *ah
-}
+func (dr *DigestRequest) Execute() (*http.Response, error) {
-func (ah *AuthorizationHeader) ComputeA2() (s string) {
-
- if strings.Compare(ah.Qop, "auth") == 0 || strings.Compare(ah.Qop, "") == 0 {
- s = fmt.Sprintf("%s:%s", ah.Method, ah.Uri)
+ req, err := http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body)))
+ if err != nil {
+ return nil, err
}
- if strings.Compare(ah.Qop, "auth-int") == 0 {
- s = fmt.Sprintf("%s:%s", s, ah.Hash(ah.Body))
+ client := &http.Client{
+ Timeout: 30 * time.Second,
+ }
+ resp, err := client.Do(req)
+
+ if resp.StatusCode == 401 {
+ return dr.executeDigest(resp)
}
- return
+ return resp, err
}
-func (ah *AuthorizationHeader) Hash(a string) (s string) {
+func (dr *DigestRequest) executeDigest(resp *http.Response) (*http.Response, error) {
- var h hash.Hash
+ wwwAuthenticateHeaderString := resp.Header.Get("WWW-Authenticate")
- if strings.Compare(ah.Algorithm, "MD5") == 0 {
- h = md5.New()
- } else if strings.Compare(ah.Algorithm, "SHA-256") == 0 {
- h = sha256.New()
+ if strings.Compare(wwwAuthenticateHeaderString, "") == 0 {
+ return nil, fmt.Errorf("Failed to get WWW-Authenticate header, please check your server configuration.")
}
- io.WriteString(h, a)
- s = string(h.Sum(nil))
+ wwwAuthenticateHeader, err = newWwwAuthenticateHeader(wwwAuthenticateHeaderString)
- return
+ return nil, nil
}
diff --git a/header_authorization.go b/header_authorization.go
new file mode 100644
index 0000000..3eee54f
--- /dev/null
+++ b/header_authorization.go
@@ -0,0 +1,77 @@
+package digest_auth_client
+
+import (
+ "crypto/md5"
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "io"
+ "strings"
+)
+
+type authorizationHeader struct {
+ Algorithm string // unquoted
+ Cnonce string // quoted
+ Nc string // unquoted
+ Nounce string // quoted
+ Opaque string // quoted
+ Qop string // unquoted
+ Realm string // quoted
+ Resposne string // quoted
+ Uri string // quoted
+ Userhash string // quoted
+ Username string // quoted
+ Username_ string // quoted
+}
+
+func (ah *authorizationHeader) ComputeResponse() authorizationHeader {
+ return *ah
+}
+
+func (ah *authorizationHeader) ComputeA1(password string) (s string) {
+
+ if strings.Compare(ah.Algorithm, "") == 0 ||
+ strings.Compare(ah.Algorithm, "MD5") == 0 ||
+ strings.Compare(ah.Algorithm, "SHA-256") == 0 {
+ s = fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, password)
+ }
+
+ if strings.Compare(ah.Algorithm, "MD5-sess") ||
+ strings.Compare(ah.Algorithm, "SHA-256-sess") {
+ upHash := ah.Hash(fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, password))
+ s = fmt.Sprintf("%s:%s:%s", upHash, ah.Nc)
+ }
+
+ return
+}
+
+func (ah *authorizationHeader) ComputeA2() (s string) {
+
+ if strings.Compare(ah.Qop, "auth") == 0 || strings.Compare(ah.Qop, "") == 0 {
+ s = fmt.Sprintf("%s:%s", ah.Method, ah.Uri)
+ }
+
+ if strings.Compare(ah.Qop, "auth-int") == 0 {
+ s = fmt.Sprintf("%s:%s", s, ah.Hash(ah.Body))
+ }
+
+ return
+}
+
+func (ah *authorizationHeader) Hash(a string) (s string) {
+
+ var h hash.Hash
+
+ if strings.Compare(ah.Algorithm, "MD5") == 0 ||
+ strings.Compare(ah.Algorithm, "MD5-sess") == 0 {
+ h = md5.New()
+ } else if strings.Compare(ah.Algorithm, "SHA-256") == 0 ||
+ strings.Compare(ah.Algorithm, "SHA-256-sess") == 0 {
+ h = sha256.New()
+ }
+
+ io.WriteString(h, a)
+ s = string(h.Sum(nil))
+
+ return
+}
diff --git a/header_www_authenticate.go b/header_www_authenticate.go
new file mode 100644
index 0000000..a1e5a40
--- /dev/null
+++ b/header_www_authenticate.go
@@ -0,0 +1,17 @@
+package digest_auth_client
+
+type wwwAuthenticate struct {
+ Algorithm string // unquoted
+ Domain string // quoted
+ Nonce string // quoted
+ Opaque string // quoted
+ Qop string // quoted
+ Realm string // quoted
+ Stale bool // unquoted
+ charset string // quoted
+ userhash bool // quoted
+}
+
+func newWwwAuthenticateHeader(newWwwAuthenticateHeaderString string) (*wwwAuthenticate, error) {
+
+}