* HttpResponseStream.cs: Added argument checks to Write. Modified
authorGert Driesen <drieseng@users.sourceforge.net>
Sun, 12 Jul 2009 22:19:02 +0000 (22:19 -0000)
committerGert Driesen <drieseng@users.sourceforge.net>
Sun, 12 Jul 2009 22:19:02 +0000 (22:19 -0000)
methods/properties that requires a readable stream to throw
NotSupportedException instead of InvalidOperationException for
compatibility with MS.
* HttpResponseTest.cs: Store data from all calls to
SendResponseFromMemory. Fixed ClearHeaders test to pass on MS. Added
several tests for outputstream of HttpResponse.

svn path=/trunk/mcs/; revision=137758

mcs/class/System.Web/System.Web/ChangeLog
mcs/class/System.Web/System.Web/HttpResponseStream.cs
mcs/class/System.Web/Test/System.Web/ChangeLog
mcs/class/System.Web/Test/System.Web/HttpResponseTest.cs

index cebe930c660cfbc226c3663cbfefc115202c6f7f..b5a3fca58f656da332806788c62d34c0ff110a28 100644 (file)
@@ -1,3 +1,10 @@
+2009-07-13  Gert Driesen  <drieseng@users.sourceforge.net>
+
+       * HttpResponseStream.cs: Added argument checks to Write. Modified
+       methods/properties that requires a readable stream to throw
+       NotSupportedException instead of InvalidOperationException for
+       compatibility with MS.
+
 2009-07-09 Gonzalo Paniagua Javier <gonzalo@novell.com>
 
        * HttpApplication.cs: use GetSection instead of
index d7e86bb7a598f04fc0316a34924820f7b0fa855e..6d95d895e93fcd1c84e2f68504683bb11f09d15a 100644 (file)
@@ -513,10 +513,31 @@ namespace System.Web {
 
                }
 
