public async Task StreamWriteAsyncTest()
        {
            byte[] buffer = GetRandomBuffer(1 * 1024 * 1024);
            MemoryStream stream1 = new MemoryStream(buffer);
            MemoryStream stream2 = new MemoryStream();

            OperationContext tempOperationContext = new OperationContext();
            RESTCommand<NullType> cmd = new RESTCommand<NullType>(TestBase.StorageCredentials, null);
            ExecutionState<NullType> tempExecutionState = new ExecutionState<NullType>(cmd, null, tempOperationContext);

            // Test basic write
            await stream1.WriteToAsync(stream2, null, null, false, tempExecutionState, null, CancellationToken.None);
            stream1.Position = 0;

            TestHelper.AssertStreamsAreEqual(stream1, stream2);

            stream2.Dispose();
            stream2 = new MemoryStream();

            await TestHelper.ExpectedExceptionAsync<ArgumentException>(
                async () => await stream1.WriteToAsync(stream2, 1024, 1024, false, tempExecutionState, null, CancellationToken.None),
                "Parameters copyLength and maxLength cannot be passed simultaneously.");

            stream1.Dispose();
            stream2.Dispose();
        }
예제 #2
0
        private static RESTCommand<TableQuerySegment> QueryImpl(TableQuery query, TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions)
        {
            UriQueryBuilder builder = query.GenerateQueryBuilder();

            if (token != null)
            {
                token.ApplyToUriQueryBuilder(builder);
            }

            StorageUri tempUriList = NavigationHelper.AppendPathToUri(client.StorageUri, tableName);
            RESTCommand<TableQuerySegment> queryCmd = new RESTCommand<TableQuerySegment>(client.Credentials, tempUriList);
            requestOptions.ApplyToStorageCommand(queryCmd);

            queryCmd.CommandLocationMode = CommonUtility.GetListingLocationMode(token);
            queryCmd.RetrieveResponseStream = true;
            queryCmd.Handler = client.AuthenticationHandler;
            queryCmd.BuildClient = HttpClientFactory.BuildHttpClient;
            queryCmd.Builder = builder;
            queryCmd.BuildRequest = (cmd, uri, queryBuilder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(uri, builder, serverTimeout, cnt, ctx);
            queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp.StatusCode, null /* retVal */, cmd, ex);
            queryCmd.PostProcessResponse = async (cmd, resp, ctx) =>
            {
                TableQuerySegment resSeg = await TableOperationHttpResponseParsers.TableQueryPostProcess(cmd.ResponseStream, resp, ctx);
                if (resSeg.ContinuationToken != null)
                {
                    resSeg.ContinuationToken.TargetLocation = cmd.CurrentResult.TargetLocation;
                }

                return resSeg;
            };

            return queryCmd;
        }
        public void StreamWriteSyncTestCopyLengthBoundary()
        {
            byte[] buffer = GetRandomBuffer(1 * 1024 * 1024);
            MemoryStream stream1 = new MemoryStream(buffer);
            MemoryStream stream2 = new MemoryStream();
            MemoryStream stream3 = new MemoryStream();
            
            OperationContext tempOperationContext = new OperationContext();
            RESTCommand<NullType> cmd = new RESTCommand<NullType>(TestBase.StorageCredentials, null);
            ExecutionState<NullType> tempExecutionState = new ExecutionState<NullType>(cmd, null, tempOperationContext);
            
            // Test write with exact number of bytes
            stream1.WriteToSync(stream2, stream1.Length, null, true, false, tempExecutionState, null);
            stream1.Position = 0;
            stream1.WriteToSync(stream3, stream1.Length, null, true, true, tempExecutionState, null);
            stream1.Position = 0;

            TestHelper.AssertStreamsAreEqual(stream1, stream2);
            TestHelper.AssertStreamsAreEqual(stream1, stream3);

            stream2.Dispose();
            stream2 = new MemoryStream();
            stream3.Dispose();
            stream3 = new MemoryStream();

            // Test write with one less byte
            stream1.WriteToSync(stream2, stream1.Length - 1, null, true, false, tempExecutionState, null);
            stream1.Position = 0;
            stream1.WriteToSync(stream3, stream1.Length - 1, null, true, true, tempExecutionState, null);
            stream1.Position = 0;

            Assert.AreEqual(stream1.Length - 1, stream2.Length);
            Assert.AreEqual(stream1.Length - 1, stream3.Length);
            TestHelper.AssertStreamsAreEqualAtIndex(stream1, stream2, 0, 0, (int)stream1.Length - 1);
            TestHelper.AssertStreamsAreEqualAtIndex(stream1, stream3, 0, 0, (int)stream1.Length - 1);

            stream2.Dispose();
            stream2 = new MemoryStream();
            stream3.Dispose();
            stream3 = new MemoryStream();

            // Test with copyLength greater than length
            TestHelper.ExpectedException<ArgumentOutOfRangeException>(
                () => stream1.WriteToSync(stream2, stream1.Length + 1, null, true, false, tempExecutionState, null),
                "The given stream does not contain the requested number of bytes from its given position.");
            stream1.Position = 0;
            TestHelper.ExpectedException<ArgumentOutOfRangeException>(
                () => stream1.WriteToSync(stream3, stream1.Length + 1, null, true, true, tempExecutionState, null),
                "The given stream does not contain the requested number of bytes from its given position.");
            stream1.Position = 0;

            stream1.Dispose();
            stream2.Dispose();
            stream3.Dispose();
        }
예제 #4
0
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="blob">The blob.</param>
        /// <param name="attributes">The attributes.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>
        /// A <see cref="RESTCommand{T}"/> that fetches the attributes.
        /// </returns>
        internal static RESTCommand <NullType> FetchAttributesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> getCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode  = CommandLocationMode.PrimaryOrSecondary;
            getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, useVersionHeader, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, attributes.SnapshotTime, accessCondition, useVersionHeader, ctx);
            getCmd.SignRequest          = blob.ServiceClient.AuthenticationHandler.SignRequest;
            getCmd.PreProcessResponse   = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false);
                return(NullType.Value);
            };

            return(getCmd);
        }
예제 #5
0
        /// <summary>
        /// Generates a <see cref="RESTCommand{T}"/> for releasing a lease.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> implementing the release lease operation.</returns>
        internal static RESTCommand <NullType> ReleaseLeaseImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            CommonUtils.AssertNotNull("accessCondition", accessCondition);
            if (accessCondition.LeaseId == null)
            {
                throw new ArgumentException(SR.MissingLeaseIDReleasing, "accessCondition");
            }

            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx);
            putCmd.SignRequest          = blob.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse   = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);

            return(putCmd);
        }
예제 #6
0
        internal Task <TableQuerySegment <TResult> > ExecuteQuerySegmentedAsync <TResult>(TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver <TResult> resolver, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken)
        {
            CommonUtility.AssertNotNullOrEmpty("tableName", tableName);
            CommonUtility.AssertNotNull("resolver", resolver);

            TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client);

            operationContext = operationContext ?? new OperationContext();

            RESTCommand <TableQuerySegment <TResult> > cmdToExecute = QueryImpl(this, token, client, tableName, resolver, modifiedOptions);

            return(Executor.ExecuteAsync(
                       cmdToExecute,
                       modifiedOptions.RetryPolicy,
                       operationContext,
                       cancellationToken));
        }
예제 #7
0
        private static RESTCommand <IList <TableResult> > BatchImpl(TableBatchOperation batch, CloudTableClient client, string tableName, TableRequestOptions requestOptions)
        {
            RESTCommand <IList <TableResult> > batchCmd = new RESTCommand <IList <TableResult> >(client.Credentials, client.BaseUri);

            requestOptions.ApplyToStorageCommand(batchCmd);

            List <TableResult> results = new List <TableResult>();

            batchCmd.RetrieveResponseStream = true;
            batchCmd.Handler             = client.AuthenticationHandler;
            batchCmd.BuildClient         = HttpClientFactory.BuildHttpClient;
            batchCmd.BuildRequest        = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableBatchOperation(cmd.Uri, cmd.ServerTimeoutInSeconds, client.BaseUri, tableName, batch, ctx);
            batchCmd.PreProcessResponse  = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp.StatusCode, results, cmd, ex, ctx);
            batchCmd.PostProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableBatchOperationPostProcess(results, batch, cmd, resp, ctx);

            return(batchCmd);
        }
