Skip to content

Commit

Permalink
Path escape the data return in the X-Object-Manifest header
Browse files Browse the repository at this point in the history
This fixes an rclone bug 5180 where openstack/swift returned
an url encoded path in the X-Object-Manifest header.

This then caused problems when resolving the segments.
  • Loading branch information
houtmanj authored and ncw committed Oct 6, 2021
1 parent e8c1ee3 commit f746922
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 5 deletions.
6 changes: 5 additions & 1 deletion dlo.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ func (c *Connection) DynamicLargeObjectMove(ctx context.Context, srcContainer st
return err
}

segmentContainer, segmentPath := parseFullPath(headers["X-Object-Manifest"])
segmentContainer, segmentPath, err := parseFullPath(headers["X-Object-Manifest"])
if err != nil {
return err
}

if err := c.createDLOManifest(ctx, dstContainer, dstObjectName, segmentContainer+"/"+segmentPath, info.ContentType, sanitizeLargeObjectMoveHeaders(headers)); err != nil {
return err
}
Expand Down
14 changes: 11 additions & 3 deletions largeobjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"io"
"net/url"
"os"
gopath "path"
"strconv"
Expand Down Expand Up @@ -57,13 +58,17 @@ func getSegment(segmentPath string, partNumber int) string {
return fmt.Sprintf("%s/%016d", segmentPath, partNumber)
}

func parseFullPath(manifest string) (container string, prefix string) {
func parseFullPath(manifest string) (container string, prefix string, err error) {
manifest, err = url.PathUnescape(manifest)
if err != nil {
return
}
components := strings.SplitN(manifest, "/", 2)
container = components[0]
if len(components) > 1 {
prefix = components[1]
}
return container, prefix
return container, prefix, nil
}

func (headers Headers) IsLargeObjectDLO() bool {
Expand All @@ -82,7 +87,10 @@ func (headers Headers) IsLargeObject() bool {

func (c *Connection) getAllSegments(ctx context.Context, container string, path string, headers Headers) (string, []Object, error) {
if manifest, isDLO := headers["X-Object-Manifest"]; isDLO {
segmentContainer, segmentPath := parseFullPath(manifest)
segmentContainer, segmentPath, err := parseFullPath(manifest)
if err != nil {
return segmentContainer, nil, err
}
segments, err := c.getAllDLOSegments(ctx, segmentContainer, segmentPath)
return segmentContainer, segments, err
}
Expand Down
5 changes: 4 additions & 1 deletion slo.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ func (c *Connection) getAllSLOSegments(ctx context.Context, container, path stri

json.Unmarshal(content, &segmentList)
for _, segment := range segmentList {
segmentContainer, segPath = parseFullPath(segment.Name[1:])
segmentContainer, segPath, err = parseFullPath(segment.Name[1:])
if err != nil {
return "", nil, err
}
segments = append(segments, Object{
Name: segPath,
Bytes: segment.Bytes,
Expand Down

0 comments on commit f746922

Please sign in to comment.