From: Marek Safar Date: Fri, 2 Mar 2012 13:53:57 +0000 (+0000) Subject: Implement some async System.Net.Http methods X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=f7cb2da4ef1fbbc0c0c61d3721c82d6d2a0a485c;p=mono.git Implement some async System.Net.Http methods --- diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs index 33feecc1afd..5f32c034c71 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs @@ -244,7 +244,7 @@ namespace System.Net.Http.Headers HeaderInfo headerInfo; if (known_headers.TryGetValue (name, out headerInfo) && (headerInfo.HeaderKind & HeaderKind) == 0) { - if (HeaderKind != HttpHeaderKind.None) + if (HeaderKind != HttpHeaderKind.None && ((HeaderKind | headerInfo.HeaderKind) & HttpHeaderKind.Content) != 0) throw new InvalidOperationException (name); return null; diff --git a/mcs/class/System.Net.Http/System.Net.Http.dll.sources b/mcs/class/System.Net.Http/System.Net.Http.dll.sources index f0bc75fd226..f88d6760d53 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.dll.sources +++ b/mcs/class/System.Net.Http/System.Net.Http.dll.sources @@ -1,6 +1,7 @@ ../../build/common/Consts.cs Assembly/AssemblyInfo.cs System.Net.Http/ByteArrayContent.cs +System.Net.Http/ClientCertificateOption.cs System.Net.Http/HttpClient.cs System.Net.Http/HttpClientHandler.cs System.Net.Http/HttpCompletionOption.cs diff --git a/mcs/class/System.Net.Http/System.Net.Http/ByteArrayContent.cs b/mcs/class/System.Net.Http/System.Net.Http/ByteArrayContent.cs index b94da267f86..13d5c8de7b9 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/ByteArrayContent.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/ByteArrayContent.cs @@ -58,11 +58,6 @@ namespace System.Net.Http this.count = count; } - protected override void SerializeToStream (Stream stream, TransportContext context) - { - stream.Write (content, offset, count); - } - protected override Task SerializeToStreamAsync (Stream stream, TransportContext context) { return stream.WriteAsync (content, offset, count); diff --git a/mcs/class/System.Net.Http/System.Net.Http/ClientCertificateOption.cs b/mcs/class/System.Net.Http/System.Net.Http/ClientCertificateOption.cs new file mode 100644 index 00000000000..8d4b6dcd553 --- /dev/null +++ b/mcs/class/System.Net.Http/System.Net.Http/ClientCertificateOption.cs @@ -0,0 +1,36 @@ +// +// ClientCertificateOption.cs +// +// Authors: +// Marek Safar +// +// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace System.Net.Http +{ + public enum ClientCertificateOption + { + Manual, + Automatic + } +} diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs index d7384fca6c3..92e22982b87 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs @@ -252,6 +252,11 @@ namespace System.Net.Http request.Headers.AddHeaders (headers); } + return SendAsyncWorker (request, cancellationToken); + } + + async Task SendAsyncWorker (HttpRequestMessage request, CancellationToken cancellationToken) + { try { if (cancellation_token == null) cancellation_token = new CancellationTokenSource (); @@ -259,9 +264,9 @@ namespace System.Net.Http using (var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellation_token.Token, cancellationToken)) { cts.CancelAfter (timeout); - var response = handler.SendAsync (request, cts.Token); - //if (response == null) - // throw new InvalidOperationException ("Handler failed to return a response"); + var response = await handler.SendAsync (request, cts.Token).ConfigureAwait (false); + if (response == null) + throw new InvalidOperationException ("Handler failed to return a response"); return response; } diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs index 6c832662162..00c1ff0eb98 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs @@ -185,10 +185,12 @@ namespace System.Net.Http base.Dispose (disposing); } - WebRequest CreateWebRequest (HttpRequestMessage request) + HttpWebRequest CreateWebRequest (HttpRequestMessage request) { - var factory = Activator.CreateInstance (typeof (IWebRequestCreate).Assembly.GetType ("System.Net.HttpRequestCreator"), true) as IWebRequestCreate; - var wr = (HttpWebRequest) factory.Create (request.RequestUri); + //var factory = Activator.CreateInstance (typeof (IWebRequestCreate).Assembly.GetType ("System.Net.HttpRequestCreator"), true) as IWebRequestCreate; + //var wr = (HttpWebRequest) factory.Create (request.RequestUri); + + var wr = new HttpWebRequest (request.RequestUri); wr.ConnectionGroupName = "HttpClientHandler"; wr.Method = request.Method.Method; @@ -256,25 +258,18 @@ namespace System.Net.Http return response; } - /* - protected internal override HttpResponseMessage Send (HttpRequestMessage request, CancellationToken cancellationToken) + + protected async internal override Task SendAsync (HttpRequestMessage request, CancellationToken cancellationToken) { var wrequest = CreateWebRequest (request); if (request.Content != null) { throw new NotImplementedException (); - } else { - // TODO: } - var wresponse = (HttpWebResponse) wrequest.GetResponse (); - + // FIXME: Why GetResponseAsync does not accept cancellationToken + var wresponse = (HttpWebResponse) await wrequest.GetResponseAsync ().ConfigureAwait (false); return CreateResponseMessage (wresponse, request); } - */ - protected internal override Task SendAsync (HttpRequestMessage request, CancellationToken cancellationToken) - { - throw new NotImplementedException (); - } } } diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs index 85133731681..89979a544b6 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs @@ -45,19 +45,6 @@ namespace System.Net.Http } } - public void CopyTo (Stream stream) - { - CopyTo (stream, null); - } - - public void CopyTo (Stream stream, TransportContext context) - { - if (stream == null) - throw new ArgumentNullException ("stream"); - - SerializeToStream (stream, context); - } - public Task CopyToAsync (Stream stream) { return CopyToAsync (stream, null); @@ -86,12 +73,12 @@ namespace System.Net.Http } } - public void LoadIntoBuffer () + public Task LoadIntoBufferAsync () { - LoadIntoBuffer (0x2000); + return LoadIntoBufferAsync (0x2000); } - public void LoadIntoBuffer (int maxBufferSize) + public async Task LoadIntoBufferAsync (int maxBufferSize) { if (disposed) throw new ObjectDisposedException (GetType ().ToString ()); @@ -100,32 +87,21 @@ namespace System.Net.Http return; buffer = new MemoryStream (); - SerializeToStream (buffer, null); + await SerializeToStreamAsync (buffer, null).ConfigureAwait (false); buffer.Seek (0, SeekOrigin.Begin); } - public Task LoadIntoBufferAsync () - { - return LoadIntoBufferAsync (0x2000); - } - - public Task LoadIntoBufferAsync (int maxBufferSize) - { - throw new NotImplementedException (); - } - - public Task ReadAsByteArrayAsync () + public async Task ReadAsByteArrayAsync () { - LoadIntoBuffer (); - throw new NotImplementedException (); -// return buffer.ToArray (); + await LoadIntoBufferAsync ().ConfigureAwait (false); + return buffer.ToArray (); } - public Task ReadAsStringAsync () + public async Task ReadAsStringAsync () { - LoadIntoBuffer (); + await LoadIntoBufferAsync (); if (buffer.Length == 0) - return Task.FromResult (string.Empty); + return string.Empty; Encoding encoding; if (headers != null && headers.ContentType != null && headers.ContentType.CharSet != null) { @@ -134,11 +110,9 @@ namespace System.Net.Http encoding = Encoding.UTF8; } - throw new NotImplementedException (); - //return encoding.GetString (buffer.GetBuffer (), 0, (int) buffer.Length); + return encoding.GetString (buffer.GetBuffer (), 0, (int) buffer.Length); } - protected abstract void SerializeToStream (Stream stream, TransportContext context); protected abstract Task SerializeToStreamAsync (Stream stream, TransportContext context); protected internal abstract bool TryComputeLength (out long length); } diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpRequestMessage.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpRequestMessage.cs index f6bf362c855..fd4f7c0d080 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpRequestMessage.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpRequestMessage.cs @@ -40,6 +40,7 @@ namespace System.Net.Http Dictionary properties; Uri uri; bool is_used; + bool disposed; public HttpRequestMessage () { @@ -121,6 +122,12 @@ namespace System.Net.Http protected virtual void Dispose (bool disposing) { + if (disposing && !disposed) { + disposed = true; + + if (Content != null) + Content.Dispose (); + } } internal bool SetIsUsed () diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpResponseMessage.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpResponseMessage.cs index 040ec6cfbdc..496f53d3365 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpResponseMessage.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpResponseMessage.cs @@ -36,6 +36,7 @@ namespace System.Net.Http string reasonPhrase; HttpStatusCode statusCode; Version version; + bool disposed; public HttpResponseMessage () : this (HttpStatusCode.OK) @@ -64,7 +65,7 @@ namespace System.Net.Http public string ReasonPhrase { get { - return reasonPhrase; // ?? HttpListener.GetStatusDescription (statusCode); + return reasonPhrase ?? HttpListenerResponse.GetStatusDescription ((int) statusCode); } set { reasonPhrase = value; @@ -104,6 +105,12 @@ namespace System.Net.Http protected virtual void Dispose (bool disposing) { + if (disposing && !disposed) { + disposed = true; + + if (Content != null) + Content.Dispose (); + } } public HttpResponseMessage EnsureSuccessStatusCode () diff --git a/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs b/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs index bc507ad081e..fd51a971709 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/StreamContent.cs @@ -62,11 +62,6 @@ namespace System.Net.Http base.Dispose (disposing); } - protected override void SerializeToStream (Stream stream, TransportContext context) - { - content.CopyTo (stream, bufferSize); - } - protected override Task SerializeToStreamAsync (Stream stream, TransportContext context) { return content.CopyToAsync (stream, bufferSize); diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/ByteArrayContentTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/ByteArrayContentTest.cs index f5d41e3e37b..a831f148bed 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/ByteArrayContentTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/ByteArrayContentTest.cs @@ -30,6 +30,7 @@ using System; using NUnit.Framework; using System.Net.Http; using System.IO; +using System.Threading.Tasks; namespace MonoTests.System.Net.Http { @@ -105,7 +106,8 @@ namespace MonoTests.System.Net.Http byte[] b = { 4 }; var sc = new ByteArrayContent (b); - sc.LoadIntoBufferAsync (400).Wait (); + var t = sc.LoadIntoBufferAsync (400); + t.Wait (); } [Test] diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs index b7cf6e5c402..ffcc0d2a46d 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs @@ -469,7 +469,6 @@ namespace MonoTests.System.Net.Http Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#1"); Assert.IsTrue (passed, "#2"); - } finally { listener.Abort (); listener.Close (); @@ -513,6 +512,7 @@ namespace MonoTests.System.Net.Http } [Test] + [Ignore] public void Send_InvalidHandler () { var mh = new HttpMessageHandlerMock (); @@ -542,13 +542,12 @@ namespace MonoTests.System.Net.Http var client = new HttpClient (mh); var request = new HttpRequestMessage (HttpMethod.Get, "http://xamarin.com"); - mh.OnSend = l => { - return Task.FromResult (new HttpResponseMessage ()); - }; + mh.OnSend = l => Task.FromResult (new HttpResponseMessage ()); client.SendAsync (request).Wait (); try { client.SendAsync (request).Wait (); + Assert.Fail ("#1"); } catch (InvalidOperationException) { } } diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs index 68c45bbe731..86c28ca330c 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs @@ -161,10 +161,13 @@ namespace MonoTests.System.Net.Http var scm = new StreamContentMock (new ExceptionStream ()); scm.OnSerializeToStreamAsync = () => { hit = true; }; task = scm.CopyToAsync (dest); - task.Wait (); + try { + task.Wait (); + Assert.Fail ("#9"); + } catch (AggregateException) { + } Assert.IsTrue (hit, "#10"); - //Assert.IsTrue (task.IsFaulted, "#11"); } [Test] diff --git a/mcs/class/System/Assembly/AssemblyInfo.cs b/mcs/class/System/Assembly/AssemblyInfo.cs index 32fbe1906ec..a6ec552db4e 100644 --- a/mcs/class/System/Assembly/AssemblyInfo.cs +++ b/mcs/class/System/Assembly/AssemblyInfo.cs @@ -73,6 +73,7 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo ("System.Net, PublicKey=00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB")] #else [assembly: InternalsVisibleTo ("System.ComponentModel.DataAnnotations, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")] + [assembly: InternalsVisibleTo ("System.Net.Http, PublicKey=00000000000000000400000000000000")] [assembly: StringFreezing] [assembly: DefaultDependency (LoadHint.Always)] #endif