예제 #8
0
        /// <summary>
        /// Implementation for the SetProperties method.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that sets the metadata.</returns>
        internal static RESTCommand <NullType> SetPropertiesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.SetProperties(uri, serverTimeout, attributes.Properties, accessCondition, ctx);
            putCmd.SetHeaders           = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata);
            putCmd.SignRequest          = blob.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse   = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);
                CloudBlobSharedImpl.ParseSizeAndLastModified(attributes, resp);
                return(NullType.Value);
            };

            return(putCmd);
        }
        private RESTCommand <ServiceStats> GetServiceStatsImpl(QueueRequestOptions requestOptions)
        {
            if (RetryPolicies.LocationMode.PrimaryOnly == requestOptions.LocationMode)
            {
                throw new InvalidOperationException(SR.GetServiceStatsInvalidOperation);
            }

            RESTCommand <ServiceStats> retCmd = new RESTCommand <ServiceStats>(this.Credentials, this.StorageUri);

            requestOptions.ApplyToStorageCommand(retCmd);
            retCmd.CommandLocationMode      = CommandLocationMode.PrimaryOrSecondary;
            retCmd.BuildRequest             = (cmd, uri, builder, cnt, serverTimeout, ctx) => QueueHttpRequestMessageFactory.GetServiceStats(uri, serverTimeout, ctx, this.GetCanonicalizer(), this.Credentials);
            retCmd.RetrieveResponseStream   = true;
            retCmd.PreProcessResponse       = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            retCmd.PostProcessResponseAsync = (cmd, resp, ctx, ct) => QueueHttpResponseParsers.ReadServiceStatsAsync(cmd.ResponseStream, ct);
            return(retCmd);
        }
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">An object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        internal static RESTCommand <NullType> FetchAttributesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> getCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.Uri);

            getCmd.ApplyRequestOptions(options);
            getCmd.Handler            = blob.ServiceClient.AuthenticationHandler;
            getCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest       = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, accessCondition, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);
                CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false);
                return(NullType.Value);
            };

            return(getCmd);
        }
예제 #11
0
        /// <summary>
        /// Implementation for the FetchAttributes method.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the share. If null, no condition is used.</param>
        /// <param name="options">An object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        private RESTCommand <NullType> FetchAttributesImpl(AccessCondition accessCondition, FileRequestOptions options)
        {
            RESTCommand <NullType> getCmd = new RESTCommand <NullType>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
            getCmd.BuildRequest        = (cmd, uri, builder, cnt, serverTimeout, ctx) => ShareHttpRequestMessageFactory.GetProperties(uri, serverTimeout, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
            getCmd.PreProcessResponse  = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                this.Properties = ShareHttpResponseParsers.GetProperties(resp);
                this.Metadata   = ShareHttpResponseParsers.GetMetadata(resp);
                return(NullType.Value);
            };

            return(getCmd);
        }
예제 #12
0
        /// <summary>
        /// Implementation for the SetProperties method.
        /// </summary>
        /// <param name="blob">The blob.</param>
        /// <param name="attributes">The attributes.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>
        /// A <see cref="RESTCommand{T}"/> that sets the properties.
        /// </returns>
        internal static RESTCommand <NullType> SetPropertiesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(blob.ServiceClient.Credentials, attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, useVersionHeader, ctx) => BlobHttpWebRequestFactory.SetProperties(uri, serverTimeout, attributes.Properties, accessCondition, useVersionHeader, ctx);
            putCmd.SetHeaders           = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata);
            putCmd.SignRequest          = blob.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse   = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                CloudBlobSharedImpl.UpdateETagLMTLengthAndSequenceNumber(attributes, resp, false);
                return(NullType.Value);
            };

            return(putCmd);
        }
예제 #13
0
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="blobUri">The URI of the blob.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        private RESTCommand <ICloudBlob> GetBlobReferenceImpl(StorageUri blobUri, AccessCondition accessCondition, BlobRequestOptions options)
        {
            // If the blob Uri contains SAS credentials, we need to use those
            // credentials instead of this service client's stored credentials.
            StorageCredentials parsedCredentials;
            DateTimeOffset?    parsedSnapshot;

            blobUri = NavigationHelper.ParseBlobQueryAndVerify(blobUri, out parsedCredentials, out parsedSnapshot);
            CloudBlobClient client = parsedCredentials != null ? new CloudBlobClient(this.StorageUri, parsedCredentials) : this;

            RESTCommand <ICloudBlob> getCmd = new RESTCommand <ICloudBlob>(client.Credentials, blobUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
            getCmd.Handler             = client.AuthenticationHandler;
            getCmd.BuildClient         = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest        = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.GetProperties(uri, serverTimeout, parsedSnapshot, accessCondition, cnt, ctx);
            getCmd.PreProcessResponse  = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
                BlobAttributes attributes = new BlobAttributes()
                {
                    StorageUri   = blobUri,
                    SnapshotTime = parsedSnapshot,
                };

                CloudBlob.UpdateAfterFetchAttributes(attributes, resp, false);

                switch (attributes.Properties.BlobType)
                {
                case BlobType.BlockBlob:
                    return(new CloudBlockBlob(attributes, client));

                case BlobType.PageBlob:
                    return(new CloudPageBlob(attributes, client));

                case BlobType.AppendBlob:
                    return(new CloudAppendBlob(attributes, client));

                default:
                    throw new InvalidOperationException();
                }
            };

            return(getCmd);
        }
예제 #14
0
        private static RESTCommand <TableQuerySegment <RESULT_TYPE> > QueryImpl <RESULT_TYPE>(TableQuery query, TableContinuationToken token, CloudTableClient client, CloudTable table, EntityResolver <RESULT_TYPE> resolver, TableRequestOptions requestOptions)
        {
            UriQueryBuilder builder = query.GenerateQueryBuilder(requestOptions.ProjectSystemProperties);

            if (token != null)
            {
                token.ApplyToUriQueryBuilder(builder);
            }

            StorageUri tempUri = NavigationHelper.AppendPathToUri(client.StorageUri, table.Name);
            RESTCommand <TableQuerySegment <RESULT_TYPE> > queryCmd = new RESTCommand <TableQuerySegment <RESULT_TYPE> >(client.Credentials, tempUri);

            requestOptions.ApplyToStorageCommand(queryCmd);

            queryCmd.CommandLocationMode    = CommonUtility.GetListingLocationMode(token);
            queryCmd.RetrieveResponseStream = true;
            queryCmd.SignRequest            = client.AuthenticationHandler.SignRequest;
            queryCmd.Builder              = builder;
            queryCmd.ParseError           = ODataErrorHelper.ReadFromStreamUsingODataLib;
            queryCmd.BuildRequestDelegate = (uri, queryBuilder, timeout, useVersionHeader, ctx) => TableOperationHttpWebRequestFactory.BuildRequestForTableQuery(uri, queryBuilder, timeout, useVersionHeader, ctx, requestOptions.PayloadFormat.Value);
            queryCmd.PreProcessResponse   = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp != null ? resp.StatusCode : HttpStatusCode.Unused, null /* retVal */, cmd, ex);
            queryCmd.PostProcessResponse  = (cmd, resp, ctx) =>
            {
                ResultSegment <RESULT_TYPE> resSeg = TableOperationHttpResponseParsers.TableQueryPostProcessGeneric <RESULT_TYPE, DynamicTableEntity>(cmd.ResponseStream, resolver.Invoke, resp, requestOptions, ctx);
                if (resSeg.ContinuationToken != null)
                {
                    resSeg.ContinuationToken.TargetLocation = cmd.CurrentResult.TargetLocation;
                }

                return(new TableQuerySegment <RESULT_TYPE>(resSeg));
            };
            queryCmd.PostProcessResponseAsync = async(cmd, resp, ctx) =>
            {
                ResultSegment <RESULT_TYPE> resSeg = await TableOperationHttpResponseParsers.TableQueryPostProcessGenericAsync <RESULT_TYPE, DynamicTableEntity>(cmd.ResponseStream, resolver.Invoke, resp, requestOptions, ctx);

                if (resSeg.ContinuationToken != null)
                {
                    resSeg.ContinuationToken.TargetLocation = cmd.CurrentResult.TargetLocation;
                }

                return(new TableQuerySegment <RESULT_TYPE>(resSeg));
            };

            return(queryCmd);
        }
        public async Task WriteToMultiBufferMemoryStreamTestAsync()
        {
            OperationContext          tempOperationContext = new OperationContext();
            RESTCommand <NullType>    cmd = new RESTCommand <NullType>(TestBase.StorageCredentials, null);
            ExecutionState <NullType> tempExecutionState = new ExecutionState <NullType>(cmd, null, tempOperationContext);

            byte[]       buffer  = GetRandomBuffer(1 * 1024 * 1024);
            MemoryStream stream1 = new MemoryStream(buffer);

            MultiBufferMemoryStream stream2 = new MultiBufferMemoryStream(null /* bufferManager */);
            await stream1.WriteToAsync(stream2, null, null, false, tempExecutionState, null, CancellationToken.None);

            stream1.Seek(0, SeekOrigin.Begin);
            stream2.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream1, stream2);

            MultiBufferMemoryStream stream3 = new MultiBufferMemoryStream(null /* bufferManager */);
            await TestHelper.ExpectedExceptionAsync <TimeoutException>(
                () => stream2.FastCopyToAsync(stream3, DateTime.Now.AddMinutes(-1)),
                "Past expiration time should immediately fail");

            stream2.Seek(0, SeekOrigin.Begin);
            stream3.Seek(0, SeekOrigin.Begin);
            await stream2.FastCopyToAsync(stream3, DateTime.Now.AddHours(1));

            stream2.Seek(0, SeekOrigin.Begin);
            stream3.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream2, stream3);

            MultiBufferMemoryStream stream4 = new MultiBufferMemoryStream(null /* bufferManager */, 12345);
            await stream3.FastCopyToAsync(stream4, null);

            stream3.Seek(0, SeekOrigin.Begin);
            stream4.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream3, stream4);

            MemoryStream stream5 = new MemoryStream();
            await stream4.WriteToAsync(stream5, null, null, false, tempExecutionState, null, CancellationToken.None);

            stream4.Seek(0, SeekOrigin.Begin);
            stream5.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream4, stream5);

            TestHelper.AssertStreamsAreEqual(stream1, stream5);
        }
