예제 #1
0
        /// <summary>
        /// private helper method to remove list of objects from bucket
        /// </summary>
        /// <param name="args">GetObjectArgs Arguments Object encapsulates information like - bucket name, object name etc </param>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        private async Task <ObjectStat> getObjectHelper(GetObjectArgs args, CancellationToken cancellationToken = default(CancellationToken))
        {
            // StatObject is called to both verify the existence of the object and return it with GetObject.
            // NOTE: This avoids writing the error body to the action stream passed (Do not remove).
            StatObjectArgs statArgs = new StatObjectArgs()
                                      .WithBucket(args.BucketName)
                                      .WithObject(args.ObjectName)
                                      .WithVersionId(args.VersionId)
                                      .WithMatchETag(args.MatchETag)
                                      .WithNotMatchETag(args.NotMatchETag)
                                      .WithModifiedSince(args.ModifiedSince)
                                      .WithUnModifiedSince(args.UnModifiedSince)
                                      .WithServerSideEncryption(args.SSE);

            if (args.OffsetLengthSet)
            {
                statArgs.WithOffsetAndLength(args.ObjectOffset, args.ObjectLength);
            }
            ObjectStat objStat = await this.StatObjectAsync(statArgs, cancellationToken : cancellationToken).ConfigureAwait(false);

            args.Validate();
            if (args.FileName != null)
            {
                await this.getObjectFileAsync(args, objStat, cancellationToken);
            }
            else
            {
                await this.getObjectStreamAsync(args, objStat, args.CallBack, cancellationToken);
            }
            return(objStat);
        }
예제 #2
0
        /// <summary>
        ///  Copy a source object into a new destination object.
        /// </summary>
        /// <param name="bucketName"> Bucket name where the object to be copied exists.</param>
        /// <param name="objectName">Object name source to be copied.</param>
        /// <param name="destBucketName">Bucket name where the object will be copied to.</param>
        /// <param name="destObjectName">Object name to be created, if not provided uses source object name as destination object name.</param>
        /// <param name="copyConditions">optionally can take a key value CopyConditions as well for conditionally attempting copyObject.</param>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        /// <returns></returns>
        public async Task CopyObjectAsync(string bucketName, string objectName, string destBucketName, string destObjectName = null, CopyConditions copyConditions = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (bucketName == null)
            {
                throw new ArgumentException("Source bucket name cannot be empty");
            }
            if (objectName == null)
            {
                throw new ArgumentException("Source object name cannot be empty");
            }
            if (destBucketName == null)
            {
                throw new ArgumentException("Destination bucket name cannot be empty");
            }
            // Escape source object path.
            string sourceObjectPath = bucketName + "/" + utils.UrlEncode(objectName);

            // Destination object name is optional, if empty default to source object name.
            if (destObjectName == null)
            {
                destObjectName = objectName;
            }

            // Get Stats on the source object
            ObjectStat srcStats = await this.StatObjectAsync(bucketName, objectName, cancellationToken);

            long srcByteRangeSize = 0L;

            if (copyConditions != null)
            {
                srcByteRangeSize = copyConditions.GetByteRange();
            }
            long copySize = (srcByteRangeSize == 0) ? srcStats.Size : srcByteRangeSize;

            if ((srcByteRangeSize > srcStats.Size) ||
                ((srcByteRangeSize > 0) && (copyConditions.byteRangeEnd >= srcStats.Size)))
            {
                throw new ArgumentException("Specified byte range (" + copyConditions.byteRangeStart.ToString() + "-" + copyConditions.byteRangeEnd.ToString() + ") does not fit within source object (size=" + srcStats.Size.ToString() + ")");
            }

            if ((copySize > Constants.MaxSingleCopyObjectSize) ||
                (srcByteRangeSize > 0 && (srcByteRangeSize != srcStats.Size)))
            {
                await MultipartCopyUploadAsync(bucketName, objectName, destBucketName, destObjectName, copyConditions, copySize, cancellationToken);
            }
            else
            {
                await this.CopyObjectRequestAsync(bucketName, objectName, destBucketName, destObjectName, copyConditions, null, null, cancellationToken, typeof(CopyObjectResult));
            }
        }
예제 #3
0
        /// <summary>
        /// private helper method return the specified object from the bucket
        /// </summary>
        /// <param name="args">GetObjectArgs Arguments Object encapsulates information like - bucket name, object name etc </param>
        /// <param name="objectStat"> ObjectStat object encapsulates information like - object name, size, etag etc </param>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        private Task getObjectFileAsync(GetObjectArgs args, ObjectStat objectStat, CancellationToken cancellationToken = default(CancellationToken))
        {
            long   length = objectStat.Size;
            string etag   = objectStat.ETag;

            long   tempFileSize = 0;
            string tempFileName = $"{args.FileName}.{etag}.part.minio";

            if (!string.IsNullOrEmpty(args.VersionId))
            {
                tempFileName = $"{args.FileName}.{etag}.{args.VersionId}.part.minio";
            }
            if (File.Exists(args.FileName))
            {
                File.Delete(args.FileName);
            }

            utils.ValidateFile(tempFileName);
            if (File.Exists(tempFileName))
            {
                File.Delete(tempFileName);
            }

            args = args.WithCallbackStream(stream =>
            {
                using (var fileStream = File.Create(tempFileName))
                {
                    stream.CopyTo(fileStream);
                }
                FileInfo writtenInfo = new FileInfo(tempFileName);
                long writtenSize     = writtenInfo.Length;
                if (writtenSize != (length - tempFileSize))
                {
                    throw new IOException(tempFileName + ": unexpected data written.  expected = " + (length - tempFileSize)
                                          + ", written = " + writtenSize);
                }
                utils.MoveWithReplace(tempFileName, args.FileName);
            });
            return(getObjectStreamAsync(args, objectStat, null, cancellationToken));
        }
