Updated Branches:
  refs/heads/wicket-1.5.x 7308d624b -> 7b711dcda

WICKET-4927 merged from trunk

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/7b711dcd
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/7b711dcd
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/7b711dcd

Branch: refs/heads/wicket-1.5.x
Commit: 7b711dcdadd4386039feb4f7ea2ec93ed409f9a0
Parents: 7308d62
Author: svenmeier <[email protected]>
Authored: Fri Dec 14 16:31:49 2012 +0100
Committer: svenmeier <[email protected]>
Committed: Fri Dec 14 16:31:49 2012 +0100

----------------------------------------------------------------------
 .../protocol/http/HeaderBufferingWebResponse.java  |   98 ++++++-----
 .../http/HeaderBufferingWebResponseTest.java       |  119 ++++---------
 .../protocol/http/ResponseIOExceptionTest.java     |  134 +++++++++++++++
 .../wicket/request/HttpHeaderCollection.java       |   56 +++---
 4 files changed, 247 insertions(+), 160 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/7b711dcd/wicket-core/src/main/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponse.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponse.java
 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponse.java
index 5463114..44c5073 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponse.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponse.java
@@ -24,135 +24,134 @@ import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.time.Time;
 
 /**
- * Response that keeps headers in buffers but writes the content directly to 
the response.
+ * Response that keeps headers in buffers until the first content is written.
  * 
  * This is necessary to get {@link #reset()} working without removing the 
JSESSIONID cookie. When
  * {@link HttpServletResponse#reset()} is called it removes all cookies, 
including the JSESSIONID
- * cookie.
+ * cookie - see <a 
href="https://issues.apache.org/bugzilla/show_bug.cgi?id=26183";>Bug 26183</a>.
  * 
- * Calling {@link #reset()} on this response only clears the buffered headers. 
If there is any
- * content written to response it throws {@link IllegalStateException}.
+ * Calling {@link #reset()} on this response clears the buffered meta data, if 
there is already any
+ * content written it throws {@link IllegalStateException}.
  * 
  * @author Matej Knopp
  */
 class HeaderBufferingWebResponse extends WebResponse implements 