예제 #16
0
        private static RESTCommand <TableResult> DeleteImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions)
        {
            RESTCommand <TableResult> deleteCmd = new RESTCommand <TableResult>(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName));

            deleteCmd.ApplyRequestOptions(requestOptions);

            TableResult result = new TableResult()
            {
                Result = operation.Entity
            };

            deleteCmd.RetrieveResponseStream = false;
            deleteCmd.SignRequest            = client.AuthenticationHandler.SignRequest;
            deleteCmd.BuildRequestDelegate   = (uri, builder, timeout, ctx) => TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, ctx).Item1;
            deleteCmd.PreProcessResponse     = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd);

            return(deleteCmd);
        }
예제 #17
0
        private RESTCommand <ServiceProperties> GetServicePropertiesImpl(QueueRequestOptions requestOptions)
        {
            RESTCommand <ServiceProperties> retCmd = new RESTCommand <ServiceProperties>(this.Credentials, this.StorageUri);

            retCmd.CommandLocationMode    = CommandLocationMode.PrimaryOrSecondary;
            retCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => QueueHttpRequestMessageFactory.GetServiceProperties(uri, serverTimeout, ctx, this.GetCanonicalizer(), this.Credentials);
            retCmd.RetrieveResponseStream = true;
            retCmd.PreProcessResponse     =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            retCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                return(Task.FromResult(QueueHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream)));
            };

            requestOptions.ApplyToStorageCommand(retCmd);
            return(retCmd);
        }
        private static RESTCommand <TableResult> ReplaceImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions)
        {
            RESTCommand <TableResult> replaceCmd = new RESTCommand <TableResult>(client.Credentials, operation.GenerateRequestURI(client.StorageUri, tableName));

            requestOptions.ApplyToStorageCommand(replaceCmd);

            TableResult result = new TableResult()
            {
                Result = operation.Entity
            };

            replaceCmd.RetrieveResponseStream = false;
            replaceCmd.ParseError             = StorageExtendedErrorInformation.ReadFromStreamUsingODataLib;
            replaceCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, builder, serverTimeout, operation, client, cnt, ctx, requestOptions.PayloadFormat.Value, client.GetCanonicalizer(), client.Credentials);
            replaceCmd.PreProcessResponse     = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx);

            return(replaceCmd);
        }
예제 #19
0
        private static RESTCommand <IList <TableResult> > BatchImpl(TableBatchOperation batch, CloudTableClient client, string tableName, TableRequestOptions requestOptions)
        {
            RESTCommand <IList <TableResult> > batchCmd = new RESTCommand <IList <TableResult> >(client.Credentials, client.StorageUri);

            requestOptions.ApplyToStorageCommand(batchCmd);

            List <TableResult> results = new List <TableResult>();

            batchCmd.CommandLocationMode    = batch.ContainsWrites ? CommandLocationMode.PrimaryOnly : CommandLocationMode.PrimaryOrSecondary;
            batchCmd.RetrieveResponseStream = true;
            batchCmd.ParseError             = StorageExtendedErrorInformation.ReadFromStreamUsingODataLib;
            batchCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableBatchOperation(cmd, uri, builder, serverTimeout, tableName, batch, client, cnt, ctx, requestOptions.PayloadFormat.Value, client.GetCanonicalizer(), client.Credentials);
            batchCmd.PreProcessResponse     = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp.StatusCode, results, cmd, ex);
            batchCmd.PostProcessResponse    = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableBatchOperationPostProcess(results, batch, cmd, resp, ctx, requestOptions, client.AccountName);
            batchCmd.RecoveryAction         = (cmd, ex, ctx) => results.Clear();

            return(batchCmd);
        }
예제 #20
0
        private RESTCommand <ServiceStats> GetServiceStatsImpl(TableRequestOptions requestOptions)
        {
            if (RetryPolicies.LocationMode.PrimaryOnly == requestOptions.LocationMode)
            {
                throw new InvalidOperationException(SR.GetServiceStatsInvalidOperation);
            }

            RESTCommand <ServiceStats> retCmd = new RESTCommand <ServiceStats>(this.Credentials, this.StorageUri);

            requestOptions.ApplyToStorageCommand(retCmd);
            retCmd.CommandLocationMode    = CommandLocationMode.PrimaryOrSecondary;
            retCmd.BuildRequestDelegate   = TableHttpWebRequestFactory.GetServiceStats;
            retCmd.SignRequest            = this.AuthenticationHandler.SignRequest;
            retCmd.RetrieveResponseStream = true;
            retCmd.PreProcessResponse     = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            retCmd.PostProcessResponse    = (cmd, resp, ctx) => TableHttpWebResponseParsers.ReadServiceStats(cmd.ResponseStream);
            return(retCmd);
        }
예제 #21
0
        /// <summary>
        /// Gets the close handles implementation.
        /// </summary>
        /// <param name="token">Continuation token for closing many files.</param>
        /// <param name="handleId">Id of the handle, "*" if all handles on the file.</param>
        /// <param name="recursive">Whether to recurse through this directory's files and subfolders.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the file. If <c>null</c>, no condition is used.</param>
        /// <param name="options">An <see cref="FileRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> for closing the handles.</returns>
        private RESTCommand <CloseFileHandleResultSegment> CloseHandleImpl(FileContinuationToken token, string handleId, bool?recursive, AccessCondition accessCondition, FileRequestOptions options)
        {
            RESTCommand <CloseFileHandleResultSegment> putCmd = new RESTCommand <CloseFileHandleResultSegment>(this.ServiceClient.Credentials, this.StorageUri, this.ServiceClient.HttpClient);

            options.ApplyToStorageCommand(putCmd);

            putCmd.CommandLocationMode    = CommandLocationMode.PrimaryOrSecondary;
            putCmd.RetrieveResponseStream = true;
            putCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) =>
            {
                StorageRequestMessage msg = FileHttpRequestMessageFactory.CloseHandle(uri, serverTimeout, handleId, recursive, token, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
                FileHttpRequestMessageFactory.AddMetadata(msg, this.Metadata);
                return(msg);
            };
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                CloseFileHandleResultSegment res = HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
                int handlesClosed;

                if (!int.TryParse(resp.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.NumHandlesClosed), out handlesClosed))
                {
                    handlesClosed = -1;
                }

                FileContinuationToken continuation = null;
                string marker;

                if ((marker = resp.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.Marker)) != "")
                {
                    continuation = new FileContinuationToken()
                    {
                        NextMarker = marker
                    };
                }

                return(new CloseFileHandleResultSegment()
                {
                    NumHandlesClosed = handlesClosed,
                    ContinuationToken = continuation
                });
            };

            return(putCmd);
        }
