public async Task PutAsync(IBlob blob, PutBlobOptions options) { if (blob is null) { throw new ArgumentNullException(nameof(blob)); } if (blob.Key is null) { throw new ArgumentNullException("blob.Key"); } // TODO: Chunked upload Stream stream = await blob.OpenAsync().ConfigureAwait(false); #region Stream conditions if (stream.Length == 0) { throw new ArgumentException("May not be empty", nameof(blob)); } // Ensure we're at the start of the stream if (stream.CanSeek && stream.Position != 0) { throw new ArgumentException($"Must be 0. Was {stream.Position}.", paramName: "blob.Position"); } #endregion int retryCount = 0; Exception lastException; do { var request = new PutObjectRequest(client.Host, bucketName, blob.Key); request.SetStream(stream); // Server side encrpytion if (options.EncryptionKey != null) { request.SetCustomerEncryptionKey(new ServerSideEncryptionKey(options.EncryptionKey)); } SetHeaders(request, blob.Properties); try { await client.PutObjectAsync(request).ConfigureAwait(false); return; } catch (S3Exception ex) when(ex.IsTransient) { lastException = ex; } stream.Position = 0; // reset the stream position retryCount++; await Task.Delay(retryPolicy.GetDelay(retryCount)).ConfigureAwait(false); }while (retryPolicy.ShouldRetry(retryCount)); throw lastException; }