Merge b992021af0773d3931fd67d95b0a57891e862051 into 839eef0db269333870dc04cb79d0dd0c95e5a418

This commit is contained in:
Laurento Frittella 2025-03-31 17:12:01 +02:00 committed by GitHub
commit 09972ac272
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 0 deletions

View File

@ -429,6 +429,24 @@ func (o *Object) filePath() string {
return o.fs.filePath(o.remote)
}
// checkForDigestAuth issues an unauthenticated request to the server to
// determine if 'Digest' is among the supported authentication schemes.
// Multiple challenges may be specified in a single response header
// or provided in separate headers in the same response.
//
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate
func checkForDigestAuth(url string) bool {
resp, err := http.Get(url)
if err == nil {
for _, challenge := range resp.Header["Www-Authenticate"] {
if strings.Contains(challenge, "Digest") {
return true
}
}
}
return false
}
// NewFs constructs an Fs from the path, container:path
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
// Parse config into Options struct
@ -502,6 +520,14 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
rt: ntlmssp.Negotiator{RoundTripper: t},
}
}
if opt.Vendor == "other" {
// If available, prefer Digest authentication.
if checkForDigestAuth(opt.URL) {
fs.Debugf(nil, "using Digest authentication scheme")
client = fshttp.NewClientWithDigestAuth(ctx, opt.User, opt.Pass)
}
}
f.srv = rest.NewClient(client).SetRoot(u.String())
f.features = (&fs.Features{

View File

@ -14,6 +14,7 @@ import (
"sync"
"time"
"github.com/icholy/digest"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/accounting"
"github.com/rclone/rclone/lib/structs"
@ -168,6 +169,27 @@ func NewClientWithUnixSocket(ctx context.Context, path string) *http.Client {
})
}
// NewClientWithDigestAuth returns an http.Client that supports the Digest authentication scheme.
func NewClientWithDigestAuth(ctx context.Context, username, password string) *http.Client {
ci := fs.GetConfig(ctx)
dt := &digest.Transport{
Username: username,
Password: password,
}
// override the default transport with the custom implementation.
dt.Transport = NewTransport(ctx)
client := &http.Client{
Transport: dt,
}
if ci.Cookie {
client.Jar = cookieJar
dt.Jar = cookieJar
}
return client
}
// Transport is our http Transport which wraps an http.Transport
// * Sets the User Agent
// * Does logging

1
go.mod
View File

@ -240,6 +240,7 @@ require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v1.1.5
github.com/golang-jwt/jwt/v4 v4.5.1
github.com/icholy/digest v1.0.1
github.com/pkg/xattr v0.4.10
golang.org/x/mobile v0.0.0-20250218173827-cd096645fcd3
golang.org/x/term v0.29.0

2
go.sum
View File

@ -394,6 +394,8 @@ github.com/henrybear327/Proton-API-Bridge v1.0.0/go.mod h1:gunH16hf6U74W2b9CGDaW
github.com/henrybear327/go-proton-api v1.0.0 h1:zYi/IbjLwFAW7ltCeqXneUGJey0TN//Xo851a/BgLXw=
github.com/henrybear327/go-proton-api v1.0.0/go.mod h1:w63MZuzufKcIZ93pwRgiOtxMXYafI8H74D77AxytOBc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/icholy/digest v1.0.1 h1:HBhK5/Ab2Z4rHgw6n5UooxcJpLSeMR+TuD5rkvRc7Z8=
github.com/icholy/digest v1.0.1/go.mod h1:QNrsSGQ5v7v9cReDI0+eyjsXGUoRSUZQHeQ5C4XLa0Y=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=