예제 #22
0
        private static RESTCommand <TableQuerySegment <RESULT_TYPE> > QueryImpl <T, RESULT_TYPE>(TableQuery <T> query, TableContinuationToken token, CloudTableClient client, CloudTable table, EntityResolver <RESULT_TYPE> resolver, TableRequestOptions requestOptions)
        {
            requestOptions.AssertPolicyIfRequired();

            // If encryption policy is set, then add the encryption metadata column to Select columns in order to be able to decrypt properties.
            if (requestOptions.EncryptionPolicy != null && query.SelectColumns != null && query.SelectColumns.Count() > 0)
            {
                query.SelectColumns.Add(Constants.EncryptionConstants.TableEncryptionKeyDetails);
                query.SelectColumns.Add(Constants.EncryptionConstants.TableEncryptionPropertyDetails);
            }

            UriQueryBuilder builder = query.GenerateQueryBuilder(requestOptions.ProjectSystemProperties);

            if (token != null)
            {
                token.ApplyToUriQueryBuilder(builder);
            }

            StorageUri tempUri = NavigationHelper.AppendPathToUri(client.StorageUri, table.Name);
            RESTCommand <TableQuerySegment <RESULT_TYPE> > queryCmd = new RESTCommand <TableQuerySegment <RESULT_TYPE> >(client.Credentials, tempUri);

            requestOptions.ApplyToStorageCommand(queryCmd);

            queryCmd.CommandLocationMode    = CommonUtility.GetListingLocationMode(token);
            queryCmd.RetrieveResponseStream = true;
            queryCmd.SignRequest            = client.AuthenticationHandler.SignRequest;
            queryCmd.Builder              = builder;
            queryCmd.ParseError           = ODataErrorHelper.ReadFromStreamUsingODataLib;
            queryCmd.BuildRequestDelegate = (uri, queryBuilder, timeout, useVersionHeader, ctx) => TableOperationHttpWebRequestFactory.BuildRequestForTableQuery(uri, queryBuilder, timeout, useVersionHeader, ctx, requestOptions.PayloadFormat.Value);

            queryCmd.PreProcessResponse  = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp != null ? resp.StatusCode : HttpStatusCode.Unused, null /* retVal */, cmd, ex);
            queryCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                ResultSegment <RESULT_TYPE> resSeg = TableOperationHttpResponseParsers.TableQueryPostProcessGeneric <RESULT_TYPE, T>(cmd.ResponseStream, resolver.Invoke, resp, requestOptions, ctx, client.AccountName);
                if (resSeg.ContinuationToken != null)
                {
                    resSeg.ContinuationToken.TargetLocation = cmd.CurrentResult.TargetLocation;
                }

                return(new TableQuerySegment <RESULT_TYPE>(resSeg));
            };

            return(queryCmd);
        }
        private static RESTCommand <TableResult> ReplaceImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions)
        {
            RESTCommand <TableResult> replaceCmd = new RESTCommand <TableResult>(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName));

            replaceCmd.ApplyRequestOptions(requestOptions);

            TableResult result = new TableResult()
            {
                Result = operation.Entity
            };

            replaceCmd.RetrieveResponseStream = false;
            replaceCmd.Handler            = client.AuthenticationHandler;
            replaceCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            replaceCmd.BuildRequest       = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, cmd.ServerTimeoutInSeconds, operation, client, ctx);
            replaceCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx);

            return(replaceCmd);
        }
        internal static HttpRequestMessage BuildRequestForTableOperation <T>(RESTCommand <T> cmd, int?timeout, TableOperation operation, CloudTableClient client, OperationContext ctx)
        {
            HttpRequestMessage msg = BuildRequestCore(cmd.Uri, operation.HttpMethod, timeout, ctx);

            if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge)
            {
                // post tunnelling
                msg.Headers.Add("X-HTTP-Method", "MERGE");
            }

            // etag
            if (operation.OperationType == TableOperationType.Delete ||
                operation.OperationType == TableOperationType.Replace ||
                operation.OperationType == TableOperationType.Merge)
            {
                msg.Headers.Add("If-Match", operation.Entity.ETag);
            }

            if (operation.OperationType == TableOperationType.Insert ||
                operation.OperationType == TableOperationType.Merge ||
                operation.OperationType == TableOperationType.InsertOrMerge ||
                operation.OperationType == TableOperationType.InsertOrReplace ||
                operation.OperationType == TableOperationType.Replace)
            {
                // create the writer, indent for readability of the examples.
                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    CheckCharacters = false,          // sets this flag on the XmlWriter for ATOM
                    Version         = ODataVersion.V2 // set the Odata version to use when writing the entry
                };

                HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, (int)Constants.KB);
                cmd.StreamToDispose = adapterMsg.GetStream();

                ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);
                ODataWriter        writer      = odataWriter.CreateODataEntryWriter();
                WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer);

                return(adapterMsg.GetPopulatedMessage());
            }

            return(msg);
        }
예제 #25
0
        private static RESTCommand <TableResult> MergeImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions)
        {
            RESTCommand <TableResult> mergeCmd = new RESTCommand <TableResult>(client.Credentials, operation.GenerateRequestURI(client.StorageUri, tableName));

            requestOptions.ApplyToStorageCommand(mergeCmd);

            TableResult result = new TableResult()
            {
                Result = operation.Entity
            };

            mergeCmd.RetrieveResponseStream = false;
            mergeCmd.Handler            = client.AuthenticationHandler;
            mergeCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            mergeCmd.BuildRequest       = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, builder, serverTimeout, operation, client, cnt, ctx);
            mergeCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx);

            return(mergeCmd);
        }
        /// <summary>
        /// Core implementation for the ListQueues method.
        /// </summary>
        /// <param name="prefix">The queue prefix.</param>
        /// <param name="detailsIncluded">The details included.</param>
        /// <param name="currentToken">The continuation token.</param>
        /// <param name="maxResults">A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the
        /// per-operation limit of 5000. If this value is <c>null</c>, the maximum possible number of results will be returned, up to 5000.</param>
        /// <returns>A <see cref="TaskSequence"/> that lists the queues.</returns>
        private RESTCommand <ResultSegment <CloudQueue> > ListQueuesImpl(string prefix, int?maxResults, QueueListingDetails detailsIncluded, QueueRequestOptions options, QueueContinuationToken currentToken)
        {
            ListingContext listingContext = new ListingContext(prefix, maxResults)
            {
                Marker = currentToken != null ? currentToken.NextMarker : null
            };

            RESTCommand <ResultSegment <CloudQueue> > getCmd = new RESTCommand <ResultSegment <CloudQueue> >(this.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode    = CommonUtility.GetListingLocationMode(currentToken);
            getCmd.RetrieveResponseStream = true;
            getCmd.Handler             = this.AuthenticationHandler;
            getCmd.BuildClient         = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest        = (cmd, uri, builder, cnt, serverTimeout, ctx) => QueueHttpRequestMessageFactory.List(uri, serverTimeout, listingContext, detailsIncluded, cnt, ctx);
            getCmd.PreProcessResponse  = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            getCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                return(Task.Factory.StartNew(() =>
                {
                    ListQueuesResponse listQueuesResponse = new ListQueuesResponse(cmd.ResponseStream);

                    List <CloudQueue> queuesList = listQueuesResponse.Queues.Select(item => new CloudQueue(item.Metadata, item.Name, this)).ToList();

                    QueueContinuationToken continuationToken = null;
                    if (listQueuesResponse.NextMarker != null)
                    {
                        continuationToken = new QueueContinuationToken()
                        {
                            NextMarker = listQueuesResponse.NextMarker,
                            TargetLocation = cmd.CurrentResult.TargetLocation,
                        };
                    }

                    return new ResultSegment <CloudQueue>(queuesList)
                    {
                        ContinuationToken = continuationToken,
                    };
                }));
            };

            return(getCmd);
        }
예제 #27
0
        private static RESTCommand <TableResult> DeleteImpl(TableOperation operation, CloudTableClient client, CloudTable table, TableRequestOptions requestOptions)
        {
            RESTCommand <TableResult> deleteCmd = new RESTCommand <TableResult>(client.Credentials, operation.GenerateRequestURI(client.StorageUri, table.Name));

            requestOptions.ApplyToStorageCommand(deleteCmd);

            TableResult result = new TableResult()
            {
                Result = operation.Entity
            };

            deleteCmd.RetrieveResponseStream = false;
            deleteCmd.SignRequest            = client.AuthenticationHandler.SignRequest;
            deleteCmd.ParseError             = StorageExtendedErrorInformation.ReadFromStreamUsingODataLib;
            deleteCmd.BuildRequestDelegate   = (uri, builder, timeout, useVersionHeader, ctx) => TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, useVersionHeader, ctx, requestOptions, client.AccountName).Item1;
            deleteCmd.PreProcessResponse     = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex);

            return(deleteCmd);
        }
예제 #28
0
        /// <summary>
        /// Implementation for the Exists method.
        /// </summary>
        /// <param name="options">An object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that checks existence.</returns>
        private RESTCommand <bool> ExistsImpl(FileRequestOptions options)
        {
            RESTCommand <bool> getCmd = new RESTCommand <bool>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.BuildRequest       = (cmd, uri, builder, cnt, serverTimeout, ctx) => DirectoryHttpRequestMessageFactory.GetProperties(uri, serverTimeout, null, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                if (resp.StatusCode == HttpStatusCode.NotFound)
                {
                    return(false);
                }

                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex);
                this.Properties = DirectoryHttpResponseParsers.GetProperties(resp);
                return(true);
            };

            return(getCmd);
        }
