aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2018-05-30 11:38:52 +0200
committerStefan Majewsky <majewsky@gmx.net>2018-05-30 11:38:52 +0200
commitbb7eb0faacb77436a492d4b9b9775f2771a546d7 (patch)
treec13ec2cd6079cf400413fddcc43908ca12df868a
parent63541ba5897fdd20cf563461b42eb9599e6437a5 (diff)
downloadgo-schwift-bb7eb0faacb77436a492d4b9b9775f2771a546d7.tar.gz
adjust semantics of Object.InspectSymlink, rename to Object.SymlinkHeaders
The additional guarantee that Object.SymlinkHeaders becomes equivalent to Object.Headers for non-symlinks will be useful e.g. for swift-http-import's usecase.
-rw-r--r--errors.go3
-rw-r--r--object.go30
-rw-r--r--tests/object_test.go14
3 files changed, 28 insertions, 19 deletions
diff --git a/errors.go b/errors.go
index 598419a..825e96a 100644
--- a/errors.go
+++ b/errors.go
@@ -54,9 +54,6 @@ var (
//provided is malformed or uses features not supported by the LargeObject's
//strategy. See documentation for LargeObject.AddSegment() for details.
ErrSegmentInvalid = errors.New("segment invalid or incompatible with large object strategy")
- //ErrNotASymlink is returned by Object.SymlinkTarget() if the object in
- //question exists, but is not a symlink.
- ErrNotASymlink = errors.New("not a symlink")
)
//UnexpectedStatusCodeError is generated when a request to Swift does not yield
diff --git a/object.go b/object.go
index affa9c3..776dd21 100644
--- a/object.go
+++ b/object.go
@@ -93,7 +93,7 @@ func (o *Object) Exists() (bool, error) {
//has not been cached yet, a HEAD request is issued on the object.
//
//For symlinks, this operation returns the metadata for the target object. Use
-//Object.InspectSymlink() to obtain the metadata for the symlink instead.
+//Object.SymlinkHeaders() to obtain the metadata for the symlink instead.
//
//This operation fails with http.StatusNotFound if the object does not exist.
func (o *Object) Headers() (ObjectHeaders, error) {
@@ -526,29 +526,41 @@ func (o *Object) SymlinkTo(target *Object, opts *SymlinkOptions, ropts *RequestO
return o.Upload(nil, uopts, ropts)
}
-//InspectSymlink returns the object that this symlink points to, and the
-//metadata of the symlink. ErrNotASymlink is returned if the object is not a
-//symlink.
+//SymlinkHeaders is similar to Headers, but if the object is a symlink, it
+//returns the metadata of the symlink rather than the metadata of the target.
+//It also returns a reference to the target object.
+//
+//If this object is not a symlink, Object.SymlinkHeaders() returns the same
+//ObjectHeaders as Object.Headers(), and a nil target object.
+//
+//In a nutshell, if Object.Headers() is like os.Stat(), then
+//Object.SymlinkHeaders() is like os.Lstat().
+//
+//If you do not know whether a given object is a symlink or not, it's a good
+//idea to call Object.SymlinkHeaders() first: If the object turns out not to be
+//a symlink, the cache for Object.Headers() has already been populated.
//
//This operation fails with http.StatusNotFound if the object does not exist.
-func (o *Object) InspectSymlink() (target *Object, headers ObjectHeaders, err error) {
+func (o *Object) SymlinkHeaders() (headers ObjectHeaders, target *Object, err error) {
if o.symlinkHeaders == nil {
o.symlinkHeaders, err = o.fetchHeaders(&RequestOptions{
Values: url.Values{"symlink": []string{"get"}},
})
if err != nil {
- return nil, ObjectHeaders{}, err
+ return ObjectHeaders{}, nil, err
}
}
//is this a symlink?
targetFullName := o.symlinkHeaders.Get("X-Symlink-Target")
if targetFullName == "" {
- return nil, ObjectHeaders{}, ErrNotASymlink
+ //not a symlink - the o.symlinkHeaders are just the regular headers
+ o.headers = o.symlinkHeaders
+ return *o.headers, nil, nil
}
fields := strings.SplitN(targetFullName, "/", 2)
if len(fields) < 2 {
- return nil, ObjectHeaders{}, MalformedHeaderError{
+ return ObjectHeaders{}, nil, MalformedHeaderError{
Key: "X-Symlink-Target",
ParseError: fmt.Errorf("expected \"container/object\", got \"%s\"", targetFullName),
}
@@ -561,5 +573,5 @@ func (o *Object) InspectSymlink() (target *Object, headers ObjectHeaders, err er
targetAccount = targetAccount.SwitchAccount(accountName)
}
target = targetAccount.Container(fields[0]).Object(fields[1])
- return target, *o.symlinkHeaders, nil
+ return *o.symlinkHeaders, target, nil
}
diff --git a/tests/object_test.go b/tests/object_test.go
index 618c835..15aa8f2 100644
--- a/tests/object_test.go
+++ b/tests/object_test.go
@@ -277,21 +277,21 @@ func expectObjectContent(t *testing.T, obj *schwift.Object, expected []byte) {
func expectObjectSymlink(t *testing.T, source, expectedTarget *schwift.Object) {
t.Helper()
- target, _, err := source.InspectSymlink()
+ _, target, err := source.SymlinkHeaders()
if expectedTarget == nil {
switch err {
- case schwift.ErrNotASymlink:
- return //success
case nil:
- t.Errorf("expected %s to not be a symlink, but found symlink to %s\n",
- source.FullName(), target.FullName())
+ if target != nil {
+ t.Errorf("expected %s to not be a symlink, but found symlink to %s\n",
+ source.FullName(), target.FullName())
+ }
default:
- t.Errorf("got unexpected error from Object.SymlinkTarget() for %s: %s\n",
+ t.Errorf("got unexpected error from Object.SymlinkHeaders() for %s: %s\n",
source.FullName(), err.Error())
}
} else {
if err != nil {
- t.Errorf("expected %s to be a symlink to %s, but Object.SymlinkTarget() returned error: %s\n",
+ t.Errorf("expected %s to be a symlink to %s, but Object.SymlinkHeaders() returned error: %s\n",
source.FullName(), expectedTarget.FullName(), err.Error())
} else if target.FullName() != expectedTarget.FullName() {
t.Errorf("expected %s to be a symlink to %s, but got target %s\n",