2
* Copyright 1999-2004 The Apache Software Foundation
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
18
package org.jboss.remoting.transport.coyote;
20
import org.apache.coyote.ActionCode;
21
import org.apache.coyote.Adapter;
22
import org.apache.coyote.ProtocolHandler;
23
import org.apache.coyote.Request;
24
import org.apache.coyote.Response;
25
import org.apache.tomcat.util.buf.B2CConverter;
26
import org.apache.tomcat.util.buf.ByteChunk;
27
import org.apache.tomcat.util.buf.CharChunk;
28
import org.apache.tomcat.util.buf.MessageBytes;
29
import org.apache.tomcat.util.http.MimeHeaders;
30
import org.apache.tomcat.util.net.SocketStatus;
31
import org.jboss.remoting.Home;
32
import org.jboss.remoting.InvocationRequest;
33
import org.jboss.remoting.InvocationResponse;
34
import org.jboss.remoting.InvokerLocator;
35
import org.jboss.remoting.Remoting;
36
import org.jboss.remoting.Version;
37
import org.jboss.remoting.marshal.Marshaller;
38
import org.jboss.remoting.marshal.UnMarshaller;
39
import org.jboss.remoting.marshal.VersionedMarshaller;
40
import org.jboss.remoting.marshal.VersionedUnMarshaller;
41
import org.jboss.remoting.marshal.http.HTTPUnMarshaller;
42
import org.jboss.remoting.security.SSLSocketBuilder;
43
import org.jboss.remoting.transport.coyote.ssl.RemotingSSLImplementation;
44
import org.jboss.remoting.transport.coyote.ssl.RemotingServerSocketFactory;
45
import org.jboss.remoting.transport.http.HTTPMetadataConstants;
46
import org.jboss.remoting.transport.web.WebServerInvoker;
47
import org.jboss.remoting.transport.web.WebUtil;
48
import org.jboss.remoting.util.SecurityUtility;
49
import org.jboss.logging.Logger;
51
import javax.net.ServerSocketFactory;
53
import java.io.IOException;
54
import java.lang.reflect.Method;
55
import java.net.InetAddress;
56
import java.net.UnknownHostException;
57
import java.security.AccessController;
58
import java.security.PrivilegedAction;
59
import java.security.PrivilegedActionException;
60
import java.security.PrivilegedExceptionAction;
61
import java.util.ArrayList;
62
import java.util.Enumeration;
63
import java.util.HashMap;
64
import java.util.Iterator;
65
import java.util.List;
69
* This is the stand alone http server invoker which acts basically as a web server.
70
* Server invoker implementation based on http protocol. Is basically a stand alone http server whose request are
71
* forwared to the invocation handler and responses from invocation handler are sent back to caller as http response.
73
* @author <a href="mailto:telrod@e2technologies.net">Tom Elrod</a>
74
* @author Craig R. McClanahan
75
* @author Remy Maucherat
79
* Some of the code in this class was pulled from org.apache.coyote.tomcat4.CoyoteAdapter
80
* and hence will maintain the Apache License (and author credit from original source).
82
public class CoyoteInvoker extends WebServerInvoker implements Adapter
84
private static final Logger log = Logger.getLogger(CoyoteInvoker.class);
86
/** Indicates if input was raw or an InvocationRequest */
87
protected static ThreadLocal receivedInvocationRequest = new ThreadLocal();
88
protected static final Boolean FALSE = new Boolean(false);
89
protected static final Boolean TRUE = new Boolean(true);
91
private boolean running = false;
93
// protected ProtocolHandler protocolHandler = null;
94
protected List protocolHandlers = new ArrayList();
96
protected String URIEncoding = null;
98
protected String useRemotingContentType = "false";
101
public CoyoteInvoker(InvokerLocator locator)
106
public CoyoteInvoker(InvokerLocator locator, Map configuration)
108
super(locator, configuration);
111
protected void setup() throws Exception
116
Map config = getConfiguration();
122
AccessController.doPrivileged( new PrivilegedExceptionAction()
124
public Object run() throws Exception
126
String methodName = "initialize";
127
Class paramTypes[] = new Class[1];
128
paramTypes[0] = String.class;
129
Object paramValues[] = new Object[1];
130
paramValues[0] = null;
131
String className = "org.apache.tomcat.jni.Library";
132
Method method = Class.forName(className).getMethod(methodName, paramTypes);
133
method.invoke(null, paramValues);
139
catch (PrivilegedActionException e)
142
log.trace("", e.getCause());
145
// Instantiate the associated HTTP protocol handler
146
String protocolHandlerClassName = null;
147
Object value = config.get("protocolHandlerClassName");
150
protocolHandlerClassName = String.valueOf(value);
156
protocolHandlerClassName = "org.apache.coyote.http11.Http11AprProtocol";
160
protocolHandlerClassName = "org.apache.coyote.http11.Http11Protocol";
163
log.info("Using " + protocolHandlerClassName + " for http (coyote) invoker protocol handler.");
168
clazz = (Class) forName(protocolHandlerClassName);
170
catch (ClassNotFoundException e)
172
log.error("Protocol handler class instatiation failed: protocolHandlerClassName", e);
176
ProtocolHandler protocolHandler = null;
177
for (int i = 0; i < connectHomes.size(); i++)
181
protocolHandler = (ProtocolHandler) clazz.newInstance();
185
log.error("Protocol handler instantiation failed", e);
188
protocolHandler.setAdapter(this);
190
// Pass all attributes to the protocol handler
191
Iterator keys = config.keySet().iterator();
192
while(keys.hasNext())
194
String key = (String) keys.next();
195
Object obj = config.get(key);
196
if (obj instanceof String)
198
String val = (String) obj;
199
setProperty(protocolHandler, key, val);
203
// need to convert standard remoting timeout config to tomcat timeout
204
String timeoutValue = (String)config.get(TIMEOUT);
205
if(timeoutValue != null)
207
setProperty(protocolHandler, "connectionTimeout", timeoutValue);
210
// Configuration of URI encoding
211
value = config.get("URIEncoding");
214
URIEncoding = String.valueOf(value);
217
protocolHandlers.add(protocolHandler);
219
value = config.get(HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE);
220
if (value instanceof String)
222
useRemotingContentType = (String) value;
224
else if (value != null)
226
log.warn(HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE + " value should be a String: " + value);
228
log.debug(this + " useRemotingContentType: " + useRemotingContentType);
232
protected ServerSocketFactory getDefaultServerSocketFactory() throws IOException
235
* Returning a null here as if has not already been set previously
236
* via config in ServerInvoker, then want to return null so that
237
* will use the default within tomcat (and not override with own default).
240
if ("https".equals(locator.getProtocol()))
242
SSLSocketBuilder builder = new SSLSocketBuilder(configuration);
243
builder.setUseSSLServerSocketFactory(false);
246
return builder.createSSLServerSocketFactory();
248
catch (IOException e)
250
log.debug("unable to create server socket factory", e);
258
public void start() throws IOException
262
for (int i = 0; i < protocolHandlers.size(); i++)
266
final ProtocolHandler protocolHandler = (ProtocolHandler) protocolHandlers.get(i);
267
Home home = (Home) getHomes().get(i);
268
setProperty(protocolHandler, "address", home.host);
269
setProperty(protocolHandler, "port", "" + home.port);
271
//TODO: -TME - Should not have to hard set this every time. Should
272
// be a way to figure out if this is needed or not.
274
// Need to set the MBeanServer to use since there is no direct way to do it.
275
setProperty(protocolHandler, "locator", getLocator().getLocatorURI());
276
RemotingSSLImplementation.setMBeanServer(getLocator().getLocatorURI(), getMBeanServer());
278
ServerSocketFactory svrSocketFactory = getServerSocketFactory();
279
if(svrSocketFactory != null)
281
RemotingServerSocketFactory.setServerSocketFactory(getLocator().getLocatorURI(), svrSocketFactory);
282
setProperty(protocolHandler, "SocketFactory", RemotingServerSocketFactory.class.getName());
287
AccessController.doPrivileged( new PrivilegedExceptionAction()
289
public Object run() throws Exception
291
protocolHandler.init();
292
protocolHandler.start();
297
catch (PrivilegedActionException e)
299
throw (Exception) e.getCause();
307
log.debug("Error starting protocol handler. Bind port: " + getServerBindPort() + ", bind address: " + getServerBindAddress(), e);
308
throw new IOException("" + e.getMessage());
318
public void service(org.apache.coyote.Request req,
319
org.apache.coyote.Response res)
323
RequestMap request = (RequestMap) req.getNote(1);
324
ResponseMap response = (ResponseMap) res.getNote(1);
330
request = new RequestMap();
331
request.setCoyoteRequest(req);
332
response = new ResponseMap();
333
response.setCoyoteResponse(res);
336
req.setNote(1, request);
337
res.setNote(1, response);
339
// Set query string encoding
340
// FIMXE?: req.getParameters().setQueryStringEncoding(protocolHandler.getAttribute("URIEncoding"));
352
if(postParseRequest(req, request, res, response))
354
populateRequestMetadata(request, req);
356
Object responseObject = null;
357
boolean isError = false;
359
int version = getVersion(request);
361
// Check if client is HTTPClientInvoker
362
boolean isRemotingUserAgent = false;
363
Object userAgentObj = request.get(HTTPMetadataConstants.REMOTING_USER_AGENT);
364
if (userAgentObj != null)
366
String userAgent = (String) userAgentObj;
367
isRemotingUserAgent = userAgent.startsWith("JBossRemoting");
370
InvocationRequest invocationRequest = versionedRead(req, request, response, version);
372
if (invocationRequest.getRequestPayload() == null)
373
invocationRequest.setRequestPayload(new HashMap());
375
MessageBytes remoteAddressMB = req.remoteAddr();
376
if (remoteAddressMB != null)
378
String remoteAddressString = remoteAddressMB.toString();
379
InetAddress remoteAddress = getAddressByName(remoteAddressString);
380
invocationRequest.getRequestPayload().put(Remoting.CLIENT_ADDRESS, remoteAddress);
384
log.debug("unable to retrieve client address from coyote transport layer");
388
// FIXME: OPTIONS method handling ?
391
// call transport on the subclass, get the result to handback
392
responseObject = invoke(invocationRequest);
396
log.debug("Error thrown calling invoke on server invoker.", ex);
401
//Start with response code of 204 (no content), then if is a return from handler, change to 200 (ok)
405
if(responseObject != null)
410
message = "JBoss Remoting: Error occurred within target application.";
420
if (isRemotingUserAgent && !req.method().equals("HEAD"))
428
message = "No Content";
432
// extract response code/message if exists
433
Map responseMap = invocationRequest.getReturnPayload();
434
if(responseMap != null)
436
Integer handlerStatus = (Integer) responseMap.get(HTTPMetadataConstants.RESPONSE_CODE);
437
if(handlerStatus != null)
439
status = handlerStatus.intValue();
441
String handlerMessage = (String) responseMap.get(HTTPMetadataConstants.RESPONSE_CODE_MESSAGE);
442
if(handlerMessage != null)
444
message = handlerMessage;
447
res.setStatus(status);
448
res.setMessage(message);
450
if (isRemotingUserAgent && ((Boolean)receivedInvocationRequest.get()).booleanValue())
452
responseMap = ((ResponseMap) responseMap).getMap();
453
responseObject = new InvocationResponse(invocationRequest.getSessionId(),
454
responseObject, isError, responseMap);
457
if(responseObject != null)
459
versionedWrite(version, responseObject, req, res, response);
464
response.outputBuffer.close();
466
req.action(ActionCode.ACTION_POST_REQUEST, null);
469
catch (ClientAbortException e)
471
log.debug("Client didn't wait", e);
475
log.error("Error processing request", e);
479
log.error("Service error", t);
483
// Recycle the wrapper request and response
490
private void addLeaseInfo(ResponseMap response)
492
boolean leaseManagement = isLeaseActivated();
493
response.put("LEASING_ENABLED", new Boolean(leaseManagement));
497
long leasePeriod = getLeasePeriod();
498
response.put("LEASE_PERIOD", new Long(leasePeriod));
502
private void versionedWrite(int version, Object responseObject, Request req, org.apache.coyote.Response res, ResponseMap response)
507
case Version.VERSION_1:
508
case Version.VERSION_2:
509
case Version.VERSION_2_2:
511
String responseContentType = (String) response.get("Content-Type");
512
if (responseContentType != null)
514
if (isInvalidContentType(responseContentType))
516
log.warn("Ignoring invalid content-type from ServerInvocationHandler: " + responseContentType);
517
if (responseObject == null)
519
responseContentType = req.getContentType();
520
if (isInvalidContentType(responseContentType))
522
log.warn("Ignoring invalid content-type from request: " + responseContentType);
523
responseContentType = WebUtil.getContentType(responseObject);
528
responseContentType = WebUtil.getContentType(responseObject);
534
if (responseObject == null)
536
responseContentType = req.getContentType();
537
if (isInvalidContentType(responseContentType))
539
log.warn("Ignoring invalid content-type from request: " + responseContentType);
540
responseContentType = WebUtil.getContentType(responseObject);
545
responseContentType = WebUtil.getContentType(responseObject);
548
res.setContentType(responseContentType);
550
if (responseObject instanceof String)
552
res.addHeader(HTTPMetadataConstants.REMOTING_CONTENT_TYPE, HTTPMetadataConstants.REMOTING_CONTENT_TYPE_STRING);
556
res.addHeader(HTTPMetadataConstants.REMOTING_CONTENT_TYPE, HTTPMetadataConstants.REMOTING_CONTENT_TYPE_NON_STRING);
559
Marshaller marshaller = getMarshaller();
560
if (marshaller instanceof VersionedMarshaller)
561
((VersionedMarshaller) marshaller).write(responseObject, response.getOutputStream(), version);
563
marshaller.write(responseObject, response.getOutputStream());
568
throw new IOException("Can not send response due to version (" + version + ") not being supported. Supported versions: " + Version.VERSION_1 + ", " + Version.VERSION_2 + ", " + Version.VERSION_2_2);
573
private InvocationRequest versionedRead(Request req, RequestMap request, ResponseMap response, int version)
574
throws IOException, ClassNotFoundException
578
case Version.VERSION_1:
579
case Version.VERSION_2:
580
case Version.VERSION_2_2:
582
// UnMarshaller may not be an HTTPUnMarshaller, in which case it
583
// can ignore this parameter.
584
Object o = configuration.get(HTTPUnMarshaller.PRESERVE_LINES);
587
request.put(HTTPUnMarshaller.PRESERVE_LINES, o);
590
receivedInvocationRequest.set(FALSE);
591
InvocationRequest invocationRequest = null;
592
MessageBytes method = req.method();
593
if (method.equals("GET") || method.equals("HEAD")
594
|| (method.equals("OPTIONS") && req.getContentLength() <= 0))
596
invocationRequest = createNewInvocationRequest(request, response, null);
599
// must be POST or PUT
600
UnMarshaller unmarshaller = getUnMarshaller();
601
request.put(HTTPMetadataConstants.USE_REMOTING_CONTENT_TYPE, useRemotingContentType);
603
if (unmarshaller instanceof VersionedUnMarshaller)
604
obj = ((VersionedUnMarshaller)unmarshaller).read(request.getInputStream(), request, version);
606
obj = unmarshaller.read(request.getInputStream(), request);
607
if (obj instanceof InvocationRequest)
609
receivedInvocationRequest.set(TRUE);
610
invocationRequest = (InvocationRequest) obj;
611
if (invocationRequest.getReturnPayload() == null)
613
// need to create a return payload map, so can be populated with metadata
614
invocationRequest.setReturnPayload(response);
616
Map requestPayloadMap = invocationRequest.getRequestPayload();
617
if (requestPayloadMap != null)
619
request.putAll(requestPayloadMap);
621
invocationRequest.setRequestPayload(request);
624
invocationRequest = createNewInvocationRequest(request, response, obj);
628
return invocationRequest;
633
throw new IOException("Can not processes request due to incorrect version (" + version + "). Can only process versions: " + Version.VERSION_1 + ", " + Version.VERSION_2 + ", " + Version.VERSION_2_2);
638
private int getVersion(RequestMap request)
640
int version = Version.VERSION_1; // going to default to old version
641
Object versionObj = request.get(HTTPMetadataConstants.REMOTING_VERSION_HEADER);
642
if (versionObj != null)
644
String versionString = (String) versionObj;
647
version = Integer.parseInt(versionString);
648
} catch (NumberFormatException e)
650
log.error("Can not processes remoting version of " + versionString + " as is not a number.");
656
private void populateRequestMetadata(RequestMap metadata, Request req)
658
final MimeHeaders headers = req.getMimeHeaders();
659
Enumeration nameEnum = null;
661
if (SecurityUtility.skipAccessControl())
663
nameEnum = headers.names();
667
nameEnum = (Enumeration)AccessController.doPrivileged( new PrivilegedAction()
671
return headers.names();
676
while (nameEnum.hasMoreElements())
678
Object nameObj = nameEnum.nextElement();
679
if (nameObj instanceof String)
681
Object valueObj = headers.getHeader((String) nameObj);
682
metadata.put(nameObj, valueObj);
686
metadata.put(HTTPMetadataConstants.METHODTYPE, req.method().getString());
687
metadata.put(HTTPMetadataConstants.PATH, req.requestURI().getString());
688
metadata.put(HTTPMetadataConstants.QUERY, req.query().toString());
689
metadata.put(HTTPMetadataConstants.HTTPVERSION, req.protocol().getString());
694
protected InvocationRequest createNewInvocationRequest(RequestMap requestMap, ResponseMap responseMap,
697
// will try to use the same session id if possible to track
698
String sessionId = getSessionId(requestMap);
699
String subSystem = (String) requestMap.get(HEADER_SUBSYSTEM);
701
InvocationRequest request = null;
703
boolean isLeaseQueury = checkForLeaseQuery(requestMap);
706
addLeaseInfo(responseMap);
707
request = new InvocationRequest(sessionId, subSystem, "$PING$", null, responseMap, null);
711
request = new InvocationRequest(sessionId, subSystem, payload,
712
requestMap, responseMap, null);
717
private boolean checkForLeaseQuery(RequestMap headers)
719
boolean isLeaseQuery = false;
723
Object val = headers.get(HTTPMetadataConstants.REMOTING_LEASE_QUERY);
724
if(val != null && val instanceof String)
726
isLeaseQuery = Boolean.valueOf((String)val).booleanValue();
733
* Parse additional request parameters.
735
protected boolean postParseRequest(org.apache.coyote.Request req,
737
org.apache.coyote.Response res,
738
ResponseMap response)
743
MessageBytes decodedURI = req.decodedURI();
744
decodedURI.duplicate(req.requestURI());
746
if(decodedURI.getType() == MessageBytes.T_BYTES)
748
// %xx decoding of the URL
751
req.getURLDecoder().convert(decodedURI, false);
753
catch(IOException ioe)
756
res.setMessage("Invalid URI");
760
if(!normalize(req.decodedURI()))
763
res.setMessage("Invalid URI");
766
// Character decoding
767
convertURI(decodedURI, request);
771
// The URL is chars or String, and has been sent using an in-memory
772
// protocol handler, we have to assume the URL has been properly
774
decodedURI.toChars();
783
* Character conversion of the URI.
785
protected void convertURI(MessageBytes uri, RequestMap request)
789
ByteChunk bc = uri.getByteChunk();
790
CharChunk cc = uri.getCharChunk();
791
cc.allocate(bc.getLength(), -1);
793
String enc = URIEncoding;
796
B2CConverter conv = request.getURIConverter();
801
conv = new B2CConverter(enc);
802
request.setURIConverter(conv);
812
log.error("Invalid URI encoding; using HTTP default");
819
conv.convert(bc, cc);
820
uri.setChars(cc.getBuffer(), cc.getStart(),
826
log.error("Invalid URI character encoding; trying ascii");
832
// Default encoding: fast conversion
833
byte[] bbuf = bc.getBuffer();
834
char[] cbuf = cc.getBuffer();
835
int start = bc.getStart();
836
for(int i = 0; i < bc.getLength(); i++)
838
cbuf[i] = (char) (bbuf[i + start] & 0xff);
840
uri.setChars(cbuf, 0, bc.getLength());
846
* Character conversion of the a US-ASCII MessageBytes.
848
protected void convertMB(MessageBytes mb)
851
// This is of course only meaningful for bytes
852
if(mb.getType() != MessageBytes.T_BYTES)
857
ByteChunk bc = mb.getByteChunk();
858
CharChunk cc = mb.getCharChunk();
859
cc.allocate(bc.getLength(), -1);
861
// Default encoding: fast conversion
862
byte[] bbuf = bc.getBuffer();
863
char[] cbuf = cc.getBuffer();
864
int start = bc.getStart();
865
for(int i = 0; i < bc.getLength(); i++)
867
cbuf[i] = (char) (bbuf[i + start] & 0xff);
869
mb.setChars(cbuf, 0, bc.getLength());
877
* This method normalizes "\", "//", "/./" and "/../". This method will
878
* return false when trying to go above the root, or if the URI contains
881
* @param uriMB URI to be normalized
883
public static boolean normalize(MessageBytes uriMB)
886
ByteChunk uriBC = uriMB.getByteChunk();
887
byte[] b = uriBC.getBytes();
888
int start = uriBC.getStart();
889
int end = uriBC.getEnd();
891
// Expect request URI to be at least one character.
892
if (start - end == 0)
897
// URL * is acceptable
898
if((end - start == 1) && b[start] == (byte) '*')
906
// Replace '\' with '/'
907
// Check for null byte
908
for(pos = start; pos < end; pos++)
910
if(b[pos] == (byte) '\\')
914
if(b[pos] == (byte) 0)
920
// The URL must start with '/'
921
if(b[start] != (byte) '/')
926
// Replace "//" with "/"
927
for(pos = start; pos < (end - 1); pos++)
929
if(b[pos] == (byte) '/')
931
while((pos + 1 < end) && (b[pos + 1] == (byte) '/'))
933
copyBytes(b, pos, pos + 1, end - pos - 1);
939
// If the URI ends with "/." or "/..", then we append an extra "/"
940
// Note: It is possible to extend the URI by 1 without any side effect
941
// as the next character is a non-significant WS.
942
if(((end - start) >= 2) && (b[end - 1] == (byte) '.'))
944
if((b[end - 2] == (byte) '/')
945
|| ((b[end - 2] == (byte) '.')
946
&& (b[end - 3] == (byte) '/')))
957
// Resolve occurrences of "/./" in the normalized path
960
index = uriBC.indexOf("/./", 0, 3, index);
965
copyBytes(b, start + index, start + index + 2,
966
end - start - index - 2);
973
// Resolve occurrences of "/../" in the normalized path
976
index = uriBC.indexOf("/../", 0, 4, index);
981
// Prevent from going outside our context
987
for(pos = start + index - 1; (pos >= 0) && (index2 < 0); pos --)
989
if(b[pos] == (byte) '/')
994
copyBytes(b, start + index2, start + index + 3,
995
end - start - index - 3);
996
end = end + index2 - index - 3;
1001
uriBC.setBytes(b, start, end);
1009
* Copy an array of bytes to a different position. Used during
1012
protected static void copyBytes(byte[] b, int dest, int src, int len)
1014
for(int pos = 0; pos < len; pos++)
1016
b[pos + dest] = b[pos + src];
1027
if (protocolHandlers != null)
1029
Iterator it = protocolHandlers.iterator();
1030
while (it.hasNext())
1034
ProtocolHandler protocolHandler = (ProtocolHandler) it.next();
1035
protocolHandler.destroy();
1039
log.error("Stop error", e);
1046
log.debug("CoyoteInvoker stopped.");
1050
* Find a method with the right name If found, call the method ( if param is
1051
* int or boolean we'll convert value to the right type before) - that means
1052
* you can have setDebug(1).
1054
public static boolean setProperty(final Object o, String name, final String value)
1056
String setter = "set" + capitalize(name);
1060
Method[] methods = null;
1062
if (SecurityUtility.skipAccessControl())
1064
methods = o.getClass().getMethods();
1068
methods = (Method[]) AccessController.doPrivileged( new PrivilegedAction()
1072
return o.getClass().getMethods();
1077
Method setPropertyMethod = null;
1079
// First, the ideal case - a setFoo( String ) method
1080
for(int i = 0; i < methods.length; i++)
1082
Class paramT[] = methods[i].getParameterTypes();
1083
if(setter.equals(methods[i].getName()) && paramT.length == 1
1084
&& "java.lang.String".equals(paramT[0].getName()))
1087
methods[i].invoke(o, new Object[]{value});
1092
// Try a setFoo ( int ) or ( boolean )
1093
for(int i = 0; i < methods.length; i++)
1096
if(setter.equals(methods[i].getName())
1097
&& methods[i].getParameterTypes().length == 1)
1100
// match - find the type and invoke it
1101
Class paramType = methods[i].getParameterTypes()[0];
1102
Object params[] = new Object[1];
1104
// Try a setFoo ( int )
1105
if("java.lang.Integer".equals(paramType.getName())
1106
|| "int".equals(paramType.getName()))
1110
params[0] = new Integer(value);
1112
catch(NumberFormatException ex)
1116
// Try a setFoo ( long )
1118
else if("java.lang.Long".equals(paramType.getName())
1119
|| "long".equals(paramType.getName()))
1123
params[0] = new Long(value);
1125
catch(NumberFormatException ex)
1130
// Try a setFoo ( boolean )
1132
else if("java.lang.Boolean".equals(paramType.getName())
1133
|| "boolean".equals(paramType.getName()))
1135
params[0] = new Boolean(value);
1137
// Try a setFoo ( InetAddress )
1139
else if("java.net.InetAddress".equals(paramType.getName()))
1143
params[0] = getAddressByName(value);
1145
catch(UnknownHostException exc)
1155
methods[i].invoke(o, params);
1160
// save "setProperty" for later
1161
if("setProperty".equals(methods[i].getName()))
1163
setPropertyMethod = methods[i];
1167
// Ok, no setXXX found, try a setProperty("name", "value")
1168
if(setPropertyMethod != null)
1170
Object params[] = new Object[2];
1173
setPropertyMethod.invoke(o, params);
1186
* Reverse of Introspector.decapitalize
1188
public static String capitalize(String name)
1190
if(name == null || name.length() == 0)
1194
char chars[] = name.toCharArray();
1195
chars[0] = Character.toUpperCase(chars[0]);
1196
return new String(chars);
1201
* Necessary for implementation of org.apache.coyote.Adapter interface.
1202
* Body is vacuous because event() is only used in comet mode.
1204
public boolean event(Request arg0, Response arg1, SocketStatus arg2) throws Exception
1209
static private boolean isInvalidContentType(String contentType)
1211
return contentType.indexOf('\n') + contentType.indexOf('\r') > -2;
1214
static private Object forName(final String className) throws ClassNotFoundException
1216
if (SecurityUtility.skipAccessControl())
1218
return Class.forName(className);
1223
return AccessController.doPrivileged( new PrivilegedExceptionAction()
1225
public Object run() throws Exception
1227
return Class.forName(className);
1231
catch (PrivilegedActionException e)
1233
throw (ClassNotFoundException) e.getCause();
1237
static private InetAddress getAddressByName(final String host) throws UnknownHostException
1239
if (SecurityUtility.skipAccessControl())
1241
return InetAddress.getByName(host);
1246
return (InetAddress)AccessController.doPrivileged( new PrivilegedExceptionAction()
1248
public Object run() throws IOException
1250
return InetAddress.getByName(host);
1254
catch (PrivilegedActionException e)
1256
throw (UnknownHostException) e.getCause();