/// <summary> /// Uploads the full blob. /// </summary> /// <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="SynchronousTask"/> that gets the stream.</returns> private RESTCommand<NullType> PutBlobImpl(Stream stream, long? length, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) { long offset = stream.Position; length = length ?? stream.Length - offset; this.Properties.ContentMD5 = contentMD5; CappedLengthReadOnlyStream cappedStream = new CappedLengthReadOnlyStream(stream, length.Value + offset); RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.Uri); putCmd.ApplyRequestOptions(options); putCmd.Handler = this.ServiceClient.AuthenticationHandler; putCmd.BuildClient = HttpClientFactory.BuildHttpClient; putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(cappedStream, offset, length, null /* md5 */, cmd, ctx); putCmd.BuildRequest = (cmd, cnt, ctx) => { HttpRequestMessage msg = BlobHttpRequestMessageFactory.Put(cmd.Uri, cmd.ServerTimeoutInSeconds, this.Properties, BlobType.BlockBlob, 0, accessCondition, cnt, ctx); BlobHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); return msg; }; putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); this.Properties.Length = length.Value; return NullType.Value; }; return putCmd; }
/// <summary> /// Uploads the full blob. /// </summary> /// <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="SynchronousTask"/> that gets the stream.</returns> private RESTCommand<NullType> PutBlobImpl(Stream stream, long? length, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) { long offset = stream.Position; length = length ?? stream.Length - offset; this.Properties.ContentMD5 = contentMD5; CappedLengthReadOnlyStream cappedStream = new CappedLengthReadOnlyStream(stream, length.Value + offset); RESTCommand<NullType> putCmd = new RESTCommand<NullType>(this.ServiceClient.Credentials, this.attributes.StorageUri); options.ApplyToStorageCommand(putCmd); putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(cappedStream, offset, length, null /* md5 */, cmd, ctx); putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => { StorageRequestMessage msg = BlobHttpRequestMessageFactory.Put(uri, serverTimeout, this.Properties, BlobType.BlockBlob, 0, 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 = length.Value; return NullType.Value; }; return putCmd; }