Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PutObject throws NotSupportException with streams of no length, even when over-ridden. #60

Closed
Stormsys opened this issue Jan 28, 2014 · 2 comments

Comments

@Stormsys
Copy link
Contributor

It is currently impossible to use client.PutObject with a stream that does not present a length regardless if you over-ride this or not. see below for the example that will cause this issue to happen.

please note ive intentionally condensed the code to jump to the important parts, i am also aware that you can copy from bucket-bucket with other methods but for reasons i wont go into i'm not doing it that way.

private static String _bucketName = "__REPLACE_ME__";
private static String _objectToCopy = "__REPLACE_ME__";
private static String _objectDest = "__REPLACE_ME__";

static void Main(string[] args)
{

    Console.WriteLine("Starting...");
    //Test Case

    //simply get the metadata for the object to copy, this will contain the length.
    long contentLength = (new AmazonS3Client(Amazon.RegionEndpoint.USEast1)).GetObjectMetadata(new GetObjectMetadataRequest {
        BucketName = _bucketName, Key = _objectToCopy
    }).ContentLength;

    //get the stream for reading, this is out read only stream without a length...
    Stream inputStream = (new AmazonS3Client(Amazon.RegionEndpoint.USEast1)).GetObject(new GetObjectRequest {
        BucketName = _bucketName, Key = _objectToCopy
    }).ResponseStream;


    //Begin to copy it to new bucket.
    var request = new PutObjectRequest
    {
        BucketName = _bucketName,
        Key = _objectDest,
        InputStream = inputStream
    };

    //set the "hintLength"
    request.Headers.ContentLength = contentLength;


    //Throws a NotSupportedException - always.
    (new AmazonS3Client(Amazon.RegionEndpoint.USEast1)).PutObject(request);

    //Problem Explenation:
    //Look at file, PutObjectRequestMarshaller.cs and start at line 71.
    //above is where override the content length, this will be used when exception at line 106 on PutObjectRequestMarshaller.cs 
    //then line 116 will wrap the stream inside PartialReadOnlyWrapperStream, this object is returned to line 71.
    //finally on line 74(the immediate next line to execute) then attempts to access .Position which is set to throw an exception.

    Console.WriteLine("Done...");
    Console.ReadKey();
}

So what went wrong?
Lets look at PutObjectRequestMarshaller.cs and start at line 71. this will enter a GetStreamWithLength method, which will either return a wrapped stream, or the existing stream. on line 106, the we get exception telling us that we do not have a length associated with the stream, this will set-up the rest of the flow to return the wrapped object. line 116 wraps the stream inside PartialReadOnlyWrapperStream, we then exit this method back to line 71. Then we proceed to the next line, line 74 which attempts to access .Position property of the wrapped stream, which currently does nothing but throw an exception.

@Stormsys
Copy link
Contributor Author

@PavelSafronov
Copy link

Thanks for this. The fix has been accepted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants