Author: markt Date: Mon Sep 13 20:03:17 2010 New Revision: 996672 URL: http://svn.apache.org/viewvc?rev=996672&view=rev Log: Re-factoring the connectors. Remove large chunks of duplicated code in the Processors. Some minor changes elsewhere to support the re-factoring.
Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java tomcat/trunk/java/org/apache/coyote/http11/LocalStrings.properties tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=996672&r1=996671&r2=996672&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Mon Sep 13 20:03:17 2010 @@ -16,10 +16,12 @@ */ package org.apache.coyote.http11; +import java.io.IOException; import java.util.StringTokenizer; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import org.apache.coyote.ActionCode; import org.apache.coyote.Adapter; import org.apache.coyote.Request; import org.apache.coyote.Response; @@ -29,6 +31,7 @@ import org.apache.coyote.http11.filters. import org.apache.coyote.http11.filters.GzipOutputFilter; import org.apache.coyote.http11.filters.IdentityInputFilter; import org.apache.coyote.http11.filters.IdentityOutputFilter; +import org.apache.coyote.http11.filters.SavedRequestInputFilter; import org.apache.coyote.http11.filters.VoidInputFilter; import org.apache.coyote.http11.filters.VoidOutputFilter; import org.apache.juli.logging.Log; @@ -36,6 +39,9 @@ import org.apache.juli.logging.LogFactor import org.apache.tomcat.util.buf.Ascii; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.MessageBytes; +import org.apache.tomcat.util.http.FastHttpDateFormat; +import org.apache.tomcat.util.http.MimeHeaders; +import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.res.StringManager; public abstract class AbstractHttp11Processor { @@ -227,6 +233,13 @@ public abstract class AbstractHttp11Proc */ protected String server = null; + + /** + * Async used + */ + protected boolean async = false; + + /** * Set compression level. */ @@ -823,4 +836,249 @@ public abstract class AbstractHttp11Proc } + /** + * Send an action to the connector. + * + * @param actionCode Type of the action + * @param param Action parameter + */ + public final void action(ActionCode actionCode, Object param) { + + if (actionCode == ActionCode.ACTION_COMMIT) { + // Commit current response + + if (response.isCommitted()) + return; + + // Validate and write response headers + try { + prepareResponse(); + getOutputBuffer().commit(); + } catch (IOException e) { + // Set error flag + error = true; + } + } else if (actionCode == ActionCode.ACTION_ACK) { + // Acknowledge request + // Send a 100 status back if it makes sense (response not committed + // yet, and client specified an expectation for 100-continue) + + if ((response.isCommitted()) || !expectation) + return; + + getInputBuffer().setSwallowInput(true); + try { + getOutputBuffer().sendAck(); + } catch (IOException e) { + // Set error flag + error = true; + } + } else if (actionCode == ActionCode.ACTION_CLIENT_FLUSH) { + + try { + getOutputBuffer().flush(); + } catch (IOException e) { + // Set error flag + error = true; + response.setErrorException(e); + } + + } else if (actionCode == ActionCode.ACTION_RESET) { + // Reset response + // Note: This must be called before the response is committed + + getOutputBuffer().reset(); + + } else if (actionCode == ActionCode.ACTION_CUSTOM) { + // Do nothing + // TODO Remove this action + + } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) { + ByteChunk body = (ByteChunk) param; + + InputFilter savedBody = new SavedRequestInputFilter(body); + savedBody.setRequest(request); + + AbstractInputBuffer internalBuffer = (AbstractInputBuffer) + request.getInputBuffer(); + internalBuffer.addActiveFilter(savedBody); + } else if (actionCode == ActionCode.ACTION_ASYNC_START) { + async = true; + } else { + actionInternal(actionCode, param); + } + } + + abstract void actionInternal(ActionCode actionCode, Object param); + + + /** + * When committing the response, we have to validate the set of headers, as + * well as setup the response filters. + */ + private void prepareResponse() { + + boolean entityBody = true; + contentDelimitation = false; + + OutputFilter[] outputFilters = getOutputBuffer().getFilters(); + + if (http09 == true) { + // HTTP/0.9 + getOutputBuffer().addActiveFilter + (outputFilters[Constants.IDENTITY_FILTER]); + return; + } + + int statusCode = response.getStatus(); + if ((statusCode == 204) || (statusCode == 205) + || (statusCode == 304)) { + // No entity body + getOutputBuffer().addActiveFilter + (outputFilters[Constants.VOID_FILTER]); + entityBody = false; + contentDelimitation = true; + } + + MessageBytes methodMB = request.method(); + if (methodMB.equals("HEAD")) { + // No entity body + getOutputBuffer().addActiveFilter + (outputFilters[Constants.VOID_FILTER]); + contentDelimitation = true; + } + + // Sendfile support + boolean sendingWithSendfile = false; + if (getEndpoint().getUseSendfile()) { + sendingWithSendfile = prepareSendfile(outputFilters); + } + + // Check for compression + boolean useCompression = false; + if (entityBody && (compressionLevel > 0) && !sendingWithSendfile) { + useCompression = isCompressable(); + // Change content-length to -1 to force chunking + if (useCompression) { + response.setContentLength(-1); + } + } + + MimeHeaders headers = response.getMimeHeaders(); + if (!entityBody) { + response.setContentLength(-1); + } else { + String contentType = response.getContentType(); + if (contentType != null) { + headers.setValue("Content-Type").setString(contentType); + } + String contentLanguage = response.getContentLanguage(); + if (contentLanguage != null) { + headers.setValue("Content-Language") + .setString(contentLanguage); + } + } + + long contentLength = response.getContentLengthLong(); + if (contentLength != -1) { + headers.setValue("Content-Length").setLong(contentLength); + getOutputBuffer().addActiveFilter + (outputFilters[Constants.IDENTITY_FILTER]); + contentDelimitation = true; + } else { + if (entityBody && http11) { + getOutputBuffer().addActiveFilter + (outputFilters[Constants.CHUNKED_FILTER]); + contentDelimitation = true; + headers.addValue(Constants.TRANSFERENCODING).setString(Constants.CHUNKED); + } else { + getOutputBuffer().addActiveFilter + (outputFilters[Constants.IDENTITY_FILTER]); + } + } + + if (useCompression) { + getOutputBuffer().addActiveFilter(outputFilters[Constants.GZIP_FILTER]); + headers.setValue("Content-Encoding").setString("gzip"); + // Make Proxies happy via Vary (from mod_deflate) + MessageBytes vary = headers.getValue("Vary"); + if (vary == null) { + // Add a new Vary header + headers.setValue("Vary").setString("Accept-Encoding"); + } else if (vary.equals("*")) { + // No action required + } else { + // Merge into current header + headers.setValue("Vary").setString( + vary.getString() + ",Accept-Encoding"); + } + } + + // Add date header + headers.setValue("Date").setString(FastHttpDateFormat.getCurrentDate()); + + // FIXME: Add transfer encoding header + + if ((entityBody) && (!contentDelimitation)) { + // Mark as close the connection after the request, and add the + // connection: close header + keepAlive = false; + } + + // If we know that the request is bad this early, add the + // Connection: close header. + keepAlive = keepAlive && !statusDropsConnection(statusCode); + if (!keepAlive) { + headers.addValue(Constants.CONNECTION).setString(Constants.CLOSE); + } else if (!http11 && !error) { + headers.addValue(Constants.CONNECTION).setString(Constants.KEEPALIVE); + } + + // Build the response header + getOutputBuffer().sendStatus(); + + // Add server header + if (server != null) { + // Always overrides anything the app might set + headers.setValue("Server").setString(server); + } else if (headers.getValue("Server") == null) { + // If app didn't set the header, use the default + getOutputBuffer().write(Constants.SERVER_BYTES); + } + + int size = headers.size(); + for (int i = 0; i < size; i++) { + getOutputBuffer().sendHeader(headers.getName(i), headers.getValue(i)); + } + getOutputBuffer().endHeaders(); + + } + + abstract AbstractEndpoint getEndpoint(); + abstract boolean prepareSendfile(OutputFilter[] outputFilters); + + public void endRequest() { + + // Finish the handling of the request + try { + getInputBuffer().endRequest(); + } catch (IOException e) { + error = true; + } catch (Throwable t) { + log.error(sm.getString("http11processor.request.finish"), t); + // 500 - Internal Server Error + response.setStatus(500); + adapter.log(request, response, 0); + error = true; + } + try { + getOutputBuffer().endRequest(); + } catch (IOException e) { + error = true; + } catch (Throwable t) { + log.error(sm.getString("http11processor.response.finish"), t); + error = true; + } + + } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=996672&r1=996671&r2=996672&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Mon Sep 13 20:03:17 2010 @@ -31,7 +31,6 @@ import org.apache.coyote.Request; import org.apache.coyote.RequestInfo; import org.apache.coyote.Response; import org.apache.coyote.http11.filters.BufferedInputFilter; -import org.apache.coyote.http11.filters.SavedRequestInputFilter; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.jni.Address; @@ -42,7 +41,6 @@ import org.apache.tomcat.jni.Socket; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.HexUtils; import org.apache.tomcat.util.buf.MessageBytes; -import org.apache.tomcat.util.http.FastHttpDateFormat; import org.apache.tomcat.util.http.MimeHeaders; import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState; @@ -117,12 +115,6 @@ public class Http11AprProcessor extends /** - * Async used - */ - protected boolean async = false; - - - /** * SSL enabled ? */ protected boolean ssl = false; @@ -138,7 +130,10 @@ public class Http11AprProcessor extends * Associated endpoint. */ protected AprEndpoint endpoint; - + @Override + protected AbstractEndpoint getEndpoint() { + return endpoint; + } // --------------------------------------------------------- Public Methods @@ -397,32 +392,6 @@ public class Http11AprProcessor extends } - public void endRequest() { - - // Finish the handling of the request - try { - inputBuffer.endRequest(); - } catch (IOException e) { - error = true; - } catch (Throwable t) { - log.error(sm.getString("http11processor.request.finish"), t); - // 500 - Internal Server Error - response.setStatus(500); - adapter.log(request, response, 0); - error = true; - } - try { - outputBuffer.endRequest(); - } catch (IOException e) { - error = true; - } catch (Throwable t) { - log.error(sm.getString("http11processor.response.finish"), t); - error = true; - } - - } - - public void recycle() { inputBuffer.recycle(); outputBuffer.recycle(); @@ -440,52 +409,9 @@ public class Http11AprProcessor extends * @param param Action parameter */ @Override - public void action(ActionCode actionCode, Object param) { + public void actionInternal(ActionCode actionCode, Object param) { - if (actionCode == ActionCode.ACTION_COMMIT) { - // Commit current response - - if (response.isCommitted()) - return; - - // Validate and write response headers - prepareResponse(); - try { - outputBuffer.commit(); - } catch (IOException e) { - // Set error flag - error = true; - } - - } else if (actionCode == ActionCode.ACTION_ACK) { - - // Acknowledge request - - // Send a 100 status back if it makes sense (response not committed - // yet, and client specified an expectation for 100-continue) - - if ((response.isCommitted()) || !expectation) - return; - - inputBuffer.setSwallowInput(true); - try { - outputBuffer.sendAck(); - } catch (IOException e) { - // Set error flag - error = true; - } - - } else if (actionCode == ActionCode.ACTION_CLIENT_FLUSH) { - - try { - outputBuffer.flush(); - } catch (IOException e) { - // Set error flag - error = true; - response.setErrorException(e); - } - - } else if (actionCode == ActionCode.ACTION_CLOSE) { + if (actionCode == ActionCode.ACTION_CLOSE) { // Close // End the processing of the current request, and stop any further @@ -500,18 +426,6 @@ public class Http11AprProcessor extends error = true; } - } else if (actionCode == ActionCode.ACTION_RESET) { - - // Reset response - - // Note: This must be called before the response is committed - - outputBuffer.reset(); - - } else if (actionCode == ActionCode.ACTION_CUSTOM) { - - // Do nothing - } else if (actionCode == ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE) { // Get remote host address @@ -673,16 +587,6 @@ public class Http11AprProcessor extends } } - } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) { - ByteChunk body = (ByteChunk) param; - - InputFilter savedBody = new SavedRequestInputFilter(body); - savedBody.setRequest(request); - - InternalAprInputBuffer internalBuffer = (InternalAprInputBuffer) - request.getInputBuffer(); - internalBuffer.addActiveFilter(savedBody); - } else if (actionCode == ActionCode.ACTION_AVAILABLE) { request.setAvailable(inputBuffer.available()); } else if (actionCode == ActionCode.ACTION_COMET_BEGIN) { @@ -693,9 +597,6 @@ public class Http11AprProcessor extends //no op } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) { //no op - } else if (actionCode == ActionCode.ACTION_ASYNC_START) { - //TODO SERVLET3 - async - async = true; } else if (actionCode == ActionCode.ACTION_ASYNC_COMPLETE) { //TODO SERVLET3 - async - that is bit hacky - AtomicBoolean dispatch = (AtomicBoolean)param; @@ -987,160 +888,25 @@ public class Http11AprProcessor extends } - /** - * When committing the response, we have to validate the set of headers, as - * well as setup the response filters. - */ - protected void prepareResponse() { - - boolean entityBody = true; - contentDelimitation = false; - - OutputFilter[] outputFilters = outputBuffer.getFilters(); - - if (http09 == true) { - // HTTP/0.9 - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - return; - } - - int statusCode = response.getStatus(); - if ((statusCode == 204) || (statusCode == 205) - || (statusCode == 304)) { - // No entity body - outputBuffer.addActiveFilter - (outputFilters[Constants.VOID_FILTER]); - entityBody = false; - contentDelimitation = true; - } - - MessageBytes methodMB = request.method(); - if (methodMB.equals("HEAD")) { - // No entity body + @Override + protected boolean prepareSendfile(OutputFilter[] outputFilters) { + String fileName = (String) request.getAttribute("org.apache.tomcat.sendfile.filename"); + if (fileName != null) { + // No entity body sent here outputBuffer.addActiveFilter (outputFilters[Constants.VOID_FILTER]); contentDelimitation = true; + sendfileData = new AprEndpoint.SendfileData(); + sendfileData.fileName = fileName; + sendfileData.start = + ((Long) request.getAttribute("org.apache.tomcat.sendfile.start")).longValue(); + sendfileData.end = + ((Long) request.getAttribute("org.apache.tomcat.sendfile.end")).longValue(); + return true; } - - // Sendfile support - if (endpoint.getUseSendfile()) { - String fileName = (String) request.getAttribute("org.apache.tomcat.sendfile.filename"); - if (fileName != null) { - // No entity body sent here - outputBuffer.addActiveFilter - (outputFilters[Constants.VOID_FILTER]); - contentDelimitation = true; - sendfileData = new AprEndpoint.SendfileData(); - sendfileData.fileName = fileName; - sendfileData.start = - ((Long) request.getAttribute("org.apache.tomcat.sendfile.start")).longValue(); - sendfileData.end = - ((Long) request.getAttribute("org.apache.tomcat.sendfile.end")).longValue(); - } - } - - // Check for compression - boolean useCompression = false; - if (entityBody && (compressionLevel > 0) && (sendfileData == null)) { - useCompression = isCompressable(); - // Change content-length to -1 to force chunking - if (useCompression) { - response.setContentLength(-1); - } - } - - MimeHeaders headers = response.getMimeHeaders(); - if (!entityBody) { - response.setContentLength(-1); - } else { - String contentType = response.getContentType(); - if (contentType != null) { - headers.setValue("Content-Type").setString(contentType); - } - String contentLanguage = response.getContentLanguage(); - if (contentLanguage != null) { - headers.setValue("Content-Language") - .setString(contentLanguage); - } - } - - long contentLength = response.getContentLengthLong(); - if (contentLength != -1) { - headers.setValue("Content-Length").setLong(contentLength); - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - contentDelimitation = true; - } else { - if (entityBody && http11) { - outputBuffer.addActiveFilter - (outputFilters[Constants.CHUNKED_FILTER]); - contentDelimitation = true; - headers.addValue(Constants.TRANSFERENCODING).setString(Constants.CHUNKED); - } else { - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - } - } - - if (useCompression) { - outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]); - headers.setValue("Content-Encoding").setString("gzip"); - // Make Proxies happy via Vary (from mod_deflate) - MessageBytes vary = headers.getValue("Vary"); - if (vary == null) { - // Add a new Vary header - headers.setValue("Vary").setString("Accept-Encoding"); - } else if (vary.equals("*")) { - // No action required - } else { - // Merge into current header - headers.setValue("Vary").setString( - vary.getString() + ",Accept-Encoding"); - } - } - - // Add date header - headers.setValue("Date").setString(FastHttpDateFormat.getCurrentDate()); - - // FIXME: Add transfer encoding header - - if ((entityBody) && (!contentDelimitation)) { - // Mark as close the connection after the request, and add the - // connection: close header - keepAlive = false; - } - - // If we know that the request is bad this early, add the - // Connection: close header. - keepAlive = keepAlive && !statusDropsConnection(statusCode); - if (!keepAlive) { - headers.addValue(Constants.CONNECTION).setString(Constants.CLOSE); - } else if (!http11 && !error) { - headers.addValue(Constants.CONNECTION).setString(Constants.KEEPALIVE); - } - - // Build the response header - outputBuffer.sendStatus(); - - // Add server header - if (server != null) { - // Always overrides anything the app might set - headers.setValue("Server").setString(server); - } else if (headers.getValue("Server") == null) { - // If app didn't set the header, use the default - outputBuffer.write(Constants.SERVER_BYTES); - } - - int size = headers.size(); - for (int i = 0; i < size; i++) { - outputBuffer.sendHeader(headers.getName(i), headers.getValue(i)); - } - outputBuffer.endHeaders(); - + return false; } - @Override protected AbstractInputBuffer getInputBuffer() { return inputBuffer; Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=996672&r1=996671&r2=996672&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Mon Sep 13 20:03:17 2010 @@ -29,15 +29,14 @@ import org.apache.coyote.Request; import org.apache.coyote.RequestInfo; import org.apache.coyote.Response; import org.apache.coyote.http11.filters.BufferedInputFilter; -import org.apache.coyote.http11.filters.SavedRequestInputFilter; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.buf.Ascii; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.HexUtils; import org.apache.tomcat.util.buf.MessageBytes; -import org.apache.tomcat.util.http.FastHttpDateFormat; import org.apache.tomcat.util.http.MimeHeaders; +import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState; import org.apache.tomcat.util.net.NioChannel; import org.apache.tomcat.util.net.NioEndpoint; @@ -123,11 +122,6 @@ public class Http11NioProcessor extends protected boolean cometClose = false; /** - * Async used - */ - protected boolean async = false; - - /** * SSL enabled ? */ protected boolean ssl = false; @@ -147,6 +141,13 @@ public class Http11NioProcessor extends // ------------------------------------------------------------- Properties + /** + * Expose the endpoint. + */ + @Override + protected AbstractEndpoint getEndpoint() { + return endpoint; + } // --------------------------------------------------------- Public Methods @@ -464,32 +465,6 @@ public class Http11NioProcessor extends } - public void endRequest() { - - // Finish the handling of the request - try { - inputBuffer.endRequest(); - } catch (IOException e) { - error = true; - } catch (Throwable t) { - log.error(sm.getString("http11processor.request.finish"), t); - // 500 - Internal Server Error - response.setStatus(500); - adapter.log(request, response, 0); - error = true; - } - try { - outputBuffer.endRequest(); - } catch (IOException e) { - error = true; - } catch (Throwable t) { - log.error(sm.getString("http11processor.response.finish"), t); - error = true; - } - - } - - public void recycle() { inputBuffer.recycle(); outputBuffer.recycle(); @@ -515,53 +490,9 @@ public class Http11NioProcessor extends * @param param Action parameter */ @Override - public void action(ActionCode actionCode, Object param) { - - if (actionCode == ActionCode.ACTION_COMMIT) { - // Commit current response - - if (response.isCommitted()) - return; + public void actionInternal(ActionCode actionCode, Object param) { - // Validate and write response headers - - try { - prepareResponse(); - outputBuffer.commit(); - } catch (IOException e) { - // Set error flag - error = true; - } - - } else if (actionCode == ActionCode.ACTION_ACK) { - - // Acknowledge request - - // Send a 100 status back if it makes sense (response not committed - // yet, and client specified an expectation for 100-continue) - - if ((response.isCommitted()) || !expectation) - return; - - inputBuffer.setSwallowInput(true); - try { - outputBuffer.sendAck(); - } catch (IOException e) { - // Set error flag - error = true; - } - - } else if (actionCode == ActionCode.ACTION_CLIENT_FLUSH) { - - try { - outputBuffer.flush(); - } catch (IOException e) { - // Set error flag - error = true; - response.setErrorException(e); - } - - } else if (actionCode == ActionCode.ACTION_CLOSE) { + if (actionCode == ActionCode.ACTION_CLOSE) { // Close // End the processing of the current request, and stop any further @@ -589,18 +520,6 @@ public class Http11NioProcessor extends error = true; } - } else if (actionCode == ActionCode.ACTION_RESET) { - - // Reset response - - // Note: This must be called before the response is committed - - outputBuffer.reset(); - - } else if (actionCode == ActionCode.ACTION_CUSTOM) { - - // Do nothing - } else if (actionCode == ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE) { // Get remote host address @@ -711,16 +630,6 @@ public class Http11NioProcessor extends } } - } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) { - ByteChunk body = (ByteChunk) param; - - InputFilter savedBody = new SavedRequestInputFilter(body); - savedBody.setRequest(request); - - InternalNioInputBuffer internalBuffer = (InternalNioInputBuffer) - request.getInputBuffer(); - internalBuffer.addActiveFilter(savedBody); - } else if (actionCode == ActionCode.ACTION_AVAILABLE) { request.setAvailable(inputBuffer.available()); } else if (actionCode == ActionCode.ACTION_COMET_BEGIN) { @@ -744,9 +653,6 @@ public class Http11NioProcessor extends RequestInfo rp = request.getRequestProcessor(); if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) //async handling attach.setTimeout(timeout); - } else if (actionCode == ActionCode.ACTION_ASYNC_START) { - //TODO SERVLET3 - async - async = true; } else if (actionCode == ActionCode.ACTION_ASYNC_COMPLETE) { //TODO SERVLET3 - async AtomicBoolean dispatch = (AtomicBoolean)param; @@ -1044,159 +950,22 @@ public class Http11NioProcessor extends } - /** - * When committing the response, we have to validate the set of headers, as - * well as setup the response filters. - */ - protected void prepareResponse() { - - boolean entityBody = true; - contentDelimitation = false; - - OutputFilter[] outputFilters = outputBuffer.getFilters(); - - if (http09 == true) { - // HTTP/0.9 - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - return; - } - - int statusCode = response.getStatus(); - if ((statusCode == 204) || (statusCode == 205) - || (statusCode == 304)) { - // No entity body - outputBuffer.addActiveFilter - (outputFilters[Constants.VOID_FILTER]); - entityBody = false; - contentDelimitation = true; - } - - MessageBytes methodMB = request.method(); - if (methodMB.equals("HEAD")) { - // No entity body - outputBuffer.addActiveFilter - (outputFilters[Constants.VOID_FILTER]); - contentDelimitation = true; - } - - // Sendfile support - if (this.endpoint.getUseSendfile()) { - String fileName = (String) request.getAttribute("org.apache.tomcat.sendfile.filename"); - if (fileName != null) { - // No entity body sent here - outputBuffer.addActiveFilter(outputFilters[Constants.VOID_FILTER]); - contentDelimitation = true; - sendfileData = new NioEndpoint.SendfileData(); - sendfileData.fileName = fileName; - sendfileData.pos = ((Long) request.getAttribute("org.apache.tomcat.sendfile.start")).longValue(); - sendfileData.length = ((Long) request.getAttribute("org.apache.tomcat.sendfile.end")).longValue() - sendfileData.pos; - } - } - - - - // Check for compression - boolean useCompression = false; - if (entityBody && (compressionLevel > 0) && (sendfileData == null)) { - useCompression = isCompressable(); - // Change content-length to -1 to force chunking - if (useCompression) { - response.setContentLength(-1); - } - } - - MimeHeaders headers = response.getMimeHeaders(); - if (!entityBody) { - response.setContentLength(-1); - } else { - String contentType = response.getContentType(); - if (contentType != null) { - headers.setValue("Content-Type").setString(contentType); - } - String contentLanguage = response.getContentLanguage(); - if (contentLanguage != null) { - headers.setValue("Content-Language") - .setString(contentLanguage); - } - } - - long contentLength = response.getContentLengthLong(); - if (contentLength != -1) { - headers.setValue("Content-Length").setLong(contentLength); - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); + @Override + protected boolean prepareSendfile(OutputFilter[] outputFilters) { + String fileName = (String) request.getAttribute("org.apache.tomcat.sendfile.filename"); + if (fileName != null) { + // No entity body sent here + outputBuffer.addActiveFilter(outputFilters[Constants.VOID_FILTER]); contentDelimitation = true; - } else { - if (entityBody && http11) { - outputBuffer.addActiveFilter - (outputFilters[Constants.CHUNKED_FILTER]); - contentDelimitation = true; - headers.addValue(Constants.TRANSFERENCODING).setString(Constants.CHUNKED); - } else { - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - } + sendfileData = new NioEndpoint.SendfileData(); + sendfileData.fileName = fileName; + sendfileData.pos = ((Long) request.getAttribute("org.apache.tomcat.sendfile.start")).longValue(); + sendfileData.length = ((Long) request.getAttribute("org.apache.tomcat.sendfile.end")).longValue() - sendfileData.pos; + return true; } - - if (useCompression) { - outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]); - headers.setValue("Content-Encoding").setString("gzip"); - // Make Proxies happy via Vary (from mod_deflate) - MessageBytes vary = headers.getValue("Vary"); - if (vary == null) { - // Add a new Vary header - headers.setValue("Vary").setString("Accept-Encoding"); - } else if (vary.equals("*")) { - // No action required - } else { - // Merge into current header - headers.setValue("Vary").setString( - vary.getString() + ",Accept-Encoding"); - } - } - - // Add date header - headers.setValue("Date").setString(FastHttpDateFormat.getCurrentDate()); - - // FIXME: Add transfer encoding header - - if ((entityBody) && (!contentDelimitation)) { - // Mark as close the connection after the request, and add the - // connection: close header - keepAlive = false; - } - - // If we know that the request is bad this early, add the - // Connection: close header. - keepAlive = keepAlive && !statusDropsConnection(statusCode); - if (!keepAlive) { - headers.addValue(Constants.CONNECTION).setString(Constants.CLOSE); - } else if (!http11 && !error) { - headers.addValue(Constants.CONNECTION).setString(Constants.KEEPALIVE); - } - - // Build the response header - outputBuffer.sendStatus(); - - // Add server header - if (server != null) { - // Always overrides anything the app might set - headers.setValue("Server").setString(server); - } else if (headers.getValue("Server") == null) { - // If app didn't set the header, use the default - outputBuffer.write(Constants.SERVER_BYTES); - } - - int size = headers.size(); - for (int i = 0; i < size; i++) { - outputBuffer.sendHeader(headers.getName(i), headers.getValue(i)); - } - outputBuffer.endHeaders(); - + return false; } - /** * Specialized utility method: find a sequence of lower case bytes inside * a ByteChunk. Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=996672&r1=996671&r2=996672&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Mon Sep 13 20:03:17 2010 @@ -30,14 +30,13 @@ import org.apache.coyote.Request; import org.apache.coyote.RequestInfo; import org.apache.coyote.Response; import org.apache.coyote.http11.filters.BufferedInputFilter; -import org.apache.coyote.http11.filters.SavedRequestInputFilter; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.HexUtils; import org.apache.tomcat.util.buf.MessageBytes; -import org.apache.tomcat.util.http.FastHttpDateFormat; import org.apache.tomcat.util.http.MimeHeaders; +import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState; import org.apache.tomcat.util.net.JIoEndpoint; import org.apache.tomcat.util.net.SSLSupport; @@ -105,12 +104,6 @@ public class Http11Processor extends Abs /** - * Async used - */ - protected boolean async = false; - - - /** * State flag. */ protected boolean started = false; @@ -130,6 +123,15 @@ public class Http11Processor extends Abs // --------------------------------------------------------- Public Methods + + /** + * Expose the endpoint. + */ + @Override + protected AbstractEndpoint getEndpoint() { + return this.endpoint; + } + /** * Set the SSL information for this HTTP connection. */ @@ -359,32 +361,6 @@ public class Http11Processor extends Abs } - public void endRequest() { - - // Finish the handling of the request - try { - inputBuffer.endRequest(); - } catch (IOException e) { - error = true; - } catch (Throwable t) { - log.error(sm.getString("http11processor.request.finish"), t); - // 500 - Internal Server Error - response.setStatus(500); - adapter.log(request, response, 0); - error = true; - } - try { - outputBuffer.endRequest(); - } catch (IOException e) { - error = true; - } catch (Throwable t) { - log.error(sm.getString("http11processor.response.finish"), t); - error = true; - } - - } - - public void recycle() { // Recycle inputBuffer.recycle(); @@ -406,52 +382,9 @@ public class Http11Processor extends Abs * @param param Action parameter */ @Override - public void action(ActionCode actionCode, Object param) { + public void actionInternal(ActionCode actionCode, Object param) { - if (actionCode == ActionCode.ACTION_COMMIT) { - // Commit current response - - if (response.isCommitted()) - return; - - // Validate and write response headers - prepareResponse(); - try { - outputBuffer.commit(); - } catch (IOException e) { - // Set error flag - error = true; - } - - } else if (actionCode == ActionCode.ACTION_ACK) { - - // Acknowledge request - - // Send a 100 status back if it makes sense (response not committed - // yet, and client specified an expectation for 100-continue) - - if ((response.isCommitted()) || !expectation) - return; - - inputBuffer.setSwallowInput(true); - try { - outputBuffer.sendAck(); - } catch (IOException e) { - // Set error flag - error = true; - } - - } else if (actionCode == ActionCode.ACTION_CLIENT_FLUSH) { - - try { - outputBuffer.flush(); - } catch (IOException e) { - // Set error flag - error = true; - response.setErrorException(e); - } - - } else if (actionCode == ActionCode.ACTION_CLOSE) { + if (actionCode == ActionCode.ACTION_CLOSE) { // Close async = false; // End the processing of the current request, and stop any further @@ -464,18 +397,6 @@ public class Http11Processor extends Abs error = true; } - } else if (actionCode == ActionCode.ACTION_RESET) { - - // Reset response - - // Note: This must be called before the response is committed - - outputBuffer.reset(); - - } else if (actionCode == ActionCode.ACTION_CUSTOM) { - - // Do nothing - } else if (actionCode == ActionCode.ACTION_START) { started = true; @@ -589,18 +510,6 @@ public class Http11Processor extends Abs log.warn(sm.getString("http11processor.socket.ssl"), e); } } - } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) { - ByteChunk body = (ByteChunk) param; - - InputFilter savedBody = new SavedRequestInputFilter(body); - savedBody.setRequest(request); - - InternalInputBuffer internalBuffer = (InternalInputBuffer) - request.getInputBuffer(); - internalBuffer.addActiveFilter(savedBody); - } else if (actionCode == ActionCode.ACTION_ASYNC_START) { - //TODO SERVLET3 - async - async = true; } else if (actionCode == ActionCode.ACTION_ASYNC_COMPLETE) { //TODO SERVLET3 - async AtomicBoolean dispatch = (AtomicBoolean)param; @@ -828,145 +737,14 @@ public class Http11Processor extends Abs } - - /** - * When committing the response, we have to validate the set of headers, as - * well as setup the response filters. - */ - protected void prepareResponse() { - - boolean entityBody = true; - contentDelimitation = false; - - OutputFilter[] outputFilters = outputBuffer.getFilters(); - - if (http09 == true) { - // HTTP/0.9 - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - return; - } - - int statusCode = response.getStatus(); - if ((statusCode == 204) || (statusCode == 205) - || (statusCode == 304)) { - // No entity body - outputBuffer.addActiveFilter - (outputFilters[Constants.VOID_FILTER]); - entityBody = false; - contentDelimitation = true; - } - - MessageBytes methodMB = request.method(); - if (methodMB.equals("HEAD")) { - // No entity body - outputBuffer.addActiveFilter - (outputFilters[Constants.VOID_FILTER]); - contentDelimitation = true; - } - - // Check for compression - boolean useCompression = false; - if (entityBody && (compressionLevel > 0)) { - useCompression = isCompressable(); - - // Change content-length to -1 to force chunking - if (useCompression) { - response.setContentLength(-1); - } - } - - MimeHeaders headers = response.getMimeHeaders(); - if (!entityBody) { - response.setContentLength(-1); - } else { - String contentType = response.getContentType(); - if (contentType != null) { - headers.setValue("Content-Type").setString(contentType); - } - String contentLanguage = response.getContentLanguage(); - if (contentLanguage != null) { - headers.setValue("Content-Language") - .setString(contentLanguage); - } - } - - long contentLength = response.getContentLengthLong(); - if (contentLength != -1) { - headers.setValue("Content-Length").setLong(contentLength); - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - contentDelimitation = true; - } else { - if (entityBody && http11) { - outputBuffer.addActiveFilter - (outputFilters[Constants.CHUNKED_FILTER]); - contentDelimitation = true; - headers.addValue(Constants.TRANSFERENCODING).setString(Constants.CHUNKED); - } else { - outputBuffer.addActiveFilter - (outputFilters[Constants.IDENTITY_FILTER]); - } - } - - if (useCompression) { - outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]); - headers.setValue("Content-Encoding").setString("gzip"); - // Make Proxies happy via Vary (from mod_deflate) - MessageBytes vary = headers.getValue("Vary"); - if (vary == null) { - // Add a new Vary header - headers.setValue("Vary").setString("Accept-Encoding"); - } else if (vary.equals("*")) { - // No action required - } else { - // Merge into current header - headers.setValue("Vary").setString( - vary.getString() + ",Accept-Encoding"); - } - } - - // Add date header - headers.setValue("Date").setString(FastHttpDateFormat.getCurrentDate()); - - // FIXME: Add transfer encoding header - - if ((entityBody) && (!contentDelimitation)) { - // Mark as close the connection after the request, and add the - // connection: close header - keepAlive = false; - } - - // If we know that the request is bad this early, add the - // Connection: close header. - keepAlive = keepAlive && !statusDropsConnection(statusCode); - if (!keepAlive) { - headers.addValue(Constants.CONNECTION).setString(Constants.CLOSE); - } else if (!http11 && !error) { - headers.addValue(Constants.CONNECTION).setString(Constants.KEEPALIVE); - } - - // Build the response header - outputBuffer.sendStatus(); - - // Add server header - if (server != null) { - // Always overrides anything the app might set - headers.setValue("Server").setString(server); - } else if (headers.getValue("Server") == null) { - // If app didn't set the header, use the default - outputBuffer.write(Constants.SERVER_BYTES); - } - - int size = headers.size(); - for (int i = 0; i < size; i++) { - outputBuffer.sendHeader(headers.getName(i), headers.getValue(i)); - } - outputBuffer.endHeaders(); - + @Override + protected boolean prepareSendfile(OutputFilter[] outputFilters) { + // Should never, ever call this code + Exception e = new Exception(); + log.error(sm.getString("http11processor.neverused"), e); + return false; } - /** * Parse host. */ Modified: tomcat/trunk/java/org/apache/coyote/http11/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/LocalStrings.properties?rev=996672&r1=996671&r2=996672&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/coyote/http11/LocalStrings.properties Mon Sep 13 20:03:17 2010 @@ -51,6 +51,7 @@ http11processor.regexp.error=Error parsi http11processor.filter.unknown=Unknown filter {0} http11processor.filter.error=Error intializing filter {0} http11processor.header.parse=Error parsing HTTP request header +http11processor.neverused=This method should never be used http11processor.request.prepare=Error preparing request http11processor.request.process=Error processing request http11processor.request.finish=Error finishing request Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=996672&r1=996671&r2=996672&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Mon Sep 13 20:03:17 2010 @@ -480,6 +480,7 @@ public abstract class AbstractEndpoint { } protected abstract Log getLog(); + public abstract boolean getUseSendfile(); // -------------------- SSL related properties -------------------- Modified: tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=996672&r1=996671&r2=996672&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Mon Sep 13 20:03:17 2010 @@ -107,8 +107,17 @@ public class JIoEndpoint extends Abstrac public ServerSocketFactory getServerSocketFactory() { return serverSocketFactory; } - // ------------------------------------------------ Handler Inner Interface + /** + * Is sendfile available + */ + @Override + public boolean getUseSendfile() { + // Not supported + return false; + } + + // ------------------------------------------------ Handler Inner Interface /** * Bare bones interface used for socket processing. Per thread data is to be --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org