fshttp: Add cookie support with cmdline switch --use-cookies

Cookies are handled by cookiejar in memory with fshttp module through
the entire session.

One useful scenario is, with HTTP storage system where index server
adds authentication cookie while redirecting to CDN for actual files.

Also, it can be helpful to reuse fshttp in other storage systems
requiring cookie.
This commit is contained in:
qip 2019-01-12 01:35:29 +08:00 committed by Nick Craig-Wood
parent d7a1fd2a6b
commit f471a7e3f5
3 changed files with 13 additions and 4 deletions

View File

@ -85,6 +85,7 @@ type ConfigInfo struct {
MaxBacklog int
StatsOneLine bool
Progress bool
Cookie bool
}
// NewConfig creates a new config with everything set to the default

View File

@ -87,6 +87,7 @@ func AddFlags(flagSet *pflag.FlagSet) {
flags.IntVarP(flagSet, &fs.Config.MaxBacklog, "max-backlog", "", fs.Config.MaxBacklog, "Maximum number of objects in sync or check backlog.")
flags.BoolVarP(flagSet, &fs.Config.StatsOneLine, "stats-one-line", "", fs.Config.StatsOneLine, "Make the stats fit on one line.")
flags.BoolVarP(flagSet, &fs.Config.Progress, "progress", "P", fs.Config.Progress, "Show progress during transfer.")
flags.BoolVarP(flagSet, &fs.Config.Cookie, "use-cookies", "", fs.Config.Cookie, "Enable session cookiejar.")
}
// SetFlags converts any flags into config which weren't straight foward

View File

@ -7,12 +7,14 @@ import (
"crypto/tls"
"net"
"net/http"
"net/http/cookiejar"
"net/http/httputil"
"reflect"
"sync"
"time"
"github.com/ncw/rclone/fs"
"golang.org/x/net/publicsuffix"
"golang.org/x/time/rate"
)
@ -25,6 +27,7 @@ var (
transport http.RoundTripper
noTransport sync.Once
tpsBucket *rate.Limiter // for limiting number of http transactions per second
cookieJar, _ = cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
)
// StartHTTPTokenBucket starts the token bucket if necessary
@ -142,9 +145,13 @@ func NewTransport(ci *fs.ConfigInfo) http.RoundTripper {
// NewClient returns an http.Client with the correct timeouts
func NewClient(ci *fs.ConfigInfo) *http.Client {
return &http.Client{
transport := &http.Client{
Transport: NewTransport(ci),
}
if ci.Cookie {
transport.Jar = cookieJar
}
return transport
}
// Transport is a our http Transport which wraps an http.Transport