WICKET-6599: unwrap ResponseIOException before leaving WicketFilter

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

Branch: refs/heads/WICKET-6563
Commit: b1247255b12dd3736654bc32a59f54fcd01c0e2c
Parents: e749e61
Author: Emond Papegaaij <emond.papega...@topicus.nl>
Authored: Thu Oct 18 13:40:11 2018 +0200
Committer: Emond Papegaaij <emond.papega...@topicus.nl>
Committed: Thu Oct 18 14:22:49 2018 +0200

----------------------------------------------------------------------
 .../wicket/protocol/http/WicketFilter.java      | 37 ++++++++----
 .../http/servlet/ResponseIOException.java       |  5 ++
 .../wicket/protocol/http/WicketFilterTest.java  | 63 ++++++++++++++++++++
 3 files changed, 93 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/b1247255/wicket-core/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
index 47d54cc..fb3ee46 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/WicketFilter.java
@@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.apache.wicket.ThreadContext;
 import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.protocol.http.servlet.ResponseIOException;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.http.WebRequest;
 import org.apache.wicket.request.http.WebResponse;
@@ -152,6 +153,7 @@ public class WicketFilter implements Filter
                HttpServletRequest httpServletRequest = 
(HttpServletRequest)request;
                HttpServletResponse httpServletResponse = 
(HttpServletResponse)response;
 
+               boolean ioExceptionOccurred = false;
                try
                {
                        if (previousClassLoader != newClassLoader)
@@ -212,18 +214,21 @@ public class WicketFilter implements Filter
                                        redirectURL += "?" + 
httpServletRequest.getQueryString();
                                }
 
-                               try
-                               {
-                                       // send redirect - this will discard 
POST parameters if the request is POST
-                                       // - still better than getting an error 
because of lacking trailing slash
-                                       
httpServletResponse.sendRedirect(httpServletResponse.encodeRedirectURL(redirectURL));
-                               }
-                               catch (IOException e)
-                               {
-                                       throw new RuntimeException(e);
-                               }
+                               // send redirect - this will discard POST 
parameters if the request is POST
+                               // - still better than getting an error because 
of lacking trailing slash
+                               
httpServletResponse.sendRedirect(httpServletResponse.encodeRedirectURL(redirectURL));
                        }
                }
+               catch (IOException e)
+               {
+                       ioExceptionOccurred = true;
+                       throw e;
+               }
+               catch (ResponseIOException e)
+               {
+                       ioExceptionOccurred = true;
+                       throw e.getCause();
+               }
                finally
                {
                        ThreadContext.restore(previousThreadContext);
@@ -233,9 +238,17 @@ public class WicketFilter implements Filter
                                
Thread.currentThread().setContextClassLoader(previousClassLoader);
                        }
 
-                       if (response.isCommitted() && 
httpServletRequest.isAsyncStarted() == false)
+                       if (!ioExceptionOccurred && response.isCommitted() &&
+                               !httpServletRequest.isAsyncStarted())
                        {
-                               response.flushBuffer();
+                               try
+                               {
+                                       response.flushBuffer();
+                               }
+                               catch (ResponseIOException e)
+                               {
+                                       throw e.getCause();
+                               }
                        }
                }
                return res;

http://git-wip-us.apache.org/repos/asf/wicket/blob/b1247255/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ResponseIOException.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ResponseIOException.java
 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ResponseIOException.java
index e6b3691..c033ba7 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ResponseIOException.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ResponseIOException.java
@@ -41,4 +41,9 @@ public class ResponseIOException extends 
WicketRuntimeException implements IWick
                super(cause);
        }
 
+       @Override
+       public synchronized IOException getCause()
+       {
+               return (IOException)super.getCause();
+       }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/b1247255/wicket-core/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java
index c12737c..5b4db27 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/WicketFilterTest.java
@@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 import static org.mockito.Mockito.mock;
@@ -58,10 +59,15 @@ import org.apache.wicket.mock.MockApplication;
 import org.apache.wicket.protocol.http.mock.MockHttpServletRequest;
 import org.apache.wicket.protocol.http.mock.MockHttpServletResponse;
 import org.apache.wicket.protocol.http.mock.MockServletContext;
+import org.apache.wicket.protocol.http.servlet.ResponseIOException;
 import org.apache.wicket.request.http.WebRequest;
 import org.apache.wicket.request.resource.AbstractResource;
+import org.apache.wicket.request.resource.ContentDisposition;
 import org.apache.wicket.request.resource.DynamicImageResource;
 import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.AbstractResource.ResourceResponse;
+import org.apache.wicket.request.resource.AbstractResource.WriteCallback;
+import org.apache.wicket.request.resource.IResource.Attributes;
 import org.apache.wicket.util.WicketTestTag;
 import org.apache.wicket.util.file.WebXmlFile;
 import org.apache.wicket.util.string.Strings;
@@ -214,6 +220,63 @@ public class WicketFilterTest
                }
        }
 
+       /**
+        * @throws IOException
+        * @throws ServletException
+        * @throws ParseException
+        */
+       @Test
+       public void ioExceptionNotWrapped() throws IOException, 
ServletException, ParseException
+       {
+               assertThrows(IOException.class, this::doIOExceptionNotWrapped);
+       }
+
+       private void doIOExceptionNotWrapped() throws IOException, 
ServletException, ParseException
+       {
+               try
+               {
+                       application = new MockApplication();
+                       WicketFilter filter = new WicketFilter();
+                       filter.init(new FilterTestingConfig());
+                       ThreadContext.setApplication(application);
+                       IResource resource = new AbstractResource()
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               @Override
+                               protected ResourceResponse 
newResourceResponse(Attributes attributes)
+                               {
+                                       return new ResourceResponse();
+                               }
+                       };
+                       application.getSharedResources().add("foo.txt", 
resource);
+                       MockHttpServletRequest request = new 
MockHttpServletRequest(application, null, null);
+                       request.setURL(request.getContextPath() + 
request.getServletPath() +
+                               "/wicket/resource/" + 
Application.class.getName() + "/foo.txt");
+                       setIfModifiedSinceToNextWeek(request);
+                       MockHttpServletResponse response = new 
MockHttpServletResponse(request)
+                       {
+                               @Override
+                               public void flushBuffer() throws IOException
+                               {
+                                       throw new IOException("caused by test");
+                               }
+                       };
+                       filter.doFilter(request, response, new FilterChain()
+                       {
+                               @Override
+                               public void doFilter(ServletRequest 
servletRequest, ServletResponse servletResponse)
+                                       throws IOException, ServletException
+                               {
+                               }
+                       });
+               }
+               finally
+               {
+                       ThreadContext.detach();
+               }
+       }
+
        @Test
        void options() throws IOException, ServletException, ParseException
        {

Reply via email to