-               public override void Write (byte [] buffer, int offset, int count)
+               public override void Write (byte [] buffer, int offset, int count)
                {
                        bool buffering = response.BufferOutput;
 
+#if NET_2_0
+                       if (buffer == null)
+                               throw new ArgumentNullException ("buffer");
+#endif
+
+                       int max_count = buffer.Length - offset;
+#if NET_2_0
+                       if (offset < 0 || max_count <= 0)
+#else
+                       if (offset < 0)
+#endif
+                               throw new ArgumentOutOfRangeException ("offset");
+                       if (count < 0)
+                               throw new ArgumentOutOfRangeException ("count");
+                       if (count > max_count)
+                               count = max_count;
+#if ONLY_1_1
+                       if (max_count <= 0)
+                               return;
+#endif
+
                        if (buffering) {
                                // It does not matter whether we're in ApplyFilter or not
                                AppendBuffer (buffer, offset, count);
@@ -721,54 +742,54 @@ namespace System.Web {
                        memcpy4 (dest, src, size);
                }
 
-               public override bool CanRead {
-                       get {
+               public override bool CanRead {
+                       get {
                                return false;
-                       }       
-               }
-                       
-               public override bool CanSeek {
-                       get {
+                       }
+               }
+
+               public override bool CanSeek {
+                       get {
                                return false;
                        }
-               }
-               public override bool CanWrite {
-                       get {
+               }
+
+               public override bool CanWrite {
+                       get {
                                return true;
                        }
-               }
-               
+               }
+
                const string notsupported = "HttpResponseStream is a forward, write-only stream";
-               
-               public override long Length {
-                       get {
-                               throw new InvalidOperationException (notsupported);
+
+               public override long Length {
+                       get {
+                               throw new NotSupportedException (notsupported);
                        }
-               }
+               }
        
                public override long Position {
-                       get {
-                               throw new InvalidOperationException (notsupported);
+                       get {
+                               throw new NotSupportedException (notsupported);
                        }
-                       set {
-                               throw new InvalidOperationException (notsupported);
+                       set {
+                               throw new NotSupportedException (notsupported);
                        }
-               }
+               }
                
-               public override long Seek (long offset, SeekOrigin origin)
+               public override long Seek (long offset, SeekOrigin origin)
                {
-                       throw new InvalidOperationException (notsupported);
+                       throw new NotSupportedException (notsupported);
                }
-               
-               public override void SetLength (long value) 
+
+               public override void SetLength (long value) 
                {
-                       throw new InvalidOperationException (notsupported);
+                       throw new NotSupportedException (notsupported);
                }
        
                public override int Read (byte [] buffer, int offset, int count)
                {
-                       throw new InvalidOperationException (notsupported);
+                       throw new NotSupportedException (notsupported);
                }
        }
 }
-
index cb2d6997c1864535c71340de70fb911bbdb533ca..1c35caa3c06ae391b9baf53f98ad5508f9cb1ffb 100644 (file)
@@ -1,3 +1,9 @@
+2009-07-13  Gert Driesen  <drieseng@users.sourceforge.net>
+
+       * HttpResponseTest.cs: Store data from all calls to
+       SendResponseFromMemory. Fixed ClearHeaders test to pass on MS. Added
+       several tests for outputstream of HttpResponse.
+
 2009-05-28  Marek Habersack  <mhabersack@novell.com>
 
        * HttpUtilityTest.cs: added test for bug #507666
index 691eb392c0c2cfedc5c28765a029c6ab1582e9b8..52ab2c680602c59fc8f7f5ca228896fd277c99f4 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System.Text;
-using System.Web;
 using System;
 using System.Collections;
 using System.Collections.Specialized;
+using System.IO;
+using System.Text;
+using System.Web;
+
 using NUnit.Framework;
 
 namespace MonoTests.System.Web {
@@ -151,11 +153,19 @@ namespace MonoTests.System.Web {
                public override void SendResponseFromMemory(byte[] arr, int x)
                {
                        data_sent = true;
-                       data = new byte [x];
-                       for (int i = 0; i < x; i++)
-                               data [i] = arr [i];
-                       data_len = x;
-                       total += data_len;
+                       if (data != null) {
+                               byte [] tmp = new byte [data.Length + x];
+                               Array.Copy (data, tmp, data.Length);
+                               Array.Copy (arr, 0, tmp, data.Length, x);
+                               data = tmp;
+                               data_len = data.Length;
+                       } else {
+                               data = new byte [x];
+                               for (int i = 0; i < x; i++)
+                                       data [i] = arr [i];
+                               data_len = x;
+                       }
+                       total += x;
                }
                
                public override void SendResponseFromFile(string a, long b , long c)
@@ -261,11 +271,12 @@ namespace MonoTests.System.Web {
                        c.Response.Write ("Hola");
                        Assert.AreEqual (1, f.data_len, "T3");
                        c.Response.Flush ();
-                       Assert.AreEqual (4, f.data_len, "T4");
-                       Assert.AreEqual ((byte) 'H', f.data [0], "T5");
-                       Assert.AreEqual ((byte) 'o', f.data [1], "T6");
-                       Assert.AreEqual ((byte) 'l', f.data [2], "T7");
-                       Assert.AreEqual ((byte) 'a', f.data [3], "T8");
+                       Assert.AreEqual (5, f.data_len, "T4");
+                       Assert.AreEqual ((byte) 'a', f.data [0], "T5");
+                       Assert.AreEqual ((byte) 'H', f.data [1], "T6");
+                       Assert.AreEqual ((byte) 'o', f.data [2], "T7");
+                       Assert.AreEqual ((byte) 'l', f.data [3], "T8");
+                       Assert.AreEqual ((byte) 'a', f.data [4], "T9");
                }
 
                [Test]
@@ -505,22 +516,22 @@ namespace MonoTests.System.Web {
                        UnknownResponseHeader unknown;
 
                        Assert.AreEqual (3, f.UnknownResponseHeaders.Count, "#C1");
-                       
+
                        unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["X-AspNet-Version"];
                        Assert.AreEqual ("X-AspNet-Version", unknown.Name, "#C2");
                        Assert.AreEqual (Environment.Version.ToString (3), unknown.Value, "#C3");
-                       
+
                        unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["Content-Disposition"];
                        Assert.AreEqual ("Content-Disposition", unknown.Name, "#C4");
                        Assert.AreEqual ("inline", unknown.Value, "#C5");
 
                        ArrayList al = f.UnknownResponseHeaders ["My-Custom-Header"] as ArrayList;
                        Assert.AreEqual (2, al.Count, "#C6");
-                       
+
                        unknown = (UnknownResponseHeader) al [0];
                        Assert.AreEqual ("My-Custom-Header", unknown.Name, "#C7");
                        Assert.AreEqual ("never", unknown.Value, "#C8");
-                       
+
                        unknown = (UnknownResponseHeader) al [1];
                        Assert.AreEqual ("My-Custom-Header", unknown.Name, "#C9");
                        Assert.AreEqual ("always", unknown.Value, "#C10");
@@ -554,14 +565,11 @@ namespace MonoTests.System.Web {
 
                        KnownResponseHeader known;
 
-                       Assert.AreEqual (2, f.KnownResponseHeaders.Count, "#B1");
-                       // Assert.IsTrue (f != null, "f is null");
-                       // Assert.IsTrue (f.KnownResponseHeaders != null, "f.KnownResponseHeaders is null");
-                       // Assert.IsTrue (f.KnownResponseHeaders ["Transfer-Encoding"] != null, "No Transfer-Encoding");
+                       Assert.AreEqual (3, f.KnownResponseHeaders.Count, "#B1");
                        
-                       // known = (KnownResponseHeader) f.KnownResponseHeaders ["Transfer-Encoding"];
-                       // Assert.AreEqual (HttpWorkerRequest.HeaderTransferEncoding, known.Index, "#B2");
-                       // Assert.AreEqual ("chunked", known.Value, "#B3");
+                       known = (KnownResponseHeader) f.KnownResponseHeaders ["Transfer-Encoding"];
+                       Assert.AreEqual (HttpWorkerRequest.HeaderTransferEncoding, known.Index, "#B2");
+                       Assert.AreEqual ("chunked", known.Value, "#B3");
                        
                        known = (KnownResponseHeader) f.KnownResponseHeaders ["Cache-Control"];
                        Assert.AreEqual (HttpWorkerRequest.HeaderCacheControl, known.Index, "#B4");
@@ -581,4 +589,280 @@ namespace MonoTests.System.Web {
 #endif
                }
        }
+
+       [TestFixture]
+       public class HttpResponseOutputStreamTest
+       {
+               FakeHttpWorkerRequest2 worker;
+               HttpContext context;
+               HttpResponse response;
+               Stream out_stream;
+
+               [SetUp]
+               public void Setup ()
+               {
+                       context = Cook (2, out worker);
+                       response = context.Response;
+                       out_stream = response.OutputStream;
+               }
+
+               [TearDown]
+               public void TearDown ()
+               {
+                       if (response != null)
+                               response.Close ();
+               }
+
+               [Test]
+               public void CanRead ()
+               {
+                       Assert.IsFalse (out_stream.CanRead, "#1");
+                       out_stream.Close ();
+                       Assert.IsFalse (out_stream.CanRead, "#2");
+               }
+
+               [Test]
+               public void CanSeek ()
+               {
+                       Assert.IsFalse (out_stream.CanSeek, "#1");
+                       out_stream.Close ();
+                       Assert.IsFalse (out_stream.CanSeek, "#2");
+               }
+
+               [Test]
+               public void CanWrite ()
+               {
+                       Assert.IsTrue (out_stream.CanWrite, "#1");
+                       out_stream.Close ();
+                       Assert.IsTrue (out_stream.CanWrite, "#2");
+               }
+
+               [Test]
+               public void Flush ()
+               {
+                       byte [] buffer = Encoding.UTF8.GetBytes ("mono");
+                       out_stream.Write (buffer, 0, buffer.Length);
+                       out_stream.Flush ();
+                       Assert.AreEqual (0, worker.data_len);
+               }
+
+               [Test]
+               public void Length ()
+               {
+                       try {
+                               long len = out_stream.Length;
+                               Assert.Fail ("#1:" + len);
+                       } catch (NotSupportedException ex) {
+                               Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                       }
+               }
+
+               [Test]
+               public void Position ()
+               {
+                       try {
+                               long pos = out_stream.Position;
+                               Assert.Fail ("#A1:" + pos);
+                       } catch (NotSupportedException ex) {
+                               Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                       }
+
+                       try {
+                               out_stream.Position = 0;
+                               Assert.Fail ("#B1");
+                       } catch (NotSupportedException ex) {
+                               Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                       }
+               }
+
+               [Test]
+               public void Read ()
+               {
+                       byte [] buffer = new byte [5];
+
+                       try {
+                               out_stream.Read (buffer, 0, buffer.Length);
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException ex) {
+                               Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                       }
+               }
+
+               [Test]
+               public void Seek ()
+               {
+                       try {
+                               out_stream.Seek (5, SeekOrigin.Begin);
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException ex) {
+                               Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                       }
+               }
+
+               [Test]
+               public void SetLength ()
+               {
+                       try {
+                               out_stream.SetLength (5L);
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException ex) {
+                               Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                       }
+               }
+
+               [Test]
+               public void Write ()
+               {
+                       byte [] buffer;
+
+                       buffer = Encoding.UTF8.GetBytes ("mono");
+                       out_stream.Write (buffer, 0, buffer.Length);
+                       buffer = Encoding.UTF8.GetBytes ("just rocks!!");
+                       out_stream.Write (buffer, 5, 6);
+                       out_stream.Write (buffer, 0, 4);
+                       Assert.IsFalse (worker.OutputProduced, "#1");
+                       response.Flush ();
+                       Assert.IsTrue (worker.OutputProduced, "#2");
+
+                       string output = Encoding.UTF8.GetString (worker.data);
+                       Assert.AreEqual ("e\r\nmonorocks!just\r\n", output);
+               }
+
+               [Test]
+               public void Write_Buffer_Null ()
+               {
+                       try {
+                               out_stream.Write ((byte []) null, 0, 0);
+                               Assert.Fail ("#1");
+#if NET_2_0
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.AreEqual ("buffer", ex.ParamName, "#5");
+                       }
+#else
+                       } catch (NullReferenceException) {
+                       }
+#endif
+               }
+
+               [Test]
+               public void Write_Count_Negative ()
+               {
+                       byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
+
+                       // offset < 0
+                       try {
+                               out_stream.Write (buffer, 1, -1);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentOutOfRangeException ex) {
+                               Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.AreEqual ("count", ex.ParamName, "#5");
+                       }
+               }
+
+               [Test]
+               public void Write_Count_Overflow ()
+               {
+                       byte [] buffer;
+
+                       buffer = Encoding.UTF8.GetBytes ("Mono");
+                       out_stream.Write (buffer, 0, buffer.Length + 5);
+                       buffer = Encoding.UTF8.GetBytes ("Just Rocks!!");
+                       out_stream.Write (buffer, 5, buffer.Length - 2);
+                       response.Flush ();
+
+                       string output = Encoding.UTF8.GetString (worker.data);
+                       Assert.AreEqual ("b\r\nMonoRocks!!\r\n", output);
+               }
+
+               [Test]
+               public void Write_Offset_Negative ()
+               {
+                       byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
+
+                       // offset < 0
+                       try {
+                               out_stream.Write (buffer, -1, 0);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentOutOfRangeException ex) {
+                               Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.AreEqual ("offset", ex.ParamName, "#5");
+                       }
+               }
+
+               [Test]
+               public void Write_Offset_Overflow ()
+               {
+                       byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
+
+                       // offset == buffer length
+#if NET_2_0
+                       try {
+                               out_stream.Write (buffer, buffer.Length, 0);
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentOutOfRangeException ex) {
+                               Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.AreEqual ("offset", ex.ParamName, "#A5");
+                       }
+#else
+                       out_stream.Write (buffer, buffer.Length, 0);
+#endif
+
+                       // offset > buffer length
+#if NET_2_0
+                       try {
+                               out_stream.Write (buffer, buffer.Length + 1, 0);
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentOutOfRangeException ex) {
+                               Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.AreEqual ("offset", ex.ParamName, "#B5");
+                       }
+#else
+                       out_stream.Write (buffer, buffer.Length + 1, 0);
+#endif
+
+                       response.Flush ();
+                       Assert.AreEqual (0, worker.data_len);
+               }
+
+               [Test]
+               public void Write_Stream_Closed ()
+               {
+                       byte [] buffer = Encoding.UTF8.GetBytes ("mono");
+                       out_stream.Close ();
+                       out_stream.Write (buffer, 0, buffer.Length);
+                       response.Flush ();
+
+                       string output = Encoding.UTF8.GetString (worker.data);
+                       Assert.AreEqual ("4\r\nmono\r\n", output);
+               }
+
+               HttpContext Cook (int re, out FakeHttpWorkerRequest2 f)
+               {
+                       f = new FakeHttpWorkerRequest2 (re);
+                       return new HttpContext (f);
+               }
+       }
 }