diff --git a/auth.go b/auth.go index 707a06ff..3c14daef 100644 --- a/auth.go +++ b/auth.go @@ -141,12 +141,35 @@ func (as *AuthServer) ValidateHeader(header []string, method Method, ur *url.URL return fmt.Errorf("wrong username") } - if inUri != ur.String() { - return fmt.Errorf("wrong url") + uri := ur.String() + + if inUri != uri { + // VLC strips any subpath + newUrl := *ur + newUrl.Path = func() string { + ret := newUrl.Path + + // remove leading slash + if len(ret) > 1 { + ret = ret[1:] + } + + // strip any subpath + if n := strings.Index(ret, "/"); n >= 0 { + ret = ret[:n] + } + + return "/" + ret + }() + uri = newUrl.String() + + if inUri != uri { + return fmt.Errorf("wrong url") + } } response := md5Hex(md5Hex(as.user+":"+as.realm+":"+as.pass) + - ":" + as.nonce + ":" + md5Hex(string(method)+":"+ur.String())) + ":" + as.nonce + ":" + md5Hex(string(method)+":"+uri)) if inResponse != response { return fmt.Errorf("wrong response") diff --git a/header-auth.go b/header-auth.go index 8647b70e..42d7fa30 100644 --- a/header-auth.go +++ b/header-auth.go @@ -46,11 +46,17 @@ func ReadHeaderAuth(in string) (*HeaderAuth, error) { func (ha *HeaderAuth) Write() string { ret := ha.Prefix + " " + // always put realm first, otherwise VLC does not send back the response var sortedKeys []string for key := range ha.Values { - sortedKeys = append(sortedKeys, key) + if key != "realm" { + sortedKeys = append(sortedKeys, key) + } } sort.Strings(sortedKeys) + if _, ok := ha.Values["realm"]; ok { + sortedKeys = append([]string{"realm"}, sortedKeys...) + } var tmp []string for _, key := range sortedKeys { diff --git a/header-auth_test.go b/header-auth_test.go index a7dd9ffa..96435547 100644 --- a/header-auth_test.go +++ b/header-auth_test.go @@ -26,7 +26,7 @@ var casesHeaderAuth = []struct { { "digest request 1", `Digest realm="4419b63f5e51", nonce="8b84a3b789283a8bea8da7fa7d41f08b", stale="FALSE"`, - `Digest nonce="8b84a3b789283a8bea8da7fa7d41f08b", realm="4419b63f5e51", stale="FALSE"`, + `Digest realm="4419b63f5e51", nonce="8b84a3b789283a8bea8da7fa7d41f08b", stale="FALSE"`, &HeaderAuth{ Prefix: "Digest", Values: map[string]string{ @@ -39,7 +39,7 @@ var casesHeaderAuth = []struct { { "digest request 2", `Digest realm="4419b63f5e51", nonce="8b84a3b789283a8bea8da7fa7d41f08b", stale=FALSE`, - `Digest nonce="8b84a3b789283a8bea8da7fa7d41f08b", realm="4419b63f5e51", stale="FALSE"`, + `Digest realm="4419b63f5e51", nonce="8b84a3b789283a8bea8da7fa7d41f08b", stale="FALSE"`, &HeaderAuth{ Prefix: "Digest", Values: map[string]string{ @@ -52,7 +52,7 @@ var casesHeaderAuth = []struct { { "digest response", `Digest username="aa", realm="bb", nonce="cc", uri="dd", response="ee"`, - `Digest nonce="cc", realm="bb", response="ee", uri="dd", username="aa"`, + `Digest realm="bb", nonce="cc", response="ee", uri="dd", username="aa"`, &HeaderAuth{ Prefix: "Digest", Values: map[string]string{