cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gkossakow...@apache.org
Subject svn commit: r615697 - in /cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl: ./ src/main/java/org/apache/cocoon/servletservice/ src/test/java/org/apache/cocoon/servletservice/
Date Mon, 28 Jan 2008 01:56:30 GMT
Author: gkossakowski
Date: Sun Jan 27 17:56:28 2008
New Revision: 615697

URL: http://svn.apache.org/viewvc?rev=615697&view=rev
Log:
COCOON-2150: Fixed this issue by buffering response and making more sane checking of status
code returned by called servlet.

Modified:
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/pom.xml
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletServiceContext.java
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/test/java/org/apache/cocoon/servletservice/ServletServiceContextTestCase.java

Modified: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/pom.xml?rev=615697&r1=615696&r2=615697&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/pom.xml (original)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/pom.xml Sun Jan 27
17:56:28 2008
@@ -114,6 +114,10 @@
       <groupId>commons-collections</groupId>
       <artifactId>commons-collections</artifactId>
     </dependency>
+    <dependency>
+    	<groupId>commons-io</groupId>
+    	<artifactId>commons-io</artifactId>
+    </dependency>
     <!-- test -->
     <dependency>
       <groupId>junit</groupId>

Modified: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletServiceContext.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletServiceContext.java?rev=615697&r1=615696&r2=615697&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletServiceContext.java
(original)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/main/java/org/apache/cocoon/servletservice/ServletServiceContext.java
Sun Jan 27 17:56:28 2008
@@ -16,9 +16,13 @@
  */
 package org.apache.cocoon.servletservice;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -37,6 +41,7 @@
 import javax.servlet.Servlet;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
@@ -44,6 +49,7 @@
 import javax.servlet.http.HttpServletResponseWrapper;
 
 import org.apache.cocoon.servletservice.util.ServletContextWrapper;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.excalibur.source.Source;
@@ -476,7 +482,7 @@
         protected void forward(ServletRequest request, ServletResponse response, boolean
superCall)
                         throws ServletException, IOException {
             try {
-                StatusRetrievableWrappedResponse wrappedResponse = new StatusRetrievableWrappedResponse(
+                StatusRetrievableBufferedWrappedResponse wrappedResponse = new StatusRetrievableBufferedWrappedResponse(
                                 (HttpServletResponse) response);
                 // FIXME: I think that Cocoon should always set status code on
                 // its own
@@ -496,24 +502,24 @@
                                     wrappedResponse);
                 }
 
-                ServletException se = null;
+                //FIXME: I'm disabling catching of ServletException for now because I'm not
sure if we should catch it at all (GK)
+                /*ServletException se = null;
                 try {
                     ServletServiceContext.this.servlet.service(request, wrappedResponse);
                 } catch (ServletException e) {
                     se = e;
-                }
+                }*/
+                ServletServiceContext.this.servlet.service(request, wrappedResponse);
 
-                int status = wrappedResponse.getStatus();
-                if (se != null || (status < 200 || status >= 400)) {
-                    wrappedResponse.reset();
-                    NamedDispatcher _super = (NamedDispatcher) ServletServiceContext.this.getNamedDispatcher(SUPER);
-                    if (_super != null) {
-                        _super.forward(request, wrappedResponse);
-                    } else {
-                        wrappedResponse.getWriter().println("Resource not found");
-                        wrappedResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
-                        throw se;
-                    }
+                NamedDispatcher _super = (NamedDispatcher) ServletServiceContext.this.getNamedDispatcher(SUPER);
+                //If servlet returned SC_NOT_FOUND and there is a super servlet we are trying
to call it in order to check
+                //whether super servlet does not happen to handle currently processed request
+                if (wrappedResponse.getStatus() == HttpServletResponse.SC_NOT_FOUND &&
_super != null) {
+                	//Here we can pass original response object because we don't need to buffer
response anymore
+                    _super.forward(request, response);
+                } else {
+                	wrappedResponse.setFlushToWrapped(true);
+                	wrappedResponse.flushBuffer();
                 }
 
             } finally {
@@ -526,12 +532,25 @@
         }
     }
 
