Updated Branches:
  refs/heads/master 1f5989f54 -> 8c827e33e

WICKET-4927 allow headers to be set even if meta data is no longer
buffered

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

Branch: refs/heads/master
Commit: 8c827e33e6ae1d4177df2eab9bd3cf9b5a84248f
Parents: d70b7f4
Author: svenmeier <[email protected]>
Authored: Fri Dec 14 16:15:04 2012 +0100
Committer: svenmeier <[email protected]>
Committed: Fri Dec 14 16:18:19 2012 +0100

----------------------------------------------------------------------
 .../protocol/http/HeaderBufferingWebResponse.java  |   98 ++++++++-------
 .../http/HeaderBufferingWebResponseTest.java       |   82 ++++++++++++
 2 files changed, 134 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/8c827e33/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 0ac0c2a..8771dca 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;
        }
 
        @Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/8c827e33/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
new file mode 100644
index 0000000..1383b4b
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/HeaderBufferingWebResponseTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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 org.apache.wicket.mock.MockWebResponse;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+/**
+ * Test for {@link HeaderBufferingWebResponse}.
+ * 
+ * @author svenmeier
+ */
+public class HeaderBufferingWebResponseTest extends Assert
+{
+
+       /**
+        * WICKET-4927
+        */
+       @Test
+       public void additionalHeaderAfterWrittenContent()
+       {
+               MockWebResponse originalResponse = new MockWebResponse();
+
+               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"));
+       }
+
+       /**
+        */
+       @Test
+       public void resetAfterWrittenContent()
+       {
+               MockWebResponse originalResponse = new MockWebResponse();
+
+               HeaderBufferingWebResponse response = new 
HeaderBufferingWebResponse(originalResponse);
+
+               response.addHeader("key1", "value1");
+
+               assertNull(originalResponse.getHeader("key1"));
+
+               response.reset();
+
+               response.write("written");
+
+               try
+               {
+                       response.reset();
+
+                       fail();
+               }
+               catch (IllegalStateException expected)
+               {
+               }
+       }
+}

Reply via email to