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