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/05/25 08:44:02 UTC

svn commit: r947936 - /tomcat/trunk/modules/tomcat-lite/java/org/apache/coyote/lite/LiteProtocolHandler.java

Author: costin
Date: Tue May 25 06:44:02 2010
New Revision: 947936

URL: http://svn.apache.org/viewvc?rev=947936&view=rev
Log:
More coyote support.

Modified:
    tomcat/trunk/modules/tomcat-lite/java/org/apache/coyote/lite/LiteProtocolHandler.java

Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/coyote/lite/LiteProtocolHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/coyote/lite/LiteProtocolHandler.java?rev=947936&r1=947935&r2=947936&view=diff
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/coyote/lite/LiteProtocolHandler.java (original)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/coyote/lite/LiteProtocolHandler.java Tue May 25 06:44:02 2010
@@ -1,9 +1,9 @@
 package org.apache.coyote.lite;
 
-
-
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 
 import org.apache.coyote.ActionCode;
 import org.apache.coyote.ActionHook;
@@ -13,17 +13,27 @@ import org.apache.coyote.OutputBuffer;
 import org.apache.coyote.ProtocolHandler;
 import org.apache.coyote.Request;
 import org.apache.coyote.Response;
+import org.apache.tomcat.lite.http.HttpClient;
+import org.apache.tomcat.lite.http.HttpChannel;
+import org.apache.tomcat.lite.http.HttpConnectionPool;
 import org.apache.tomcat.lite.http.HttpConnector;
 import org.apache.tomcat.lite.http.HttpRequest;
 import org.apache.tomcat.lite.http.HttpResponse;
+import org.apache.tomcat.lite.http.HttpServer;
 import org.apache.tomcat.lite.http.MultiMap;
 import org.apache.tomcat.lite.http.HttpChannel.HttpService;
+import org.apache.tomcat.lite.http.HttpConnectionPool.RemoteServer;
+import org.apache.tomcat.lite.http.HttpConnector.HttpChannelEvents;
+import org.apache.tomcat.lite.http.HttpConnector.HttpConnection;
 import org.apache.tomcat.lite.http.MultiMap.Entry;
 import org.apache.tomcat.lite.io.CBuffer;
+import org.apache.tomcat.lite.io.IOConnector;
 import org.apache.tomcat.lite.io.SocketConnector;
+import org.apache.tomcat.lite.io.SslProvider;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.http.MimeHeaders;
+import org.apache.tomcat.util.modeler.Registry;
 
 /**
  * Work in progress - use the refactored http as a coyote connector.
@@ -36,6 +46,17 @@ import org.apache.tomcat.util.http.MimeH
 public class LiteProtocolHandler implements ProtocolHandler {
 
     Adapter adapter;
+    Map<String, Object> attributes = new HashMap<String, Object>();
+    
+    
+    HttpConnector httpConnServer;
+    int port = 8999;
+    
+    // Tomcat JMX integration
+    Registry registry;
+    
+    public LiteProtocolHandler() {
+    }
     
     @Override
     public void destroy() throws Exception {
@@ -48,16 +69,93 @@ public class LiteProtocolHandler impleme
 
     @Override
     public Object getAttribute(String name) {
-        return null;
+        // TODO: dynamic
+        return attributes.get(name);
     }
 
     @Override
     public Iterator<String> getAttributeNames() {
-        return null;
+        return attributes.keySet().iterator();
     }
 
     @Override
     public void init() throws Exception {
+        registry = Registry.getRegistry(null, null);
+        httpConnServer = HttpServer.newServer(port);
+
+        httpConnServer.getDispatcher().setDefaultService(new HttpService() {
+            @Override
+            public void service(HttpRequest httpReq, HttpResponse httpRes)
+                    throws IOException {
+                coyoteService(httpReq, httpRes);
+            }
+
+        });
+        final String base = "" + port;
+        bind("Httpconnector-" + port, httpConnServer);
+        bind("HttpconnectorPool-" + port, httpConnServer.cpool);
+        IOConnector io = httpConnServer.getIOConnector();
+        int ioLevel = 0;
+        while (io != null) {
+            bind("IOConnector-" + (ioLevel++) + "-" + base, io);
+            if (io instanceof SocketConnector) {
+                bind("NioThread-" + base, 
+                        ((SocketConnector) io).getSelector());
+                
+            }
+            io = io.getNet();
+        }
+        httpConnServer.cpool.setEvents(new HttpConnectionPool.HttpConnectionPoolEvents() {
+
+            @Override
+            public void closedConnection(RemoteServer host, HttpConnection con) {
+                unbind("HttpConnection-" + base + "-" + con.getId());
+            }
+
+            @Override
+            public void newConnection(RemoteServer host, HttpConnection con) {
+                bind("HttpConnection-" + base + "-" + con.getId(), con);
+            }
+
+            @Override
+            public void newTarget(RemoteServer host) {
+                bind("AsyncHttp-" + base + "-" + host.target, host);
+            }
+
+            @Override
+            public void targetRemoved(RemoteServer host) {
+                unbind("AsyncHttp-" + base + "-" + host.target);
+            }
+            
+        });
+        
+        httpConnServer.setOnCreate(new HttpChannelEvents() {
+            @Override
+            public void onCreate(HttpChannel data, HttpConnector extraData)
+                    throws IOException {
+                bind("AsyncHttp-" + base + "-" + data.getId(), data);
+            }
+            @Override
+            public void onDestroy(HttpChannel data, HttpConnector extraData)
+                    throws IOException {
+                unbind("AsyncHttp-" + base + "-" + data.getId());
+            }
+        });
+        
+        // TODO: process attributes via registry !!
+        
+    }
+    
+    private void bind(String name, Object o) {
+        try {
+            registry.registerComponent(o, "name=" + name, null);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void unbind(String name) {
+        registry.unregisterComponent("name=" + name);
     }
 
     @Override
@@ -73,43 +171,34 @@ public class LiteProtocolHandler impleme
         this.adapter = adapter;
         
     }
-
-    int port = 8999;
-    
-    public void setPort(int port) {
-        this.port = port;
-    }
     
     @Override
     public void setAttribute(String name, Object value) {
-        System.err.println("setAttribute " + name + " " + value);
+        attributes.put(name, value);
     }
-
+    
     @Override
     public void start() throws Exception {
-        HttpConnector c = new HttpConnector(new SocketConnector());
-        c.setPort(port);
-        
-//        c.setDebug(true);
-//        c.setDebugHttp(true);
-        
-        c.getDispatcher().setDefaultService(new HttpService() {
-            @Override
-            public void service(HttpRequest httpReq, HttpResponse httpRes)
-                    throws IOException {
-                coyoteService(httpReq, httpRes);
-            }
-
-        });
-        c.start();
+        httpConnServer.start();
     }
     
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    /**
+     * Wrap old tomcat buffer to lite buffer.
+     */
     private void wrap(MessageBytes dest, CBuffer buffer) {
         dest.setChars(buffer.array(), buffer.position(), 
                 buffer.length());
     }
 
+    /**
+     * Main lite service method, will wrap to coyote request
+     */
     private void coyoteService(final HttpRequest httpReq, final HttpResponse httpRes) {
+        // TODO: reuse, per req
         RequestData rc = new RequestData();
         rc.init(httpReq, httpRes);
         
@@ -122,7 +211,7 @@ public class LiteProtocolHandler impleme
     }
     
     /** 
-     * Per request data.
+     * ActionHook implementation, include coyote request/response objects.
      */
     public class RequestData implements ActionHook {
         private final class LiteOutputBuffer implements OutputBuffer {
@@ -142,6 +231,7 @@ public class LiteProtocolHandler impleme
         Response res = new Response();
         HttpResponse httpRes;
         HttpRequest httpReq;
+        
         InputBuffer inputBuffer = new InputBuffer() {
             @Override
             public int doRead(ByteChunk bchunk, Request request)
@@ -198,43 +288,10 @@ public class LiteProtocolHandler impleme
          */
         public void action(ActionCode actionCode, Object param) {
 
-            if (actionCode == ActionCode.ACTION_COMMIT) {
-                if (res.isCommitted())
-                    return;
-                
-                // TODO: copy headers, fields
-                httpRes.setStatus(res.getStatus());
-                httpRes.setMessage(res.getMessage());
-                MultiMap mimeHeaders = httpRes.getMimeHeaders();
-                MimeHeaders coyoteHeaders = res.getMimeHeaders();
-                for (int i = 0; i < coyoteHeaders.size(); i++ ) {
-                    MessageBytes name = coyoteHeaders.getName(i);
-                    MessageBytes val = coyoteHeaders.getValue(i);
-                    Entry entry = mimeHeaders.addEntry(name.toString());
-                    entry.getValue().set(val.toString());
-                }
-                String contentType = res.getContentType();
-                if (contentType != null) {
-                    mimeHeaders.addEntry("Content-Type").getValue().set(contentType);
-                }
-                String contentLang = res.getContentType();
-                if (contentLang != null) {
-                    mimeHeaders.addEntry("Content-Language").getValue().set(contentLang);
-                }
-                long contentLength = res.getContentLengthLong();
-                if (contentLength != -1) {
-                    httpRes.setContentLength(contentLength);
-                }
-                String lang = res.getContentLanguage();
-                if (lang != null) {
-                    httpRes.setHeader("Content-Language", lang);
-                }
-                
-                try {
-                    httpReq.send();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
+            if (actionCode == ActionCode.ACTION_POST_REQUEST) {
+                commit(); // make sure it's sent - on errors 
+            } else if (actionCode == ActionCode.ACTION_COMMIT) {
+                commit();
             } else if (actionCode == ActionCode.ACTION_ACK) {
                 // Done automatically by http connector
             } else if (actionCode == ActionCode.ACTION_CLIENT_FLUSH) {
@@ -282,93 +339,28 @@ public class LiteProtocolHandler impleme
                 req.setLocalPort(httpReq.getLocalPort());
             } else if (actionCode == ActionCode.ACTION_REQ_SSL_ATTRIBUTE ) {
 
-//                if (ssl && (socket != 0)) {
-//                    try {
-//                        // Cipher suite
-//                        Object sslO = SSLSocket.getInfoS(socket, SSL.SSL_INFO_CIPHER);
-//                        if (sslO != null) {
-//                            request.setAttribute(AprEndpoint.CIPHER_SUITE_KEY, sslO);
-//                        }
-//                        // Get client certificate and the certificate chain if present
-//                        // certLength == -1 indicates an error
-//                        int certLength = SSLSocket.getInfoI(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN);
-//                        byte[] clientCert = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT);
-//                        X509Certificate[] certs = null;
-//                        if (clientCert != null  && certLength > -1) {
-//                            certs = new X509Certificate[certLength + 1];
-//                            CertificateFactory cf = CertificateFactory.getInstance("X.509");
-//                            certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert));
-//                            for (int i = 0; i < certLength; i++) {
-//                                byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i);
-//                                certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data));
-//                            }
-//                        }
-//                        if (certs != null) {
-//                            request.setAttribute(AprEndpoint.CERTIFICATE_KEY, certs);
-//                        }
-//                        // User key size
-//                        sslO = new Integer(SSLSocket.getInfoI(socket, SSL.SSL_INFO_CIPHER_USEKEYSIZE));
-//                        request.setAttribute(AprEndpoint.KEY_SIZE_KEY, sslO);
-//
-//                        // SSL session ID
-//                        sslO = SSLSocket.getInfoS(socket, SSL.SSL_INFO_SESSION_ID);
-//                        if (sslO != null) {
-//                            request.setAttribute(AprEndpoint.SESSION_ID_KEY, sslO);
-//                        }
-//                        //TODO provide a hook to enable the SSL session to be
-//                        // invalidated. Set AprEndpoint.SESSION_MGR req attr
-//                    } catch (Exception e) {
-//                        log.warn(sm.getString("http11processor.socket.ssl"), e);
-//                    }
-//                }
+                Object sslAtt = httpReq.getHttpChannel().getNet().getAttribute(SslProvider.ATT_SSL_CIPHER);
+                req.setAttribute("javax.servlet.request.cipher_suite", sslAtt);
+                
+                sslAtt = httpReq.getHttpChannel().getNet().getAttribute(SslProvider.ATT_SSL_KEY_SIZE);
+                req.setAttribute("javax.servlet.request.key_size", sslAtt);
+
+                sslAtt = httpReq.getHttpChannel().getNet().getAttribute(SslProvider.ATT_SSL_SESSION_ID);
+                req.setAttribute("javax.servlet.request.ssl_session", sslAtt);
 
             } else if (actionCode == ActionCode.ACTION_REQ_SSL_CERTIFICATE) {
 
-//                if (ssl && (socket != 0)) {
-//                    // Consume and buffer the request body, so that it does not
-//                    // interfere with the client's handshake messages
-//                    InputFilter[] inputFilters = inputBuffer.getFilters();
-//                    ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]).setLimit(maxSavePostSize);
-//                    inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]);
-//                    try {
-//                        // Configure connection to require a certificate
-//                        SSLSocket.setVerify(socket, SSL.SSL_CVERIFY_REQUIRE,
-//                                endpoint.getSSLVerifyDepth());
-//                        // Renegotiate certificates
-//                        if (SSLSocket.renegotiate(socket) == 0) {
-//                            // Don't look for certs unless we know renegotiation worked.
-//                            // Get client certificate and the certificate chain if present
-//                            // certLength == -1 indicates an error 
-//                            int certLength = SSLSocket.getInfoI(socket,SSL.SSL_INFO_CLIENT_CERT_CHAIN);
-//                            byte[] clientCert = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT);
-//                            X509Certificate[] certs = null;
-//                            if (clientCert != null && certLength > -1) {
-//                                certs = new X509Certificate[certLength + 1];
-//                                CertificateFactory cf = CertificateFactory.getInstance("X.509");
-//                                certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert));
-//                                for (int i = 0; i < certLength; i++) {
-//                                    byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i);
-//                                    certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data));
-//                                }
-//                            }
-//                            if (certs != null) {
-//                                request.setAttribute(AprEndpoint.CERTIFICATE_KEY, certs);
-//                            }
-//                        }
-//                    } catch (Exception e) {
-//                        log.warn(sm.getString("http11processor.socket.ssl"), e);
-//                    }
-//                }
+                Object cert = httpReq.getHttpChannel().getNet().getAttribute(SslProvider.ATT_SSL_CERT);
+                req.setAttribute("javax.servlet.request.X509Certificate", cert);
 
             } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) {
-//                ByteChunk body = (ByteChunk) param;
-//
-//                InputFilter savedBody = new SavedRequestInputFilter(body);
-//                savedBody.setRequest(request);
-//
-//                InternalAprInputBuffer internalBuffer = (InternalAprInputBuffer)
-//                request.getInputBuffer();
-//                internalBuffer.addActiveFilter(savedBody);
+                ByteChunk body = (ByteChunk) param;
+                httpReq.getBody().clear();
+                try {
+                    httpReq.getBody().append(body.getBuffer(), body.getStart(), body.getLength());
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
 
             } else if (actionCode == ActionCode.ACTION_AVAILABLE) {
                 req.setAvailable(httpReq.getBody().available());
@@ -391,5 +383,44 @@ public class LiteProtocolHandler impleme
 
         }
 
+        private void commit() {
+            if (res.isCommitted())
+                return;
+            
+            // TODO: copy headers, fields
+            httpRes.setStatus(res.getStatus());
+            httpRes.setMessage(res.getMessage());
+            MultiMap mimeHeaders = httpRes.getMimeHeaders();
+            MimeHeaders coyoteHeaders = res.getMimeHeaders();
+            for (int i = 0; i < coyoteHeaders.size(); i++ ) {
+                MessageBytes name = coyoteHeaders.getName(i);
+                MessageBytes val = coyoteHeaders.getValue(i);
+                Entry entry = mimeHeaders.addEntry(name.toString());
+                entry.getValue().set(val.toString());
+            }
+            String contentType = res.getContentType();
+            if (contentType != null) {
+                mimeHeaders.addEntry("Content-Type").getValue().set(contentType);
+            }
+            String contentLang = res.getContentType();
+            if (contentLang != null) {
+                mimeHeaders.addEntry("Content-Language").getValue().set(contentLang);
+            }
+            long contentLength = res.getContentLengthLong();
+            if (contentLength != -1) {
+                httpRes.setContentLength(contentLength);
+            }
+            String lang = res.getContentLanguage();
+            if (lang != null) {
+                httpRes.setHeader("Content-Language", lang);
+            }
+            
+            try {
+                httpReq.send();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org