forked from TrueCloudLab/restic
rest backend: Fixes
This commit is contained in:
parent
f7a10a9b9c
commit
8ad98e8040
2 changed files with 64 additions and 10 deletions
|
@ -9,6 +9,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"restic/backend"
|
"restic/backend"
|
||||||
)
|
)
|
||||||
|
@ -17,16 +18,14 @@ const connLimit = 10
|
||||||
|
|
||||||
// restPath returns the path to the given resource.
|
// restPath returns the path to the given resource.
|
||||||
func restPath(url *url.URL, h backend.Handle) string {
|
func restPath(url *url.URL, h backend.Handle) string {
|
||||||
p := url.Path
|
u := *url
|
||||||
if p == "" {
|
|
||||||
p = "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
var dir string
|
var dir string
|
||||||
|
|
||||||
switch h.Type {
|
switch h.Type {
|
||||||
case backend.Config:
|
case backend.Config:
|
||||||
dir = ""
|
dir = ""
|
||||||
|
h.Name = "config"
|
||||||
case backend.Data:
|
case backend.Data:
|
||||||
dir = backend.Paths.Data
|
dir = backend.Paths.Data
|
||||||
case backend.Snapshot:
|
case backend.Snapshot:
|
||||||
|
@ -41,7 +40,9 @@ func restPath(url *url.URL, h backend.Handle) string {
|
||||||
dir = string(h.Type)
|
dir = string(h.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.Join(p, dir, h.Name)
|
u.Path = path.Join(url.Path, dir, h.Name)
|
||||||
|
|
||||||
|
return u.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type restBackend struct {
|
type restBackend struct {
|
||||||
|
@ -98,8 +99,8 @@ func (b *restBackend) Load(h backend.Handle, p []byte, off int64) (n int, err er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if resp.StatusCode != 206 {
|
if resp.StatusCode != 200 && resp.StatusCode != 206 {
|
||||||
return 0, errors.New("blob not found")
|
return 0, fmt.Errorf("unexpected HTTP response code %v", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return io.ReadFull(resp.Body, p)
|
return io.ReadFull(resp.Body, p)
|
||||||
|
@ -132,7 +133,7 @@ func (b *restBackend) Save(h backend.Handle, p []byte) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
return errors.New("blob not saved")
|
return fmt.Errorf("unexpected HTTP response code %v", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -157,7 +158,7 @@ func (b *restBackend) Stat(h backend.Handle) (backend.BlobInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
return backend.BlobInfo{}, errors.New("blob not saved")
|
return backend.BlobInfo{}, fmt.Errorf("unexpected HTTP response code %v", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.ContentLength < 0 {
|
if resp.ContentLength < 0 {
|
||||||
|
@ -215,9 +216,14 @@ func (b *restBackend) Remove(t backend.Type, name string) error {
|
||||||
func (b *restBackend) List(t backend.Type, done <-chan struct{}) <-chan string {
|
func (b *restBackend) List(t backend.Type, done <-chan struct{}) <-chan string {
|
||||||
ch := make(chan string)
|
ch := make(chan string)
|
||||||
|
|
||||||
|
url := restPath(b.url, backend.Handle{Type: t})
|
||||||
|
if !strings.HasSuffix(url, "/") {
|
||||||
|
url += "/"
|
||||||
|
}
|
||||||
|
|
||||||
client := *b.client
|
client := *b.client
|
||||||
<-b.connChan
|
<-b.connChan
|
||||||
resp, err := client.Get(restPath(b.url, backend.Handle{Type: t}))
|
resp, err := client.Get(url)
|
||||||
b.connChan <- struct{}{}
|
b.connChan <- struct{}{}
|
||||||
|
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
|
|
48
src/restic/backend/rest/rest_path_test.go
Normal file
48
src/restic/backend/rest/rest_path_test.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package rest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"restic/backend"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var restPathTests = []struct {
|
||||||
|
Handle backend.Handle
|
||||||
|
URL *url.URL
|
||||||
|
Result string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
URL: parseURL("https://hostname.foo"),
|
||||||
|
Handle: backend.Handle{
|
||||||
|
Type: backend.Data,
|
||||||
|
Name: "foobar",
|
||||||
|
},
|
||||||
|
Result: "https://hostname.foo/data/foobar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
URL: parseURL("https://hostname.foo:1234/prefix/repo"),
|
||||||
|
Handle: backend.Handle{
|
||||||
|
Type: backend.Lock,
|
||||||
|
Name: "foobar",
|
||||||
|
},
|
||||||
|
Result: "https://hostname.foo:1234/prefix/repo/locks/foobar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
URL: parseURL("https://hostname.foo:1234/prefix/repo"),
|
||||||
|
Handle: backend.Handle{
|
||||||
|
Type: backend.Config,
|
||||||
|
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