diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs index 97089cda3ea2..97097c93b0ef 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs @@ -17,12 +17,12 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Net.Http; using System.Threading.Tasks; using Windows.Foundation; using Windows.Storage.Streams; using NetHttpContent = System.Net.Http.HttpContent; +using NetHttpRequestMessage = System.Net.Http.HttpRequestMessage; using NetHttpResponseMessage = System.Net.Http.HttpResponseMessage; namespace Microsoft.WindowsAzure.ServiceLayer.Http @@ -181,7 +181,7 @@ public IAsyncAction CopyToBufferAsync() /// Submits content data into the given request. /// /// Target request. - internal void SubmitTo(HttpRequestMessage request) + internal void SubmitTo(NetHttpRequestMessage request) { NetHttpContent content = new System.Net.Http.StreamContent( _rawContent.ReadAsStreamAsync().Result); diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpMethod.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpMethod.cs new file mode 100644 index 000000000000..4e5322fe7134 --- /dev/null +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpMethod.cs @@ -0,0 +1,34 @@ +// +// 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; + +namespace Microsoft.WindowsAzure.ServiceLayer.Http +{ + /// + /// Lists HTTP methods used by pipeline implementation. + /// + internal static class HttpMethod + { + internal const string Post = "POST"; + internal const string Get = "GET"; + internal const string Put = "PUT"; + internal const string Delete = "DELETE"; + } +} diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpRequest.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpRequest.cs new file mode 100644 index 000000000000..3800f55931c0 --- /dev/null +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpRequest.cs @@ -0,0 +1,100 @@ +// +// 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.Net.Http; +using System.Text; +using System.Threading.Tasks; +using NetHttpMethod = System.Net.Http.HttpMethod; +using NetHttpRequestMessage = System.Net.Http.HttpRequestMessage; + +namespace Microsoft.WindowsAzure.ServiceLayer.Http +{ + /// + /// Represents an HTTP request. + /// + public sealed class HttpRequest + { + private NetHttpMethod _method; // HTTP method verb (get/put/post, etc.) + + /// + /// Gets the URI used for the HTTP request. + /// + public Uri Uri { get; private set; } + + /// + /// Gets the HTTP method used for HTTP request. + /// + public string Method + { + get { return _method.ToString(); } + } + + /// + /// Gets the headers. + /// + public IDictionary Headers { get; private set; } + + /// + /// Gets the content of the request. + /// + public HttpContent Content { get; set; } + + /// + /// Initializes the request. + /// + /// The request's HTTP method. + /// The request's URI. + public HttpRequest(string method, Uri uri) + { + if (uri == null) + { + throw new ArgumentNullException("uri"); + } + if (method == null) + { + throw new ArgumentNullException("method"); + } + + Uri = uri; + _method = new NetHttpMethod(method); + Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + /// + /// Creates a .Net request and populates it with all data. + /// + /// .Net request. + internal NetHttpRequestMessage CreateNetRequest() + { + NetHttpRequestMessage request = new NetHttpRequestMessage(_method, Uri); + + // Populate headers. + foreach (KeyValuePair headerItem in Headers) + { + request.Headers.Add(headerItem.Key, headerItem.Value); + } + + // Populate content. + if (Content != null) + { + Content.SubmitTo(request); + } + return request; + } + } +} 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 880172b39917..2a897c911219 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj @@ -106,6 +106,8 @@ + + diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokerProperties.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokerProperties.cs index 71113da6c2ca..a6e11197ffe8 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokerProperties.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokerProperties.cs @@ -16,10 +16,10 @@ using System; using System.Globalization; using System.IO; -using System.Net.Http; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; +using Microsoft.WindowsAzure.ServiceLayer.Http; namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus { @@ -266,7 +266,7 @@ private static string DateTimeToUtcString(DateTimeOffset? source) /// Submits content of the class to the given HTTP request. /// /// Target request. - internal void SubmitTo(HttpRequestMessage request) + internal void SubmitTo(HttpRequest request) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(BrokerProperties)); using (MemoryStream stream = new MemoryStream()) diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs index f9c6b6586d85..61764514361f 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageInfo.cs @@ -25,7 +25,6 @@ using Windows.Foundation; using Windows.Storage.Streams; -using NetHttpContent = System.Net.Http.HttpContent; using NetHttpResponseMessage = System.Net.Http.HttpResponseMessage; namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs index b9f719741331..0b38a7e54979 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs @@ -23,9 +23,6 @@ using Windows.Foundation.Metadata; using Windows.Storage.Streams; -using NetHttpContent = System.Net.Http.HttpContent; -using NetHttpRequestMessage = System.Net.Http.HttpRequestMessage; - namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus { /// @@ -206,16 +203,15 @@ public static BrokeredMessageSettings CreateFromStream(IInputStream stream) return new BrokeredMessageSettings(content); } - /// /// Submits content to the given request. /// /// Target request. - internal void SubmitTo(NetHttpRequestMessage request) + internal void SubmitTo(HttpRequest request) { _brokerProperties.SubmitTo(request); _customProperties.SubmitTo(request); - Content.SubmitTo(request); + request.Content = Content; } } } diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs index 3faf69ecdae6..a8c32f1b7571 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/CustomPropertiesDictionary.cs @@ -18,11 +18,13 @@ using System.Globalization; using System.Diagnostics; using System.Linq; -using System.Net.Http; using System.Text; using System.Threading.Tasks; +using Microsoft.WindowsAzure.ServiceLayer.Http; using Windows.Data.Json; +using NetHttpResponseMessage = System.Net.Http.HttpResponseMessage; + namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus { /// @@ -42,7 +44,7 @@ internal CustomPropertiesDictionary() /// Initializes a dictionary with properties from the response. /// /// Response. - internal CustomPropertiesDictionary(HttpResponseMessage response) + internal CustomPropertiesDictionary(NetHttpResponseMessage response) : this() { foreach (KeyValuePair> item in response.Headers) @@ -66,7 +68,7 @@ internal CustomPropertiesDictionary(HttpResponseMessage response) /// Submits stored properties to the request. /// /// HTTP request. - internal void SubmitTo(HttpRequestMessage request) + internal void SubmitTo(HttpRequest request) { foreach (KeyValuePair item in this) { @@ -107,7 +109,6 @@ private static object DecodeValue(JsonValue value) return dateTime.ToUniversalTime(); } return stringValue; - } /// diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs index a4e7caa6661f..4a9921dc6f82 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs @@ -17,14 +17,19 @@ using System.Collections.Generic; using System.Diagnostics; using System.Net; -using System.Net.Http; using System.Text; using System.Threading.Tasks; - +using Microsoft.WindowsAzure.ServiceLayer.Http; using Windows.Data.Xml.Dom; using Windows.Foundation; using Windows.Web.Syndication; +using NetHttpClient = System.Net.Http.HttpClient; +using NetHttpMessageHandler = System.Net.Http.HttpMessageHandler; +using NetHttpMethod = System.Net.Http.HttpMethod; +using NetHttpResponseMessage = System.Net.Http.HttpResponseMessage; +using NetHttpRequestMessage = System.Net.Http.HttpRequestMessage; + namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus { /// @@ -51,7 +56,7 @@ internal class ServiceBusRestProxy: IServiceBusService /// /// Gets HTTP client used for communicating with the service. /// - private HttpClient Channel { get; set; } + private NetHttpClient Channel { get; set; } /// @@ -64,8 +69,8 @@ internal ServiceBusRestProxy(ServiceConfiguration serviceOptions) ServiceConfig = serviceOptions; - HttpMessageHandler chain = new WrapAuthenticationHandler(serviceOptions); - Channel = new HttpClient(chain); + NetHttpMessageHandler chain = new WrapAuthenticationHandler(serviceOptions); + Channel = new NetHttpClient(chain); } /// @@ -599,7 +604,7 @@ IAsyncAction IServiceBusService.SendMessageAsync(string destination, BrokeredMes } Uri uri = ServiceConfig.GetDestinationUri(destination); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri); + HttpRequest request = new HttpRequest(HttpMethod.Post, uri); message.SubmitTo(request); return SendAsync(request).AsAsyncAction(); @@ -619,7 +624,7 @@ IAsyncOperation IServiceBusService.PeekQueueMessageAsync(st } Uri uri = ServiceConfig.GetUnlockedMessageUri(queueName, lockInterval); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri); + HttpRequest request = new HttpRequest(HttpMethod.Post, uri); return SendAsync(request, CheckNoContent) .ContinueWith((t) => BrokeredMessageInfo.CreateFromPeekResponse(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion) .AsAsyncOperation(); @@ -639,7 +644,7 @@ IAsyncOperation IServiceBusService.GetQueueMessageAsync(str } Uri uri = ServiceConfig.GetUnlockedMessageUri(queueName, lockInterval); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, uri); + HttpRequest request = new HttpRequest(HttpMethod.Delete, uri); return SendAsync(request, CheckNoContent) .ContinueWith((t) => new BrokeredMessageInfo(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion) .AsAsyncOperation(); @@ -664,7 +669,7 @@ IAsyncAction IServiceBusService.UnlockQueueMessageAsync(string queueName, long s } Uri uri = ServiceConfig.GetLockedMessageUri(queueName, sequenceNumber, lockToken); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, uri); + HttpRequest request = new HttpRequest(HttpMethod.Put, uri); return SendAsync(request) .AsAsyncAction(); } @@ -688,7 +693,7 @@ IAsyncAction IServiceBusService.DeleteQueueMessageAsync(string queueName, long s } Uri uri = ServiceConfig.GetLockedMessageUri(queueName, sequenceNumber, lockToken); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, uri); + HttpRequest request = new HttpRequest(HttpMethod.Delete, uri); return SendAsync(request) .AsAsyncAction(); } @@ -714,7 +719,7 @@ IAsyncOperation IServiceBusService.PeekSubscriptionMessageA } Uri uri = ServiceConfig.GetUnlockedSubscriptionMessageUri(topicName, subscriptionName, lockInterval); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri); + HttpRequest request = new HttpRequest(HttpMethod.Post, uri); return SendAsync(request, CheckNoContent) .ContinueWith(t => new BrokeredMessageInfo(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion) .AsAsyncOperation(); @@ -740,7 +745,7 @@ IAsyncOperation IServiceBusService.GetSubscriptionMessageAs } Uri uri = ServiceConfig.GetUnlockedSubscriptionMessageUri(topicName, subscriptionName, lockInterval); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, uri); + HttpRequest request = new HttpRequest(HttpMethod.Delete, uri); return SendAsync(request, CheckNoContent) .ContinueWith(t => new BrokeredMessageInfo(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion) .AsAsyncOperation(); @@ -771,7 +776,7 @@ IAsyncAction IServiceBusService.UnlockSubscriptionMessageAsync(string topicName, } Uri uri = ServiceConfig.GetLockedSubscriptionMessageUri(topicName, subscriptionName, sequenceNumber, lockToken); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, uri); + HttpRequest request = new HttpRequest(HttpMethod.Put, uri); return SendAsync(request) .AsAsyncAction(); } @@ -800,7 +805,7 @@ IAsyncAction IServiceBusService.DeleteSubscriptionMessageAsync(string topicName, } Uri uri = ServiceConfig.GetLockedSubscriptionMessageUri(topicName, subscriptionName, sequenceNumber, lockToken); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, uri); + HttpRequest request = new HttpRequest(HttpMethod.Delete, uri); return SendAsync(request) .AsAsyncAction(); } @@ -815,7 +820,7 @@ IAsyncAction IServiceBusService.DeleteSubscriptionMessageAsync(string topicName, /// A collection of items. private IAsyncOperation> GetItemsAsync(Uri containerUri, Action initAction, params Type[] extraTypes) { - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, containerUri); + HttpRequest request = new HttpRequest(HttpMethod.Get, containerUri); return SendAsync(request, CheckNoContent) .ContinueWith>(r => GetItems(r.Result, initAction, extraTypes), TaskContinuationOptions.OnlyOnRanToCompletion) @@ -852,7 +857,7 @@ private IAsyncOperation> GetItemsAsync( /// Initialization action. /// Extra types for deserialization. /// Collection of deserialized items. - private IEnumerable GetItems(HttpResponseMessage response, Action initAction, params Type[] extraTypes) + private IEnumerable GetItems(NetHttpResponseMessage response, Action initAction, params Type[] extraTypes) { Debug.Assert(response.IsSuccessStatusCode); SyndicationFeed feed = new SyndicationFeed(); @@ -871,7 +876,7 @@ private IEnumerable GetItems(HttpResponseMessage response, Action< /// Item data private IAsyncOperation GetItemAsync(Uri itemUri, Action initAction, params Type[] extraTypes) { - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, itemUri); + HttpRequest request = new HttpRequest(HttpMethod.Get, itemUri); return SendAsync(request, CheckNoContent) .ContinueWith(tr => GetItem(tr.Result, initAction, extraTypes), TaskContinuationOptions.OnlyOnRanToCompletion) @@ -887,7 +892,7 @@ private IAsyncOperation GetItemAsync(Uri itemUri, ActionInitialization action for deserialized items. /// Extra types for deserialization. /// Deserialized object. - private TInfo GetItem(HttpResponseMessage response, Action initAction, params Type[] extraTypes) + private TInfo GetItem(NetHttpResponseMessage response, Action initAction, params Type[] extraTypes) { Debug.Assert(response.IsSuccessStatusCode); XmlDocument doc = new XmlDocument(); @@ -906,7 +911,7 @@ private TInfo GetItem(HttpResponseMessage response, ActionDeletion result. private IAsyncAction DeleteItemAsync(Uri itemUri) { - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, itemUri); + HttpRequest request = new HttpRequest(HttpMethod.Delete, itemUri); return SendAsync(request) .AsAsyncAction(); @@ -926,11 +931,11 @@ private IAsyncOperation CreateItemAsync( TSettings itemSettings, Action initAction) where TSettings: class { - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, itemUri); + HttpRequest request = new HttpRequest(HttpMethod.Put, itemUri); 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(); } @@ -941,11 +946,11 @@ private IAsyncOperation CreateItemAsync( /// Target request. /// Object to serialize. /// Supported types. - private void SetBody(HttpRequestMessage request, object bodyObject, params Type[] supportedTypes) + private void SetBody(HttpRequest request, object bodyObject, params Type[] supportedTypes) { string content = SerializationHelper.Serialize(bodyObject, supportedTypes); - request.Content = new StringContent(content, Encoding.UTF8, Constants.BodyContentType); - request.Content.Headers.ContentType.Parameters.Add(new System.Net.Http.Headers.NameValueHeaderValue("type", "entry")); + request.Content = HttpContent.CreateFromText(content, Constants.BodyContentType); + request.Headers.Add("type", "entry"); } /// @@ -994,7 +999,7 @@ private static void InitRule(SyndicationItem feedItem, RuleInfo ruleInfo) /// Source HTTP response. /// Additional validators. /// Processed HTTP response. - private HttpResponseMessage CheckResponse(HttpResponseMessage response, IEnumerable> validators) + private NetHttpResponseMessage CheckResponse(NetHttpResponseMessage response, IEnumerable> validators) { if (!response.IsSuccessStatusCode) { @@ -1002,7 +1007,7 @@ private HttpResponseMessage CheckResponse(HttpResponseMessage response, IEnumera } // Pass the response through all validators. - foreach (Func validator in validators) + foreach (Func validator in validators) { response = validator(response); } @@ -1014,10 +1019,11 @@ private HttpResponseMessage CheckResponse(HttpResponseMessage response, IEnumera /// /// Request to send. /// HTTP response. - private Task SendAsync(HttpRequestMessage request, params Func[] validators) + private Task SendAsync(HttpRequest request, params Func[] validators) { - return Channel.SendAsync(request) - .ContinueWith((task) => CheckResponse(task.Result, validators), TaskContinuationOptions.OnlyOnRanToCompletion); + NetHttpRequestMessage netRequest = request.CreateNetRequest(); + return Channel.SendAsync(netRequest) + .ContinueWith((task) => CheckResponse(task.Result, validators), TaskContinuationOptions.OnlyOnRanToCompletion); } /// @@ -1025,7 +1031,7 @@ private Task SendAsync(HttpRequestMessage request, params F /// /// Source response. /// Processed HTTP response. - private HttpResponseMessage CheckNoContent(HttpResponseMessage response) + private NetHttpResponseMessage CheckNoContent(NetHttpResponseMessage response) { if (response.StatusCode == System.Net.HttpStatusCode.NoContent || response.StatusCode == HttpStatusCode.ResetContent) {