-    public static class StatusRetrievableWrappedResponse extends HttpServletResponseWrapper
{
+    /**
+     * This class buffers response and lets to read status code that servlet set to it. This
way it can be read later
+     * and OO machinery can decide whether to call super servlet (if servlet set NOT_FOUND
status code) or to really
+     * flush the buffer to the wrapped response object.
+     */
+    public static class StatusRetrievableBufferedWrappedResponse extends HttpServletResponseWrapper
{
 
        	private int status;
+       	private ServletOutputStream servletStream;
+        private PrintWriter writer;
+        private ByteArrayOutputStream bufferingStream;
+        private boolean committed;
+        private boolean flushToWrapped;
 
-       	public StatusRetrievableWrappedResponse(HttpServletResponse wrapped) {
+       	public StatusRetrievableBufferedWrappedResponse(HttpServletResponse wrapped) {
        		super(wrapped);
+       		bufferingStream = new ByteArrayOutputStream();
+       		committed = false;
+       		this.flushToWrapped = false;
        	}
 
     	public void setStatus(int sc, String sm) {
@@ -557,6 +576,78 @@
     		this.status = errorCode;
     		super.sendError(errorCode, errorMessage);
     	}
+    	
+        public ServletOutputStream getOutputStream() throws IOException {
+            if (this.writer != null) {
+                throw new IllegalStateException( "Tried to create output stream; writer already
exists" );
+            }
+
+            if (this.servletStream == null) {
+                this.servletStream = new ServletOutputStream() {
+
+                    public void flush() throws IOException {
+                        StatusRetrievableBufferedWrappedResponse.this.bufferingStream.flush();
+                    }
+
+                    public void write(int b) throws IOException {
+                        StatusRetrievableBufferedWrappedResponse.this.bufferingStream.write(b);
+                    }
+
+                    /*
+                     * This method is probably never called, the close will be
+                     * initiated directly on this.outputStream by the one who set
+                     * it via BlockCallHttpServletResponse.setOutputStream()
+                     */
+                    public void close() throws IOException {
+                        StatusRetrievableBufferedWrappedResponse.this.bufferingStream.close();
+                    }
+
+
+                };
+            }
+
+            return this.servletStream;
+        }
+
+        public PrintWriter getWriter() throws IOException {
+            if (this.servletStream != null) {
+                throw new IllegalStateException( "Tried to create writer; output stream already
exists" );
+            }
+
+            if (this.writer == null) {
+                this.writer =
+                        new PrintWriter(new OutputStreamWriter(this.bufferingStream, this.getCharacterEncoding()));
+            }
+
+            return this.writer;
+        }
+        
+        public void flushBuffer() throws IOException {
+        	committed = true;
+        	if (flushToWrapped) {
+        		IOUtils.copy(new ByteArrayInputStream(bufferingStream.toByteArray()), super.getOutputStream());
+        		super.flushBuffer();
+        	}
+        }
+        
+        public void reset() {
+        	resetBuffer();
+        }
+        
+        public void resetBuffer() {
+        	if (committed)
+        		throw new IllegalStateException("The response has been already committed.");
+        	
+        	servletStream = null;
+        	writer = null;
+        	bufferingStream = new ByteArrayOutputStream();
+        	super.reset();
+        }
+        
+        public void setFlushToWrapped(boolean flushToWrapped) {
+        	this.flushToWrapped = flushToWrapped;
+        }
+
     }
 
 }

Modified: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/test/java/org/apache/cocoon/servletservice/ServletServiceContextTestCase.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/test/java/org/apache/cocoon/servletservice/ServletServiceContextTestCase.java?rev=615697&r1=615696&r2=615697&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/test/java/org/apache/cocoon/servletservice/ServletServiceContextTestCase.java
(original)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-impl/src/test/java/org/apache/cocoon/servletservice/ServletServiceContextTestCase.java
Sun Jan 27 17:56:28 2008
@@ -219,8 +219,8 @@
             protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
                 super.service(request, response);
                 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
-                //FIXME: Uncomment this line in order to see the same error as reported in
COCOON-2150 issue
-                //response.flushBuffer();
+                //Testing if error reported in COCOON-2150 issue is resolved
+                response.flushBuffer();
             }
 
         };
@@ -284,8 +284,8 @@
             protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
                 super.service(request, response);
                 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
-                //FIXME: Uncomment this line in order to see the same error as reported in
COCOON-2150 issue
-                //response.flushBuffer();
+                //Testing if error reported in COCOON-2150 issue is resolved
+                response.flushBuffer();
             }
 
         };
@@ -296,8 +296,8 @@
             protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
             	super.service(request, response);
                 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
-                //FIXME: Uncomment this line in order to see the same error as reported in
COCOON-2150 issue
-                //response.flushBuffer();
+                //Testing if error reported in COCOON-2150 issue is resolved
+                response.flushBuffer();
             }
         };
 



Mime
View raw message