More work on System.Net.Http
authorMarek Safar <marek.safar@gmail.com>
Thu, 26 Apr 2012 12:40:26 +0000 (13:40 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 26 Apr 2012 12:50:05 +0000 (13:50 +0100)
mcs/class/System.Net.Http/Assembly/AssemblyInfo.cs
mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs
mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs
mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs
mcs/class/System.Net.Http/System.Net.Http/HttpRequestMessage.cs
mcs/class/System.Net.Http/System.Net.Http/HttpResponseMessage.cs
mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs
mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs
mcs/class/System/Assembly/AssemblyInfo.cs

index 1b530078df56c56cebc665a514372c3279be8a22..869ab38bc95ef97f051374682be282473a69ef47 100644 (file)
@@ -53,7 +53,7 @@ using System.Runtime.InteropServices;
 [assembly: CLSCompliant (true)]
 [assembly: AssemblyDelaySign (true)]
 
-[assembly: AssemblyKeyFile ("../ecma.pub")]
+[assembly: AssemblyKeyFile ("../msfinal.pub")]
 
 [assembly: ComVisible (false)]
 
index acfea3ef918a5db41d85c26365006a0d937533de..9a4ac95f9e31387f536615040a0a7ba3f3584cbf 100644 (file)
@@ -253,10 +253,10 @@ namespace System.Net.Http
                                request.Headers.AddHeaders (headers);
                        }
 
-                       return SendAsyncWorker (request, cancellationToken);
+                       return SendAsyncWorker (request, completionOption, cancellationToken);
                }
 
