/// <summary> /// Constructs a new ReadObjectStreamResponse /// </summary> /// <param name="s">The object content stream</param> /// <param name="contentType">The MIME type of the stream</param> /// <param name="length">The length. Set to -1 if unknown.</param> /// <param name="meta">The object metadata</param> /// <param name="acl">The object's ACL</param> /// <param name="extent">The extent that was read, or null</param> /// <param name="response">the HTTP response object to close the connection</param> /// <param name="checksum">The content checksum if the Atmos server had one stored</param> public ReadObjectStreamResponse(Stream s, string contentType, long length, MetadataList meta, Acl acl, Extent extent, HttpWebResponse response, string checksum) { this.Content = s; this.ContentType = contentType; this.Length = length; this.Metadata = meta; this.Acl = acl; this.response = response; this.ContentChecksum = checksum; }
/// <summary> /// Continues writing data to the object until EOF /// </summary> private void AppendChunks( Identifier id ) { while ( true ) { bool eof = ReadChunk(); if ( eof ) { // done OnComplete(); return; } Extent extent = new Extent( currentBytes, buffer.Count ); esu.UpdateObjectFromSegment( id, null, null, extent, buffer, contentType, checksum ); this.OnProgress( buffer.Count ); } }
/// <summary> /// Downloads the given object's contents to a stream. /// </summary> /// <param name="id">the identifier of the object to download.</param> /// <param name="stream">the stream to write the object's contents to.</param> /// <param name="closeStream">specifies whether to close the stream after /// the transfer is complete.</param> public void ReadObject( Identifier id, Stream stream, bool closeStream ) { this.currentBytes = 0; this.complete = false; this.failed = false; this.error = null; this.closeStream = closeStream; this.stream = stream; if (Checksumming) { checksum = new Checksum(Checksum.Algorithm.SHA0); } // Get the file size. Set to -1 if unknown. MetadataList sMeta = this.esu.GetSystemMetadata( id, null ); if ( sMeta.GetMetadata( "size" ) != null ) { string size = sMeta.GetMetadata( "size" ).Value; if ( size != null && size.Length > 0 ) { this.totalBytes = long.Parse( size ); } else { this.totalBytes = -1; } } else { this.totalBytes = -1; } // We need to know how big the object is to download it. Fail the // transfer if we can't determine the object size. if ( this.totalBytes == -1 ) { throw new EsuException( "Failed to get object size" ); } // Loop, downloading chunks until the transfer is complete. while ( true ) { try { Extent extent = null; // Determine how much data to download. If we're at the last // request in the transfer, only request as many bytes as needed // to get to the end of the file. Use bcmath since these values // can easily exceed 2GB. if ( currentBytes + buffer.Array.Length > totalBytes ) { // Would go past end of file. Request less bytes. extent = new Extent( this.currentBytes, totalBytes - currentBytes ); } else { extent = new Extent( this.currentBytes, buffer.Array.Length ); } if ( extent.Size != buffer.Count ) { buffer = new ArraySegment<byte>( buffer.Array, 0, (int)extent.Size ); } // Read data from the server. byte[] responseBuffer = this.esu.ReadObject( id, extent, buffer.Array, checksum ); // Write to the stream stream.Write( responseBuffer, 0, (int)extent.Size ); // Update progress this.OnProgress( buffer.Count ); // See if we're done. if ( this.currentBytes == this.totalBytes ) { if (Checksumming && checksum != null && checksum.ExpectedValue != null) { if (!checksum.ExpectedValue.Equals(checksum.ToString())) { throw new EsuException("Checksum validation failed. Expected " + checksum.ExpectedValue + " but computed " + checksum.ToString()); } Debug.WriteLine("Checksum OK: " + checksum.ExpectedValue); } this.OnComplete(); return; } } catch ( EsuException e ) { OnFail( e ); throw e; } catch ( IOException e ) { OnFail( e ); throw new EsuException( "Error downloading file", e ); } } }
/// <summary> /// Downloads the given object's contents to a stream. /// </summary> /// <param name="id">the identifier of the object to download.</param> /// <param name="stream">the stream to write the object's contents to.</param> /// <param name="closeStream">specifies whether to close the stream after /// the transfer is complete.</param> public void ReadObject(Identifier id, Stream stream, bool closeStream) { this.currentBytes = 0; this.complete = false; this.failed = false; this.error = null; this.closeStream = closeStream; this.stream = stream; if (Checksumming) { checksum = new Checksum(Checksum.Algorithm.SHA0); } // Get the file size. Set to -1 if unknown. MetadataList sMeta = this.esu.GetSystemMetadata(id, null); if (sMeta.GetMetadata("size") != null) { string size = sMeta.GetMetadata("size").Value; if (size != null && size.Length > 0) { this.totalBytes = long.Parse(size); } else { this.totalBytes = -1; } } else { this.totalBytes = -1; } // We need to know how big the object is to download it. Fail the // transfer if we can't determine the object size. if (this.totalBytes == -1) { throw new EsuException("Failed to get object size"); } // Loop, downloading chunks until the transfer is complete. while (true) { try { Extent extent = null; // Determine how much data to download. If we're at the last // request in the transfer, only request as many bytes as needed // to get to the end of the file. Use bcmath since these values // can easily exceed 2GB. if (currentBytes + buffer.Array.Length > totalBytes) { // Would go past end of file. Request less bytes. extent = new Extent(this.currentBytes, totalBytes - currentBytes); } else { extent = new Extent(this.currentBytes, buffer.Array.Length); } if (extent.Size != buffer.Count) { buffer = new ArraySegment <byte>(buffer.Array, 0, (int)extent.Size); } // Read data from the server. byte[] responseBuffer = this.esu.ReadObject(id, extent, buffer.Array, checksum); // Write to the stream stream.Write(responseBuffer, 0, (int)extent.Size); // Update progress this.OnProgress(buffer.Count); // See if we're done. if (this.currentBytes == this.totalBytes) { if (Checksumming && checksum != null && checksum.ExpectedValue != null) { if (!checksum.ExpectedValue.Equals(checksum.ToString())) { throw new EsuException("Checksum validation failed. Expected " + checksum.ExpectedValue + " but computed " + checksum.ToString()); } Debug.WriteLine("Checksum OK: " + checksum.ExpectedValue); } this.OnComplete(); return; } } catch (EsuException e) { OnFail(e); throw e; } catch (IOException e) { OnFail(e); throw new EsuException("Error downloading file", e); } } }
public void testUpdateObjectContent() { // Create an object ObjectId id = this.esu.CreateObject( null, null, Encoding.UTF8.GetBytes( "hello" ), "text/plain" ); Assert.IsNotNull( id,"null ID returned" ); cleanup.Add( id ); // Update part of the content Extent extent = new Extent( 1,1 ); this.esu.UpdateObject( id, null, null, extent, Encoding.UTF8.GetBytes( "u" ), null ); // Read back the content and check it string content = Encoding.UTF8.GetString( this.esu.ReadObject( id, null, null ) ); Assert.AreEqual( "hullo", content, "object content wrong" ); }
public void testReadObjectStream() { Acl acl = new Acl(); acl.AddGrant(new Grant(new Grantee(getUid(esu.GetUid()), Grantee.GRANTEE_TYPE.USER), Permission.FULL_CONTROL)); acl.AddGrant(new Grant(Grantee.OTHER, Permission.READ)); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); Metadata empty = new Metadata("empty", "", false); //Metadata withEqual = new Metadata("withEqual", "x=y=z", false); mlist.AddMetadata(listable); mlist.AddMetadata(unlistable); mlist.AddMetadata(listable2); mlist.AddMetadata(unlistable2); mlist.AddMetadata(empty); ObjectId id = esu.CreateObject(acl, mlist, Encoding.UTF8.GetBytes("hello"), "text/plain; charset=UTF-8"); cleanup.Add(id); // Read back ReadObjectStreamResponse response = esu.ReadObjectStream(id, null); // Check content Assert.AreEqual(5, response.Length, "Content length incorrect"); Assert.AreEqual("text/plain; charset=UTF-8", response.ContentType, "Content type incorrect"); byte[] buffer = new byte[1024]; int count = response.Content.Read(buffer, 0, buffer.Length); response.Close(); Assert.AreEqual(5, count, "Incorrect number of bytes read from stream"); string content = Encoding.UTF8.GetString(buffer, 0, count); Assert.AreEqual("hello", content, "Stream content incorrect"); // Check metadata MetadataList meta = response.Metadata; Assert.AreEqual("foo", meta.GetMetadata("listable").Value, "value of 'listable' wrong"); Assert.AreEqual("foo2 foo2", meta.GetMetadata("listable2").Value, "value of 'listable2' wrong"); Assert.AreEqual("bar", meta.GetMetadata("unlistable").Value, "value of 'unlistable' wrong"); Assert.AreEqual("bar2 bar2", meta.GetMetadata("unlistable2").Value, "value of 'unlistable2' wrong"); Assert.AreEqual("", meta.GetMetadata("empty").Value, "value of 'empty' wrong"); // Check ACL Acl newacl = response.Acl; Debug.WriteLine("Comparing " + newacl + " with " + acl); Assert.AreEqual(acl, newacl, "ACLs don't match"); // Read a segment of the data back Extent extent = new Extent(1, 2); response = esu.ReadObjectStream(id, extent); count = response.Content.Read(buffer, 0, buffer.Length); response.Close(); Assert.AreEqual(2, count, "Incorrect number of bytes read from stream"); content = Encoding.UTF8.GetString(buffer, 0, count); Assert.AreEqual("el", content, "Stream content incorrect"); }
public void testReadObject() { ObjectId id = this.esu.CreateObject( null, null, Encoding.UTF8.GetBytes( "hello" ), "text/plain" ); Assert.IsNotNull( id, "null ID returned" ); cleanup.Add( id ); // Read back the content string content = Encoding.UTF8.GetString( this.esu.ReadObject( id, null, null ) ); Assert.AreEqual( "hello", content, "object content wrong" ); // Read back only 2 bytes Extent extent = new Extent( 1, 2 ); content = Encoding.UTF8.GetString( this.esu.ReadObject( id, extent, null ) ); Assert.AreEqual( "el", content, "partial object content wrong" ); }
public void testMultipleRanges() { string input = "Four score and seven years ago"; ObjectId id = this.esu.CreateObject(null, null, Encoding.UTF8.GetBytes(input), "text/plain" ); cleanup.Add( id ); Assert.IsNotNull( id, "Object null" ); Extent[] extents = new Extent[5]; extents[0] = new Extent( 27, 2 ); //ag extents[1] = new Extent( 9, 1 ); // e extents[2] = new Extent( 5, 1 ); // s extents[3] = new Extent( 4, 1 ); // ' ' extents[4] = new Extent( 27, 3 ); // ago MultipartEntity entity = this.esu.ReadObjectExtents( id, extents ); string content = Encoding.UTF8.GetString( entity.AggregateBytes() ); Assert.AreEqual("ages ago", content, "Content incorrect"); }
public void testUpdateObjectFromStream() { MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("hello")); ObjectId id = this.esu.CreateObjectFromStream(null, null, ms, 5, "text/plain", null); Assert.IsNotNull(id, "null ID returned"); cleanup.Add(id); // Read back the content string content = Encoding.UTF8.GetString(this.esu.ReadObject(id, null, null)); Assert.AreEqual("hello", content, "object content wrong"); ms = new MemoryStream(Encoding.UTF8.GetBytes("And now for something different")); this.esu.UpdateObjectFromStream(id, null, null, null, ms, ms.Length, "text/plain", null); content = Encoding.UTF8.GetString(this.esu.ReadObject(id, null, null)); Assert.AreEqual("And now for something different", content, "object content wrong"); // Update an extent Extent extent = new Extent(4, 3); ms = new MemoryStream(Encoding.UTF8.GetBytes("how")); this.esu.UpdateObjectFromStream(id, null, null, extent, ms, ms.Length, "text/plain", null); content = Encoding.UTF8.GetString(this.esu.ReadObject(id, null, null)); Assert.AreEqual("And how for something different", content, "object content wrong after update"); }