diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/HttpTests/ContentTests.cs
similarity index 99%
rename from microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs
rename to microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/HttpTests/ContentTests.cs
index cb22569ae4ea..5976e0e224fd 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/HttpTests/ContentTests.cs
@@ -23,7 +23,7 @@
using Windows.Storage.Streams;
using Xunit;
-namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.ServiceBusTests
+namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.HttpTests
{
///
/// Tests for the Content class.
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/HttpTests/PipelineTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/HttpTests/PipelineTests.cs
new file mode 100644
index 000000000000..3ad3a891e925
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/HttpTests/PipelineTests.cs
@@ -0,0 +1,53 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.WindowsAzure.ServiceLayer.Http;
+using Xunit;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.HttpTests
+{
+ ///
+ /// HTTP pipeline tests.
+ ///
+ public class PipelineTests
+ {
+ ///
+ /// Tests passing invalid arguments in the request's constructor.
+ ///
+ [Fact]
+ public void InvalidArgsInRequestConstructor()
+ {
+ Uri validUri = new Uri("http://microsoft.com");
+ Assert.Throws(() => new HttpRequest(null, validUri));
+ Assert.Throws(() => new HttpRequest("PUT", null));
+ }
+
+ ///
+ /// Tests passing invalid arguments in the response's constructor.
+ ///
+ [Fact]
+ public void InvalidArgsInResponseConstructor()
+ {
+ HttpRequest validRequest = new HttpRequest("PUT", new Uri("http://microsoft.com"));
+ Assert.Throws(() => new HttpResponse(null, 200));
+ Assert.Throws(() => new HttpResponse(validRequest, -5));
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj
index 36ee264b446b..b420e14f3cbb 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj
@@ -113,9 +113,10 @@
+
-
+
@@ -134,6 +135,7 @@
References\xunit.dll
+
11.0
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpResponse.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpResponse.cs
new file mode 100644
index 000000000000..5fb65949c7da
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpResponse.cs
@@ -0,0 +1,105 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+using NetHttpResponseMessage = System.Net.Http.HttpResponseMessage;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.Http
+{
+ ///
+ /// Represents an HTTP response message.
+ /// server.
+ ///
+ public sealed class HttpResponse
+ {
+ ///
+ /// Gets the request that lead to this response.
+ ///
+ public HttpRequest Request { get; private set; }
+
+ ///
+ /// Gets the status code of the HTTP response.
+ ///
+ public int StatusCode { get; set; }
+
+ ///
+ /// Tells whether the HTTP response was successful.
+ ///
+ public bool IsSuccessStatusCode { get { return StatusCode >= 200 && StatusCode < 299; } }
+
+ ///
+ /// Gets or sets the reason phrase which typically is sent by servers
+ /// together with the status code.
+ ///
+ public string ReasonPhrase { get; set; }
+
+ ///
+ /// Gets or sets the content of the response.
+ ///
+ public HttpContent Content { get; set; }
+
+ ///
+ /// Gets the collection of HTTP response headers.
+ ///
+ public IDictionary Headers { get; private set; }
+
+ ///
+ /// Initializes the response object.
+ ///
+ /// Request that initiated the response.
+ /// Status code of the HTTP response.
+ public HttpResponse(HttpRequest originalRequest, int statusCode)
+ {
+ if (originalRequest == null)
+ {
+ throw new ArgumentNullException("originalRequest");
+ }
+ if (!Enum.IsDefined(typeof(System.Net.HttpStatusCode), statusCode))
+ {
+ throw new ArgumentOutOfRangeException("statusCode");
+ }
+
+ Request = originalRequest;
+ StatusCode = statusCode;
+ Headers = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ }
+
+ ///
+ /// Initializes the response object.
+ ///
+ /// Request that initiated the response.
+ /// .Net HTTP response.
+ internal HttpResponse(HttpRequest originalRequest, NetHttpResponseMessage response)
+ {
+ Debug.Assert(originalRequest != null);
+ Debug.Assert(response != null);
+
+ Request = originalRequest;
+ StatusCode = (int)response.StatusCode;
+ ReasonPhrase = response.ReasonPhrase;
+ Content = HttpContent.CreateFromResponse(response);
+ Headers = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ foreach (KeyValuePair> item in response.Headers)
+ {
+ string valueString = string.Join(string.Empty, item.Value);
+ Headers.Add(item.Key, valueString);
+ }
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj
index 2a897c911219..cdf376957496 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj
@@ -108,6 +108,7 @@
+
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs
index 61764514361f..27017abeaac5 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs
@@ -25,8 +25,6 @@
using Windows.Foundation;
using Windows.Storage.Streams;
-using NetHttpResponseMessage = System.Net.Http.HttpResponseMessage;
-
namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus
{
///
@@ -231,9 +229,9 @@ public IAsyncInfo CopyContentToAsync(IOutputStream stream)
///
/// Response with data.
///
- internal static BrokeredMessageInfo CreateFromPeekResponse(NetHttpResponseMessage response)
+ internal static BrokeredMessageInfo CreateFromPeekResponse(HttpResponse response)
{
- if (response.StatusCode == System.Net.HttpStatusCode.NoContent || response.StatusCode == System.Net.HttpStatusCode.ResetContent)
+ if (response.StatusCode == (int)System.Net.HttpStatusCode.NoContent || response.StatusCode == (int)System.Net.HttpStatusCode.ResetContent)
{
return null;
}
@@ -244,21 +242,16 @@ internal static BrokeredMessageInfo CreateFromPeekResponse(NetHttpResponseMessag
/// Constructor. Initializes the object from the HTTP response.
///
/// HTTP reponse with the data.
- internal BrokeredMessageInfo(NetHttpResponseMessage response)
+ internal BrokeredMessageInfo(HttpResponse response)
{
Debug.Assert(response.IsSuccessStatusCode);
- _content = HttpContent.CreateFromResponse(response);
+ _content = response.Content;
_customProperties = new CustomPropertiesDictionary(response);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary));
string propertiesString = null;
- IEnumerable values;
-
- if (response.Headers.TryGetValues(Constants.BrokerPropertiesHeader, out values))
- {
- propertiesString = string.Join(string.Empty, values);
- }
+ response.Headers.TryGetValue(Constants.BrokerPropertiesHeader, out propertiesString);
if (string.IsNullOrEmpty(propertiesString))
{
_brokerProperties = new BrokerProperties();
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs
index a8c32f1b7571..a7d87e10c589 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs
@@ -44,13 +44,13 @@ internal CustomPropertiesDictionary()
/// Initializes a dictionary with properties from the response.
///
/// Response.
- internal CustomPropertiesDictionary(NetHttpResponseMessage response)
+ internal CustomPropertiesDictionary(HttpResponse response)
: this()
{
- foreach (KeyValuePair> item in response.Headers)
+ foreach (KeyValuePair item in response.Headers)
{
string key = item.Key;
- string valueString = string.Join(string.Empty, item.Value);
+ string valueString = item.Value;
JsonValue translatedValue;
if (JsonValue.TryParse(valueString, out translatedValue) && IsSupportedType(translatedValue.ValueType))
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs
index 4a9921dc6f82..034b2db28f86 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs
@@ -16,7 +16,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.ServiceLayer.Http;
@@ -626,7 +625,7 @@ IAsyncOperation IServiceBusService.PeekQueueMessageAsync(st
Uri uri = ServiceConfig.GetUnlockedMessageUri(queueName, lockInterval);
HttpRequest request = new HttpRequest(HttpMethod.Post, uri);
return SendAsync(request, CheckNoContent)
- .ContinueWith((t) => BrokeredMessageInfo.CreateFromPeekResponse(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
+ .ContinueWith(t => BrokeredMessageInfo.CreateFromPeekResponse(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
.AsAsyncOperation();
}
@@ -857,11 +856,11 @@ private IAsyncOperation> GetItemsAsync(
/// Initialization action.
/// Extra types for deserialization.
/// Collection of deserialized items.
- private IEnumerable GetItems(NetHttpResponseMessage response, Action initAction, params Type[] extraTypes)
+ private IEnumerable GetItems(HttpResponse response, Action initAction, params Type[] extraTypes)
{
Debug.Assert(response.IsSuccessStatusCode);
SyndicationFeed feed = new SyndicationFeed();
- feed.Load(response.Content.ReadAsStringAsync().Result);
+ feed.Load(response.Content.ReadAsStringAsync().AsTask().Result);
return SerializationHelper.DeserializeCollection(feed, initAction, extraTypes);
}
@@ -892,11 +891,11 @@ private IAsyncOperation GetItemAsync(Uri itemUri, ActionInitialization action for deserialized items.
/// Extra types for deserialization.
/// Deserialized object.
- private TInfo GetItem(NetHttpResponseMessage response, Action initAction, params Type[] extraTypes)
+ private TInfo GetItem(HttpResponse response, Action initAction, params Type[] extraTypes)
{
Debug.Assert(response.IsSuccessStatusCode);
XmlDocument doc = new XmlDocument();
- doc.LoadXml(response.Content.ReadAsStringAsync().Result);
+ doc.LoadXml(response.Content.ReadAsStringAsync().AsTask().Result);
SyndicationItem feedItem = new SyndicationItem();
feedItem.LoadFromXml(doc);
@@ -935,7 +934,7 @@ private IAsyncOperation CreateItemAsync(
return Task.Factory
.StartNew(() => SetBody(request, itemSettings, ExtraRuleTypes))
- .ContinueWith(tr => SendAsync(request).Result, TaskContinuationOptions.OnlyOnRanToCompletion)
+ .ContinueWith(tr => SendAsync(request).Result, TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith(tr => GetItem(tr.Result, initAction, ExtraRuleTypes), TaskContinuationOptions.OnlyOnRanToCompletion)
.AsAsyncOperation();
}
@@ -999,7 +998,7 @@ private static void InitRule(SyndicationItem feedItem, RuleInfo ruleInfo)
/// Source HTTP response.
/// Additional validators.
/// Processed HTTP response.
- private NetHttpResponseMessage CheckResponse(NetHttpResponseMessage response, IEnumerable> validators)
+ private HttpResponse CheckResponse(HttpResponse response, IEnumerable> validators)
{
if (!response.IsSuccessStatusCode)
{
@@ -1007,7 +1006,7 @@ private NetHttpResponseMessage CheckResponse(NetHttpResponseMessage response, IE
}
// Pass the response through all validators.
- foreach (Func validator in validators)
+ foreach (Func validator in validators)
{
response = validator(response);
}
@@ -1019,11 +1018,12 @@ private NetHttpResponseMessage CheckResponse(NetHttpResponseMessage response, IE
///
/// Request to send.
/// HTTP response.
- private Task SendAsync(HttpRequest request, params Func[] validators)
+ private Task SendAsync(HttpRequest request, params Func[] validators)
{
NetHttpRequestMessage netRequest = request.CreateNetRequest();
return Channel.SendAsync(netRequest)
- .ContinueWith((task) => CheckResponse(task.Result, validators), TaskContinuationOptions.OnlyOnRanToCompletion);
+ .ContinueWith(t => new HttpResponse(request, t.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
+ .ContinueWith(t => CheckResponse(t.Result, validators));
}
///
@@ -1031,9 +1031,9 @@ private Task SendAsync(HttpRequest request, params Func<
///
/// Source response.
/// Processed HTTP response.
- private NetHttpResponseMessage CheckNoContent(NetHttpResponseMessage response)
+ private HttpResponse CheckNoContent(HttpResponse response)
{
- if (response.StatusCode == System.Net.HttpStatusCode.NoContent || response.StatusCode == HttpStatusCode.ResetContent)
+ if (response.StatusCode == (int)System.Net.HttpStatusCode.NoContent || response.StatusCode == (int)System.Net.HttpStatusCode.ResetContent)
{
throw new WindowsAzureServiceException(response);
}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/WindowsAzureServiceException.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/WindowsAzureServiceException.cs
index 52761bd73a98..891f2512d782 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/WindowsAzureServiceException.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/WindowsAzureServiceException.cs
@@ -16,10 +16,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Net;
-using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
+using Microsoft.WindowsAzure.ServiceLayer.Http;
namespace Microsoft.WindowsAzure.ServiceLayer
{
@@ -31,7 +30,7 @@ internal class WindowsAzureServiceException: WindowsAzureException
///
/// Gets the HTTP status code.
///
- internal HttpStatusCode StatusCode { get; private set; }
+ internal int StatusCode { get; private set; }
///
/// Gets the reason string fore th exception.
@@ -42,7 +41,7 @@ internal class WindowsAzureServiceException: WindowsAzureException
/// Constructor.
///
/// Source HTTP response.
- internal WindowsAzureServiceException(HttpResponseMessage response)
+ internal WindowsAzureServiceException(HttpResponse response)
{
StatusCode = response.StatusCode;
ReasonPhrase = response.ReasonPhrase;