Source code: org/apache/jk/server/JkCoyoteHandler.java
1 /*
2 * Copyright 1999-2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.jk.server;
18
19 import java.io.IOException;
20 import java.util.Iterator;
21
22 import javax.management.MBeanServer;
23 import javax.management.ObjectName;
24
25 import org.apache.commons.modeler.Registry;
26 import org.apache.coyote.Adapter;
27 import org.apache.coyote.ProtocolHandler;
28 import org.apache.coyote.Request;
29 import org.apache.coyote.Response;
30 import org.apache.coyote.RequestInfo;
31 import org.apache.coyote.Constants;
32 import org.apache.jk.common.HandlerRequest;
33 import org.apache.jk.common.JkInputStream;
34 import org.apache.jk.common.MsgAjp;
35 import org.apache.jk.core.JkHandler;
36 import org.apache.jk.core.Msg;
37 import org.apache.jk.core.MsgContext;
38 import org.apache.jk.core.WorkerEnv;
39 import org.apache.tomcat.util.buf.ByteChunk;
40 import org.apache.tomcat.util.buf.C2BConverter;
41 import org.apache.tomcat.util.buf.MessageBytes;
42 import org.apache.tomcat.util.http.HttpMessages;
43 import org.apache.tomcat.util.http.MimeHeaders;
44 import org.apache.tomcat.util.net.SSLSupport;
45
46 /** Plugs Jk into Coyote. Must be named "type=JkHandler,name=container"
47 *
48 * jmx:notification-handler name="org.apache.jk.SEND_PACKET
49 * jmx:notification-handler name="org.apache.coyote.ACTION_COMMIT
50 */
51 public class JkCoyoteHandler extends JkHandler implements ProtocolHandler {
52 protected static org.apache.commons.logging.Log log
53 = org.apache.commons.logging.LogFactory.getLog(JkCoyoteHandler.class);
54 // Set debug on this logger to see the container request time
55
56 // ----------------------------------------------------------- DoPrivileged
57 private boolean paused = false;
58 int epNote;
59 Adapter adapter;
60 protected JkMain jkMain=null;
61
62 /** Set a property. Name is a "component.property". JMX should
63 * be used instead.
64 */
65 public void setProperty( String name, String value ) {
66 if( log.isTraceEnabled())
67 log.trace("setProperty " + name + " " + value );
68 getJkMain().setProperty( name, value );
69 properties.put( name, value );
70 }
71
72 public String getProperty( String name ) {
73 return properties.getProperty(name) ;
74 }
75
76 public Iterator getAttributeNames() {
77 return properties.keySet().iterator();
78 }
79
80 /** Pass config info
81 */
82 public void setAttribute( String name, Object value ) {
83 if( log.isDebugEnabled())
84 log.debug("setAttribute " + name + " " + value );
85 if( value instanceof String )
86 this.setProperty( name, (String)value );
87 }
88
89 /**
90 * Retrieve config info.
91 * Primarily for use with the admin webapp.
92 */
93 public Object getAttribute( String name ) {
94 return getJkMain().getProperty(name);
95 }
96
97 /** The adapter, used to call the connector
98 */
99 public void setAdapter(Adapter adapter) {
100 this.adapter=adapter;
101 }
102
103 public Adapter getAdapter() {
104 return adapter;
105 }
106
107 public JkMain getJkMain() {
108 if( jkMain == null ) {
109 jkMain=new JkMain();
110 jkMain.setWorkerEnv(wEnv);
111
112 }
113 return jkMain;
114 }
115
116 boolean started=false;
117
118 /** Start the protocol
119 */
120 public void init() {
121 if( started ) return;
122
123 started=true;
124
125 if( wEnv==null ) {
126 // we are probably not registered - not very good.
127 wEnv=getJkMain().getWorkerEnv();
128 wEnv.addHandler("container", this );
129 }
130
131 try {
132 // jkMain.setJkHome() XXX;
133
134 getJkMain().init();
135
136 } catch( Exception ex ) {
137 log.error("Error during init",ex);
138 }
139 }
140
141 public void start() {
142 try {
143 if( oname != null && getJkMain().getDomain() == null) {
144 try {
145 ObjectName jkmainOname =
146 new ObjectName(oname.getDomain() + ":type=JkMain");
147 Registry.getRegistry(null, null)
148 .registerComponent(getJkMain(), jkmainOname, "JkMain");
149 } catch (Exception e) {
150 log.error( "Error registering jkmain " + e );
151 }
152 }
153 getJkMain().start();
154 } catch( Exception ex ) {
155 log.error("Error during startup",ex);
156 }
157 }
158
159 public void pause() throws Exception {
160 if(!paused) {
161 paused = true;
162 getJkMain().pause();
163 }
164 }
165
166 public void resume() throws Exception {
167 if(paused) {
168 paused = false;
169 getJkMain().resume();
170 }
171 }
172
173 public void destroy() {
174 if( !started ) return;
175
176 started = false;
177 getJkMain().stop();
178 }
179
180
181 // -------------------- Jk handler implementation --------------------
182 // Jk Handler mehod
183 public int invoke( Msg msg, MsgContext ep )
184 throws IOException {
185 if( ep.isLogTimeEnabled() )
186 ep.setLong( MsgContext.TIMER_PRE_REQUEST, System.currentTimeMillis());
187
188 Request req=ep.getRequest();
189 Response res=req.getResponse();
190
191 if( log.isDebugEnabled() )
192 log.debug( "Invoke " + req + " " + res + " " + req.requestURI().toString());
193
194 res.setNote( epNote, ep );
195 ep.setStatus( MsgContext.JK_STATUS_HEAD );
196 RequestInfo rp = req.getRequestProcessor();
197 rp.setStage(Constants.STAGE_SERVICE);
198 try {
199 adapter.service( req, res );
200 } catch( Exception ex ) {
201 log.info("Error servicing request " + req,ex);
202 }
203 if(ep.getStatus() != MsgContext.JK_STATUS_CLOSED) {
204 res.finish();
205 }
206
207 req.recycle();
208 req.updateCounters();
209 res.recycle();
210 ep.recycle();
211 if( ep.getStatus() == MsgContext.JK_STATUS_ERROR ) {
212 return ERROR;
213 }
214 ep.setStatus( MsgContext.JK_STATUS_NEW );
215 rp.setStage(Constants.STAGE_KEEPALIVE);
216 return OK;
217 }
218
219
220 public ObjectName preRegister(MBeanServer server,
221 ObjectName oname) throws Exception
222 {
223 // override - we must be registered as "container"
224 this.name="container";
225 return super.preRegister(server, oname);
226 }
227 }