예제 #29
0
        /// <summary>
        /// Implementation for the SetMetadata method.
        /// </summary>
        /// <param name="accessCondition">An object that represents the access conditions for the directory. If null, no condition is used.</param>
        /// <param name="options">An object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that sets the metadata.</returns>
        private RESTCommand <NullType> SetMetadataImpl(AccessCondition accessCondition, FileRequestOptions options)
        {
            RESTCommand <NullType> putCmd = new RESTCommand <NullType>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) =>
            {
                StorageRequestMessage msg = DirectoryHttpRequestMessageFactory.SetMetadata(uri, serverTimeout, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
                DirectoryHttpRequestMessageFactory.AddMetadata(msg, this.Metadata);
                return(msg);
            };
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                this.UpdateETagAndLastModified(resp);
                return(NullType.Value);
            };

            return(putCmd);
        }
        public static HttpClient BuildHttpClient <T>(RESTCommand <T> cmd, HttpMessageHandler handler, OperationContext operationContext)
        {
            HttpClient client = handler != null ? new HttpClient(handler, false) : new HttpClient();

            client.DefaultRequestHeaders.ExpectContinue = false;
            client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(Constants.HeaderConstants.UserAgentProductName, Constants.HeaderConstants.UserAgentProductVersion));
            client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(Constants.HeaderConstants.UserAgentComment));

            client.DefaultRequestHeaders.TryAddWithoutValidation(Constants.HeaderConstants.StorageVersionHeader, Constants.HeaderConstants.TargetStorageVersion);

            if (operationContext != null && operationContext.UserHeaders != null)
            {
                foreach (string key in operationContext.UserHeaders.Keys)
                {
                    client.DefaultRequestHeaders.Add(key, operationContext.UserHeaders[key]);
                }
            }

            return(client);
        }
        internal IAsyncOperation <IList <TableResult> > ExecuteAsync(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext)
        {
            TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client);

            operationContext = operationContext ?? new OperationContext();

            CommonUtility.AssertNotNullOrEmpty("tableName", tableName);
            if (this.operations.Count == 0)
            {
                throw new InvalidOperationException(SR.EmptyBatchOperation);
            }

            RESTCommand <IList <TableResult> > cmdToExecute = BatchImpl(this, client, tableName, modifiedOptions);

            return(AsyncInfo.Run(async(cancellationToken) => await Executor.ExecuteAsync(
                                     cmdToExecute,
                                     modifiedOptions.RetryPolicy,
                                     operationContext,
                                     cancellationToken)));
        }
예제 #32
0
        private RESTCommand <ServiceProperties> GetServicePropertiesImpl(QueueRequestOptions requestOptions)
        {
            RESTCommand <ServiceProperties> retCmd = new RESTCommand <ServiceProperties>(this.Credentials, this.BaseUri);

            retCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.GetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx);

            retCmd.RetrieveResponseStream = true;
            retCmd.Handler            = this.AuthenticationHandler;
            retCmd.BuildClient        = HttpClientFactory.BuildHttpClient;
            retCmd.PreProcessResponse =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            retCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                return(Task.Factory.StartNew(() => QueueHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream)));
            };

            retCmd.ApplyRequestOptions(requestOptions);
            return(retCmd);
        }
예제 #33
0
        private static RESTCommand <TableResult> RetrieveImpl(TableOperation operation, CloudTableClient client, CloudTable table, TableRequestOptions requestOptions)
        {
            requestOptions.AssertPolicyIfRequired();

            RESTCommand <TableResult> retrieveCmd = new RESTCommand <TableResult>(client.Credentials, operation.GenerateRequestURI(client.StorageUri, table.Name));

            requestOptions.ApplyToStorageCommand(retrieveCmd);

            TableResult result = new TableResult();

            if (operation.SelectColumns != null && operation.SelectColumns.Count > 0)
            {
                // If encryption policy is set, then add the encryption metadata column to Select columns in order to be able to decrypt properties.
                if (requestOptions.EncryptionPolicy != null)
                {
                    operation.SelectColumns.Add(Constants.EncryptionConstants.TableEncryptionKeyDetails);
                    operation.SelectColumns.Add(Constants.EncryptionConstants.TableEncryptionPropertyDetails);
                }

                retrieveCmd.Builder = operation.GenerateQueryBuilder(requestOptions.ProjectSystemProperties);
            }

            retrieveCmd.CommandLocationMode    = operation.isPrimaryOnlyRetrieve ? CommandLocationMode.PrimaryOnly : CommandLocationMode.PrimaryOrSecondary;
            retrieveCmd.RetrieveResponseStream = true;
            retrieveCmd.SignRequest            = client.AuthenticationHandler.SignRequest;
            retrieveCmd.ParseError             = StorageExtendedErrorInformation.ReadFromStreamUsingODataLib;
            retrieveCmd.BuildRequestDelegate   = (uri, builder, timeout, useVersionHeader, ctx) => TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, useVersionHeader, ctx, requestOptions, client.AccountName).Item1;
            retrieveCmd.PreProcessResponse     = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex);
            retrieveCmd.PostProcessResponse    = (cmd, resp, ctx) =>
            {
                if (resp.StatusCode == HttpStatusCode.NotFound)
                {
                    return(result);
                }

                result = TableOperationHttpResponseParsers.TableOperationPostProcess(result, operation, cmd, resp, ctx, requestOptions, client.AccountName);
                return(result);
            };

            return(retrieveCmd);
        }
        public async Task WriteToMultiBufferMemoryStreamTestAsync()
        {
            OperationContext tempOperationContext = new OperationContext();
            RESTCommand<NullType> cmd = new RESTCommand<NullType>(TestBase.StorageCredentials, null);
            ExecutionState<NullType> tempExecutionState = new ExecutionState<NullType>(cmd, null, tempOperationContext);

            byte[] buffer = GetRandomBuffer(1 * 1024 * 1024);
            MemoryStream stream1 = new MemoryStream(buffer);

            MultiBufferMemoryStream stream2 = new MultiBufferMemoryStream(null /* bufferManager */);
            await stream1.WriteToAsync(stream2, null, null, false, tempExecutionState, null, CancellationToken.None);
            stream1.Seek(0, SeekOrigin.Begin);
            stream2.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream1, stream2);

            MultiBufferMemoryStream stream3 = new MultiBufferMemoryStream(null /* bufferManager */);
            await TestHelper.ExpectedExceptionAsync<TimeoutException>(
                () => stream2.FastCopyToAsync(stream3, DateTime.Now.AddMinutes(-1)),
                "Past expiration time should immediately fail");
            stream2.Seek(0, SeekOrigin.Begin);
            stream3.Seek(0, SeekOrigin.Begin);
            await stream2.FastCopyToAsync(stream3, DateTime.Now.AddHours(1));
            stream2.Seek(0, SeekOrigin.Begin);
            stream3.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream2, stream3);

            MultiBufferMemoryStream stream4 = new MultiBufferMemoryStream(null /* bufferManager */, 12345);
            await stream3.FastCopyToAsync(stream4, null);
            stream3.Seek(0, SeekOrigin.Begin);
            stream4.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream3, stream4);

            MemoryStream stream5 = new MemoryStream();
            await stream4.WriteToAsync(stream5, null, null, false, tempExecutionState, null, CancellationToken.None);
            stream4.Seek(0, SeekOrigin.Begin);
            stream5.Seek(0, SeekOrigin.Begin);
            TestHelper.AssertStreamsAreEqual(stream4, stream5);

            TestHelper.AssertStreamsAreEqual(stream1, stream5);
        }
        /// <summary>
        /// Gets the download block list.
        /// </summary>
        /// <param name="typesOfBlocks">The types of blocks.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that gets the download block list.</returns>
        internal RESTCommand<IEnumerable<ListBlockItem>> GetBlockListImpl(BlockListingFilter typesOfBlocks, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<IEnumerable<ListBlockItem>> getCmd = new RESTCommand<IEnumerable<ListBlockItem>>(this.ServiceClient.Credentials, this.Uri);

            getCmd.ApplyRequestOptions(options);
            getCmd.RetrieveResponseStream = true;
            getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetBlockList(uri, serverTimeout, this.SnapshotTime, typesOfBlocks, accessCondition, ctx);
            getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            getCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp);
                GetBlockListResponse responseParser = new GetBlockListResponse(cmd.ResponseStream);
                IEnumerable<ListBlockItem> blocks = new List<ListBlockItem>(responseParser.Blocks);
                return blocks;
            };

            return getCmd;
        }
        /// <summary>
        /// Uploads the block list.
        /// </summary>
        /// <param name="blocks">The blocks to upload.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that uploads the block list.</returns>
        internal RESTCommand<NullType> PutBlockListImpl(IEnumerable<PutBlockListItem> blocks, AccessCondition accessCondition, BlobRequestOptions options)
        {
            MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager);
            BlobRequest.WriteBlockListBody(blocks, memoryStream);
            memoryStream.Seek(0, SeekOrigin.Begin);
#if !WINDOWS_PHONE
            string contentMD5 = memoryStream.ComputeMD5Hash();
            memoryStream.Seek(0, SeekOrigin.Begin);