예제 #4
0
        /// <summary>
        /// private helper method return the specified object from the bucket
        /// </summary>
        /// <param name="args">GetObjectArgs Arguments Object encapsulates information like - bucket name, object name etc </param>
        /// <param name="objectStat"> ObjectStat object encapsulates information like - object name, size, etag etc </param>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        private Task getObjectFileAsync(GetObjectArgs args, ObjectStat objectStat, CancellationToken cancellationToken = default(CancellationToken))
        {
            long   length = objectStat.Size;
            string etag   = objectStat.ETag;

            string tempFileName = $"{args.FileName}.{etag}.part.minio";

            if (!string.IsNullOrEmpty(args.VersionId))
            {
                tempFileName = $"{args.FileName}.{etag}.{args.VersionId}.part.minio";
            }
            if (File.Exists(args.FileName))
            {
                File.Delete(args.FileName);
            }

            utils.ValidateFile(tempFileName);
            if (File.Exists(tempFileName))
            {
                File.Delete(tempFileName);
            }

            return(getObjectStreamAsync(args, objectStat, null, cancellationToken));
        }
 internal StatObjectResponse(HttpStatusCode statusCode, string responseContent, Dictionary <string, string> responseHeaders, StatObjectArgs args)
     : base(statusCode, responseContent)
 {
     // StatObjectResponse object is populated with available stats from the response.
     this.ObjectInfo = ObjectStat.FromResponseHeaders(args.ObjectName, responseHeaders);
 }
예제 #6
0
        /// <summary>
        /// private helper method to remove list of objects from bucket
        /// </summary>
        /// <param name="args">GetObjectArgs Arguments Object encapsulates information like - bucket name, object name etc </param>
        /// <param name="objectStat"> ObjectStat object encapsulates information like - object name, size, etag etc, represents Object Information </param>
        /// <param name="cb"> Action object of type Stream, callback to send Object contents, if assigned </param>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        private async Task getObjectStreamAsync(GetObjectArgs args, ObjectStat objectStat, Action <Stream> cb, CancellationToken cancellationToken = default(CancellationToken))
        {
            RestRequest request = await this.CreateRequest(args).ConfigureAwait(false);

            await this.ExecuteAsync(this.NoErrorHandlers, request, cancellationToken);
        }
예제 #7
0
        /// <summary>
        /// Get an object. The object will be streamed to the callback given by the user.
        /// </summary>
        /// <param name="bucketName">Bucket to retrieve object from</param>
        /// <param name="objectName">Name of object to retrieve</param>
        /// <param name="fileName">string with file path</param>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        /// <returns></returns>
        public async Task GetObjectAsync(string bucketName, string objectName, string fileName, CancellationToken cancellationToken = default(CancellationToken))
        {
            bool fileExists = File.Exists(fileName);

            utils.ValidateFile(fileName);

            ObjectStat objectStat = await StatObjectAsync(bucketName, objectName, cancellationToken);

            long   length = objectStat.Size;
            string etag   = objectStat.ETag;

            string tempFileName = fileName + "." + etag + ".part.minio";

            bool tempFileExists = File.Exists(tempFileName);

            utils.ValidateFile(tempFileName);

            FileInfo tempFileInfo = new FileInfo(tempFileName);
            long     tempFileSize = 0;

            if (tempFileExists)
            {
                tempFileSize = tempFileInfo.Length;
                if (tempFileSize > length)
                {
                    File.Delete(tempFileName);
                    tempFileExists = false;
                    tempFileSize   = 0;
                }
            }

            if (fileExists)
            {
                FileInfo fileInfo = new FileInfo(fileName);
                long     fileSize = fileInfo.Length;
                if (fileSize == length)
                {
                    // already downloaded. nothing to do
                    return;
                }
                else if (fileSize > length)
                {
                    throw new ArgumentException("'" + fileName + "': object size " + length + " is smaller than file size "
                                                + fileSize);
                }
                else if (!tempFileExists)
                {
                    // before resuming the download, copy filename to tempfilename
                    File.Copy(fileName, tempFileName);
                    tempFileSize   = fileSize;
                    tempFileExists = true;
                }
            }
            await GetObjectAsync(bucketName, objectName, (stream) =>
            {
                var fileStream = File.Create(tempFileName);
                stream.CopyTo(fileStream);
                fileStream.Dispose();
                FileInfo writtenInfo = new FileInfo(tempFileName);
                long writtenSize     = writtenInfo.Length;
                if (writtenSize != length - tempFileSize)
                {
                    new IOException(tempFileName + ": unexpected data written.  expected = " + (length - tempFileSize)
                                    + ", written = " + writtenSize);
                }
                utils.MoveWithReplace(tempFileName, fileName);
            }, cancellationToken);
        }
예제 #8
0
        /// <summary>
        /// private helper method to remove list of objects from bucket
        /// </summary>
        /// <param name="args">GetObjectArgs Arguments Object encapsulates information like - bucket name, object name etc </param>
        /// <param name="objectStat"> ObjectStat object encapsulates information like - object name, size, etag etc, represents Object Information </param>
        /// <param name="cb"> Action object of type Stream, callback to send Object contents, if assigned </param>
        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
        private async Task getObjectStreamAsync(GetObjectArgs args, ObjectStat objectStat, Action <Stream> cb, CancellationToken cancellationToken = default(CancellationToken))
        {
            HttpRequestMessageBuilder requestMessageBuilder = await CreateRequest(args).ConfigureAwait(false);

            await ExecuteTaskAsync(this.NoErrorHandlers, requestMessageBuilder, cancellationToken).ConfigureAwait(false);
        }