mirror of
https://github.com/restic/restic.git
synced 2024-12-24 16:54:00 +00:00
rest: Convert to Layout
This commit is contained in:
parent
7f3bcdb4cc
commit
0da7264e75
2 changed files with 20 additions and 83 deletions
|
@ -22,39 +22,11 @@ const connLimit = 40
|
||||||
// make sure the rest backend implements restic.Backend
|
// make sure the rest backend implements restic.Backend
|
||||||
var _ restic.Backend = &restBackend{}
|
var _ restic.Backend = &restBackend{}
|
||||||
|
|
||||||
// restPath returns the path to the given resource.
|
|
||||||
func restPath(url *url.URL, h restic.Handle) string {
|
|
||||||
u := *url
|
|
||||||
|
|
||||||
var dir string
|
|
||||||
|
|
||||||
switch h.Type {
|
|
||||||
case restic.ConfigFile:
|
|
||||||
dir = ""
|
|
||||||
h.Name = "config"
|
|
||||||
case restic.DataFile:
|
|
||||||
dir = backend.Paths.Data
|
|
||||||
case restic.SnapshotFile:
|
|
||||||
dir = backend.Paths.Snapshots
|
|
||||||
case restic.IndexFile:
|
|
||||||
dir = backend.Paths.Index
|
|
||||||
case restic.LockFile:
|
|
||||||
dir = backend.Paths.Locks
|
|
||||||
case restic.KeyFile:
|
|
||||||
dir = backend.Paths.Keys
|
|
||||||
default:
|
|
||||||
dir = string(h.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
u.Path = path.Join(url.Path, dir, h.Name)
|
|
||||||
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
type restBackend struct {
|
type restBackend struct {
|
||||||
url *url.URL
|
url *url.URL
|
||||||
connChan chan struct{}
|
connChan chan struct{}
|
||||||
client http.Client
|
client http.Client
|
||||||
|
backend.Layout
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens the REST backend with the given config.
|
// Open opens the REST backend with the given config.
|
||||||
|
@ -66,7 +38,20 @@ func Open(cfg Config) (restic.Backend, error) {
|
||||||
tr := &http.Transport{MaxIdleConnsPerHost: connLimit}
|
tr := &http.Transport{MaxIdleConnsPerHost: connLimit}
|
||||||
client := http.Client{Transport: tr}
|
client := http.Client{Transport: tr}
|
||||||
|
|
||||||
return &restBackend{url: cfg.URL, connChan: connChan, client: client}, nil
|
// use url without trailing slash for layout
|
||||||
|
url := cfg.URL.String()
|
||||||
|
if url[len(url)-1] == '/' {
|
||||||
|
url = url[:len(url)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
be := &restBackend{
|
||||||
|
url: cfg.URL,
|
||||||
|
connChan: connChan,
|
||||||
|
client: client,
|
||||||
|
Layout: &backend.CloudLayout{URL: url, Join: path.Join},
|
||||||
|
}
|
||||||
|
|
||||||
|
return be, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new REST on server configured in config.
|
// Create creates a new REST on server configured in config.
|
||||||
|
@ -124,7 +109,7 @@ func (b *restBackend) Save(h restic.Handle, rd io.Reader) (err error) {
|
||||||
rd = backend.Closer{Reader: rd}
|
rd = backend.Closer{Reader: rd}
|
||||||
|
|
||||||
<-b.connChan
|
<-b.connChan
|
||||||
resp, err := b.client.Post(restPath(b.url, h), "binary/octet-stream", rd)
|
resp, err := b.client.Post(b.Filename(h), "binary/octet-stream", rd)
|
||||||
b.connChan <- struct{}{}
|
b.connChan <- struct{}{}
|
||||||
|
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
|
@ -167,7 +152,7 @@ func (b *restBackend) Load(h restic.Handle, length int, offset int64) (io.ReadCl
|
||||||
return nil, errors.Errorf("invalid length %d", length)
|
return nil, errors.Errorf("invalid length %d", length)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", restPath(b.url, h), nil)
|
req, err := http.NewRequest("GET", b.Filename(h), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "http.NewRequest")
|
return nil, errors.Wrap(err, "http.NewRequest")
|
||||||
}
|
}
|
||||||
|
@ -207,7 +192,7 @@ func (b *restBackend) Stat(h restic.Handle) (restic.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
<-b.connChan
|
<-b.connChan
|
||||||
resp, err := b.client.Head(restPath(b.url, h))
|
resp, err := b.client.Head(b.Filename(h))
|
||||||
b.connChan <- struct{}{}
|
b.connChan <- struct{}{}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return restic.FileInfo{}, errors.Wrap(err, "client.Head")
|
return restic.FileInfo{}, errors.Wrap(err, "client.Head")
|
||||||
|
@ -249,7 +234,7 @@ func (b *restBackend) Remove(h restic.Handle) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("DELETE", restPath(b.url, h), nil)
|
req, err := http.NewRequest("DELETE", b.Filename(h), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "http.NewRequest")
|
return errors.Wrap(err, "http.NewRequest")
|
||||||
}
|
}
|
||||||
|
@ -275,7 +260,7 @@ func (b *restBackend) Remove(h restic.Handle) error {
|
||||||
func (b *restBackend) List(t restic.FileType, done <-chan struct{}) <-chan string {
|
func (b *restBackend) List(t restic.FileType, done <-chan struct{}) <-chan string {
|
||||||
ch := make(chan string)
|
ch := make(chan string)
|
||||||
|
|
||||||
url := restPath(b.url, restic.Handle{Type: t})
|
url := b.Dirname(restic.Handle{Type: t})
|
||||||
if !strings.HasSuffix(url, "/") {
|
if !strings.HasSuffix(url, "/") {
|
||||||
url += "/"
|
url += "/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
package rest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"restic"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var restPathTests = []struct {
|
|
||||||
Handle restic.Handle
|
|
||||||
URL *url.URL
|
|
||||||
Result string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
URL: parseURL("https://hostname.foo"),
|
|
||||||
Handle: restic.Handle{
|
|
||||||
Type: restic.DataFile,
|
|
||||||
Name: "foobar",
|
|
||||||
},
|
|
||||||
Result: "https://hostname.foo/data/foobar",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
URL: parseURL("https://hostname.foo:1234/prefix/repo"),
|
|
||||||
Handle: restic.Handle{
|
|
||||||
Type: restic.LockFile,
|
|
||||||
Name: "foobar",
|
|
||||||
},
|
|
||||||
Result: "https://hostname.foo:1234/prefix/repo/locks/foobar",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
URL: parseURL("https://hostname.foo:1234/prefix/repo"),
|
|
||||||
Handle: restic.Handle{
|
|
||||||
Type: restic.ConfigFile,
|
|
||||||
Name: "foobar",
|
|
||||||
},
|
|
||||||
Result: "https://hostname.foo:1234/prefix/repo/config",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRESTPaths(t *testing.T) {
|
|
||||||
for i, test := range restPathTests {
|
|
||||||
result := restPath(test.URL, test.Handle)
|
|
||||||
if result != test.Result {
|
|
||||||
t.Errorf("test %d: resulting URL does not match, want:\n %#v\ngot: \n %#v",
|
|
||||||
i, test.Result, result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue