001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.coyote.tomcat3;
018:
019: import java.util.Enumeration;
020: import java.util.Hashtable;
021:
022: import org.apache.coyote.ActionCode;
023: import org.apache.coyote.ProtocolHandler;
024: import org.apache.tomcat.core.BaseInterceptor;
025: import org.apache.tomcat.core.Context;
026: import org.apache.tomcat.core.ContextManager;
027: import org.apache.tomcat.core.TomcatException;
028: import org.apache.tomcat.util.IntrospectionUtils;
029: import org.apache.tomcat.util.net.SSLSupport;
030:
031: /** Standalone http.
032: *
033: * Connector properties:
034: * <ul>
035: * <li> secure - will load a SSL socket factory and act as https server</li>
036: * </ul>
037: *
038: * Properties passed to the net layer:
039: * <ul>
040: * <li>timeout</li>
041: * <li>backlog</li>
042: * <li>address</li>
043: * <li>port</li>
044: * </ul>
045: * Thread pool properties:
046: * <ul>
047: * <li>minSpareThreads</li>
048: * <li>maxSpareThreads</li>
049: * <li>maxThreads</li>
050: * <li>poolOn</li>
051: * </ul>
052: * Properties for HTTPS:
053: * <ul>
054: * <li>keystore - certificates - default to ~/.keystore</li>
055: * <li>keypass - password</li>
056: * <li>clientauth - true if the server should authenticate the client using certs</li>
057: * </ul>
058: * Properties for HTTP:
059: * <ul>
060: * <li>reportedname - name of server sent back to browser (security purposes)</li>
061: * </ul>
062: * <ul>
063: * <li>compression - use gzip compression in HTTP 1.1 (on/off) - def off</li>
064: * </ul>
065: * <ul>
066: * <li>compressionMinSize - minimum size content to use gzip compression in HTTP 1.1 - def 2048</li>
067: * </ul>
068: * <ul>
069: * <li>noCompressionUserAgents - comma separated list of userAgents who didn't support gzip</li>
070: * </ul>
071: * <ul>
072: * <li>restrictedUserAgents - comma separated list of userAgents who didn't support HTTP 1.1 (use HTTP 1.0)</li>
073: * </ul>
074: * <ul>
075: * <li>compressableMimeTypes - comma separated list of mime types supported for compression - def text/html,text/xml,text/plain</li>
076: * </ul>
077: */
078: public class CoyoteInterceptor2 extends BaseInterceptor {
079: private String processorClassName = "org.apache.coyote.http11.Http11Protocol";
080: Tomcat3Adapter adapter;
081: ProtocolHandler proto;
082: int protocolNote;
083:
084: public CoyoteInterceptor2() {
085: super ();
086: // defaults:
087: this .setAttribute("port", "8080");
088: this .setAttribute("soLinger", "-1");
089: }
090:
091: // -------------------- PoolTcpConnector --------------------
092:
093: /** Set the class of the processor to use.
094: */
095: public void setProcessorClassName(String pcn) {
096: processorClassName = pcn;
097: }
098:
099: // -------------------- Start/stop --------------------
100: Hashtable attributes = new Hashtable();
101:
102: public void setAttribute(String prop, Object value) {
103: attributes.put(prop, value);
104: }
105:
106: public void setProperty(String prop, String value) {
107: setAttribute(prop, value);
108: }
109:
110: /** Called when the ContextManger is started
111: */
112: public void engineInit(ContextManager cm) throws TomcatException {
113: super .engineInit(cm);
114:
115: protocolNote = cm.getNoteId(ContextManager.MODULE_NOTE,
116: "coyote.protocol");
117: adapter = new Tomcat3Adapter(cm);
118: try {
119: Class c = Class.forName(processorClassName);
120: proto = (ProtocolHandler) c.newInstance();
121: setNote(protocolNote, proto);
122: } catch (Exception ex) {
123: ex.printStackTrace();
124: }
125:
126: this .setAttribute("jkHome", cm.getHome());
127:
128: proto.setAdapter(adapter);
129: try {
130: Enumeration keys = attributes.keys();
131: while (keys.hasMoreElements()) {
132: String k = (String) keys.nextElement();
133: Object o = attributes.get(k);
134: if (o instanceof String)
135: IntrospectionUtils
136: .setProperty(proto, k, (String) o);
137: else
138: IntrospectionUtils.setAttribute(proto, k, o);
139: }
140: proto.init();
141: } catch (Exception ex) {
142: throw new TomcatException(
143: "Error setting protocol properties ", ex);
144: }
145: }
146:
147: /** Called when the ContextManger is started
148: */
149: public void engineStart(ContextManager cm) throws TomcatException {
150: try {
151: proto.start();
152: } catch (Exception ex) {
153: ex.printStackTrace();
154: throw new TomcatException(ex);
155: }
156: }
157:
158: public void engineShutdown(ContextManager cm)
159: throws TomcatException {
160: try {
161: proto.destroy();
162: } catch (Exception ex) {
163: throw new TomcatException(ex);
164: }
165: }
166:
167: // -------------------- Handler implementation --------------------
168:
169: /** Handle HTTP expectations.
170: */
171: public int preService(org.apache.tomcat.core.Request request,
172: org.apache.tomcat.core.Response response) {
173: if (response instanceof Tomcat3Response) {
174: try {
175: ((Tomcat3Response) response).sendAcknowledgement();
176: } catch (Exception ex) {
177: log("Can't send ACK", ex);
178: }
179: }
180: return 0;
181: }
182:
183: public int postRequest(org.apache.tomcat.core.Request request,
184: org.apache.tomcat.core.Response response) {
185: if (request instanceof Tomcat3Request) {
186: try {
187: Tomcat3Request httpReq = (Tomcat3Request) request;
188: org.apache.coyote.Request cReq = httpReq
189: .getCoyoteRequest();
190: cReq.action(ActionCode.ACTION_POST_REQUEST, null);
191: } catch (Exception ex) {
192: log("Can't send ACK", ex);
193: }
194: }
195: return 0;
196: }
197:
198: /**
199: getInfo calls for SSL data
200:
201: @return the requested data
202: */
203: public Object getInfo(Context ctx,
204: org.apache.tomcat.core.Request request, int id, String key) {
205: if (!(request instanceof Tomcat3Request))
206: return null;
207:
208: Tomcat3Request httpReq = (Tomcat3Request) request;
209:
210: if (key != null && httpReq != null) {
211: org.apache.coyote.Request cReq = httpReq.getCoyoteRequest();
212: Object info = cReq.getAttribute(key);
213: if (info != null)
214: return info;
215: // XXX Should use MsgContext, pass the attribute we need.
216: // This will extract both
217: if (isSSLAttribute(key)) {
218: cReq.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE,
219: httpReq.getCoyoteRequest());
220: // Only allowed a single cert under the 2.2 Spec.
221: Object[] value = (Object[]) cReq
222: .getAttribute(SSLSupport.CERTIFICATE_KEY);
223: if (value != null) {
224: cReq.setAttribute(SSLSupport.CERTIFICATE_KEY,
225: value[0]);
226: }
227:
228: return cReq.getAttribute(key);
229: }
230:
231: return cReq.getAttribute(key);
232: }
233: return super .getInfo(ctx, request, id, key);
234: }
235:
236: public int setInfo(Context ctx,
237: org.apache.tomcat.core.Request request, int id, String key,
238: String object) {
239: if (!(request instanceof Tomcat3Request))
240: return DECLINED;
241:
242: Tomcat3Request httpReq = (Tomcat3Request) request;
243:
244: if (key != null && httpReq != null) {
245: org.apache.coyote.Request cReq = httpReq.getCoyoteRequest();
246: cReq.setAttribute(key, object);
247: return OK;
248: }
249: return super .setInfo(ctx, request, id, key, object);
250: }
251:
252: /**
253: * Check if a string is a reserved SSL attribute key.
254: */
255: public static boolean isSSLAttribute(String key) {
256: return SSLSupport.CIPHER_SUITE_KEY.equals(key)
257: || SSLSupport.KEY_SIZE_KEY.equals(key)
258: || SSLSupport.CERTIFICATE_KEY.equals(key)
259: || SSLSupport.SESSION_ID_KEY.equals(key);
260: }
261: }
|