#endif

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutBlockList(uri, serverTimeout, this.Properties, accessCondition, ctx);
            putCmd.SetHeaders = (r, ctx) =>
            {
#if !WINDOWS_PHONE
                r.Headers[HttpRequestHeader.ContentMd5] = contentMD5;
#endif
                BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata);
            };
            putCmd.SendStream = memoryStream;
            putCmd.RecoveryAction = RecoveryActions.RewindStream;
            putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex);
                CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp);
                this.Properties.Length = -1;
                return NullType.Value;
            };

            return putCmd;
        }
        /// <summary>
        /// Uploads the block.
        /// </summary>
        /// <param name="source">The source stream.</param>
        /// <param name="blockId">The block ID.</param>
        /// <param name="contentMD5">The content MD5.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that uploads the block.</returns>
        internal RESTCommand<NullType> PutBlockImpl(Stream source, string blockId, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options)
        {
            long offset = source.Position;

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.SendStream = source;
            putCmd.RecoveryAction = (cmd, ex, ctx) => RecoveryActions.SeekStream(cmd, offset);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutBlock(uri, serverTimeout, blockId, accessCondition, ctx);
            putCmd.SetHeaders = (r, ctx) =>
            {
                if (!string.IsNullOrEmpty(contentMD5))
                {
                    r.Headers[HttpRequestHeader.ContentMd5] = contentMD5;
                }
            };
            putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex);

            return putCmd;
        }
        /// <summary>
        /// Uploads the full blob from a seekable stream.
        /// </summary>
        /// <param name="stream">The content stream. Must be seekable.</param>
        /// <param name="length">Number of bytes to upload from the content stream starting at its current position.</param>
        /// <param name="contentMD5">The content MD5.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that gets the stream.</returns>
        private RESTCommand<NullType> PutBlobImpl(Stream stream, long? length, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options)
        {
            long offset = stream.Position;
            this.Properties.ContentMD5 = contentMD5;

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.SendStream = stream;
            putCmd.SendStreamLength = length ?? stream.Length - offset;
            putCmd.RecoveryAction = (cmd, ex, ctx) => RecoveryActions.SeekStream(cmd, offset);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Put(uri, serverTimeout, this.Properties, BlobType.BlockBlob, 0, accessCondition, ctx);
            putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata);
            putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex);
                CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp);
                this.Properties.Length = putCmd.SendStreamLength.Value;
                return NullType.Value;
            };

            return putCmd;
        }
예제 #39
0
        /// <summary>
        /// Implementation for the SetSequenceNumber method.
        /// </summary>
        /// <param name="sequenceNumberAction">A value of type <see cref="SequenceNumberAction"/>, indicating the operation to perform on the sequence number.</param>
        /// <param name="sequenceNumber">The sequence number. Set this parameter to <c>null</c> if this operation is an increment action.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that sets the metadata.</returns>
        private RESTCommand<NullType> SetSequenceNumberImpl(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.SetSequenceNumber(uri, serverTimeout, sequenceNumberAction, sequenceNumber, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                CloudBlob.UpdateETagLMTLengthAndSequenceNumber(attributes, resp, false);
                return NullType.Value;
            };

            return putCmd;
        }
예제 #40
0
        /// <summary>
        /// Implements the Create method.
        /// </summary>
        /// <param name="sizeInBytes">The size in bytes.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If null, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="TaskSequence"/> that creates the blob.</returns>
        private RESTCommand<NullType> CreateImpl(long sizeInBytes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) =>
            {
                StorageRequestMessage msg = BlobHttpRequestMessageFactory.Put(uri, serverTimeout, this.Properties, BlobType.PageBlob, sizeInBytes, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
                BlobHttpRequestMessageFactory.AddMetadata(msg, this.Metadata);
                return msg;
            };
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex);
                CloudBlob.UpdateETagLMTLengthAndSequenceNumber(this.attributes, resp, false);
                cmd.CurrentResult.IsRequestServerEncrypted = CloudBlob.ParseServerRequestEncrypted(resp);
                this.Properties.Length = sizeInBytes;
                return NullType.Value;
            };

            return putCmd;
        }
예제 #41
0
        /// <summary>
        /// Implementation method for the WritePage methods.
        /// </summary>
        /// <param name="pageData">The page data.</param>
        /// <param name="startOffset">The start offset.</param> 
        /// <param name="contentMD5">The content MD5.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that writes the pages.</returns>
        private RESTCommand<NullType> PutPageImpl(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options)
        {
            if (startOffset % Constants.PageSize != 0)
            {
                CommonUtils.ArgumentOutOfRange("startOffset", startOffset);
            }

            long offset = pageData.Position;
            long length = pageData.Length - offset;

            PageRange pageRange = new PageRange(startOffset, startOffset + length - 1);
            PageWrite pageWrite = PageWrite.Update;

            if ((1 + pageRange.EndOffset - pageRange.StartOffset) % Constants.PageSize != 0 ||
                (1 + pageRange.EndOffset - pageRange.StartOffset) == 0)
            {
                CommonUtils.ArgumentOutOfRange("pageData", pageData);
            }

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.SendStream = pageData;
            putCmd.RecoveryAction = (cmd, ex, ctx) => RecoveryActions.SeekStream(cmd, ex, ctx, offset);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutPage(uri, serverTimeout, pageRange, pageWrite, accessCondition, ctx);
            putCmd.SetHeaders = (r, ctx) =>
            {
                if (!string.IsNullOrEmpty(contentMD5))
                {
                    r.Headers.Set(HttpRequestHeader.ContentMd5, contentMD5);
                }
            };
            putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex, ctx);
                CloudBlobSharedImpl.ParseSizeAndLastModified(this.attributes, resp);
                return NullType.Value;
            };

            return putCmd;
        }
예제 #42
0
        /// <summary>
        /// Implementation method for the WritePage methods.
        /// </summary>
        /// <param name="pageData">The page data.</param>
        /// <param name="startOffset">The start offset.</param> 
        /// <param name="contentMD5">An optional hash value that will be used to set the <see cref="BlobProperties.ContentMD5"/> property
        /// on the blob. May be <c>null</c> or an empty string.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that writes the pages.</returns>
        private RESTCommand<NullType> PutPageImpl(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options)
        {
            if (startOffset % Constants.PageSize != 0)
            {
                CommonUtility.ArgumentOutOfRange("startOffset", startOffset);
            }

            long offset = pageData.Position;
            long length = pageData.Length - offset;

            PageRange pageRange = new PageRange(startOffset, startOffset + length - 1);
            PageWrite pageWrite = PageWrite.Update;

            if ((1 + pageRange.EndOffset - pageRange.StartOffset) % Constants.PageSize != 0 ||
                (1 + pageRange.EndOffset - pageRange.StartOffset) == 0)
            {
                CommonUtility.ArgumentOutOfRange("pageData", pageData);
            }

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(pageData, offset, length, contentMD5, cmd, ctx);
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.PutPage(uri, serverTimeout, pageRange, pageWrite, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex);
                CloudBlob.UpdateETagLMTLengthAndSequenceNumber(this.attributes, resp, false);
                cmd.CurrentResult.IsRequestServerEncrypted = CloudBlob.ParseServerRequestEncrypted(resp);
                return NullType.Value;
            };

            return putCmd;
        }
예제 #43
0
        /// <summary>
        /// Implementation for the GetPageRangesDiff method.
        /// </summary>
        /// <param name="previousSnapshotTime">A <see cref="DateTimeOffset"/> representing the snapshot timestamp to use as the starting point for the diff. If this CloudPageBlob represents a snapshot, the previousSnapshotTime parameter must be prior to the current snapshot timestamp.</param>
        /// <param name="offset">The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param>
        /// <param name="length">The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> for getting the page ranges.</returns>
        private RESTCommand<IEnumerable<PageDiffRange>> GetPageRangesDiffImpl(DateTimeOffset previousSnapshotTime, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<IEnumerable<PageDiffRange>> getCmd = new RESTCommand<IEnumerable<PageDiffRange>>(this.ServiceClient.Credentials, this.attributes.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
            getCmd.RetrieveResponseStream = true;
            getCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) =>
            {
                StorageRequestMessage msg = BlobHttpRequestMessageFactory.GetPageRangesDiff(uri, serverTimeout, this.SnapshotTime, previousSnapshotTime, offset, length, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
                return msg;
            };

            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            getCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                CloudBlob.UpdateETagLMTLengthAndSequenceNumber(this.attributes, resp, true);
                return Task.Factory.StartNew(() =>
                {
                    GetPageDiffRangesResponse getPageDiffRangesResponse = new GetPageDiffRangesResponse(cmd.ResponseStream);
                    IEnumerable<PageDiffRange> pageDiffRanges = new List<PageDiffRange>(getPageDiffRangesResponse.PageDiffRanges);
                    return pageDiffRanges;
                });
            };

            return getCmd;
        }
예제 #44
0
        /// <summary>
        /// Implementation for the CreateSnapshot method.
        /// </summary>
        /// <param name="metadata">A collection of name-value pairs defining the metadata of the snapshot, or <c>null</c>.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that creates the snapshot.</returns>
        /// <remarks>If the <c>metadata</c> parameter is <c>null</c> then no metadata is associated with the request.</remarks>
        private RESTCommand<CloudPageBlob> CreateSnapshotImpl(IDictionary<string, string> metadata, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<CloudPageBlob> putCmd = new RESTCommand<CloudPageBlob>(this.ServiceClient.Credentials, this.attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) =>
            {
                StorageRequestMessage msg = BlobHttpRequestMessageFactory.Snapshot(uri, serverTimeout, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
                if (metadata != null)
                {
                    BlobHttpRequestMessageFactory.AddMetadata(msg, metadata);
                }

                return msg;
            };

            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex);
                DateTimeOffset snapshotTime = NavigationHelper.ParseSnapshotTime(BlobHttpResponseParsers.GetSnapshotTime(resp));
                CloudPageBlob snapshot = new CloudPageBlob(this.Name, snapshotTime, this.Container);
                snapshot.attributes.Metadata = new Dictionary<string, string>(metadata ?? this.Metadata);
                snapshot.attributes.Properties = new BlobProperties(this.Properties);
                CloudBlob.UpdateETagLMTLengthAndSequenceNumber(snapshot.attributes, resp, false);
                return snapshot;
            };

            return putCmd;
        }
