Example #1
0
        private async Task ExecuteWithShimmedWebRequestForBlockBlobsAsync(Dictionary <string, byte[]> simulatedBlobs, Func <Task> body)
        {
            // Note how we create the shims context here
            using (ShimsContext.Create())
            {
                // Azure storage uses IAsyncResult-pattern in the background. Therefore we have to create shims
                // for Begin/EndGetResponse. BTW - you can check the code of Azure Storage Library at
                // https://github.com/WindowsAzure/azure-storage-net
                ShimHttpWebRequest.AllInstances.BeginGetResponseAsyncCallbackObject = (@this, callback, state) =>
                {
                    // Check if the request matches on of the blobs that we should simulate
                    byte[] requestedBlob;
                    if (!simulatedBlobs.TryGetValue(@this.RequestUri.AbsolutePath, out requestedBlob))
                    {
                        Assert.Fail("Unexpected request for {0}", @this.RequestUri.AbsoluteUri);
                    }

                    // Setup IAsyncResult; note how we use a stub for that.
                    var result = new StubIAsyncResult()
                    {
                        // Azure Storage Library relies on a wait handle. We give one back that is immediately set.
                        AsyncWaitHandleGet = () => new ManualResetEvent(true),

                        // We pass on the state
                        AsyncStateGet = () => state
                    };

                    // We immediately call the callback as we do not have to wait for a real web request to finish
                    callback(result);
                    return(result);
                };

                ShimHttpWebRequest.AllInstances.EndGetResponseIAsyncResult = (@this, __) =>
                {
                    // Check if the request matches on of the blobs that we should simulate
                    byte[] requestedBlob;
                    if (!simulatedBlobs.TryGetValue(@this.RequestUri.AbsolutePath, out requestedBlob))
                    {
                        Assert.Fail("Unexpected request for {0}", @this.RequestUri.AbsoluteUri);
                    }

                    // Setup response headers. Read Azure Storage HTTP docs for details
                    // (see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx)
                    var headers = new WebHeaderCollection();
                    headers.Add("Accept-Ranges", "bytes");
                    headers.Add("ETag", "0xFFFFFFFFFFFFFFF");
                    headers.Add("x-ms-request-id", Guid.NewGuid().ToString());
                    headers.Add("x-ms-version", "2013-08-15");
                    headers.Add("x-ms-lease-status", "unlocked");
                    headers.Add("x-ms-lease-state", "available");
                    headers.Add("x-ms-blob-type", "BlockBlob");
                    headers.Add("Date", DateTime.Now.ToString("R", CultureInfo.InvariantCulture));

                    // Calculate MD5 hash for our blob and add it to the response headers
                    var md5Check = MD5.Create();
                    md5Check.TransformBlock(requestedBlob, 0, requestedBlob.Length, null, 0);
                    md5Check.TransformFinalBlock(new byte[0], 0, 0);
                    var hashBytes = md5Check.Hash;
                    var hashVal   = Convert.ToBase64String(hashBytes);
                    headers.Add("Content-MD5", hashVal);

                    // As the headers are complete, we can now build the shimmed web response
                    return(new ShimHttpWebResponse()
                    {
                        GetResponseStream = () =>
                        {
                            // Simulate downloaded bytes
                            return new MemoryStream(requestedBlob);
                        },

                        // Status code depends on x-ms-range request header
                        // (see Azure Storage HTTP docs for details)
                        StatusCodeGet = () => string.IsNullOrEmpty(@this.Headers["x-ms-range"]) ? HttpStatusCode.OK : HttpStatusCode.PartialContent,
                        HeadersGet = () => headers,
                        ContentLengthGet = () => requestedBlob.Length,
                        ContentTypeGet = () => "application/octet-stream",
                        LastModifiedGet = () => new DateTime(2014, 1, 1)
                    });
                };

                await body();
            }
        }
Example #2
0
		private async Task ExecuteWithShimmedWebRequestForBlockBlobsAsync(Dictionary<string, byte[]> simulatedBlobs, Func<Task> body)
		{
			// Note how we create the shims context here
			using (ShimsContext.Create())
			{
				// Azure storage uses IAsyncResult-pattern in the background. Therefore we have to create shims
				// for Begin/EndGetResponse. BTW - you can check the code of Azure Storage Library at
				// https://github.com/WindowsAzure/azure-storage-net
				ShimHttpWebRequest.AllInstances.BeginGetResponseAsyncCallbackObject = (@this, callback, state) =>
				{
					// Check if the request matches on of the blobs that we should simulate
					byte[] requestedBlob;
					if (!simulatedBlobs.TryGetValue(@this.RequestUri.AbsolutePath, out requestedBlob))
					{
						Assert.Fail("Unexpected request for {0}", @this.RequestUri.AbsoluteUri);
					}

					// Setup IAsyncResult; note how we use a stub for that.
					var result = new StubIAsyncResult()
					{
						// Azure Storage Library relies on a wait handle. We give one back that is immediately set.
						AsyncWaitHandleGet = () => new ManualResetEvent(true),

						// We pass on the state 
						AsyncStateGet = () => state
					};

					// We immediately call the callback as we do not have to wait for a real web request to finish
					callback(result);
					return result;
				};

				ShimHttpWebRequest.AllInstances.EndGetResponseIAsyncResult = (@this, __) =>
				{
					// Check if the request matches on of the blobs that we should simulate
					byte[] requestedBlob;
					if (!simulatedBlobs.TryGetValue(@this.RequestUri.AbsolutePath, out requestedBlob))
					{
						Assert.Fail("Unexpected request for {0}", @this.RequestUri.AbsoluteUri);
					}

					// Setup response headers. Read Azure Storage HTTP docs for details
					// (see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx)
					var headers = new WebHeaderCollection();
					headers.Add("Accept-Ranges", "bytes");
					headers.Add("ETag", "0xFFFFFFFFFFFFFFF");
					headers.Add("x-ms-request-id", Guid.NewGuid().ToString());
					headers.Add("x-ms-version", "2013-08-15");
					headers.Add("x-ms-lease-status", "unlocked");
					headers.Add("x-ms-lease-state", "available");
					headers.Add("x-ms-blob-type", "BlockBlob");
					headers.Add("Date", DateTime.Now.ToString("R", CultureInfo.InvariantCulture));

					// Calculate MD5 hash for our blob and add it to the response headers
					var md5Check = MD5.Create();
					md5Check.TransformBlock(requestedBlob, 0, requestedBlob.Length, null, 0);
					md5Check.TransformFinalBlock(new byte[0], 0, 0);
					var hashBytes = md5Check.Hash;
					var hashVal = Convert.ToBase64String(hashBytes);
					headers.Add("Content-MD5", hashVal);

					// As the headers are complete, we can now build the shimmed web response
					return new ShimHttpWebResponse()
					{
						GetResponseStream = () =>
						{
							// Simulate downloaded bytes
							return new MemoryStream(requestedBlob);
						},

						// Status code depends on x-ms-range request header
						// (see Azure Storage HTTP docs for details)
						StatusCodeGet = () => string.IsNullOrEmpty(@this.Headers["x-ms-range"]) ? HttpStatusCode.OK : HttpStatusCode.PartialContent,
						HeadersGet = () => headers,
						ContentLengthGet = () => requestedBlob.Length,
						ContentTypeGet = () => "application/octet-stream",
						LastModifiedGet = () => new DateTime(2014, 1, 1)
					};
				};

				await body();
			}
		}