jubos / fake-s3

A lightweight server clone of Amazon S3 that simulates most of the commands supported by S3 with minimal dependencies
2.94k stars 355 forks source link

[Bug] Copy object operation does not correctly generate the source pathname #189

Open alexalegre-wf opened 7 years ago

alexalegre-wf commented 7 years ago

I'm using boto3 to access local fake-s3 for testing -- when I called copy_object, in an attempt to copy an object from one local bucket to another, this error occurred:

ERROR Errno::ENOENT: No such file or directory @ rb_sysopen - /fakes3_root/source-bucket/s3_object_id/.fakes3_metadataFFF/metadata

The code causing the issue is essentially:

import boto3

s3 = boto3.resource('s3')
dest_bucket = s3.Bucket('dest-bucket')
dest_obj = dest_bucket.Object('s3_object_id')

dest_obj.copy_from(
    CopySource={
        'Bucket': 'source-bucket',
        'Key': 's3_object_id'
    }
)

(with appropriate params to point to fake-s3)

Digging in a bit it appears that the issue is the source file path that copy_object creates is

/fakes3_root/source-bucket/s3_object_id/.fakes3_metadataFFF/metadata

where this is the expected, actual path:

/fakes3_root/fake-s3/source-bucket/s3_object_id/.fakes3_metadataFFF/metadata

file store appears to expect the string 'fake-s3' as the src_bucket_name, just as dst_bucket_name is 'fake-s3', and the src_name to be bucket/object_id, just as dst_name is.

Changing the put request normalisation code to:

      copy_source = webrick_req.header["x-amz-copy-source"]
      if copy_source and copy_source.size == 1
        s_req.src_bucket = "fake-s3"
        s_req.src_object = copy_source.first
        s_req.type = Request::COPY
      end

seems to have cleared up any issues copying objects between buckets, but breaks fetching HEAD on objects.

Rhathe commented 7 years ago

I also have the same problem. As a note, it seems the file structure for fake-s3 is /fakes3_root/<sub_domain_name>/<bucket>/<key>. So if you had your url as something like https://aaa.bbb.ccc.com:4569, you would get /fakes3_root/aaa/<bucket>/<key>. Is there a way to remove the dependency on the subdomain name when creating the directories as a temporary solution?

Rhathe commented 7 years ago

@alexalegre-wf Here's a related issue: https://github.com/jubos/fake-s3/issues/114. The current workaround is to use the -H flag to get around code path checking against @root_hostnames, in your case -H fake-s3

EDIT: The bucket becomes the subdomain of the host, so actually you should put -H fake-s3.<rest-of-host> instead, i.e. -H fake-s3.somedomain.com

alexalegre-wf commented 7 years ago

@Rhathe Thanks!