IMetaDataBufferingWebResponse
 {
        private final WebResponse originalResponse;
+
+       /**
+        * Buffer of meta data.
+        */
        private final BufferedWebResponse bufferedResponse;
 
        public HeaderBufferingWebResponse(WebResponse originalResponse)
        {
                this.originalResponse = originalResponse;
+
                bufferedResponse = new BufferedWebResponse(originalResponse);
        }
 
-       private boolean bufferedWritten = false;
+       private boolean buffering = true;
 
-       private void writeBuffered()
+       private void stopBuffering()
        {
-               if (!bufferedWritten)
+               if (buffering)
                {
                        bufferedResponse.writeTo(originalResponse);
-                       bufferedWritten = true;
+                       buffering = false;
                }
        }
 
-       private void checkHeader()
+       /**
+        * The response used for meta data.
+        * 
+        * @return buffered response if nothing was written yet, the original 
response otherwise
+        */
+       private WebResponse getMetaResponse()
        {
-               if (bufferedWritten)
+               if (buffering)
+               {
+                       return bufferedResponse;
+               }
+               else
                {
-                       throw new IllegalStateException("Header was already 
written to response!");
+                       return originalResponse;
                }
        }
 
        @Override
        public void addCookie(Cookie cookie)
        {
-               checkHeader();
-               bufferedResponse.addCookie(cookie);
+               getMetaResponse().addCookie(cookie);
        }
 
        @Override
        public void clearCookie(Cookie cookie)
        {
-               checkHeader();
-               bufferedResponse.clearCookie(cookie);
+               getMetaResponse().clearCookie(cookie);
        }
 
-       private boolean flushed = false;
-
        @Override
        public void flush()
        {
-               if (!bufferedWritten)
-               {
-                       bufferedResponse.writeTo(originalResponse);
-                       bufferedResponse.reset();
-               }
+               stopBuffering();
+
                originalResponse.flush();
-               flushed = true;
        }
 
        @Override
        public boolean isRedirect()
        {
-               return bufferedResponse.isRedirect();
+               return getMetaResponse().isRedirect();
        }
 
        @Override
        public void sendError(int sc, String msg)
        {
-               checkHeader();
-               bufferedResponse.sendError(sc, msg);
+               getMetaResponse().sendError(sc, msg);
        }
 
        @Override
        public void sendRedirect(String url)
        {
-               checkHeader();
-               bufferedResponse.sendRedirect(url);
+               getMetaResponse().sendRedirect(url);
        }
 
        @Override
        public void setContentLength(long length)
        {
-               checkHeader();
-               bufferedResponse.setContentLength(length);
+               getMetaResponse().setContentLength(length);
        }
 
        @Override
        public void setContentType(String mimeType)
        {
-               checkHeader();
-               bufferedResponse.setContentType(mimeType);
+               getMetaResponse().setContentType(mimeType);
        }
 
        @Override
        public void setDateHeader(String name, Time date)
        {
                Args.notNull(date, "date");
-               checkHeader();
-               bufferedResponse.setDateHeader(name, date);
+               getMetaResponse().setDateHeader(name, date);
        }
 
        @Override
        public void setHeader(String name, String value)
        {
-               checkHeader();
-               bufferedResponse.setHeader(name, value);
+               getMetaResponse().setHeader(name, value);
        }
 
        @Override
        public void addHeader(String name, String value)
        {
-               checkHeader();
-               bufferedResponse.addHeader(name, value);
+               getMetaResponse().addHeader(name, value);
        }
 
        @Override
        public void setStatus(int sc)
        {
-               bufferedResponse.setStatus(sc);
+               getMetaResponse().setStatus(sc);
        }
 
        @Override
@@ -170,14 +169,16 @@ class HeaderBufferingWebResponse extends WebResponse 
implements IMetaDataBufferi
        @Override
        public void write(CharSequence sequence)
        {
-               writeBuffered();
+               stopBuffering();
+
                originalResponse.write(sequence);
        }
 
        @Override
        public void write(byte[] array)
        {
-               writeBuffered();
+               stopBuffering();
+
                originalResponse.write(array);
        }
 
@@ -185,19 +186,24 @@ class HeaderBufferingWebResponse extends WebResponse 
implements IMetaDataBufferi
        @Override
        public void write(byte[] array, int offset, int length)
        {
-               writeBuffered();
+               stopBuffering();
+
                originalResponse.write(array, offset, length);
        }
 
        @Override
        public void reset()
        {
-               if (flushed)
+               if (buffering)
+               {
+                       // still buffering so just reset the buffer of meta data
+                       bufferedResponse.reset();
+               }
+               else
                {
-                       throw new IllegalStateException("Response has already 
been flushed!");
+                       // the original response is never reset (see class 
javadoc)
+                       throw new IllegalStateException("Response is no longer 
buffering!");
                }
-               bufferedResponse.reset();
-               bufferedWritten = false;
        }
 
        public void writeMetaData(WebResponse webResponse)

http://git-wip-us.apache.org/repos/asf/wicket/blob/7b711dcd/wicket-core/src/test/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponseTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponseTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponseTest.java
index 6c0bca7..1383b4b 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponseTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponseTest.java
@@ -16,120 +16,67 @@
  */
 package org.apache.wicket.protocol.http;
 
-import java.net.SocketException;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.wicket.protocol.http.servlet.ResponseIOException;
-import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
-import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
-import org.apache.wicket.request.IRequestHandler;
-import org.apache.wicket.request.Response;
-import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
-import org.apache.wicket.request.cycle.RequestCycle;
-import org.apache.wicket.request.handler.EmptyRequestHandler;
-import org.apache.wicket.request.resource.ResourceStreamResource;
-import org.apache.wicket.util.resource.StringResourceStream;
-import org.apache.wicket.util.tester.WicketTester;
-import org.junit.After;
+import org.apache.wicket.mock.MockWebResponse;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
 
 
 /**
- * @author Pedro Santos
+ * Test for {@link HeaderBufferingWebResponse}.
+ * 
+ * @author svenmeier
  */
 public class HeaderBufferingWebResponseTest extends Assert
 {
-       private WicketTester tester;
 
        /**
-        * @throws Exception
+        * WICKET-4927
         */
-       @Before
-       public void before() throws Exception
+       @Test
+       public void additionalHeaderAfterWrittenContent()
        {
-               tester = new WicketTester()
-               {
-                       @Override
-                       protected Response 
newServletWebResponse(ServletWebRequest servletWebRequest)
-                       {
-                               return new HeaderBufferingWebResponse(new 
ProblematicResponse(servletWebRequest,
-                                       getResponse()));
-                       }
-               };
-               tester.setExposeExceptions(false);
-       }
+               MockWebResponse originalResponse = new MockWebResponse();
 
-       /**
-        * @throws Exception
-        */
-       @After
-       public void after() throws Exception
-       {
-               tester.destroy();
+               HeaderBufferingWebResponse response = new 
HeaderBufferingWebResponse(originalResponse);
+
+               response.addHeader("key1", "value1");
+
+               assertNull(originalResponse.getHeader("key1"));
+
+               response.write("written");
+
+               assertEquals("value1", originalResponse.getHeader("key1"));
+
+               response.addHeader("key2", "value2");
+
+               assertEquals("value2", originalResponse.getHeader("key2"));
        }
 
        /**
-        * WICKET-3570
         */
        @Test
-       public void giveUpRespondingOnIOExceptions()
+       public void resetAfterWrittenContent()
        {
-               TestRequestCycleListener testRequestCycleListener = new 
TestRequestCycleListener();
-               
tester.getApplication().getRequestCycleListeners().add(testRequestCycleListener);
-               tester.startResource(new ResourceStreamResource(new 
StringResourceStream("asdf")));
-               
assertTrue(testRequestCycleListener.lastExceptionRquestHandlerResolved 
instanceof EmptyRequestHandler);
-       }
+               MockWebResponse originalResponse = new MockWebResponse();
 
-       class TestRequestCycleListener extends AbstractRequestCycleListener
-       {
-               IRequestHandler lastExceptionRquestHandlerResolved;
+               HeaderBufferingWebResponse response = new 
HeaderBufferingWebResponse(originalResponse);
 
-               @Override
-               public void onExceptionRequestHandlerResolved(RequestCycle 
cycle, IRequestHandler handler,
-                       Exception exception)
-               {
-                       lastExceptionRquestHandlerResolved = handler;
-               }
+               response.addHeader("key1", "value1");
 
-       }
-       /**
-        * Mock response simulating connection lost problems.
-        */
-       public static class ProblematicResponse extends ServletWebResponse
-       {
+               assertNull(originalResponse.getHeader("key1"));
 
-               /**
-                * @param webRequest
-                * @param httpServletResponse
-                */
-               public ProblematicResponse(ServletWebRequest webRequest,
-                       HttpServletResponse httpServletResponse)
-               {
-                       super(webRequest, httpServletResponse);
-               }
+               response.reset();
 
-               @Override
-               public void flush()
-               {
-                       throw new ResponseIOException(new SocketException(
-                               "Connection reset by peer: socket write 
error"));
-               }
+               response.write("written");
 
-               @Override
-               public void write(byte[] array)
+               try
                {
-                       throw new ResponseIOException(new SocketException(
-                               "Connection reset by peer: socket write 
error"));
-               }
+                       response.reset();
 
-               @Override
-               public void write(CharSequence sequence)
+                       fail();
+               }
+               catch (IllegalStateException expected)
                {
-                       throw new ResponseIOException(new SocketException(
-                               "Connection reset by peer: socket write 
error"));
                }
        }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/7b711dcd/wicket-core/src/test/java/org/apache/wicket/protocol/http/ResponseIOExceptionTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/ResponseIOExceptionTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/ResponseIOExceptionTest.java
new file mode 100644
index 0000000..426d209
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/ResponseIOExceptionTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.wicket.protocol.http;
+
+import java.net.SocketException;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.wicket.protocol.http.servlet.ResponseIOException;
+import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
+import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.handler.EmptyRequestHandler;
+import org.apache.wicket.request.resource.ResourceStreamResource;
+import org.apache.wicket.util.resource.StringResourceStream;
+import org.apache.wicket.util.tester.WicketTester;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * @author Pedro Santos
+ */
+public class ResponseIOExceptionTest extends Assert
+{
+       private WicketTester tester;
+
+       /**
+        * @throws Exception
+        */
+       @Before
+       public void before() throws Exception
+       {
+               tester = new WicketTester()
+               {
+                       @Override
+                       protected Response 
newServletWebResponse(ServletWebRequest servletWebRequest)
+                       {
+                               return new 
ProblematicResponse(servletWebRequest, getResponse());
+                       }
+               };
+               tester.setExposeExceptions(false);
+       }
+
+       /**
+        * @throws Exception
+        */
+       @After
+       public void after() throws Exception
+       {
+               tester.destroy();
+       }
+
+       /**
+        * WICKET-3570
+        */
+       @Test
+       public void giveUpRespondingOnIOExceptions()
+       {
+               TestRequestCycleListener testRequestCycleListener = new 
TestRequestCycleListener();
+               
tester.getApplication().getRequestCycleListeners().add(testRequestCycleListener);
+               tester.startResource(new ResourceStreamResource(new 
StringResourceStream("asdf")));
+               
assertTrue(testRequestCycleListener.lastExceptionRquestHandlerResolved 
instanceof EmptyRequestHandler);
+       }
+
+       class TestRequestCycleListener extends AbstractRequestCycleListener
+       {
+               IRequestHandler lastExceptionRquestHandlerResolved;
+
+               @Override
+               public void onExceptionRequestHandlerResolved(RequestCycle 
cycle, IRequestHandler handler,
+                       Exception exception)
+               {
+                       lastExceptionRquestHandlerResolved = handler;
+               }
+
+       }
+       /**
+        * Mock response simulating connection lost problems.
+        */
+       public static class ProblematicResponse extends ServletWebResponse
+       {
+
+               /**
+                * @param webRequest
+                * @param httpServletResponse
+                */
+               public ProblematicResponse(ServletWebRequest webRequest,
+                       HttpServletResponse httpServletResponse)
+               {
+                       super(webRequest, httpServletResponse);
+               }
+
+               @Override
+               public void flush()
+               {
+                       throw new ResponseIOException(new SocketException(
+                               "Connection reset by peer: socket write 
error"));
+               }
+
+               @Override
+               public void write(byte[] array)
+               {
+                       throw new ResponseIOException(new SocketException(
+                               "Connection reset by peer: socket write 
error"));
+               }
+
+               @Override
+               public void write(CharSequence sequence)
+               {
+                       throw new ResponseIOException(new SocketException(
+                               "Connection reset by peer: socket write 
error"));
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/7b711dcd/wicket-request/src/main/java/org/apache/wicket/request/HttpHeaderCollection.java
----------------------------------------------------------------------
diff --git 
a/wicket-request/src/main/java/org/apache/wicket/request/HttpHeaderCollection.java
 
b/wicket-request/src/main/java/org/apache/wicket/request/HttpHeaderCollection.java
index 8e0cb55..e7851e8 100644
--- 
a/wicket-request/src/main/java/org/apache/wicket/request/HttpHeaderCollection.java
+++ 
b/wicket-request/src/main/java/org/apache/wicket/request/HttpHeaderCollection.java
@@ -32,9 +32,9 @@ import org.apache.wicket.util.time.Time;
 /**
  * a multivalue map of headers names and header values suitable for 
  * processing http request and response headers.
- *
+ * 
  * @author Peter Ertl
- *
+ * 
  * @since 1.5
  */
 public class HttpHeaderCollection
@@ -51,11 +51,11 @@ public class HttpHeaderCollection
 
        /**
         * internally add new object to header values
-        *
+        * 
         * @param name
-        *          header name
+        *            header name
         * @param object
-        *          header value (can be a string or a {@link Time} object
+        *            header value (can be a string or a {@link Time} object
         */
        private void internalAdd(String name, Object object)
        {
@@ -73,11 +73,11 @@ public class HttpHeaderCollection
 
        /**
         * set header value (and remove previous values)
-        *
+        * 
         * @param name
-        *          header name
+        *            header name
         * @param value
-        *          header value
+        *            header value
         */
        public void setHeader(String name, String value)
        {
@@ -90,11 +90,11 @@ public class HttpHeaderCollection
 
        /**
         * add header value
-        *
+        * 
         * @param name
-        *          header name
+        *            header name
         * @param value
-        *          header value
+        *            header value
         */
        public void addHeader(String name, String value)
        {
@@ -106,11 +106,11 @@ public class HttpHeaderCollection
 
        /**
         * add date header value
-        *
+        * 
         * @param name
-        *          header name
+        *            header name
         * @param time
-        *          timestamp
+        *            timestamp
         */
        public void addDateHeader(String name, Time time)
        {
@@ -119,11 +119,11 @@ public class HttpHeaderCollection
 
        /**
         * add date header value
-        *
+        * 
         * @param name
-        *          header name
+        *            header name
         * @param time
-        *          timestamp
+        *            timestamp
         */
        public void setDateHeader(String name, Time time)
        {
@@ -136,9 +136,9 @@ public class HttpHeaderCollection
 
        /**
         * remove header values for header name
-        *
+        * 
         * @param name
-        *          header name
+        *            header name
         */
        public void removeHeader(String name)
        {
@@ -170,9 +170,9 @@ public class HttpHeaderCollection
 
        /**
         * check if header is defined
-        *
+        * 
         * @param name
-        *        header name
+        *            header name
         * @return <code>true</code> if header has one or more values
         */
        public boolean containsHeader(String name)
@@ -192,7 +192,7 @@ public class HttpHeaderCollection
 
        /**
         * returns names of headers
-        *
+        * 
         * @return set of header names
         */
        public Set<String> getHeaderNames()
@@ -213,10 +213,10 @@ public class HttpHeaderCollection
 
        /**
         * get header values (dates will be converted into strings)
-        *
+        * 
         * @param name
-        *          header name
-        *
+        *            header name
+        * 
         * @return array of header values or empty array if not found
         */
        public String[] getHeaderValues(String name)
@@ -241,7 +241,7 @@ public class HttpHeaderCollection
        {
                final List<Object> objects = headers.get(new HeaderKey(name));
 
-               if (objects.isEmpty())
+               if (objects == null || objects.isEmpty())
                {
                        return null;
                }
@@ -267,7 +267,7 @@ public class HttpHeaderCollection
 
        /**
         * check if collection is empty
-        *
+        * 
         * @return <code>true</code> if collection is empty, <code>false</code> 
otherwise
         */
        public boolean isEmpty()
@@ -277,7 +277,7 @@ public class HttpHeaderCollection
 
        /**
         * get number of headers
-        *
+        * 
         * @return count
         */
        public int getCount()

Reply via email to