예제 #45
0
        private RESTCommand<NullType> SetServicePropertiesImpl(ServiceProperties properties, TableRequestOptions requestOptions)
        {
            MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB));
            try
            {
                properties.WriteServiceProperties(memoryStream);
            }
            catch (InvalidOperationException invalidOpException)
            {
                throw new ArgumentException(invalidOpException.Message, "properties");
            }

            RESTCommand<NullType> retCmd = new RESTCommand<NullType>(this.Credentials, this.StorageUri);
            requestOptions.ApplyToStorageCommand(retCmd);
            retCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableHttpRequestMessageFactory.SetServiceProperties(uri, serverTimeout, cnt, ctx);
            retCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx);
            retCmd.Handler = this.AuthenticationHandler;
            retCmd.BuildClient = HttpClientFactory.BuildHttpClient;
            retCmd.PreProcessResponse =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex);

            requestOptions.ApplyToStorageCommand(retCmd);
            return retCmd;
        }
예제 #46
0
        private RESTCommand<ServiceProperties> GetServicePropertiesImpl(BlobRequestOptions requestOptions)
        {
            RESTCommand<ServiceProperties> retCmd = new RESTCommand<ServiceProperties>(this.Credentials, this.BaseUri);
            retCmd.BuildRequestDelegate = BlobHttpWebRequestFactory.GetServiceProperties;
            retCmd.SignRequest = this.AuthenticationHandler.SignRequest;
            retCmd.RetrieveResponseStream = true;
            retCmd.PreProcessResponse =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(
                System.Net.HttpStatusCode.OK,
                resp,
                null /* retVal */,
                cmd,
                ex,
                ctx);

            retCmd.PostProcessResponse =
                (cmd, resp, ex, ctx) => BlobHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream);
            retCmd.ApplyRequestOptions(requestOptions);
            return retCmd;
        }
예제 #47
0
        /// <summary>
        /// Core implementation for the ListContainers method.
        /// </summary>
        /// <param name="prefix">The container prefix.</param>
        /// <param name="detailsIncluded">The details included.</param>
        /// <param name="currentToken">The continuation token.</param>
        /// <param name="maxResults">A non-negative integer value that indicates the maximum number of results to be returned 
        /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="ResultSegment{T}"/> that lists the containers.</returns>
        private RESTCommand<ResultSegment<CloudBlobContainer>> ListContainersImpl(string prefix, ContainerListingDetails detailsIncluded, BlobContinuationToken currentToken, int? maxResults, BlobRequestOptions options)
        {
            ListingContext listingContext = new ListingContext(prefix, maxResults)
            {
                Marker = currentToken != null ? currentToken.NextMarker : null
            };

            RESTCommand<ResultSegment<CloudBlobContainer>> getCmd = new RESTCommand<ResultSegment<CloudBlobContainer>>(this.Credentials, this.BaseUri);

            getCmd.ApplyRequestOptions(options);
            getCmd.RetrieveResponseStream = true;
            getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.List(uri, serverTimeout, listingContext, detailsIncluded, ctx);
            getCmd.SignRequest = this.AuthenticationHandler.SignRequest;
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx);
            getCmd.PostProcessResponse = (cmd, resp, ex, ctx) =>
            {
                ListContainersResponse listContainersResponse = new ListContainersResponse(cmd.ResponseStream);
                List<CloudBlobContainer> containersList = new List<CloudBlobContainer>(
                    listContainersResponse.Containers.Select(item => new CloudBlobContainer(item.Properties, item.Metadata, item.Name, this)));
                BlobContinuationToken continuationToken = null;
                if (listContainersResponse.NextMarker != null)
                {
                    continuationToken = new BlobContinuationToken()
                    {
                        NextMarker = listContainersResponse.NextMarker,
                    };
                }

                return new ResultSegment<CloudBlobContainer>(containersList)
                {
                    ContinuationToken = continuationToken,
                };
            };

            return getCmd;
        }
예제 #48
0
        /// <summary>
        /// Implementation method for the ClearPage methods.
        /// </summary>
        /// <param name="startOffset">The start offset. Must be multiples of 512.</param>
        /// <param name="length">Length of the data range to be cleared. Must be multiples of 512.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that writes the pages.</returns>
        private RESTCommand<NullType> ClearPageImpl(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options)
        {
            CommonUtility.AssertNotNull("options", options);

            if (startOffset < 0 || startOffset % Constants.PageSize != 0)
            {
                CommonUtility.ArgumentOutOfRange("startOffset", startOffset);
            }

            if (length <= 0 || length % Constants.PageSize != 0)
            {
                CommonUtility.ArgumentOutOfRange("length", length);
            }

            PageRange pageRange = new PageRange(startOffset, startOffset + length - 1);
            PageWrite pageWrite = PageWrite.Clear;

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.attributes.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.PutPage(uri, serverTimeout, pageRange, pageWrite, accessCondition, cnt, ctx, this.ServiceClient.GetCanonicalizer(), this.ServiceClient.Credentials);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex);
                CloudBlob.UpdateETagLMTLengthAndSequenceNumber(this.attributes, resp, false);
                return NullType.Value;
            };

            return putCmd;
        }
예제 #49
0
        /// <summary>
        /// Implementation for the Resize method.
        /// </summary>
        /// <param name="sizeInBytes">The size in bytes.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">An <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that sets the metadata.</returns>
        private RESTCommand<NullType> ResizeImpl(long sizeInBytes, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Resize(uri, serverTimeout, sizeInBytes, accessCondition, ctx);
            putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex, ctx);
                CloudBlobSharedImpl.ParseSizeAndLastModified(attributes, resp);
                this.Properties.Length = sizeInBytes;
                return NullType.Value;
            };

            return putCmd;
        }
예제 #50
0
        /// <summary>
        /// Implementation for the CreateSnapshot method.
        /// </summary>
        /// <param name="metadata">A collection of name-value pairs defining the metadata of the snapshot, or null.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that creates the snapshot.</returns>
        /// <remarks>If the <c>metadata</c> parameter is <c>null</c> then no metadata is associated with the request.</remarks>
        private RESTCommand<CloudPageBlob> CreateSnapshotImpl(IDictionary<string, string> metadata, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<CloudPageBlob> putCmd = new RESTCommand<CloudPageBlob>(this.ServiceClient.Credentials, this.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Snapshot(uri, serverTimeout, accessCondition, ctx);
            putCmd.SetHeaders = (r, ctx) =>
            {
                if (metadata != null)
                {
                    BlobHttpWebRequestFactory.AddMetadata(r, metadata);
                }
            };
            putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex, ctx);
                DateTimeOffset snapshotTime = NavigationHelper.ParseSnapshotTime(BlobHttpResponseParsers.GetSnapshotTime(resp));
                CloudPageBlob snapshot = new CloudPageBlob(this.Name, snapshotTime, this.Container);
                snapshot.attributes.Metadata = new Dictionary<string, string>(metadata ?? this.Metadata);
                snapshot.attributes.Properties = new BlobProperties(this.Properties);
                CloudBlobSharedImpl.ParseSizeAndLastModified(snapshot.attributes, resp);
                return snapshot;
            };

            return putCmd;
        }
예제 #51
0
        /// <summary>
        /// Gets the page ranges impl.
        /// </summary>
        /// <param name="offset">The start offset. Must be multiples of 512.</param>
        /// <param name="length">Length of the data range to be cleared. Must be multiples of 512.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> for getting the page ranges.</returns>
        private RESTCommand<IEnumerable<PageRange>> GetPageRangesImpl(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<IEnumerable<PageRange>> getCmd = new RESTCommand<IEnumerable<PageRange>>(this.ServiceClient.Credentials, this.Uri);

            getCmd.ApplyRequestOptions(options);
            getCmd.RetrieveResponseStream = true;
            getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetPageRanges(uri, serverTimeout, this.SnapshotTime, offset, length, accessCondition, ctx);
            getCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata);
            getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx);
            getCmd.PostProcessResponse = (cmd, resp, ex, ctx) =>
            {
                CloudBlobSharedImpl.ParseSizeAndLastModified(this.attributes, resp);
                GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(cmd.ResponseStream);
                IEnumerable<PageRange> pageRanges = new List<PageRange>(getPageRangesResponse.PageRanges);
                return pageRanges;
            };

            return getCmd;
        }
        /// <summary>
        /// Implementation for the FetchAttributes method.
        /// </summary>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the container. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        private RESTCommand<NullType> FetchAttributesImpl(AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<NullType> getCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
            getCmd.Handler = this.ServiceClient.AuthenticationHandler;
            getCmd.BuildClient = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => ContainerHttpRequestMessageFactory.GetProperties(uri, serverTimeout, accessCondition, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                this.Properties = ContainerHttpResponseParsers.GetProperties(resp);
                this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp);
                return NullType.Value;
            };

            return getCmd;
        }
