You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2010/02/24 19:03:01 UTC
svn commit: r915902 [1/2] - in /tomcat/trunk/modules/tomcat-lite: ./
java/org/apache/tomcat/integration/jmx/ java/org/apache/tomcat/lite/http/
java/org/apache/tomcat/lite/io/ java/org/apache/tomcat/lite/servlet/
java/org/apache/tomcat/lite/util/ java/o...
Author: costin
Date: Wed Feb 24 18:03:00 2010
New Revision: 915902
URL: http://svn.apache.org/viewvc?rev=915902&view=rev
Log:
Moved utils to connector ( the servlet part will either go away or be a separate package ). Make it compile again on android. Few sync
issues found while load testing. SSL fixes. Separate build target for connector.
Added:
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/Base64.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Base64.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/FastHttpDateFormat.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/FastHttpDateFormat.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/LocaleParser.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/LocaleParser.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/MimeMap.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/MimeMap.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/Range.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Range.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/URLEncoder.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/URLEncoder.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/util/UrlUtils.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/UrlUtils.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/util/
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/util/UEncoderTest.java
- copied, changed from r907366, tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/util/buf/UEncoderTest.java
Removed:
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Base64.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/FastHttpDateFormat.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/LocaleParser.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/MimeMap.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Range.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/URLEncoder.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/UrlUtils.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/util/buf/UEncoderTest.java
Modified:
tomcat/trunk/modules/tomcat-lite/build.xml
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/UJmxHandler.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/ContentType.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/Http11Connection.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnectionPool.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnector.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpMessage.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpRequest.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpResponse.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/SpdyConnection.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/DumpChannel.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOBuffer.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/WebappFilterMapper.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/DefaultServlet.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/WebdavServlet.java
tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/RequestUtil.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/coyote/lite/TomcatLiteCoyoteTest.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/TestMain.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/http/HttpsTest.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/http/LiveHttp1Test.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/http/SpdyTest.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/LiveHttpThreadedTest.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/MicroTest.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/load/ThreadRunner.java
tomcat/trunk/modules/tomcat-lite/test/org/apache/tomcat/lite/test.properties
Modified: tomcat/trunk/modules/tomcat-lite/build.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/build.xml?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/build.xml (original)
+++ tomcat/trunk/modules/tomcat-lite/build.xml Wed Feb 24 18:03:00 2010
@@ -14,9 +14,11 @@
<property name="tomcat.lite.src" value="${basedir}/" />
<property name="classes" value="${basedir}/target/tomcat-lite/classes" />
<property name="test-classes" value="${basedir}/target/tomcat-lite/test-classes" />
+ <property name="http.test-classes" value="${basedir}/target/tomcat-lite/http-test-classes" />
<property name="jar.dir" value="${basedir}/target/tomcat-lite/" />
<property name="MAIN" value="org.apache.tomcat.integration.simple.Main"/>
<property name="compile.source" value="1.6"/>
+ <property name="compile.debug" value="true"/>
<!-- All Ivy downloads -->
<path id='lite-classpath'>
@@ -31,9 +33,109 @@
<pathelement location="target/lib/commons-codec.jar"/>
</path>
+ <target name="http" depends="http.compile,http.test,http.pack"/>
+
+ <target name="http.compile"
+ description="Compile only the HTTP connector classes, no servlets">
+ <mkdir dir="${classes}"/>
+ <javac destdir="${classes}"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ source="${compile.source}"
+ optimize="${compile.optimize}"
+ encoding="ISO-8859-1">
+ <classpath refid="lite-classpath" />
+ <src path="${tomcat.lite.src}/java" />
+ <classpath refid="head-classpath" />
+ <exclude name="org/apache/tomcat/servlets/**"/>
+ <exclude name="org/apache/tomcat/lite/servlet/**"/>
+ </javac>
+ <copy todir="${classes}">
+ <fileset dir="${tomcat.lite.src}/java"
+ includes="**/*.properties **/*.xml" />
+ </copy>
+ </target>
+
+ <target name="http.test.compile"
+ description="Test only the HTTP connector classes, no servlets">
+ <mkdir dir="${http.test-classes}"/>
+ <javac destdir="${http.test-classes}"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ source="${compile.source}"
+ optimize="${compile.optimize}"
+ encoding="ISO-8859-1"
+ >
+ <classpath refid="lite-classpath" />
+ <classpath refid="head-classpath" />
+ <classpath path="${classes}" />
+ <src path="${tomcat.lite.src}/test" />
+ <exclude name="org/apache/tomcat/lite/servlet/**"/>
+ <exclude name="org/apache/coyote/lite/**"/>
+ <exclude name="org/apache/tomcat/test/watchdog/**"/>
+ </javac>
+ <copy todir="${http.test-classes}">
+ <fileset dir="${tomcat.lite.src}/test"
+ includes="**/*.properties **/*.xml **/*.bin **/*.keystore" />
+ </copy>
+ </target>
+
+ <target name="http.test" depends="http.test.compile" >
+ <!-- also: perTest(default) -->
+ <junit printsummary="on" fork="once"
+ timeout="600000" maxmemory="1G" outputtoformatters="no"
+ >
+ <classpath refid="lite-classpath" />
+ <classpath refid="head-classpath" />
+ <classpath path="${http.test-classes}" />
+ <classpath path="${classes}" />
+
+ <formatter type="brief" usefile="false" />
+
+ <batchtest>
+ <fileset dir="test" >
+ <!-- Include all by default -->
+ <include name="**/*Test.java" />
+ <include name="**/*Tests.java" />
+ <!-- Exclude TestAll ortherwise there will be duplicated -->
+ <exclude name="**/TestAll.java" />
+ <!-- Exclude helper classes -->
+ <exclude name="**/Tester*.java" />
+
+ <exclude name="org/apache/tomcat/lite/servlet/**"/>
+ <exclude name="org/apache/coyote/lite/**"/>
+ <exclude name="org/apache/tomcat/test/watchdog/**"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="runtest" depends="http.test.compile">
+ <junit printsummary="withOutAndErr" fork="no" dir="${tomcat.base}">
+ <sysproperty key="tests" value="${tests}"/>
+ <classpath refid="lite-classpath" />
+ <classpath refid="head-classpath" />
+ <classpath path="${http.test-classes}" />
+ <classpath path="${classes}" />
+
+ <formatter type="plain" usefile="false" />
+
+ <batchtest>
+ <fileset dir="test" >
+ <include name="**/${test}.java" />
+ </fileset>
+ </batchtest>
+ </junit>
+
+ </target>
+
+ <target name="http.pack"
+ description="Pack the HTTP client and connector">
+ </target>
<target name="compile"
- description="Build against tomcat head">
+ description="Build all classes against tomcat head.">
+ <mkdir dir="${classes}"/>
<javac destdir="${classes}"
debug="${compile.debug}"
deprecation="${compile.deprecation}"
@@ -59,14 +161,12 @@
deprecation="${compile.deprecation}"
source="${compile.source}"
optimize="${compile.optimize}"
- encoding="ISO-8859-1"
- >
+ encoding="ISO-8859-1">
<classpath refid="lite-classpath" />
<src path="${tomcat.lite.src}/java" />
<exclude name="**/ServletApi30.java"/>
<exclude name="org/apache/tomcat/coyote/servlet/*.java"/>
</javac>
-
<copy todir="${classes}">
<fileset dir="${tomcat.lite.src}/java"
includes="**/*.properties **/*.xml" />
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java Wed Feb 24 18:03:00 2010
@@ -28,7 +28,7 @@
*
* All objects of interest are registered automatically.
*/
-public class JmxObjectManagerSpi extends ObjectManager {
+public class JmxObjectManagerSpi extends ObjectManager implements Runnable {
Registry registry;
Logger log = Logger.getLogger("JmxObjectManager");
@@ -54,5 +54,15 @@
public Object get(String key) {
return null;
}
+
+ ObjectManager om;
+
+ public void setObjectManager(ObjectManager om) {
+ this.om = om;
+ }
+ public void run() {
+ om.register(this);
+ // TODO: register existing objects in JMX
+ }
}
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/UJmxHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/UJmxHandler.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/UJmxHandler.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/UJmxHandler.java Wed Feb 24 18:03:00 2010
@@ -21,14 +21,11 @@
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.HashMap;
import java.util.Iterator;
-import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import org.apache.tomcat.integration.DynamicObject;
-import org.apache.tomcat.integration.ObjectManager;
import org.apache.tomcat.lite.http.HttpRequest;
import org.apache.tomcat.lite.http.HttpResponse;
import org.apache.tomcat.lite.http.HttpWriter;
@@ -47,16 +44,18 @@
*/
public class UJmxHandler implements HttpService {
- private static Logger log = Logger.getLogger(UJmxHandler.class.getName());
+ protected static Logger log = Logger.getLogger(UJmxHandler.class.getName());
private UJmxObjectManagerSpi jmx;
+ public UJmxHandler() {
+ }
+
public UJmxHandler(UJmxObjectManagerSpi jmx) {
this.jmx = jmx;
}
public void getAttribute(PrintWriter writer, String onameStr, String att) {
try {
-
Object bean = jmx.objects.get(onameStr);
Class beanClass = bean.getClass();
DynamicObject ci = jmx.getClassInfo(beanClass);
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/ContentType.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/ContentType.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/ContentType.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/ContentType.java Wed Feb 24 18:03:00 2010
@@ -72,7 +72,7 @@
int index = type.indexOf(';');
while (index != -1) {
index++;
- while (index < len && Character.isSpace(type.charAt(index))) {
+ while (index < len && Character.isWhitespace(type.charAt(index))) {
index++;
}
if (index+8 < len
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/Http11Connection.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/Http11Connection.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/Http11Connection.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/Http11Connection.java Wed Feb 24 18:03:00 2010
@@ -4,6 +4,8 @@
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -144,6 +146,8 @@
return closeInHead();
}
}
+
+
return true;
}
@@ -209,6 +213,11 @@
if (!headersReceived) {
headRecvBuf.wrapTo(headW);
parseMessage(activeHttp, headW);
+ // Part of parseMessage we can switch the protocol
+ if (switchedProtocol != null) {
+ return;
+ }
+
if (serverMode && activeHttp.httpReq.decodedUri.remaining() == 0) {
abort(activeHttp, "Invalid url");
}
@@ -552,6 +561,8 @@
return statusCode.remaining() > 0;
}
+ List<String> connectionHeaders = new ArrayList<String>();
+
private void parseHeaders(HttpChannel http, HttpMessageBytes msgBytes,
BBuffer head)
throws IOException {
@@ -559,6 +570,9 @@
head.readLine(line);
int idx = 0;
+
+ BBuffer upgrade = null;
+
while(line.remaining() > 0) {
// not empty..
idx = msgBytes.addHeader();
@@ -567,7 +581,23 @@
parseHeader(http, head, line, nameBuf, valBuf);
// TODO: process 'interesting' headers here.
+ if (nameBuf.equalsIgnoreCase("connection")) {
+ // TODO: save and remove if not recognized
+ }
+ if (nameBuf.equalsIgnoreCase("upgrade")) {
+ upgrade = valBuf;
+ }
+ }
+
+ if (upgrade != null) {
+ if (upgrade.equalsIgnoreCase("WebSocket")) {
+
+ } else if (upgrade.equalsIgnoreCase("SPDY/1.0")) {
+
+ }
}
+
+ // TODO: process connection headers
}
/**
@@ -1406,8 +1436,10 @@
HttpChannel httpCh = activeHttp;
boolean ssl = httpCh.getRequest().isSecure();
if (ssl) {
- SslChannel ch1 = new SslChannel();
- ch1.setSslContext(httpConnector.sslConnector.getSSLContext());
+ String[] hostPort = httpCh.getTarget().split(":");
+
+ SslChannel ch1 = httpConnector.sslConnector.channel(
+ hostPort[0], Integer.parseInt(hostPort[1]));
ch1.setSink(net);
net.addFilterAfter(ch1);
net = ch1;
@@ -1419,7 +1451,7 @@
}
if (!net.isOpen()) {
- httpCh.abort("Can't connect");
+ httpCh.abort(net.lastException());
return;
}
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnectionPool.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnectionPool.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnectionPool.java Wed Feb 24 18:03:00 2010
@@ -282,14 +282,14 @@
if (con.isOpen()) {
hits.incrementAndGet();
- if (debug) {
- httpCh.trace("HTTP_CONNECT: Reuse connection " + target + " " + this);
- }
+// if (debug) {
+// log.info("HTTP_CONNECT: Reuse connection " + target + " " + this);
+// }
con.sendRequest(httpCh);
} else {
misses.incrementAndGet();
if (debug) {
- httpCh.trace("HTTP_CONNECT: Start connection " + target + " " + this);
+ log.info("HTTP_CONNECT: Start connection " + target + " " + this);
}
httpConnect(httpCh, target, ssl,
(Http11Connection) con);
@@ -300,7 +300,7 @@
boolean ssl, IOConnector.ConnectedCallback cb)
throws IOException {
if (debug) {
- httpCh.trace("HTTP_CONNECT: New connection " + target);
+ log.info("HTTP_CONNECT: New connection " + target);
}
String[] hostPort = target.split(":");
@@ -341,9 +341,6 @@
// again.
if (remoteServer.pending.size() == 0) {
con.activeHttp = null;
- if (debug) {
- log.info("After request: no pending");
- }
return;
}
req = remoteServer.pending.remove();
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnector.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnector.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnector.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpConnector.java Wed Feb 24 18:03:00 2010
@@ -115,6 +115,10 @@
return dispatcher;
}
+ public HttpConnectionPool getConnectionPool() {
+ return cpool;
+ }
+
public HttpConnector withIOConnector(IOConnector selectors) {
ioConnector = selectors;
return this;
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpMessage.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpMessage.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpMessage.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpMessage.java Wed Feb 24 18:03:00 2010
@@ -4,16 +4,23 @@
import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
import org.apache.tomcat.lite.http.HttpChannel.RequestCompleted;
import org.apache.tomcat.lite.http.HttpConnector.HttpConnection;
import org.apache.tomcat.lite.io.BBuffer;
import org.apache.tomcat.lite.io.BufferedIOReader;
import org.apache.tomcat.lite.io.CBuffer;
+import org.apache.tomcat.lite.io.FastHttpDateFormat;
import org.apache.tomcat.lite.io.IOBuffer;
import org.apache.tomcat.lite.io.IOInputStream;
import org.apache.tomcat.lite.io.IOOutputStream;
@@ -113,7 +120,9 @@
}
}
}
-
+
+ protected static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
+
private HttpMessageBytes msgBytes = new HttpMessageBytes();
protected HttpMessage.State state = HttpMessage.State.HEAD;
@@ -149,6 +158,15 @@
long contentLength = -2;
boolean chunked;
+ /**
+ * The set of SimpleDateFormat formats to use in getDateHeader().
+ *
+ * Notice that because SimpleDateFormat is not thread-safe, we can't
+ * declare formats[] as a static variable.
+ */
+ protected SimpleDateFormat formats[] = null;
+
+
BBuffer clBuffer = BBuffer.allocate(64);
public HttpMessage(HttpChannel httpCh) {
@@ -189,6 +207,41 @@
return headers;
}
+ /**
+ * Return the value of the specified date header, if any; otherwise
+ * return -1.
+ *
+ * @param name Name of the requested date header
+ *
+ * @exception IllegalArgumentException if the specified header value
+ * cannot be converted to a date
+ */
+ public long getDateHeader(String name) {
+
+ String value = getHeader(name);
+ if (value == null)
+ return (-1L);
+ if (formats == null) {
+ formats = new SimpleDateFormat[] {
+ new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
+ new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
+ new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
+ };
+ formats[0].setTimeZone(GMT_ZONE);
+ formats[1].setTimeZone(GMT_ZONE);
+ formats[2].setTimeZone(GMT_ZONE);
+ }
+
+ // Attempt to convert the date header in a variety of formats
+ long result = FastHttpDateFormat.parseDate(value, formats);
+ if (result != (-1L)) {
+ return result;
+ }
+ throw new IllegalArgumentException(value);
+
+ }
+
+
public Collection<String> getHeaderNames() {
MultiMap headers = getMimeHeaders();
@@ -373,6 +426,14 @@
return in;
}
+ public InputStream getInputStream() {
+ return in;
+ }
+
+ public IOOutputStream getOutputStream() {
+ return out;
+ }
+
public IOOutputStream getBodyOutputStream() {
return out;
}
@@ -410,6 +471,10 @@
reader.setEncoding(getCharacterEncoding());
return bufferedReader;
}
+
+ public PrintWriter getWriter() {
+ return new PrintWriter(getBodyWriter());
+ }
public HttpWriter getBodyWriter() {
conv.setEncoding(getCharacterEncoding());
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpRequest.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpRequest.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpRequest.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpRequest.java Wed Feb 24 18:03:00 2010
@@ -175,6 +175,30 @@
return (mappingData);
}
+ /**
+ * Return the portion of the request URI used to select the Context
+ * of the Request.
+ */
+ public String getContextPath() {
+ return (getMappingData().contextPath.toString());
+ }
+
+ public String getPathInfo() {
+ CBuffer pathInfo = getMappingData().pathInfo;
+ if (pathInfo.length() == 0) {
+ return null;
+ }
+ return (getMappingData().pathInfo.toString());
+ }
+
+ /**
+ * Return the portion of the request URI used to select the servlet
+ * that will process this request.
+ */
+ public String getServletPath() {
+ return (getMappingData().wrapperPath.toString());
+ }
+
/**
* Parse query parameters - but not POST body.
*
@@ -843,6 +867,9 @@
*/
protected void processReceivedHeaders() throws IOException {
BBuffer url = getMsgBytes().url();
+ if (url.remaining() == 0) {
+ System.err.println("No input");
+ }
if (url.get(0) == 'h') {
int firstSlash = url.indexOf('/', 0);
schemeMB.appendAscii(url.array(),
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpResponse.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpResponse.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpResponse.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/HttpResponse.java Wed Feb 24 18:03:00 2010
@@ -8,9 +8,336 @@
import org.apache.tomcat.lite.io.BBucket;
import org.apache.tomcat.lite.io.BBuffer;
import org.apache.tomcat.lite.io.CBuffer;
-import org.apache.tomcat.lite.io.IOBuffer;
public class HttpResponse extends HttpMessage {
+
+ /*
+ * Server status codes; see RFC 2068.
+ */
+
+ /**
+ * Status code (100) indicating the client can continue.
+ */
+
+ public static final int SC_CONTINUE = 100;
+
+
+ /**
+ * Status code (101) indicating the server is switching protocols
+ * according to Upgrade header.
+ */
+
+ public static final int SC_SWITCHING_PROTOCOLS = 101;
+
+ /**
+ * Status code (200) indicating the request succeeded normally.
+ */
+
+ public static final int SC_OK = 200;
+
+ /**
+ * Status code (201) indicating the request succeeded and created
+ * a new resource on the server.
+ */
+
+ public static final int SC_CREATED = 201;
+
+ /**
+ * Status code (202) indicating that a request was accepted for
+ * processing, but was not completed.
+ */
+
+ public static final int SC_ACCEPTED = 202;
+
+ /**
+ * Status code (203) indicating that the meta information presented
+ * by the client did not originate from the server.
+ */
+
+ public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
+
+ /**
+ * Status code (204) indicating that the request succeeded but that
+ * there was no new information to return.
+ */
+
+ public static final int SC_NO_CONTENT = 204;
+
+ /**
+ * Status code (205) indicating that the agent <em>SHOULD</em> reset
+ * the document view which caused the request to be sent.
+ */
+
+ public static final int SC_RESET_CONTENT = 205;
+
+ /**
+ * Status code (206) indicating that the server has fulfilled
+ * the partial GET request for the resource.
+ */
+
+ public static final int SC_PARTIAL_CONTENT = 206;
+
+ /**
+ * Used by Webdav.
+ */
+ public static final int SC_MULTI_STATUS = 207;
+ // This one collides with HTTP 1.1
+ // "207 Partial Update OK"
+
+ /**
+ * Status code (300) indicating that the requested resource
+ * corresponds to any one of a set of representations, each with
+ * its own specific location.
+ */
+
+ public static final int SC_MULTIPLE_CHOICES = 300;
+
+ /**
+ * Status code (301) indicating that the resource has permanently
+ * moved to a new location, and that future references should use a
+ * new URI with their requests.
+ */
+
+ public static final int SC_MOVED_PERMANENTLY = 301;
+
+ /**
+ * Status code (302) indicating that the resource has temporarily
+ * moved to another location, but that future references should
+ * still use the original URI to access the resource.
+ *
+ * This definition is being retained for backwards compatibility.
+ * SC_FOUND is now the preferred definition.
+ */
+
+ public static final int SC_MOVED_TEMPORARILY = 302;
+
+ /**
+ * Status code (302) indicating that the resource reside
+ * temporarily under a different URI. Since the redirection might
+ * be altered on occasion, the client should continue to use the
+ * Request-URI for future requests.(HTTP/1.1) To represent the
+ * status code (302), it is recommended to use this variable.
+ */
+
+ public static final int SC_FOUND = 302;
+
+ /**
+ * Status code (303) indicating that the response to the request
+ * can be found under a different URI.
+ */
+
+ public static final int SC_SEE_OTHER = 303;
+
+ /**
+ * Status code (304) indicating that a conditional GET operation
+ * found that the resource was available and not modified.
+ */
+
+ public static final int SC_NOT_MODIFIED = 304;
+
+ /**
+ * Status code (305) indicating that the requested resource
+ * <em>MUST</em> be accessed through the proxy given by the
+ * <code><em>Location</em></code> field.
+ */
+
+ public static final int SC_USE_PROXY = 305;
+
+ /**
+ * Status code (307) indicating that the requested resource
+ * resides temporarily under a different URI. The temporary URI
+ * <em>SHOULD</em> be given by the <code><em>Location</em></code>
+ * field in the response.
+ */
+
+ public static final int SC_TEMPORARY_REDIRECT = 307;
+
+ /**
+ * Status code (400) indicating the request sent by the client was
+ * syntactically incorrect.
+ */
+
+ public static final int SC_BAD_REQUEST = 400;
+
+ /**
+ * Status code (401) indicating that the request requires HTTP
+ * authentication.
+ */
+
+ public static final int SC_UNAUTHORIZED = 401;
+
+ /**
+ * Status code (402) reserved for future use.
+ */
+
+ public static final int SC_PAYMENT_REQUIRED = 402;
+
+ /**
+ * Status code (403) indicating the server understood the request
+ * but refused to fulfill it.
+ */
+
+ public static final int SC_FORBIDDEN = 403;
+
+ /**
+ * Status code (404) indicating that the requested resource is not
+ * available.
+ */
+
+ public static final int SC_NOT_FOUND = 404;
+
+ /**
+ * Status code (405) indicating that the method specified in the
+ * <code><em>Request-Line</em></code> is not allowed for the resource
+ * identified by the <code><em>Request-URI</em></code>.
+ */
+
+ public static final int SC_METHOD_NOT_ALLOWED = 405;
+
+ /**
+ * Status code (406) indicating that the resource identified by the
+ * request is only capable of generating response entities which have
+ * content characteristics not acceptable according to the accept
+ * headers sent in the request.
+ */
+
+ public static final int SC_NOT_ACCEPTABLE = 406;
+
+ /**
+ * Status code (407) indicating that the client <em>MUST</em> first
+ * authenticate itself with the proxy.
+ */
+
+ public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
+
+ /**
+ * Status code (408) indicating that the client did not produce a
+ * request within the time that the server was prepared to wait.
+ */
+
+ public static final int SC_REQUEST_TIMEOUT = 408;
+
+ /**
+ * Status code (409) indicating that the request could not be
+ * completed due to a conflict with the current state of the
+ * resource.
+ */
+
+ public static final int SC_CONFLICT = 409;
+
+ /**
+ * Status code (410) indicating that the resource is no longer
+ * available at the server and no forwarding address is known.
+ * This condition <em>SHOULD</em> be considered permanent.
+ */
+
+ public static final int SC_GONE = 410;
+
+ /**
+ * Status code (411) indicating that the request cannot be handled
+ * without a defined <code><em>Content-Length</em></code>.
+ */
+
+ public static final int SC_LENGTH_REQUIRED = 411;
+
+ /**
+ * Status code (412) indicating that the precondition given in one
+ * or more of the request-header fields evaluated to false when it
+ * was tested on the server.
+ */
+
+ public static final int SC_PRECONDITION_FAILED = 412;
+
+ /**
+ * Status code (413) indicating that the server is refusing to process
+ * the request because the request entity is larger than the server is
+ * willing or able to process.
+ */
+
+ public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
+
+ /**
+ * Status code (414) indicating that the server is refusing to service
+ * the request because the <code><em>Request-URI</em></code> is longer
+ * than the server is willing to interpret.
+ */
+
+ public static final int SC_REQUEST_URI_TOO_LONG = 414;
+
+ /**
+ * Status code (415) indicating that the server is refusing to service
+ * the request because the entity of the request is in a format not
+ * supported by the requested resource for the requested method.
+ */
+
+ public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
+
+ /**
+ * Status code (416) indicating that the server cannot serve the
+ * requested byte range.
+ */
+
+ public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+
+ /**
+ * Status code (417) indicating that the server could not meet the
+ * expectation given in the Expect request header.
+ */
+
+ public static final int SC_EXPECTATION_FAILED = 417;
+
+ /**
+ * Status code (423) indicating the destination resource of a
+ * method is locked, and either the request did not contain a
+ * valid Lock-Info header, or the Lock-Info header identifies
+ * a lock held by another principal.
+ */
+ public static final int SC_LOCKED = 423;
+
+ /**
+ * Status code (500) indicating an error inside the HTTP server
+ * which prevented it from fulfilling the request.
+ */
+
+ public static final int SC_INTERNAL_SERVER_ERROR = 500;
+
+ /**
+ * Status code (501) indicating the HTTP server does not support
+ * the functionality needed to fulfill the request.
+ */
+
+ public static final int SC_NOT_IMPLEMENTED = 501;
+
+ /**
+ * Status code (502) indicating that the HTTP server received an
+ * invalid response from a server it consulted when acting as a
+ * proxy or gateway.
+ */
+
+ public static final int SC_BAD_GATEWAY = 502;
+
+ /**
+ * Status code (503) indicating that the HTTP server is
+ * temporarily overloaded, and unable to handle the request.
+ */
+
+ public static final int SC_SERVICE_UNAVAILABLE = 503;
+
+ /**
+ * Status code (504) indicating that the server did not receive
+ * a timely response from the upstream server while acting as
+ * a gateway or proxy.
+ */
+
+ public static final int SC_GATEWAY_TIMEOUT = 504;
+
+ /**
+ * Status code (505) indicating that the server does not support
+ * or refuses to support the HTTP protocol version that was used
+ * in the request message.
+ */
+
+ public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
// will not be recycled
public Object nativeResponse;
@@ -47,6 +374,14 @@
status = i;
}
+ public void sendError(int status) {
+ this.status = status;
+ }
+
+ public void sendError(int status, String msg) {
+ message.set(msg);
+ }
+
public int getStatus() {
if (status >= 0) {
return status;
@@ -112,7 +447,7 @@
* Common messages are cached.
*
*/
- BBucket getMessage( int status ) {
+ static BBucket getMessage( int status ) {
// method from Response.
// Does HTTP requires/allow international messages or
@@ -134,6 +469,9 @@
return bb;
}
+ public static String getStatusText(int code) {
+ return getMessage(code).toString();
+ }
static BBucket st_unknown = BBuffer.wrapper("No Message");
static BBucket st_200 = BBuffer.wrapper("OK");
@@ -192,6 +530,8 @@
addStatus(504, "Gateway Timeout");
addStatus(505, "HTTP Version Not Supported");
addStatus(507, "Insufficient Storage");
+ addStatus(SC_LOCKED, "Locked");
+
}
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/SpdyConnection.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/SpdyConnection.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/SpdyConnection.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/http/SpdyConnection.java Wed Feb 24 18:03:00 2010
@@ -95,9 +95,12 @@
CompressFilter headCompressIn = new CompressFilter()
.setDictionary(SPDY_DICT, DICT_ID);
+
CompressFilter headCompressOut = new CompressFilter()
.setDictionary(SPDY_DICT, DICT_ID);
+
IOBuffer headerCompressBuffer = new IOBuffer();
+ IOBuffer headerDeCompressBuffer = new IOBuffer();
AtomicInteger inFrames = new AtomicInteger();
AtomicInteger inDataFrames = new AtomicInteger();
@@ -120,32 +123,35 @@
}
@Override
- public synchronized void dataReceived(IOBuffer iob) throws IOException {
- while (true) {
- int avail = iob.available();
- if (avail == 0) {
- return;
- }
- if (currentInFrame == null) {
- if (inFrameBuffer.remaining() + avail < 8) {
+ public void dataReceived(IOBuffer iob) throws IOException {
+ // Only one thread doing receive at a time.
+ synchronized (inFrameBuffer) {
+ while (true) {
+ int avail = iob.available();
+ if (avail == 0) {
return;
}
- if (inFrameBuffer.remaining() < 8) {
- int headRest = 8 - inFrameBuffer.remaining();
- int rd = iob.read(inFrameBuffer, headRest);
+ if (currentInFrame == null) {
+ if (inFrameBuffer.remaining() + avail < 8) {
+ return;
+ }
+ if (inFrameBuffer.remaining() < 8) {
+ int headRest = 8 - inFrameBuffer.remaining();
+ int rd = iob.read(inFrameBuffer, headRest);
+ }
+ currentInFrame = new SpdyConnection.Frame(); // TODO: reuse
+ currentInFrame.parse(this, inFrameBuffer);
}
- currentInFrame = new SpdyConnection.Frame(); // TODO: reuse
- currentInFrame.parse(this, inFrameBuffer);
- }
- if (iob.available() < currentInFrame.length) {
- return;
- }
- // We have a full frame. Process it.
- onFrame(iob);
+ if (iob.available() < currentInFrame.length) {
+ return;
+ }
+ // We have a full frame. Process it.
+ onFrame(iob);
- // TODO: extra checks, make sure the frame is correct and
- // it consumed all data.
- currentInFrame = null;
+ // TODO: extra checks, make sure the frame is correct and
+ // it consumed all data.
+ currentInFrame = null;
+ }
}
}
@@ -179,7 +185,7 @@
ch.setHttpService(this.httpConnector.defaultService);
}
- synchronized (this) {
+ synchronized (channels) {
channels.put(ch.channelId, ch);
}
@@ -206,7 +212,7 @@
} else if (currentInFrame.type == SpdyConnection.Frame.TYPE_SYN_REPLY) {
int chId = SpdyConnection.readInt(iob);
HttpChannel ch;
- synchronized (this) {
+ synchronized (channels) {
ch = channels.get(chId);
if (ch == null) {
abort("Channel not found");
@@ -239,7 +245,7 @@
inDataFrames.incrementAndGet();
// data frame - part of an existing stream
HttpChannel ch;
- synchronized (this) {
+ synchronized (channels) {
ch = channels.get(currentInFrame.streamId);
}
if (ch == null) {
@@ -280,8 +286,10 @@
*/
private void abort(String msg) throws IOException {
streamErrors.incrementAndGet();
- for (HttpChannel ch : channels.values()) {
- ch.abort(msg);
+ synchronized(channels) {
+ for (HttpChannel ch : channels.values()) {
+ ch.abort(msg);
+ }
}
close();
}
@@ -299,13 +307,13 @@
if (headerCompression) {
// 0x800 headers seems a bit too much - assume compressed.
// I wish this was a flag...
- headerCompressBuffer.recycle();
+ headerDeCompressBuffer.recycle();
// stream id ( 4 ) + unused ( 2 )
// nvCount is compressed in impl - spec is different
- headCompressIn.decompress(iob, headerCompressBuffer,
+ headCompressIn.decompress(iob, headerDeCompressBuffer,
currentInFrame.length - 6);
- headerCompressBuffer.copyAll(headRecvBuf);
- headerCompressBuffer.recycle();
+ headerDeCompressBuffer.copyAll(headRecvBuf);
+ headerDeCompressBuffer.recycle();
nvCount = readShort(headRecvBuf);
} else {
nvCount = readShort(iob);
@@ -424,7 +432,7 @@
http.setConnection(this);
- synchronized (this) {
+ synchronized (channels) {
channels.put(http.channelId, http);
}
@@ -446,7 +454,9 @@
public synchronized Collection<HttpChannel> getActives() {
- return channels.values();
+ synchronized(channels) {
+ return channels.values();
+ }
}
@Override
@@ -711,7 +721,7 @@
@Override
protected void endSendReceive(HttpChannel http) throws IOException {
- synchronized (this) {
+ synchronized (channels) {
HttpChannel doneHttp = channels.remove(http.channelId);
if (doneHttp != http) {
log.severe("Error removing " + doneHttp + " " + http);
@@ -775,8 +785,15 @@
}
secure = httpCh.getRequest().isSecure();
if (secure) {
- SslChannel ch1 = new SslChannel();
- ch1.setSslContext(httpConnector.sslConnector.getSSLContext());
+ if (httpConnector.debugHttp) {
+ IOChannel ch1 = new DumpChannel("NET-IN");
+ net.addFilterAfter(ch1);
+ net = ch1;
+ }
+ String[] hostPort = httpCh.getTarget().split(":");
+
+ SslChannel ch1 = httpConnector.sslConnector.channel(
+ hostPort[0], Integer.parseInt(hostPort[1]));
ch1.setSink(net);
net.addFilterAfter(ch1);
net = ch1;
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/DumpChannel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/DumpChannel.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/DumpChannel.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/DumpChannel.java Wed Feb 24 18:03:00 2010
@@ -46,7 +46,9 @@
}
any = true;
out("IN", first, false);
- in.queue(first);
+ if (!in.isAppendClosed()) {
+ in.queue(first);
+ }
}
}
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOBuffer.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOBuffer.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOBuffer.java Wed Feb 24 18:03:00 2010
@@ -342,8 +342,12 @@
public int write(ByteBuffer bb) throws IOException {
int len = bb.remaining();
+ int pos = bb.position();
+ if (len == 0) {
+ return 0;
+ }
append(bb);
- bb.position(bb.position() + len);
+ bb.position(pos + len);
return len;
}
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java Wed Feb 24 18:03:00 2010
@@ -21,7 +21,7 @@
* @author Costin Manolache
*/
public abstract class IOChannel implements ByteChannel, IOConnector.DataReceivedCallback,
- IOConnector.DataFlushedCallback { //, IOConnector.ClosedCallback {
+ IOConnector.DataFlushedCallback {
protected IOChannel net;
protected IOChannel app;
@@ -39,6 +39,8 @@
// TODO: update, etc
public long ts;
+ protected Throwable lastException;
+
public void setConnectedCallback(IOConnector.ConnectedCallback connectedCallback) {
this.connectedCallback = connectedCallback;
}
@@ -131,7 +133,18 @@
}
}
}
-
+
+ /**
+ * Return last IO exception.
+ *
+ * The channel is async, exceptions can happen at any time.
+ * The normal callback will be called ( connected, received ), it
+ * should check if the channel is closed and the exception.
+ */
+ public Throwable lastException() {
+ return lastException;
+ }
+
public void close() throws IOException {
shutdownOutput();
// Should it read the buffers ?
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java Wed Feb 24 18:03:00 2010
@@ -21,6 +21,12 @@
public void handleReceived(IOChannel ch) throws IOException;
}
+ /**
+ * Callback for accept and connect.
+ *
+ * Will also be called if an error happens while connecting, in
+ * which case the connection will be closed.
+ */
public static interface ConnectedCallback {
public void handleConnected(IOChannel ch) throws IOException;
}
@@ -35,6 +41,10 @@
return timer;
}
+ public IOConnector getNet() {
+ return null;
+ }
+
public abstract void acceptor(IOConnector.ConnectedCallback sc,
CharSequence port, Object extra)
throws IOException;
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java Wed Feb 24 18:03:00 2010
@@ -10,7 +10,6 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
-import java.util.BitSet;
import java.util.HashMap;
import java.util.Map;
@@ -155,6 +154,40 @@
}
}
+ // TODO: use it for utf-8
+ public static int char2utf8(byte[] ba, int off, char c, char c1) {
+ int i = 0;
+ if (c < 0x80) {
+ ba[off++] = (byte) (c & 0xFF);
+ return 1;
+ } else if (c < 0x800)
+ {
+ ba[off++] = (byte) (0xC0 | c >> 6);
+ ba[off++] = (byte) (0x80 | c & 0x3F);
+ return 2;
+ }
+ else if (c < 0x10000)
+ {
+ ba[off++] = (byte) ((0xE0 | c >> 12));
+ ba[off++] = (byte) ((0x80 | c >> 6 & 0x3F));
+ ba[off++] = (byte) ((0x80 | c & 0x3F));
+ return 3;
+ }
+ else if (c < 0x200000)
+ {
+ ba[off++] = (byte) ((0xF0 | c >> 18));
+ ba[off++] = (byte) ((0x80 | c >> 12 & 0x3F));
+ ba[off++] = (byte) ((0x80 | c >> 6 & 0x3F));
+ ba[off++] = (byte) ((0x80 | c & 0x3F));
+ return 4;
+ }
+
+
+ return i;
+ }
+
+
+
/**
* Just send the chars to the byte[], without flushing down.
*
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java Wed Feb 24 18:03:00 2010
@@ -5,7 +5,6 @@
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.Channel;
-import java.nio.channels.SelectionKey;
/**
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java Wed Feb 24 18:03:00 2010
@@ -410,23 +410,17 @@
}
readInterest(ch, true);
-
- if (ch.callback != null) {
- ch.callback.handleConnected(ch);
- }
} catch (Throwable t) {
- log.warning("Error in connect, closing " + t);
close(ch, t);
- try {
- if (ch.callback != null) {
- ch.callback.handleConnected(ch);
- }
- } catch(Throwable t1) {
- log.warning("Double error in connect, callback broken too");
- t1.printStackTrace();
+ }
+ try {
+ if (ch.callback != null) {
+ ch.callback.handleConnected(ch);
}
-
+ } catch(Throwable t1) {
+ log.log(Level.WARNING, "Error in connect callback", t1);
}
+
}
private void handleAccept(NioChannel ch, SelectionKey sk)
@@ -729,17 +723,17 @@
*/
public int close(NioChannel selectorData, Throwable exception) throws IOException {
synchronized (closeInterest) {
+ if (exception != null) {
+ selectorData.lastException = exception;
+ }
+ selectorData.readInterest = false;
if (isSelectorThread()) {
closeIOThread(selectorData, true);
return 0;
}
- if (exception != null) {
- selectorData.lastException = exception;
- }
if (!selectorData.inClosed) {
closeInterest.add(selectorData);
}
- selectorData.readInterest = false;
}
selector.wakeup();
return 0;
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java Wed Feb 24 18:03:00 2010
@@ -239,6 +239,7 @@
@Override
public void handleClosed(NioChannel ch) throws IOException {
+ lastException = ch.lastException;
closed(); // our callback.
}
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslChannel.java Wed Feb 24 18:03:00 2010
@@ -5,12 +5,14 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
+import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
@@ -30,9 +32,13 @@
IOBuffer in = new IOBuffer(this);
IOBuffer out = new IOBuffer(this);
+
+ long handshakeTimeout = 10000;
+ // Used for session reuse
+ String host;
+ int port;
public SslChannel() {
-
}
ByteBuffer myAppOutData;
@@ -52,13 +58,30 @@
private boolean closeHandshake = false;
- private void initSsl() throws GeneralSecurityException {
+ /**
+ * Setting the host/port enables clients to reuse SSL session -
+ * less traffic and encryption overhead at startup, assuming the
+ * server caches the session ( i.e. single server or distributed cache ).
+ *
+ * SSL ticket extension is another possibility.
+ */
+ public SslChannel setTarget(String host, int port) {
+ this.host = host;
+ this.port = port;
+ return this;
+ }
+
+ private synchronized void initSsl() throws GeneralSecurityException {
if (sslEngine != null) {
return;
}
if (client) {
- sslEngine = sslCtx.createSSLEngine();
+ if (port > 0) {
+ sslEngine = sslCtx.createSSLEngine(host, port);
+ } else {
+ sslEngine = sslCtx.createSSLEngine();
+ }
sslEngine.setUseClientMode(client);
} else {
sslEngine = sslCtx.createSSLEngine();
@@ -89,7 +112,7 @@
@Override
- public void setSink(IOChannel net) throws IOException {
+ public synchronized void setSink(IOChannel net) throws IOException {
try {
initSsl();
super.setSink(net);
@@ -97,7 +120,7 @@
log.log(Level.SEVERE, "Error initializing ", e);
}
}
-
+
@Override
public IOBuffer getIn() {
return in;
@@ -118,7 +141,7 @@
*/
public int processInput(IOBuffer netIn, IOBuffer appIn) throws IOException {
if (log.isLoggable(Level.FINEST)) {
- log.finest("JSSE: processInput " + handshakeInProgress + " " + netIn.getBufferCount());
+ log.info("JSSE: processInput " + handshakeInProgress + " " + netIn.getBufferCount());
}
if (!handshakeDone && !handshakeInProgress) {
handshakeInProgress = true;
@@ -134,6 +157,7 @@
private synchronized int processRealInput(IOBuffer netIn, IOBuffer appIn) throws IOException {
int rd = 0;
boolean needsMore = true;
+ boolean notEnough = false;
while (needsMore) {
if (netIn.isClosedAndEmpty()) {
@@ -142,9 +166,14 @@
return -1;
}
myNetInData.compact();
- int rdNow = netIn.read(myNetInData);
- myNetInData.flip();
- if (rdNow == 0) {
+ int rdNow;
+ try {
+ rdNow = netIn.read(myNetInData);
+ } finally {
+ myNetInData.flip();
+ }
+ if (rdNow == 0 && (myNetInData.remaining() == 0 ||
+ notEnough)) {
return rd;
}
if (rdNow == -1) {
@@ -153,10 +182,18 @@
return rd;
}
+ notEnough = true; // next read of 0
while (myNetInData.remaining() > 0) {
myAppInData.compact();
- unwrapR = sslEngine.unwrap(myNetInData, myAppInData);
- myAppInData.flip();
+ try {
+ unwrapR = sslEngine.unwrap(myNetInData, myAppInData);
+ } catch (SSLException ex) {
+ log.warning("Read error: " + ex);
+ close();
+ return -1;
+ } finally {
+ myAppInData.flip();
+ }
if (myAppInData.remaining() > 0) {
in.write(myAppInData); // all will be written
}
@@ -216,50 +253,78 @@
}
public void close() throws IOException {
+ if (net.getOut().isAppendClosed()) {
+ return;
+ }
sslEngine.closeOutbound(); // mark as closed
- myNetOutData.compact();
- SSLEngineResult wrap = sslEngine.wrap(EMPTY,
- myNetOutData);
- myNetOutData.flip();
- if (wrap.getStatus() != Status.CLOSED) {
- System.err.println("Unexpected status " + wrap);
+ synchronized(myNetOutData) {
+ myNetOutData.compact();
+
+ SSLEngineResult wrap;
+ try {
+ wrap = sslEngine.wrap(EMPTY, myNetOutData);
+ if (wrap.getStatus() != Status.CLOSED) {
+ log.warning("Unexpected close status " + wrap);
+ }
+ } catch (Throwable t ) {
+ log.info("Error wrapping " + myNetOutData);
+ } finally {
+ myNetOutData.flip();
+ }
+ if (myNetOutData.remaining() > 0) {
+ net.getOut().write(myNetOutData);
+ }
}
- net.getOut().write(myNetOutData);
// TODO: timer to close socket if we don't get
// clean close handshake
+ super.close();
}
- private synchronized void startRealSending() throws IOException {
- while (true) {
-
- myAppOutData.compact();
- int rd = out.read(myAppOutData);
- myAppOutData.flip();
- if (rd == 0) {
- break;
- }
- if (rd < 0) {
- close();
- break;
- }
+ private Object sendLock = new Object();
- myNetOutData.compact();
- SSLEngineResult wrap = sslEngine.wrap(myAppOutData,
- myNetOutData);
- myNetOutData.flip();
- net.getOut().write(myNetOutData);
-
- if (wrap != null) {
- switch (wrap.getStatus()) {
- case BUFFER_UNDERFLOW: {
+ private void startRealSending() throws IOException {
+ // Only one thread at a time
+ synchronized (sendLock) {
+ while (true) {
+
+ myAppOutData.compact();
+ int rd;
+ try {
+ rd = out.read(myAppOutData);
+ } finally {
+ myAppOutData.flip();
+ }
+ if (rd == 0) {
break;
}
- case OK: {
+ if (rd < 0) {
+ close();
break;
}
- case BUFFER_OVERFLOW: {
- throw new IOException("Overflow");
+
+ SSLEngineResult wrap;
+ synchronized(myNetOutData) {
+ myNetOutData.compact();
+ try {
+ wrap = sslEngine.wrap(myAppOutData,
+ myNetOutData);
+ } finally {
+ myNetOutData.flip();
+ }
+ net.getOut().write(myNetOutData);
}
+ if (wrap != null) {
+ switch (wrap.getStatus()) {
+ case BUFFER_UNDERFLOW: {
+ break;
+ }
+ case OK: {
+ break;
+ }
+ case BUFFER_OVERFLOW: {
+ throw new IOException("Overflow");
+ }
+ }
}
}
}
@@ -275,16 +340,16 @@
// We'll need to unregister and register again from the selector.
private void handleHandshking() {
if (log.isLoggable(Level.FINEST)) {
- log.finest("Starting handshake");
+ log.info("Starting handshake");
}
handshakeInProgress = true;
- new Thread(this).start();
+ ((SslConnector) connector).handshakeExecutor.execute(this);
}
private void endHandshake() throws IOException {
if (log.isLoggable(Level.FINEST)) {
- log.finest("Handshake done");
+ log.info("Handshake done " + net.getIn().available());
}
handshakeDone = true;
handshakeInProgress = false;
@@ -292,6 +357,10 @@
flushing = false;
startSending();
}
+ if (myNetInData.remaining() > 0 || net.getIn().available() > 0) {
+ // Last SSL packet also includes data.
+ handleReceived(net);
+ }
}
/**
@@ -311,26 +380,41 @@
long t0 = System.currentTimeMillis();
- while (hstatus != HandshakeStatus.FINISHED) {
+ while (hstatus != HandshakeStatus.NOT_HANDSHAKING
+ && hstatus != HandshakeStatus.FINISHED
+ && !net.getIn().isAppendClosed()) {
+ if (System.currentTimeMillis() - t0 > handshakeTimeout) {
+ throw new TimeoutException();
+ }
if (wrap != null && wrap.getStatus() == Status.CLOSED) {
break;
}
if (log.isLoggable(Level.FINEST)) {
- log.finest("-->doHandshake() loop: status = " + hstatus + " " +
+ log.info("-->doHandshake() loop: status = " + hstatus + " " +
sslEngine.getHandshakeStatus());
}
if (hstatus == HandshakeStatus.NEED_WRAP) {
// || initial - for client
initial = false;
- myNetOutData.compact();
-
- wrap = sslEngine.wrap(myAppOutData, myNetOutData);
- myNetOutData.flip();
-
- hstatus = wrap.getHandshakeStatus();
+ synchronized(myNetOutData) {
+ myNetOutData.compact();
- net.getOut().write(myNetOutData);
+ try {
+ wrap = sslEngine.wrap(myAppOutData, myNetOutData);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ close();
+ return;
+ } finally {
+ myNetOutData.flip();
+ }
+
+ hstatus = wrap.getHandshakeStatus();
+ if (myNetOutData.remaining() > 0) {
+ net.getOut().write(myNetOutData);
+ }
+ }
net.startSending();
@@ -356,11 +440,17 @@
|| wrap.getStatus() == Status.BUFFER_UNDERFLOW
|| (hstatus == HandshakeStatus.NEED_UNWRAP && myNetInData.remaining() == 0)) {
myNetInData.compact();
- int rd = net.getIn().read(myNetInData);
- myNetInData.flip();
+ // non-blocking
+ int rd;
+ try {
+ rd = net.getIn().read(myNetInData);
+ } finally {
+ myNetInData.flip();
+ }
if (rd == 0) {
- net.getIn().waitData(10000);
- continue;
+ net.getIn().waitData(handshakeTimeout -
+ (System.currentTimeMillis() - t0));
+ rd = net.getIn().read(myNetInData);
}
if (rd < 0) {
// in closed
@@ -368,7 +458,7 @@
}
}
if (log.isLoggable(Level.FINEST)) {
- log.finest("Unwrap chunk done " + hstatus + " " + wrap
+ log.info("Unwrap chunk done " + hstatus + " " + wrap
+ " " + sslEngine.getHandshakeStatus());
}
@@ -384,7 +474,7 @@
long t1task = System.currentTimeMillis();
hstatus = sslEngine.getHandshakeStatus();
if (log.isLoggable(Level.FINEST)) {
- log.finest("Tasks done in " + (t1task - t0task) + " new status " +
+ log.info("Tasks done in " + (t1task - t0task) + " new status " +
hstatus);
}
@@ -401,6 +491,7 @@
try {
close();
net.close();
+ sendHandleReceivedCallback();
} catch (IOException ex) {
log.log(Level.SEVERE, "Error closing", ex);
}
@@ -419,4 +510,9 @@
this.sslCtx = sslCtx;
return this;
}
+
+ public SslChannel setSslConnector(SslConnector con) {
+ this.connector = con;
+ return this;
+ }
}
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslConnector.java Wed Feb 24 18:03:00 2010
@@ -19,7 +19,6 @@
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PrivateKey;
-import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
@@ -28,8 +27,9 @@
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAKeyGenParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
@@ -42,6 +42,12 @@
public class SslConnector extends IOConnector {
+ /**
+ * TODO: option to require validation.
+ * TODO: remember cert signature. This is needed to support self-signed
+ * certs, like those used by the test.
+ *
+ */
public static class BasicTrustManager implements X509TrustManager {
private X509Certificate[] chain;
@@ -64,20 +70,21 @@
public static TrustManager[] trustAllCerts = new TrustManager[] {
new BasicTrustManager() };
- static final boolean debug = false;
- static {
- if (debug) {
- System.setProperty("javax.net.debug", "ssl");
- }
- }
+ static final boolean debug = false;
+
IOConnector net;
private KeyManager[] keyManager;
SSLContext sslCtx;
boolean server;
private TrustManager[] trustManagers;
- Executor handshakeExecutor;
+ public AtomicInteger handshakeCount = new AtomicInteger();
+ public AtomicInteger handshakeOk = new AtomicInteger();
+ public AtomicInteger handshakeErr = new AtomicInteger();
+ public AtomicInteger handshakeTime = new AtomicInteger();
+
+ Executor handshakeExecutor = Executors.newCachedThreadPool();
static int id = 0;
public SslConnector() {
@@ -92,7 +99,7 @@
try {
sslCtx = SSLContext.getInstance("TLS");
if (trustManagers == null) {
- trustManagers =
+ trustManagers =
new TrustManager[] {new BasicTrustManager()};
}
@@ -115,6 +122,18 @@
return net;
}
+ public SslChannel channel(String host, int port) {
+ return new SslChannel()
+ .setTarget(host, port)
+ .setSslContext(getSSLContext())
+ .setSslConnector(this);
+ }
+
+ public SslChannel serverChannel() {
+ return new SslChannel()
+ .setSslContext(getSSLContext())
+ .setSslConnector(this).withServer();
+ }
@Override
public void acceptor(final ConnectedCallback sc, CharSequence port, Object extra)
@@ -129,9 +148,7 @@
first = dch;
}
- IOChannel sslch = new SslChannel()
- .setSslContext(sslCtx)
- .withServer();
+ IOChannel sslch = serverChannel();
sslch.setSink(first);
first.addFilterAfter(sslch);
@@ -148,7 +165,7 @@
}
@Override
- public void connect(String host, int port, final ConnectedCallback sc)
+ public void connect(final String host, final int port, final ConnectedCallback sc)
throws IOException {
getNet().connect(host, port, new ConnectedCallback() {
@@ -161,8 +178,7 @@
first = dch;
}
- IOChannel sslch = new SslChannel()
- .setSslContext(sslCtx);
+ IOChannel sslch = channel(host, port);
sslch.setSink(first);
first.addFilterAfter(sslch);
@@ -318,7 +334,7 @@
public static void fixUrlConnection() {
try {
- SSLContext sc = SSLContext.getInstance("SSL");
+ SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, SslConnector.trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
sc.getSocketFactory());
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java Wed Feb 24 18:03:00 2010
@@ -33,147 +33,33 @@
public class ServletApi30 extends ServletApi {
public ServletContextImpl newContext() {
- return new ServletContextImpl() {
- protected void initEngineDefaults() throws ServletException {
- super.initEngineDefaults();
- setAttribute(InstanceManager.class.getName(),
- new LiteInstanceManager(getObjectManager()));
- }
- @Override
- public Dynamic addFilter(String filterName, String className) {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- fc.setData(filterName, null, new HashMap());
- fc.setData(filterName, className, new HashMap());
- filters.put(filterName, fc);
- return new DynamicFilterRegistration(fc);
- }
-
- @Override
- public Dynamic addFilter(String filterName, Filter filter) {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- fc.setData(filterName, null, new HashMap());
- fc.setFilter(filter);
- filters.put(filterName, fc);
- return new DynamicFilterRegistration(fc);
- }
-
- @Override
- public Dynamic addFilter(String filterName,
- Class<? extends Filter> filterClass) {
- FilterConfigImpl fc = new FilterConfigImpl(this);
- fc.setData(filterName, null, new HashMap());
- fc.setFilterClass(filterClass);
- filters.put(filterName, fc);
- return new DynamicFilterRegistration(fc);
- }
-
- @Override
- public javax.servlet.ServletRegistration.Dynamic addServlet(
- String servletName, String className) {
- return null;
- }
-
- @Override
- public javax.servlet.ServletRegistration.Dynamic addServlet(
- String servletName, Servlet servlet) {
- return null;
- }
-
- @Override
- public javax.servlet.ServletRegistration.Dynamic addServlet(
- String servletName, Class<? extends Servlet> servletClass) {
- return null;
- }
-
-
- @Override
- public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
- return null;
- }
-
-
- @Override
- public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
- return null;
- }
-
- @Override
- public FilterRegistration getFilterRegistration(String filterName) {
- return null;
- }
-
- @Override
- public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
- return null;
- }
-
- @Override
- public JspConfigDescriptor getJspConfigDescriptor() {
- return null;
- }
-
- @Override
- public ServletRegistration getServletRegistration(String servletName) {
- return null;
- }
-
- @Override
- public Map<String, ? extends ServletRegistration> getServletRegistrations() {
- return null;
- }
-
- @Override
- public SessionCookieConfig getSessionCookieConfig() {
- return null;
- }
-
- @Override
- public void setSessionTrackingModes(
- EnumSet<SessionTrackingMode> sessionTrackingModes)
- throws IllegalStateException, IllegalArgumentException {
- }
-
- public int getMajorVersion() {
- return 3;
- }
-
- public int getMinorVersion() {
- return 0;
- }
-
- };
+ return new Servlet30ContextImpl();
}
public ServletRequestImpl newRequest(HttpRequest req) {
return new ServletRequestImpl(req) {
- @Override
public Part getPart(String name) {
return null;
}
- @Override
public Collection<Part> getParts() throws IOException,
ServletException {
return null;
}
- @Override
public AsyncContext getAsyncContext() {
return null;
}
- @Override
public DispatcherType getDispatcherType() {
return null;
}
- @Override
public AsyncContext startAsync() {
return null;
}
- @Override
public AsyncContext startAsync(ServletRequest servletRequest,
ServletResponse servletResponse) {
return null;
@@ -182,6 +68,99 @@
};
}
+ public final class Servlet30ContextImpl extends ServletContextImpl {
+ protected void initEngineDefaults() throws ServletException {
+ super.initEngineDefaults();
+ setAttribute(InstanceManager.class.getName(),
+ new LiteInstanceManager(getObjectManager()));
+ }
+
+ public Dynamic addFilter(String filterName, String className) {
+ FilterConfigImpl fc = new FilterConfigImpl(this);
+ fc.setData(filterName, null, new HashMap());
+ fc.setData(filterName, className, new HashMap());
+ filters.put(filterName, fc);
+ return new DynamicFilterRegistration(fc);
+ }
+
+ public Dynamic addFilter(String filterName, Filter filter) {
+ FilterConfigImpl fc = new FilterConfigImpl(this);
+ fc.setData(filterName, null, new HashMap());
+ fc.setFilter(filter);
+ filters.put(filterName, fc);
+ return new DynamicFilterRegistration(fc);
+ }
+
+ public Dynamic addFilter(String filterName,
+ Class<? extends Filter> filterClass) {
+ FilterConfigImpl fc = new FilterConfigImpl(this);
+ fc.setData(filterName, null, new HashMap());
+ fc.setFilterClass(filterClass);
+ filters.put(filterName, fc);
+ return new DynamicFilterRegistration(fc);
+ }
+
+ public javax.servlet.ServletRegistration.Dynamic addServlet(
+ String servletName, String className) {
+ return null;
+ }
+
+ public javax.servlet.ServletRegistration.Dynamic addServlet(
+ String servletName, Servlet servlet) {
+ return null;
+ }
+
+ public javax.servlet.ServletRegistration.Dynamic addServlet(
+ String servletName, Class<? extends Servlet> servletClass) {
+ return null;
+ }
+
+ public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ return null;
+ }
+
+ public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
+ return null;
+ }
+
+ public FilterRegistration getFilterRegistration(String filterName) {
+ return null;
+ }
+
+ public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
+ return null;
+ }
+
+ public JspConfigDescriptor getJspConfigDescriptor() {
+ return null;
+ }
+
+ public ServletRegistration getServletRegistration(String servletName) {
+ return null;
+ }
+
+ public Map<String, ? extends ServletRegistration> getServletRegistrations() {
+ return null;
+ }
+
+ public SessionCookieConfig getSessionCookieConfig() {
+ return null;
+ }
+
+ public int getMajorVersion() {
+ return 3;
+ }
+
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ public void setSessionTrackingModes(
+ Set<SessionTrackingMode> sessionTrackingModes)
+ throws IllegalStateException, IllegalArgumentException {
+ }
+ }
+
private final class LiteInstanceManager implements InstanceManager {
private ObjectManager om;
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java Wed Feb 24 18:03:00 2010
@@ -53,6 +53,8 @@
import org.apache.tomcat.integration.ObjectManager;
import org.apache.tomcat.lite.http.BaseMapper;
import org.apache.tomcat.lite.io.FileConnectorJavaIo;
+import org.apache.tomcat.lite.util.MimeMap;
+import org.apache.tomcat.lite.util.UrlUtils;
import org.apache.tomcat.servlets.config.ConfigLoader;
import org.apache.tomcat.servlets.config.ServletContextConfig;
import org.apache.tomcat.servlets.config.ServletContextConfig.FilterData;
@@ -60,9 +62,7 @@
import org.apache.tomcat.servlets.config.ServletContextConfig.ServletData;
import org.apache.tomcat.servlets.session.UserSessionManager;
import org.apache.tomcat.servlets.util.Enumerator;
-import org.apache.tomcat.servlets.util.MimeMap;
import org.apache.tomcat.servlets.util.RequestUtil;
-import org.apache.tomcat.servlets.util.UrlUtils;
/**
Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java?rev=915902&r1=915901&r2=915902&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java Wed Feb 24 18:03:00 2010
@@ -54,9 +54,9 @@
import org.apache.tomcat.lite.io.BBuffer;
import org.apache.tomcat.lite.io.CBuffer;
import org.apache.tomcat.lite.io.FastHttpDateFormat;
+import org.apache.tomcat.lite.util.LocaleParser;
import org.apache.tomcat.servlets.session.UserSessionManager;
import org.apache.tomcat.servlets.util.Enumerator;
-import org.apache.tomcat.servlets.util.LocaleParser;
import org.apache.tomcat.servlets.util.RequestUtil;
@@ -206,8 +206,6 @@
public static final String WORK_DIR_ATTR =
"javax.servlet.context.tempdir";
- protected static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
-
/**
* The default Locale if none are specified.
@@ -228,13 +226,6 @@
protected Cookie[] cookies = null;
- /**
- * The set of SimpleDateFormat formats to use in getDateHeader().
- *
- * Notice that because SimpleDateFormat is not thread-safe, we can't
- * declare formats[] as a static variable.
- */
- protected SimpleDateFormat formats[] = null;
/**
@@ -683,28 +674,7 @@
* cannot be converted to a date
*/
public long getDateHeader(String name) {
-
- String value = getHeader(name);
- if (value == null)
- return (-1L);
- if (formats == null) {
- formats = new SimpleDateFormat[] {
- new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
- new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
- new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
- };
- formats[0].setTimeZone(GMT_ZONE);
- formats[1].setTimeZone(GMT_ZONE);
- formats[2].setTimeZone(GMT_ZONE);
- }
-
- // Attempt to convert the date header in a variety of formats
- long result = FastHttpDateFormat.parseDate(value, formats);
- if (result != (-1L)) {
- return result;
- }
- throw new IllegalArgumentException(value);
-
+ return httpRequest.getDateHeader(name);
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org