/// <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> /// Creates a new object on the server with the contents of the given stream, /// acl and metadata. /// </summary> /// <param name="path">The ObjectPath to create the object on.</param> /// <param name="stream">the stream to upload. The stream will be read until /// an EOF is encountered.</param> /// <param name="acl">the ACL to assign to the new object. Optional. If null, /// the server will generate a default ACL for the file.</param> /// <param name="metadata">The metadata to assign to the new object. /// Optional. If null, no user metadata will be assigned to the new object.</param> /// <param name="closeStream">if true, the stream will be closed after /// the transfer completes. If false, the stream will not be closed.</param> /// <returns>the identifier of the newly-created object.</returns> public ObjectId CreateObjectOnPath(ObjectPath path, Stream stream, Acl acl, MetadataList metadata, bool closeStream) { this.currentBytes = 0; this.complete = false; this.failed = false; this.error = null; this.closeStream = closeStream; this.stream = stream; if (computeChecksums) { checksum = new Checksum(Checksum.Algorithm.SHA0); } else { checksum = null; } ObjectId id = null; // First call should be to create object try { bool eof = ReadChunk(); id = this.esu.CreateObjectFromSegmentOnPath(path, acl, metadata, buffer, contentType, checksum); if (!eof) { this.OnProgress(buffer.Count); } else { // No data in file? Complete this.OnComplete(); return(id); } // Continue appending this.AppendChunks(path); } catch (EsuException e) { this.OnFail(e); throw e; } catch (IOException e) { this.OnFail(e); throw new EsuException("Error uploading object", e); } return(id); }
/// <summary> /// Updates an existing object with the contents of the given file, ACL, and /// metadata. /// </summary> /// <param name="id">the identifier of the object to update.</param> /// <param name="file">the path to the file to replace the object's current /// contents with</param> /// <param name="acl">the ACL to update the object with. Optional. If null, /// the ACL will not be modified.</param> /// <param name="metadata">The metadata to assign to the object. /// Optional. If null, no user metadata will be modified.</param> public void UpdateObject(Identifier id, string file, Acl acl, MetadataList metadata) { // Open the file and call the streaming version Stream s; try { s = File.OpenRead(file); } catch (FileNotFoundException e) { throw new EsuException("Could not open input file", e); } totalBytes = new FileInfo(file).Length; UpdateObject(id, s, acl, metadata, true); }
/// <summary> /// Creates a new object on the server with the contents of the given file, /// acl and metadata. /// </summary> /// <param name="path">The ObjectPath to create the new object on.</param> /// <param name="file">the path to the file to upload</param> /// <param name="acl">the ACL to assign to the new object. Optional. If null, /// the server will generate a default ACL for the file.</param> /// <param name="meta">The metadata to assign to the new object. /// Optional. If null, no user metadata will be assigned to the new object.</param> /// <returns>the identifier of the newly-created object.</returns> public ObjectId CreateObjectOnPath(ObjectPath path, string file, Acl acl, MetadataList meta) { Stream s; // Open the file and call the streaming version try { totalBytes = new FileInfo(file).Length; s = File.OpenRead(file); } catch (FileNotFoundException e) { throw new EsuException("Could not open input file", e); } return(CreateObjectOnPath(path, s, acl, meta, true)); }
/// <summary> /// Updates an existing object with the contents of the given stream, ACL, and /// metadata. /// </summary> /// <param name="id">the identifier of the object to update.</param> /// <param name="stream">the stream to replace the object's current /// contents with. The stream will be read until an EOF is encountered.</param> /// <param name="acl">the ACL to update the object with. Optional. If not /// specified, the ACL will not be modified.</param> /// <param name="metadata">The metadata to assign to the object. /// Optional. If null, no user metadata will be modified.</param> /// <param name="closeStream">If true, the stream will be closed after /// the object is updated.</param> public void UpdateObject(Identifier id, Stream stream, Acl acl, MetadataList metadata, bool closeStream) { this.currentBytes = 0; this.complete = false; this.failed = false; this.error = null; this.closeStream = closeStream; this.stream = stream; if (computeChecksums) { checksum = new Checksum(Checksum.Algorithm.SHA0); } else { checksum = null; } // First call uses a null extent to truncate the file. try { bool eof = ReadChunk(); this.esu.UpdateObjectFromSegment(id, acl, metadata, null, buffer, contentType, checksum); if (!eof) { this.OnProgress(buffer.Count); } else { // No data in file? Complete this.OnComplete(); return; } // Continue appending this.AppendChunks(id); } catch (EsuException e) { this.OnFail(e); throw e; } catch (IOException e) { this.OnFail(e); throw new EsuException("Error updating object", 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); } } }