예제 #53
0
        /// <summary>
        /// Implementation method for the ClearPage methods.
        /// </summary>
        /// <param name="startOffset">The start offset. Must be multiples of 512.</param>
        /// <param name="length">Length of the data range to be cleared. Must be multiples of 512.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that writes the pages.</returns>
        private RESTCommand<NullType> ClearPageImpl(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options)
        {
            CommonUtils.AssertNotNull("options", options);

            if (startOffset < 0 || startOffset % Constants.PageSize != 0)
            {
                CommonUtils.ArgumentOutOfRange("startOffset", startOffset);
            }

            if (length <= 0 || length % Constants.PageSize != 0)
            {
                CommonUtils.ArgumentOutOfRange("length", length);
            }

            PageRange pageRange = new PageRange(startOffset, startOffset + length - 1);
            PageWrite pageWrite = PageWrite.Clear;

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.Uri);

            putCmd.ApplyRequestOptions(options);
            putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutPage(uri, serverTimeout, pageRange, pageWrite, accessCondition, ctx);
            putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest;
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex, ctx);
                CloudBlobSharedImpl.ParseSizeAndLastModified(this.attributes, resp);
                return NullType.Value;
            };

            return putCmd;
        }
        /// <summary>
        /// Implementation for the Exists method.
        /// </summary>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <param name="primaryOnly">If <c>true</c>, the command will be executed against the primary location.</param>
        /// <returns>A <see cref="RESTCommand"/> that checks existence.</returns>
        private RESTCommand<bool> ExistsImpl(BlobRequestOptions options, bool primaryOnly)
        {
            RESTCommand<bool> getCmd = new RESTCommand<bool>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = primaryOnly ? CommandLocationMode.PrimaryOnly : CommandLocationMode.PrimaryOrSecondary;
            getCmd.Handler = this.ServiceClient.AuthenticationHandler;
            getCmd.BuildClient = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => ContainerHttpRequestMessageFactory.GetProperties(uri, serverTimeout, null /* accessCondition */, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                if (resp.StatusCode == HttpStatusCode.NotFound)
                {
                    return false;
                }

                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex);
                this.Properties = ContainerHttpResponseParsers.GetProperties(resp);
                this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp);
                return true;
            };

            return getCmd;
        }
예제 #55
0
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="blobUri">The URI of the blob.</param>
        /// <param name="accessCondition">An object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies any additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand{T}"/> that fetches the attributes.</returns>
        private RESTCommand<ICloudBlob> GetBlobReferenceImpl(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options)
        {
            // If the blob Uri contains SAS credentials, we need to use those
            // credentials instead of this service client's stored credentials.
            StorageCredentials parsedCredentials;
            DateTimeOffset? parsedSnapshot;
            blobUri = NavigationHelper.ParseBlobQueryAndVerify(blobUri, out parsedCredentials, out parsedSnapshot);
            CloudBlobClient client = parsedCredentials != null ? new CloudBlobClient(this.BaseUri, parsedCredentials) : this;

            RESTCommand<ICloudBlob> getCmd = new RESTCommand<ICloudBlob>(client.Credentials, blobUri);

            getCmd.ApplyRequestOptions(options);
            getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, null /* snapshot */, accessCondition, ctx);
            getCmd.SignRequest = client.AuthenticationHandler.SignRequest;
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex, ctx);
                
                BlobAttributes attributes = new BlobAttributes()
                {
                    Uri = blobUri,
                    SnapshotTime = parsedSnapshot,
                };

                CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false);

                switch (attributes.Properties.BlobType)
                {
                    case BlobType.BlockBlob:
                        return new CloudBlockBlob(attributes, client);

                    case BlobType.PageBlob:
                        return new CloudPageBlob(attributes, client);

                    default:
                        throw new InvalidOperationException();
                }
            };

            return getCmd;
        }
        /// <summary>
        /// Implementation for the SetMetadata method.
        /// </summary>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the container. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that sets the metadata.</returns>
        private RESTCommand<NullType> SetMetadataImpl(AccessCondition accessCondition, BlobRequestOptions options)
        {
            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.Handler = this.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) =>
            {
                HttpRequestMessage msg = ContainerHttpRequestMessageFactory.SetMetadata(uri, serverTimeout, accessCondition, cnt, ctx);
                ContainerHttpRequestMessageFactory.AddMetadata(msg, this.Metadata);
                return msg;
            };
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                this.UpdateETagAndLastModified(resp);
                return NullType.Value;
            };

            return putCmd;
        }
예제 #57
0
        private RESTCommand<NullType> SetServicePropertiesImpl(ServiceProperties properties, BlobRequestOptions requestOptions)
        {
            MemoryStream str = new MemoryStream();
            try
            {
                properties.WriteServiceProperties(str);
            }
            catch (InvalidOperationException invalidOpException)
            {
                throw new ArgumentException(invalidOpException.Message, "properties");
            }

            str.Seek(0, SeekOrigin.Begin);

            RESTCommand<NullType> retCmd = new RESTCommand<NullType>(this.Credentials, this.BaseUri);
            retCmd.SendStream = str;
            retCmd.BuildRequestDelegate = BlobHttpWebRequestFactory.SetServiceProperties;
            retCmd.RecoveryAction = RecoveryActions.RewindStream;
            retCmd.SignRequest = this.AuthenticationHandler.SignRequest;
            retCmd.PreProcessResponse =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex, ctx);
            retCmd.ApplyRequestOptions(requestOptions);
            return retCmd;
        }
        /// <summary>
        /// Implementation for the SetPermissions method.
        /// </summary>
        /// <param name="acl">The permissions to set.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the container. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that sets the permissions.</returns>
        private RESTCommand<NullType> SetPermissionsImpl(BlobContainerPermissions acl, AccessCondition accessCondition, BlobRequestOptions options)
        {
            MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB));
            BlobRequest.WriteSharedAccessIdentifiers(acl.SharedAccessPolicies, memoryStream);

            RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(putCmd);
            putCmd.Handler = this.ServiceClient.AuthenticationHandler;
            putCmd.BuildClient = HttpClientFactory.BuildHttpClient;
            putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => ContainerHttpRequestMessageFactory.SetAcl(uri, serverTimeout, acl.PublicAccess, accessCondition, cnt, ctx);
            putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx);
            putCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex);
                this.UpdateETagAndLastModified(resp);
                return NullType.Value;
            };

            return putCmd;
        }
예제 #59
0
 private RESTCommand<ServiceStats> GetServiceStatsImpl(TableRequestOptions requestOptions)
 {
     RESTCommand<ServiceStats> retCmd = new RESTCommand<ServiceStats>(this.Credentials, this.StorageUri);
     requestOptions.ApplyToStorageCommand(retCmd);
     retCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
     retCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableHttpRequestMessageFactory.GetServiceStats(uri, serverTimeout, ctx);
     retCmd.RetrieveResponseStream = true;
     retCmd.Handler = this.AuthenticationHandler;
     retCmd.BuildClient = HttpClientFactory.BuildHttpClient;
     retCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
     retCmd.PostProcessResponse = (cmd, resp, ctx) => Task.Factory.StartNew(() => HttpResponseParsers.ReadServiceStats(cmd.ResponseStream));
     return retCmd;
 }
        /// <summary>
        /// Implementation for the GetPermissions method.
        /// </summary>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the container. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that gets the permissions.</returns>
        private RESTCommand<BlobContainerPermissions> GetPermissionsImpl(AccessCondition accessCondition, BlobRequestOptions options)
        {
            BlobContainerPermissions containerAcl = null;

            RESTCommand<BlobContainerPermissions> getCmd = new RESTCommand<BlobContainerPermissions>(this.ServiceClient.Credentials, this.StorageUri);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
            getCmd.RetrieveResponseStream = true;
            getCmd.Handler = this.ServiceClient.AuthenticationHandler;
            getCmd.BuildClient = HttpClientFactory.BuildHttpClient;
            getCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => ContainerHttpRequestMessageFactory.GetAcl(uri, serverTimeout, accessCondition, cnt, ctx);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
                containerAcl = new BlobContainerPermissions()
                {
                    PublicAccess = ContainerHttpResponseParsers.GetAcl(resp),
                };
                return containerAcl;
            };
            getCmd.PostProcessResponse = (cmd, resp, ctx) =>
            {
                this.UpdateETagAndLastModified(resp);
                return Task.Factory.StartNew(() =>
                {
                    ContainerHttpResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, containerAcl);
                    return containerAcl;
                });
            };

            return getCmd;
        }