-               async Task<HttpResponseMessage> SendAsyncWorker (HttpRequestMessage request, CancellationToken cancellationToken)
+               async Task<HttpResponseMessage> SendAsyncWorker (HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
                {
                        try {
                                if (cancellation_token == null)
@@ -273,6 +273,13 @@ namespace System.Net.Http
                                        if (response == null)
                                                throw new InvalidOperationException ("Handler failed to return a response");
 
+                                       //
+                                       // Read the content when default HttpCompletionOption.ResponseContentRead is set
+                                       //
+                                       if (response.Content != null && (completionOption & HttpCompletionOption.ResponseHeadersRead) == 0) {
+                                               await response.Content.LoadIntoBufferAsync (MaxResponseContentBufferSize).ConfigureAwait (false);
+                                       }
+                                       
                                        return response;
                                }
                        } finally {
index 4d9eeafc369573bfb577b0784af3483ed56de374..6ba92066f167819fbce1c252b9db6c79d15ad4ea 100644 (file)
@@ -200,9 +200,6 @@ namespace System.Net.Http
 
                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 wr = new HttpWebRequest (request.RequestUri);
                        wr.ThrowOnError = false;
 
index 247e9c40454b3a2ae42ad9df4240b23dc0f69668..84d65a637e023e839e96603f65348e870eb85b5e 100644 (file)
@@ -35,7 +35,36 @@ namespace System.Net.Http
 {
        public abstract class HttpContent : IDisposable
        {
-               MemoryStream buffer;
+               sealed class FixedMemoryStream : MemoryStream
+               {
+                       readonly int maxSize;
+                       
+                       public FixedMemoryStream (int maxSize)
+                               : base ()
+                       {
+                               this.maxSize = maxSize;
+                       }
+                       
+                       void CheckOverflow (int count)
+                       {
+                               if (Length + count > maxSize)
+                                       throw new HttpRequestException (string.Format ("Cannot write more bytes to the buffer than the configured maximum buffer size: {0}", maxSize));
+                       }
+                       
+                       public override void WriteByte (byte value)
+                       {
+                               CheckOverflow (1);
+                               base.WriteByte (value);
+                       }
+                       
+                       public override void Write (byte[] buffer, int offset, int count)
+                       {
+                               CheckOverflow (count);
+                               base.Write (buffer, offset, count);
+                       }
+               }
+               
+               FixedMemoryStream buffer;
                Stream stream;
                bool disposed;
                HttpContentHeaders headers;
@@ -64,6 +93,11 @@ namespace System.Net.Http
                        await LoadIntoBufferAsync ().ConfigureAwait (false);
                        return buffer;
                }
+               
+               static FixedMemoryStream CreateFixedMemoryStream (int maxBufferSize)
+               {
+                       return new FixedMemoryStream (maxBufferSize);
+               }
 
                public void Dispose ()
                {
@@ -93,7 +127,7 @@ namespace System.Net.Http
                        if (buffer != null)
                                return;
 
-                       buffer = new MemoryStream ();
+                       buffer = CreateFixedMemoryStream (maxBufferSize);
                        await SerializeToStreamAsync (buffer, null).ConfigureAwait (false);
                        buffer.Seek (0, SeekOrigin.Begin);
                }
index 40aa64b9a2851e774718afd9fdc29d0ef71a8535..00bee6f66467405242b6b2cb63c422e7426fd2ea 100644 (file)
@@ -34,7 +34,6 @@ namespace System.Net.Http
 {
        public class HttpRequestMessage : IDisposable
        {
-               HttpContent content;
                HttpRequestHeaders headers;
                HttpMethod method;
                Version version;
@@ -59,14 +58,7 @@ namespace System.Net.Http
                        RequestUri = requestUri;
                }
 
-               public HttpContent Content {
-                       get {
-                               return content;
-                       }
-                       set {
-                               content = value;
-                       }
-               }
+               public HttpContent Content { get; set; }
 
                public HttpRequestHeaders Headers {
                        get {
@@ -148,6 +140,8 @@ namespace System.Net.Http
                        sb.Append ("', Version: ").Append (Version);
                        sb.Append (", Content: ").Append (Content != null ? Content.ToString () : "<null>");
                        sb.Append (", Headers:\r\n{\r\n").Append (Headers);
+                       if (Content != null)
+                               sb.Append (Content.Headers);
                        sb.Append ("}");
                        
                        return sb.ToString ();
index d95b7984e004cfcdb1939d11e370e76a764cf533..bf39da68917b6f46e58c0c349099a2d4d8cb5ea4 100644 (file)
@@ -130,6 +130,9 @@ namespace System.Net.Http
                        sb.Append ("', Version: ").Append (Version);
                        sb.Append (", Content: ").Append (Content != null ? Content.ToString () : "<null>");
                        sb.Append (", Headers:\r\n{\r\n").Append (Headers);
+                       if (Content != null)
+                               sb.Append (Content.Headers);
+                       
                        sb.Append ("}");
                        
                        return sb.ToString ();
index c2b6e41b7365b2742f3b492b14916f91362ee357..90c8a2d54f905f2c14337a9abc3a389afeba4910 100644 (file)
@@ -438,6 +438,81 @@ namespace MonoTests.System.Net.Http
                        }
                }
 
+               [Test]
+               public void Send_Complete_Content ()
+               {
+                       var listener = CreateListener (l => {
+                               var request = l.Request;
+                               l.Response.OutputStream.WriteByte (55);
+                               l.Response.OutputStream.WriteByte (75);
+                       });
+
+                       try {
+                               var client = new HttpClient ();
+                               var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+                               request.Headers.AddWithoutValidation ("aa", "vv");
+                               var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+                               Assert.AreEqual ("7K", response.Content.ReadAsStringAsync ().Result, "#100");
+                               Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+
+                               IEnumerable<string> values;
+                               Assert.IsTrue (response.Headers.TryGetValues ("Transfer-Encoding", out values), "#102");
+                               Assert.AreEqual ("chunked", values.First (), "#102a");
+                               Assert.AreEqual (true, response.Headers.TransferEncodingChunked, "#102b");
+                       } finally {
+                               listener.Close ();
+                       }
+               }
+
+               [Test]
+               public void Send_Complete_Content_MaxResponseContentBufferSize ()
+               {
+                       var listener = CreateListener (l => {
+                               var request = l.Request;
+                               var b = new byte[4000];
+                               l.Response.OutputStream.Write (b, 0, b.Length);
+                       });
+
+                       try {
+                               var client = new HttpClient ();
+                               client.MaxResponseContentBufferSize = 1000;
+                               var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+                               var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+                               Assert.AreEqual (4000, response.Content.ReadAsStringAsync ().Result.Length, "#100");
+                               Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+                       } finally {
+                               listener.Close ();
+                       }
+               }
+
+               [Test]
+               public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
+               {
+                       var listener = CreateListener (l => {
+                               var request = l.Request;
+                               var b = new byte[4000];
+                               l.Response.OutputStream.Write (b, 0, b.Length);
+                       });
+
+                       try {
+                               var client = new HttpClient ();
+                               client.MaxResponseContentBufferSize = 1000;
+                               var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+
+                               try {
+                                       client.SendAsync (request, HttpCompletionOption.ResponseContentRead).Wait ();
+                                       Assert.Fail ("#2");
+                               } catch (AggregateException e) {
+                                       Assert.IsInstanceOfType (typeof (HttpRequestException), e.InnerException, "#3");
+                               }
+
+                       } finally {
+                               listener.Close ();
+                       }
+               }
+
                [Test]
                public void Send_Complete_Error ()
                {
index 2e0975e030155c87497eb87404a473eef0d3c558..46459f0079aba433a4c726b666c83b61dca9f122 100644 (file)
@@ -302,6 +302,22 @@ namespace MonoTests.System.Net.Http
                        Assert.IsTrue (sc.LoadIntoBufferAsync (400).Wait (200));
                }
 
+               [Test]
+               public void LoadIntoBuffer_BufferOverflow ()
+               {
+                       var ms = new MemoryStream ();
+                       ms.Write (new byte[10000], 0, 10000);
+                       ms.Seek (0, SeekOrigin.Begin);
+
+                       var sc = new StreamContent (ms);
+                       try {
+                               Assert.IsTrue (sc.LoadIntoBufferAsync (50).Wait (200));
+                               Assert.Fail ("#1");
+                       } catch (AggregateException e) {
+                               Assert.IsInstanceOfType (typeof (HttpRequestException), e.InnerException, "#2");
+                       }
+               }
+
                [Test]
                public void ReadAsByteArrayAsync ()
                {
index a6ec552db4ea84bf94cd6d2eb3e4ec317b801e6c..a565b594ac3e93a2465b749adc11a3b0c2d3db5f 100644 (file)
@@ -73,7 +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: InternalsVisibleTo ("System.Net.Http, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
        [assembly: StringFreezing]
        [assembly: DefaultDependency (LoadHint.Always)]
 #endif