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