JBossWeb SVN: r1280 - trunk/java/org/apache/tomcat/util/net.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-20 10:36:52 -0500 (Fri, 20 Nov 2009)
New Revision: 1280
Modified:
trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
Log:
- Re cleanup.
Modified: trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/AprEndpoint.java 2009-11-19 21:49:54 UTC (rev 1279)
+++ trunk/java/org/apache/tomcat/util/net/AprEndpoint.java 2009-11-20 15:36:52 UTC (rev 1280)
@@ -1759,7 +1759,8 @@
if (event) {
// Event processes either a read or a write depending on what the poller returns
if (((desc[n*2] & Poll.APR_POLLHUP) == Poll.APR_POLLHUP)
- || ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)) {
+ || ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)
+ || ((desc[n*2] & Poll.APR_POLLNVAL) == Poll.APR_POLLNVAL)) {
if (!processSocket(desc[n*2+1], SocketStatus.ERROR)) {
// Close socket and clear pool
Socket.destroy(desc[n*2+1]);
@@ -1783,10 +1784,18 @@
}
}
} else if (((desc[n*2] & Poll.APR_POLLHUP) == Poll.APR_POLLHUP)
- || ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)) {
+ || ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)
+ || ((desc[n*2] & Poll.APR_POLLNVAL) == Poll.APR_POLLNVAL)) {
// Close socket and clear pool
Socket.destroy(desc[n*2+1]);
- } else if (!processSocket(desc[n*2+1])) {
+ } else if ((desc[n*2] & Poll.APR_POLLIN) == Poll.APR_POLLIN) {
+ if (!processSocket(desc[n*2+1])) {
+ // Close socket and clear pool
+ Socket.destroy(desc[n*2+1]);
+ }
+ } else {
+ // Unknown event
+ log.warn(sm.getString("endpoint.poll.flags", "" + desc[n*2]));
// Close socket and clear pool
Socket.destroy(desc[n*2+1]);
}
15 years, 10 months
JBossWeb SVN: r1279 - in trunk/java/org/apache/catalina: core and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-19 16:49:54 -0500 (Thu, 19 Nov 2009)
New Revision: 1279
Removed:
trunk/java/org/apache/catalina/connector/MapperListener.java
Modified:
trunk/java/org/apache/catalina/connector/Connector.java
trunk/java/org/apache/catalina/core/ServiceMapperListener.java
trunk/java/org/apache/catalina/core/StandardEngine.java
Log:
- Remove the old mapper listener.
Modified: trunk/java/org/apache/catalina/connector/Connector.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Connector.java 2009-11-19 19:10:23 UTC (rev 1278)
+++ trunk/java/org/apache/catalina/connector/Connector.java 2009-11-19 21:49:54 UTC (rev 1279)
@@ -32,13 +32,11 @@
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Service;
-import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.coyote.Adapter;
import org.apache.coyote.ProtocolHandler;
import org.apache.tomcat.util.IntrospectionUtils;
-import org.apache.tomcat.util.http.mapper.Mapper;
import org.apache.tomcat.util.modeler.Registry;
import org.jboss.logging.Logger;
@@ -252,18 +250,6 @@
/**
- * Mapper.
- */
- protected Mapper mapper = new Mapper();
-
-
- /**
- * Mapper listener.
- */
- protected MapperListener mapperListener = new MapperListener(mapper, this);
-
-
- /**
* URI encoding.
*/
protected String URIEncoding = null;
@@ -478,16 +464,6 @@
}
- /**
- * Return the mapper.
- */
- public Mapper getMapper() {
-
- return (mapper);
-
- }
-
-
/**
* Return the maximum size of a POST which will be automatically
* parsed by the container.
@@ -1017,11 +993,10 @@
this.initialized = true;
- if( oname == null && (container instanceof StandardEngine)) {
+ if (oname == null) {
try {
// we are loaded directly, via API - and no name was given to us
- StandardEngine cb=(StandardEngine)container;
- oname = createObjectName(cb.getName(), "Connector");
+ oname = createObjectName(container.getName(), "Connector");
Registry.getRegistry(null, null)
.registerComponent(this, oname, null);
controller=oname;
@@ -1125,22 +1100,6 @@
("coyoteConnector.protocolHandlerStartFailed", e));
}
- if( this.domain != null ) {
- mapperListener.setDomain( domain );
- //mapperListener.setEngine( service.getContainer().getName() );
- mapperListener.init();
- try {
- ObjectName mapperOname = createObjectName(this.domain,"Mapper");
- if (log.isDebugEnabled())
- log.debug(sm.getString(
- "coyoteConnector.MapperRegistration", mapperOname));
- Registry.getRegistry(null, null).registerComponent
- (mapper, mapperOname, "Mapper");
- } catch (Exception ex) {
- log.error(sm.getString
- ("coyoteConnector.protocolRegistrationFailed"), ex);
- }
- }
}
@@ -1161,10 +1120,7 @@
started = false;
try {
- mapperListener.destroy();
Registry.getRegistry(null, null).unregisterComponent
- (createObjectName(this.domain,"Mapper"));
- Registry.getRegistry(null, null).unregisterComponent
(createObjectName(this.domain,"ProtocolHandler"));
} catch (MalformedObjectNameException e) {
log.error( sm.getString
Deleted: trunk/java/org/apache/catalina/connector/MapperListener.java
===================================================================
--- trunk/java/org/apache/catalina/connector/MapperListener.java 2009-11-19 19:10:23 UTC (rev 1278)
+++ trunk/java/org/apache/catalina/connector/MapperListener.java 2009-11-19 21:49:54 UTC (rev 1279)
@@ -1,535 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.catalina.connector;
-
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.management.MBeanServer;
-import javax.management.MBeanServerNotification;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-import org.apache.catalina.ContainerEvent;
-import org.apache.catalina.ContainerListener;
-import org.apache.catalina.Host;
-import org.apache.catalina.core.StandardContext;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.mapper.Mapper;
-import org.apache.tomcat.util.http.mapper.MappingData;
-import org.apache.tomcat.util.modeler.Registry;
-import org.apache.tomcat.util.res.StringManager;
-import org.jboss.logging.Logger;
-
-
-/**
- * Mapper listener.
- *
- * @author Remy Maucherat
- * @author Costin Manolache
- * FIXME: redo as server listener ? see ClusterListener
- */
-public class MapperListener
- implements NotificationListener, ContainerListener
- {
- private static Logger log = Logger.getLogger(MapperListener.class);
-
-
- // ----------------------------------------------------- Instance Variables
- /**
- * Associated mapper.
- */
- protected Mapper mapper = null;
-
- /**
- * Associated connector
- */
- protected Connector connector = null;
-
- /**
- * MBean server.
- */
- protected MBeanServer mBeanServer = null;
-
-
- /**
- * The string manager for this package.
- */
- private StringManager sm =
- StringManager.getManager(Constants.Package);
-
- // It should be null - and fail if not set
- private String domain="*";
-
- // ----------------------------------------------------------- Constructors
-
-
- /**
- * Create mapper listener.
- */
- public MapperListener(Mapper mapper, Connector connector) {
- this.mapper = mapper;
- this.connector = connector;
- }
-
-
- // --------------------------------------------------------- Public Methods
-
- public String getDomain() {
- return domain;
- }
-
- public void setDomain(String domain) {
- this.domain = domain;
- }
-
- /**
- * Initialize associated mapper.
- */
- public void init() {
-
- try {
-
- mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
-
- registerEngine();
-
- // Query hosts
- String onStr = domain + ":type=Host,*";
- ObjectName objectName = new ObjectName(onStr);
- Set set = mBeanServer.queryMBeans(objectName, null);
- Iterator iterator = set.iterator();
- while (iterator.hasNext()) {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- registerHost(oi.getObjectName());
- }
-
-
- // Query contexts
- onStr = "*:j2eeType=WebModule,*";
- objectName = new ObjectName(onStr);
- set = mBeanServer.queryMBeans(objectName, null);
- iterator = set.iterator();
- while (iterator.hasNext()) {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- registerContext(oi.getObjectName());
- }
-
- // Query wrappers
- onStr = "*:j2eeType=Servlet,*";
- objectName = new ObjectName(onStr);
- set = mBeanServer.queryMBeans(objectName, null);
- iterator = set.iterator();
- while (iterator.hasNext()) {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- registerWrapper(oi.getObjectName());
- }
-
- onStr = "JMImplementation:type=MBeanServerDelegate";
- objectName = new ObjectName(onStr);
- mBeanServer.addNotificationListener(objectName, this, null, null);
-
- } catch (Exception e) {
- log.warn("Error registering contexts",e);
- }
-
- }
-
- /**
- * unregister this from JMImplementation:type=MBeanServerDelegate
- */
- public void destroy() {
- try {
-
- ObjectName objectName = new ObjectName("JMImplementation:type=MBeanServerDelegate");
- if (mBeanServer != null) {
- mBeanServer.removeNotificationListener(objectName, this);
- }
- } catch (Exception e) {
- log.warn("Error unregistering MBeanServerDelegate", e);
- }
- }
-
- // ------------------------------------------- NotificationListener Methods
-
-
- public void handleNotification(Notification notification,
- java.lang.Object handback) {
-
- if (notification instanceof MBeanServerNotification) {
- ObjectName objectName =
- ((MBeanServerNotification) notification).getMBeanName();
- String j2eeType = objectName.getKeyProperty("j2eeType");
- String engineName = null;
- if (j2eeType != null) {
- if ((j2eeType.equals("WebModule")) ||
- (j2eeType.equals("Servlet"))) {
- if (mBeanServer.isRegistered(objectName)) {
- try {
- engineName = (String)
- mBeanServer.getAttribute(objectName, "engineName");
- } catch (Exception e) {
- // Ignore
- }
- }
- }
- }
-
- // At deployment time, engineName is always = null.
- if ( (!"*".equals(domain)) &&
- ( !domain.equals(objectName.getDomain()) ) &&
- ( (!domain.equals(engineName) ) &&
- (engineName != null) ) ) {
- return;
- }
- if(log.isDebugEnabled())
- log.debug( "Handle " + objectName + " type : " + notification.getType());
- if (notification.getType().equals
- (MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
- String type=objectName.getKeyProperty("type");
- if( "Host".equals( type ) && domain.equals(objectName.getDomain())) {
- try {
- registerHost(objectName);
- } catch (Exception e) {
- log.warn("Error registering Host " + objectName, e);
- }
- }
-
- if (j2eeType != null) {
- if (j2eeType.equals("WebModule")) {
- try {
- registerContext(objectName);
- } catch (Throwable t) {
- log.warn("Error registering Context " + objectName,t);
- }
- } else if (j2eeType.equals("Servlet")) {
- try {
- registerWrapper(objectName);
- } catch (Throwable t) {
- log.warn("Error registering Wrapper " + objectName,t);
- }
- }
- }
- } else if (notification.getType().equals
- (MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
- String type=objectName.getKeyProperty("type");
- if( "Host".equals( type )&& domain.equals(objectName.getDomain())) {
- try {
- unregisterHost(objectName);
- } catch (Exception e) {
- log.warn("Error unregistering Host " + objectName,e);
- }
- }
-
- if (j2eeType != null) {
- if (j2eeType.equals("WebModule")) {
- try {
- unregisterContext(objectName);
- } catch (Throwable t) {
- log.warn("Error unregistering webapp " + objectName,t);
- }
- }
- }
- }
- }
-
- }
-
-
- // --------------------------------------------- Container Listener methods
-
- public void containerEvent(ContainerEvent event) {
-
- if (event.getType() == Host.ADD_ALIAS_EVENT) {
- mapper.addHostAlias(((Host) event.getSource()).getName(),
- event.getData().toString());
- } else if (event.getType() == Host.REMOVE_ALIAS_EVENT) {
- mapper.removeHostAlias(event.getData().toString());
- }
- }
-
- // ------------------------------------------------------ Protected Methods
-
- private void registerEngine()
- throws Exception
- {
- ObjectName engineName = new ObjectName
- (domain + ":type=Engine");
- if ( ! mBeanServer.isRegistered(engineName)) return;
- String defaultHost =
- (String) mBeanServer.getAttribute(engineName, "defaultHost");
- ObjectName hostName = new ObjectName
- (domain + ":type=Host," + "host=" + defaultHost);
- if (!mBeanServer.isRegistered(hostName)) {
-
- // Get the hosts' list
- String onStr = domain + ":type=Host,*";
- ObjectName objectName = new ObjectName(onStr);
- Set set = mBeanServer.queryMBeans(objectName, null);
- Iterator iterator = set.iterator();
- String[] aliases;
- boolean isRegisteredWithAlias = false;
-
- while (iterator.hasNext()) {
-
- if (isRegisteredWithAlias) break;
-
- ObjectInstance oi = (ObjectInstance) iterator.next();
- hostName = oi.getObjectName();
- aliases = (String[])
- mBeanServer.invoke(hostName, "findAliases", null, null);
-
- for (int i=0; i < aliases.length; i++){
- if (aliases[i].equalsIgnoreCase(defaultHost)){
- isRegisteredWithAlias = true;
- break;
- }
- }
- }
-
- if (!isRegisteredWithAlias)
- log.warn(sm.getString("mapperListener.unknownDefaultHost", defaultHost));
- }
- // This should probably be called later
- if( defaultHost != null ) {
- mapper.setDefaultHostName(defaultHost);
- }
- }
-
- /**
- * Register host.
- */
- private void registerHost(ObjectName objectName)
- throws Exception {
- String name=objectName.getKeyProperty("host");
- if( name != null ) {
- Host host = (Host) connector.getService().getContainer().findChild(name);
- String[] aliases = host.findAliases();
- mapper.addHost(name, aliases, objectName);
- host.addContainerListener(this);
- if(log.isDebugEnabled())
- log.debug(sm.getString
- ("mapperListener.registerHost", name, domain));
- }
- }
-
-
- private void unregisterHost(ObjectName objectName)
- throws Exception {
- String name=objectName.getKeyProperty("host");
- if( name != null ) {
- Host host =
- (Host) connector.getService().getContainer().findChild(name);
-
- mapper.removeHost(name);
- if (host != null) {
- host.removeContainerListener(this);
- }
- if(log.isDebugEnabled())
- log.debug(sm.getString
- ("mapperListener.unregisterHost", name, domain));
- }
- }
-
-
- /**
- * Register context.
- */
- private void registerContext(ObjectName objectName)
- throws Exception {
-
- String name = objectName.getKeyProperty("name");
-
- // If the domain is the same with ours or the engine
- // name attribute is the same... - then it's ours
- String targetDomain=objectName.getDomain();
- if( ! domain.equals( targetDomain )) {
- try {
- targetDomain = (String) mBeanServer.getAttribute
- (objectName, "engineName");
- } catch (Exception e) {
- // Ignore
- }
- if( ! domain.equals( targetDomain )) {
- // not ours
- return;
- }
- }
-
- String hostName = null;
- String contextName = null;
- if (name.startsWith("//")) {
- name = name.substring(2);
- }
- int slash = name.indexOf("/");
- if (slash != -1) {
- hostName = name.substring(0, slash);
- contextName = name.substring(slash);
- } else {
- return;
- }
- // Special case for the root context
- if (contextName.equals("/")) {
- contextName = "";
- }
-
- if(log.isDebugEnabled())
- log.debug(sm.getString
- ("mapperListener.registerContext", contextName));
-
- Object context =
- mBeanServer.invoke(objectName, "findMappingObject", null, null);
- //mBeanServer.getAttribute(objectName, "mappingObject");
- javax.naming.Context resources = (javax.naming.Context)
- mBeanServer.invoke(objectName, "findStaticResources", null, null);
- //mBeanServer.getAttribute(objectName, "staticResources");
- String[] welcomeFiles = (String[])
- mBeanServer.getAttribute(objectName, "welcomeFiles");
-
- mapper.addContext(hostName, contextName, context,
- welcomeFiles, resources);
-
- }
-
-
- /**
- * Unregister context.
- */
- private void unregisterContext(ObjectName objectName)
- throws Exception {
-
- String name = objectName.getKeyProperty("name");
-
- // If the domain is the same with ours or the engine
- // name attribute is the same... - then it's ours
- String targetDomain=objectName.getDomain();
- if( ! domain.equals( targetDomain )) {
- try {
- targetDomain = (String) mBeanServer.getAttribute
- (objectName, "engineName");
- } catch (Exception e) {
- // Ignore
- }
- if( ! domain.equals( targetDomain )) {
- // not ours
- return;
- }
- }
-
- String hostName = null;
- String contextName = null;
- if (name.startsWith("//")) {
- name = name.substring(2);
- }
- int slash = name.indexOf("/");
- if (slash != -1) {
- hostName = name.substring(0, slash);
- contextName = name.substring(slash);
- } else {
- return;
- }
- // Special case for the root context
- if (contextName.equals("/")) {
- contextName = "";
- }
- // Don't un-map a context that is paused
- MessageBytes hostMB = MessageBytes.newInstance();
- hostMB.setString(hostName);
- MessageBytes contextMB = MessageBytes.newInstance();
- contextMB.setString(contextName);
- MappingData mappingData = new MappingData();
- mapper.map(hostMB, contextMB, mappingData);
- if (mappingData.context instanceof StandardContext &&
- ((StandardContext)mappingData.context).getPaused()) {
- return;
- }
- if(log.isDebugEnabled())
- log.debug(sm.getString
- ("mapperListener.unregisterContext", contextName));
-
- mapper.removeContext(hostName, contextName);
-
- }
-
-
- /**
- * Register wrapper.
- */
- private void registerWrapper(ObjectName objectName)
- throws Exception {
-
- // If the domain is the same with ours or the engine
- // name attribute is the same... - then it's ours
- String targetDomain=objectName.getDomain();
- if( ! domain.equals( targetDomain )) {
- try {
- targetDomain=(String) mBeanServer.getAttribute(objectName, "engineName");
- } catch (Exception e) {
- // Ignore
- }
- if( ! domain.equals( targetDomain )) {
- // not ours
- return;
- }
-
- }
-
- String wrapperName = objectName.getKeyProperty("name");
- String name = objectName.getKeyProperty("WebModule");
-
- String hostName = null;
- String contextName = null;
- if (name.startsWith("//")) {
- name = name.substring(2);
- }
- int slash = name.indexOf("/");
- if (slash != -1) {
- hostName = name.substring(0, slash);
- contextName = name.substring(slash);
- } else {
- return;
- }
- // Special case for the root context
- if (contextName.equals("/")) {
- contextName = "";
- }
- if(log.isDebugEnabled())
- log.debug(sm.getString
- ("mapperListener.registerWrapper",
- wrapperName, contextName));
-
- // FIXME: need to handle enabled flag
- String[] mappings = (String[])
- mBeanServer.invoke(objectName, "findMappings", null, null);
- Object wrapper =
- mBeanServer.invoke(objectName, "findMappingObject", null, null);
-
- for (int i = 0; i < mappings.length; i++) {
- boolean jspWildCard = (wrapperName.equals("jsp")
- && mappings[i].endsWith("/*"));
- mapper.addWrapper(hostName, contextName, mappings[i], wrapper,
- jspWildCard);
- }
-
- }
-
-
-
-
-}
Modified: trunk/java/org/apache/catalina/core/ServiceMapperListener.java
===================================================================
--- trunk/java/org/apache/catalina/core/ServiceMapperListener.java 2009-11-19 19:10:23 UTC (rev 1278)
+++ trunk/java/org/apache/catalina/core/ServiceMapperListener.java 2009-11-19 21:49:54 UTC (rev 1279)
@@ -126,8 +126,6 @@
((Lifecycle) context).addLifecycleListener(this);
}
}
- } else {
- return;
}
} else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
if (source instanceof Context) {
@@ -147,8 +145,6 @@
mapper.removeContext(host.getName(), context.getName());
}
}
- } else {
- return;
}
} else if (Context.COMPLETE_CONFIG_EVENT.equals(event.getType())) {
Context context = (Context) source;
@@ -166,7 +162,6 @@
}
}
}
- } else if (Lifecycle.PERIODIC_EVENT.equals(event.getType())) {
}
}
Modified: trunk/java/org/apache/catalina/core/StandardEngine.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardEngine.java 2009-11-19 19:10:23 UTC (rev 1278)
+++ trunk/java/org/apache/catalina/core/StandardEngine.java 2009-11-19 21:49:54 UTC (rev 1279)
@@ -37,7 +37,6 @@
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomcat.util.modeler.modules.MbeansSource;
import org.jboss.logging.Logger;
-import org.jboss.logging.Logger;
/**
* Standard implementation of the <b>Engine</b> interface. Each
15 years, 10 months
JBossWeb SVN: r1278 - in trunk/java/org/apache/catalina: connector and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-19 14:10:23 -0500 (Thu, 19 Nov 2009)
New Revision: 1278
Added:
trunk/java/org/apache/catalina/core/ServiceMapperListener.java
Modified:
trunk/java/org/apache/catalina/Service.java
trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/core/StandardService.java
Log:
- Add a new simpler mapper listener, associated with Service.
Modified: trunk/java/org/apache/catalina/Service.java
===================================================================
--- trunk/java/org/apache/catalina/Service.java 2009-11-19 19:01:33 UTC (rev 1277)
+++ trunk/java/org/apache/catalina/Service.java 2009-11-19 19:10:23 UTC (rev 1278)
@@ -19,6 +19,7 @@
package org.apache.catalina;
import org.apache.catalina.connector.Connector;
+import org.apache.tomcat.util.http.mapper.Mapper;
/**
* A <strong>Service</strong> is a group of one or more
@@ -61,6 +62,12 @@
public String getInfo();
/**
+ * Return the <code>Mapper</code> that handles mapping for all
+ * <code>Connectors</code> associated with this Service.
+ */
+ public Mapper getMapper();
+
+ /**
* Return the name of this Service.
*/
public String getName();
Modified: trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
===================================================================
--- trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 2009-11-19 19:01:33 UTC (rev 1277)
+++ trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 2009-11-19 19:10:23 UTC (rev 1278)
@@ -527,7 +527,7 @@
} else {
serverName = req.serverName();
}
- connector.getMapper().map(serverName, decodedURI,
+ connector.getService().getMapper().map(serverName, decodedURI,
request.getMappingData());
request.setContext((Context) request.getMappingData().context);
request.setWrapper((Wrapper) request.getMappingData().wrapper);
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-11-19 19:01:33 UTC (rev 1277)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-11-19 19:10:23 UTC (rev 1278)
@@ -685,10 +685,7 @@
* Return the Host within which this Request is being processed.
*/
public Host getHost() {
- if (getContext() == null)
- return null;
- return (Host) getContext().getParent();
- //return ((Host) mappingData.host);
+ return ((Host) mappingData.host);
}
Added: trunk/java/org/apache/catalina/core/ServiceMapperListener.java
===================================================================
--- trunk/java/org/apache/catalina/core/ServiceMapperListener.java (rev 0)
+++ trunk/java/org/apache/catalina/core/ServiceMapperListener.java 2009-11-19 19:10:23 UTC (rev 1278)
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.core;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.ContainerEvent;
+import org.apache.catalina.ContainerListener;
+import org.apache.catalina.Context;
+import org.apache.catalina.Engine;
+import org.apache.catalina.Host;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Service;
+import org.apache.catalina.Wrapper;
+import org.apache.tomcat.util.http.mapper.Mapper;
+
+
+/**
+ * Mapper listener.
+ *
+ * @author Remy Maucherat
+ * @author Costin Manolache
+ */
+public class ServiceMapperListener
+ implements LifecycleListener, ContainerListener
+ {
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * Associated mapper.
+ */
+ protected Mapper mapper = null;
+
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Create mapper listener.
+ */
+ public ServiceMapperListener(Mapper mapper) {
+ this.mapper = mapper;
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ public void containerEvent(ContainerEvent event) {
+
+ Container container = event.getContainer();
+ String type = event.getType();
+
+ if (type.equals(Container.ADD_CHILD_EVENT)) {
+ if (container instanceof Host) {
+ // Deploying a webapp
+ Context context = (Context) event.getData();
+ ((Lifecycle) context).addLifecycleListener(this);
+ if (context.isStarted()) {
+ mapper.addContext(container.getName(), context.getName(), context,
+ context.findWelcomeFiles(), context.getResources());
+ }
+ } else if (container instanceof Engine) {
+ // Deploying a host
+ container.addContainerListener(this);
+ Host host = (Host) event.getData();
+ mapper.addHost(host.getName(), host.findAliases(), host);
+ }
+ } else if (type.equals(Container.REMOVE_CHILD_EVENT)) {
+ if (container instanceof Host) {
+ // Undeploying a webapp
+ Context context = (Context) event.getData();
+ ((Lifecycle) context).removeLifecycleListener(this);
+ mapper.removeContext(container.getName(), context.getName());
+ } else if (container instanceof Engine) {
+ // Undeploying a host
+ container.removeContainerListener(this);
+ Host host = (Host) event.getData();
+ mapper.removeHost(host.getName());
+ }
+ } else if (type == Host.ADD_ALIAS_EVENT) {
+ mapper.addHostAlias(((Host) event.getSource()).getName(),
+ event.getData().toString());
+ } else if (type == Host.REMOVE_ALIAS_EVENT) {
+ mapper.removeHostAlias(event.getData().toString());
+ }
+
+ }
+
+
+ public void lifecycleEvent(LifecycleEvent event) {
+
+ Object source = event.getLifecycle();
+
+ if (Lifecycle.START_EVENT.equals(event.getType())) {
+ if (source instanceof Service) {
+ Service service = (Service) source;
+ Engine engine = (Engine) service.getContainer();
+ engine.addContainerListener(this);
+ ((Lifecycle) engine).addLifecycleListener(this);
+ if (engine.getDefaultHost() != null) {
+ mapper.setDefaultHostName(engine.getDefaultHost());
+ }
+ for (Container host : engine.findChildren()) {
+ host.addContainerListener(this);
+ mapper.addHost(host.getName(), ((Host) host).findAliases(), host);
+ for (Container context : host.findChildren()) {
+ ((Lifecycle) context).addLifecycleListener(this);
+ }
+ }
+ } else {
+ return;
+ }
+ } else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
+ if (source instanceof Context) {
+ // Stop a webapp
+ Context context = (Context) source;
+ mapper.removeContext(context.getParent().getName(), context.getName());
+ } else if (source instanceof Service) {
+ Service service = (Service) source;
+ Engine engine = (Engine) service.getContainer();
+ engine.removeContainerListener(this);
+ ((Lifecycle) engine).removeLifecycleListener(this);
+ for (Container host : engine.findChildren()) {
+ host.removeContainerListener(this);
+ mapper.removeHost(host.getName());
+ for (Container context : host.findChildren()) {
+ ((Lifecycle) context).removeLifecycleListener(this);
+ mapper.removeContext(host.getName(), context.getName());
+ }
+ }
+ } else {
+ return;
+ }
+ } else if (Context.COMPLETE_CONFIG_EVENT.equals(event.getType())) {
+ Context context = (Context) source;
+ mapper.addContext(context.getParent().getName(), context.getName(), context,
+ context.findWelcomeFiles(), context.getResources());
+ // Add all wrappers
+ for (Container child : context.findChildren()) {
+ Wrapper wrapper = (Wrapper) child;
+ if (wrapper.getEnabled()) {
+ for (String mapping : wrapper.findMappings()) {
+ boolean jspWildCard = ("jsp".equals(wrapper.getName())
+ && mapping.endsWith("/*"));
+ mapper.addWrapper(context.getParent().getName(), context.getName(),
+ mapping, wrapper, jspWildCard);
+ }
+ }
+ }
+ } else if (Lifecycle.PERIODIC_EVENT.equals(event.getType())) {
+ }
+
+ }
+
+}
Modified: trunk/java/org/apache/catalina/core/StandardService.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardService.java 2009-11-19 19:01:33 UTC (rev 1277)
+++ trunk/java/org/apache/catalina/core/StandardService.java 2009-11-19 19:10:23 UTC (rev 1278)
@@ -38,6 +38,7 @@
import org.apache.catalina.connector.Connector;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
+import org.apache.tomcat.util.http.mapper.Mapper;
import org.apache.tomcat.util.modeler.Registry;
import org.jboss.logging.Logger;
@@ -125,8 +126,20 @@
*/
protected Container container = null;
+
+ /**
+ * Mapper.
+ */
+ protected Mapper mapper = new Mapper();
+
/**
+ * The associated mapper.
+ */
+ protected ServiceMapperListener mapperListener = new ServiceMapperListener(mapper);
+
+
+ /**
* Has this component been initialized?
*/
protected boolean initialized = false;
@@ -186,6 +199,12 @@
}
+
+ public Mapper getMapper() {
+ return mapper;
+ }
+
+
public ObjectName getContainerName() {
if( container instanceof ContainerBase ) {
return ((ContainerBase)container).getJmxName();
@@ -675,7 +694,8 @@
server.addService(this);
}
-
+ addLifecycleListener(mapperListener);
+
// Initialize our defined Connectors
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++) {
@@ -687,6 +707,7 @@
public void destroy() throws LifecycleException {
if( started ) stop();
// FIXME unregister should be here probably -- stop doing that ?
+ removeLifecycleListener(mapperListener);
}
public void init() {
15 years, 10 months
JBossWeb SVN: r1277 - in trunk/java/org/apache/tomcat/util/net: res and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-19 14:01:33 -0500 (Thu, 19 Nov 2009)
New Revision: 1277
Modified:
trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
Log:
- It is safer to add a big catch all here, as falling off without cleaning up a bit can be disastrous.
Modified: trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
===================================================================
--- trunk/java/org/apache/tomcat/util/net/AprEndpoint.java 2009-11-19 03:02:03 UTC (rev 1276)
+++ trunk/java/org/apache/tomcat/util/net/AprEndpoint.java 2009-11-19 19:01:33 UTC (rev 1277)
@@ -1774,6 +1774,13 @@
// Close socket and clear pool
Socket.destroy(desc[n*2+1]);
}
+ } else {
+ // Unknown event
+ log.warn(sm.getString("endpoint.poll.flags", "" + desc[n*2]));
+ if (!processSocket(desc[n*2+1], SocketStatus.ERROR)) {
+ // Close socket and clear pool
+ Socket.destroy(desc[n*2+1]);
+ }
}
} else if (((desc[n*2] & Poll.APR_POLLHUP) == Poll.APR_POLLHUP)
|| ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)) {
Modified: trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties 2009-11-19 03:02:03 UTC (rev 1276)
+++ trunk/java/org/apache/tomcat/util/net/res/LocalStrings.properties 2009-11-19 19:01:33 UTC (rev 1277)
@@ -19,6 +19,7 @@
endpoint.poll.limitedpollsize=Failed to create poller with specified size of {0}
endpoint.poll.initfail=Poller creation failed
endpoint.poll.fail=Critical poller failure (restarting poller): [{0}] {1}
+endpoint.poll.flags=Unfiltered poll flag {0}, sending error
endpoint.poll.error=Unexpected poller error
endpoint.maintain.error=Error processing timeouts
endpoint.process.fail=Error allocating socket processor
15 years, 10 months
JBossWeb SVN: r1276 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-18 22:02:03 -0500 (Wed, 18 Nov 2009)
New Revision: 1276
Modified:
trunk/java/org/apache/catalina/connector/Request.java
trunk/webapps/docs/changelog.xml
Log:
- Add null checks for context, like there is in other places in Request.
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-11-18 16:56:02 UTC (rev 1275)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-11-19 03:02:03 UTC (rev 1276)
@@ -1512,6 +1512,9 @@
return;
}
+ if (context == null)
+ return;
+
// Notify interested application event listeners
Object listeners[] = context.getApplicationEventListeners();
if ((listeners == null) || (listeners.length == 0))
@@ -1582,6 +1585,9 @@
coyoteRequest.setAttribute(name, value);
}
+ if (context == null)
+ return;
+
// Notify interested application event listeners
Object listeners[] = context.getApplicationEventListeners();
if ((listeners == null) || (listeners.length == 0))
@@ -2466,9 +2472,7 @@
return (session);
// Return the requested session if it exists and is valid
- Manager manager = null;
- if (context != null)
- manager = context.getManager();
+ Manager manager = context.getManager();
if (manager == null)
return (null); // Sessions are not supported
if (requestedSessionId != null) {
@@ -2488,7 +2492,7 @@
// Create a new session if requested and the response is not committed
if (!create)
return (null);
- if ((context != null) && (response != null) &&
+ if ((response != null) &&
context.getCookies() &&
response.getResponse().isCommitted()) {
throw new IllegalStateException
@@ -2524,8 +2528,7 @@
// Creating a new session cookie based on that session
// If there was no cookie with the current session id, add a cookie to the response
- if ( (session != null) && (getContext() != null)
- && getContext().getCookies()
+ if ( (session != null) && context.getCookies()
&& !(isRequestedSessionIdFromCookie() && (session.getIdInternal().equals(getRequestedSessionId()))) ) {
String cookieName = context.getSessionCookie().getName();
if (cookieName == null) {
@@ -2647,6 +2650,9 @@
parametersParsed = true;
+ if (context == null)
+ return;
+
Parameters parameters = coyoteRequest.getParameters();
// getCharacterEncoding() may have been overridden to search for
@@ -2789,6 +2795,9 @@
protected void parseMultipart()
throws IOException, ServletException {
+ if (context == null)
+ return;
+
Multipart config = wrapper.getMultipartConfig();
if (config == null) {
return;
@@ -3039,7 +3048,7 @@
throw new IllegalStateException(sm.getString("coyoteRequest.noAsync"));
}
// ISE if response is closed
- if (response.isClosed()) {
+ if (response.isClosed() || context == null) {
throw new IllegalStateException(sm.getString("coyoteRequest.closed"));
}
// ISE if this method is called again without any asynchronous dispatch
@@ -3073,7 +3082,7 @@
public boolean authenticate(HttpServletResponse response) throws IOException,
ServletException {
- if (context.getAuthenticator() != null) {
+ if (context != null && context.getAuthenticator() != null) {
return context.getAuthenticator().authenticate(this, response);
} else {
throw new ServletException(sm.getString("coyoteRequest.noAuthenticator"));
@@ -3084,7 +3093,7 @@
if (userPrincipal != null) {
throw new ServletException(sm.getString("coyoteRequest.authFailed"));
}
- if (context.getAuthenticator() != null) {
+ if (context != null && context.getAuthenticator() != null) {
context.getAuthenticator().login(this, username, password);
} else {
throw new ServletException(sm.getString("coyoteRequest.noAuthenticator"));
@@ -3096,7 +3105,7 @@
public void logout() throws ServletException {
Principal principal = userPrincipal;
- if (context.getAuthenticator() != null) {
+ if (context != null && context.getAuthenticator() != null) {
context.getAuthenticator().logout(this);
} else {
userPrincipal = null;
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2009-11-18 16:56:02 UTC (rev 1275)
+++ trunk/webapps/docs/changelog.xml 2009-11-19 03:02:03 UTC (rev 1276)
@@ -139,6 +139,9 @@
<fix>
<jboss-jira>JBAS-7159</jboss-jira>: Better usability for Context level usage of RewriteValve. (remm)
</fix>
+ <fix>
+ <jira>148</jira>: Add additional null checks for unmapped contexts. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
15 years, 10 months
JBossWeb SVN: r1275 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-18 11:56:02 -0500 (Wed, 18 Nov 2009)
New Revision: 1275
Modified:
trunk/java/org/jboss/web/rewrite/RewriteValve.java
trunk/webapps/docs/changelog.xml
Log:
- Better usability of RewriteValve at the context level.
Modified: trunk/java/org/jboss/web/rewrite/RewriteValve.java
===================================================================
--- trunk/java/org/jboss/web/rewrite/RewriteValve.java 2009-11-18 15:46:34 UTC (rev 1274)
+++ trunk/java/org/jboss/web/rewrite/RewriteValve.java 2009-11-18 16:56:02 UTC (rev 1275)
@@ -117,10 +117,15 @@
context = true;
is = ((Context) getContainer()).getServletContext()
.getResourceAsStream("/WEB-INF/" + resourcePath);
- if ((is == null) && (container.getLogger().isInfoEnabled())) {
- container.getLogger().info("No configuration resource found: /WEB-INF/" + resourcePath);
+ if (container.getLogger().isDebugEnabled()) {
+ if (is == null) {
+ container.getLogger().debug("No configuration resource found: /WEB-INF/" + resourcePath);
+ } else {
+ container.getLogger().debug("Read configuration from: /WEB-INF/" + resourcePath);
+ }
}
- } else {
+ }
+ if (is == null) {
String resourceName = getHostConfigPath(resourcePath);
File file = new File(getConfigBase(), resourceName);
try {
@@ -139,8 +144,8 @@
}
is = new FileInputStream(file);
}
- if ((is == null) && (container.getLogger().isInfoEnabled())) {
- container.getLogger().info("No configuration resource found: " + resourceName +
+ if ((is == null) && (container.getLogger().isDebugEnabled())) {
+ container.getLogger().debug("No configuration resource found: " + resourceName +
" in " + getConfigBase().getAbsolutePath() + " or in the classloader");
}
} catch (Exception e) {
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2009-11-18 15:46:34 UTC (rev 1274)
+++ trunk/webapps/docs/changelog.xml 2009-11-18 16:56:02 UTC (rev 1275)
@@ -136,6 +136,9 @@
<fix>
<bug>47705</bug>: Fix divide by zero in the manager sessions command. (funkman)
</fix>
+ <fix>
+ <jboss-jira>JBAS-7159</jboss-jira>: Better usability for Context level usage of RewriteValve. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
15 years, 10 months
JBossWeb SVN: r1274 - tags.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-18 10:46:34 -0500 (Wed, 18 Nov 2009)
New Revision: 1274
Added:
tags/JBOSSWEB_2_1_6_GA/
Log:
- SSL fix.
Copied: tags/JBOSSWEB_2_1_6_GA (from rev 1273, branches/2.1.x)
15 years, 10 months
JBossWeb SVN: r1273 - trunk/java/org/apache/tomcat/util/http.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-17 19:08:59 -0500 (Tue, 17 Nov 2009)
New Revision: 1273
Added:
trunk/java/org/apache/tomcat/util/http/CookieSupport.java
Modified:
trunk/java/org/apache/tomcat/util/http/BaseRequest.java
trunk/java/org/apache/tomcat/util/http/Cookies.java
trunk/java/org/apache/tomcat/util/http/ServerCookie.java
Log:
- Try out the latest cookie refactorings. Fun ;)
Modified: trunk/java/org/apache/tomcat/util/http/BaseRequest.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/BaseRequest.java 2009-11-17 19:21:47 UTC (rev 1272)
+++ trunk/java/org/apache/tomcat/util/http/BaseRequest.java 2009-11-18 00:08:59 UTC (rev 1273)
@@ -58,7 +58,7 @@
int contentLength = 0;
MessageBytes contentType = MessageBytes.newInstance();
MimeHeaders headers = new MimeHeaders();
- Cookies cookies = new Cookies();
+ Cookies cookies = new Cookies(headers);
HashMap attributes = new HashMap();
MessageBytes tomcatInstanceId = MessageBytes.newInstance();
Added: trunk/java/org/apache/tomcat/util/http/CookieSupport.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/CookieSupport.java (rev 0)
+++ trunk/java/org/apache/tomcat/util/http/CookieSupport.java 2009-11-18 00:08:59 UTC (rev 1273)
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.tomcat.util.http;
+
+
+/**
+ * Static constants for this package.
+ */
+public final class CookieSupport {
+
+
+ // --------------------------------------------------------------- Constants
+ /**
+ * If set to true, we parse cookies strictly according to the servlet,
+ * cookie and HTTP specs by default.
+ */
+ public static final boolean STRICT_SERVLET_COMPLIANCE;
+
+ /**
+ * If true, cookie values are allowed to contain an equals character without
+ * being quoted.
+ */
+ public static final boolean ALLOW_EQUALS_IN_VALUE;
+
+ /**
+ * If true, separators that are not explicitly dis-allowed by the v0 cookie
+ * spec but are disallowed by the HTTP spec will be allowed in v0 cookie
+ * names and values. These characters are: \"()/:<=>?@[\\]{} Note that the
+ * inclusion of / depend on the value of {@link #FWD_SLASH_IS_SEPARATOR}.
+ */
+ public static final boolean ALLOW_HTTP_SEPARATORS_IN_V0;
+
+ /**
+ * If set to false, we don't use the IE6/7 Max-Age/Expires work around.
+ * Default is usually true. If STRICT_SERVLET_COMPLIANCE==true then default
+ * is false. Explicitly setting always takes priority.
+ */
+ public static final boolean ALWAYS_ADD_EXPIRES;
+
+ /**
+ * If set to true, the <code>/</code> character will be treated as a
+ * separator. Default is usually false. If STRICT_SERVLET_COMPLIANCE==true
+ * then default is true. Explicitly setting always takes priority.
+ */
+ public static final boolean FWD_SLASH_IS_SEPARATOR;
+
+ /**
+ * The list of separators that apply to version 0 cookies. To quote the
+ * spec, these are comma, semi-colon and white-space. The HTTP spec
+ * definition of linear white space is [CRLF] 1*( SP | HT )
+ */
+ private static final char[] V0_SEPARATORS = {',', ';', ' ', '\t'};
+ private static final boolean[] V0_SEPARATOR_FLAGS = new boolean[128];
+
+ /**
+ * The list of separators that apply to version 1 cookies. This may or may
+ * not include '/' depending on the setting of
+ * {@link #FWD_SLASH_IS_SEPARATOR}.
+ */
+ private static final char[] HTTP_SEPARATORS;
+ private static final boolean[] HTTP_SEPARATOR_FLAGS = new boolean[128];
+
+ static {
+ STRICT_SERVLET_COMPLIANCE = Boolean.valueOf(System.getProperty(
+ "org.apache.catalina.STRICT_SERVLET_COMPLIANCE",
+ "false")).booleanValue();
+
+ ALLOW_EQUALS_IN_VALUE = Boolean.valueOf(System.getProperty(
+ "org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE",
+ "false")).booleanValue();
+
+ ALLOW_HTTP_SEPARATORS_IN_V0 = Boolean.valueOf(System.getProperty(
+ "org.apache.tomcat.util.http.ServerCookie.ALLOW_HTTP_SEPARATORS_IN_V0",
+ "false")).booleanValue();
+
+ String alwaysAddExpires = System.getProperty(
+ "org.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES");
+ if (alwaysAddExpires == null) {
+ ALWAYS_ADD_EXPIRES = !STRICT_SERVLET_COMPLIANCE;
+ } else {
+ ALWAYS_ADD_EXPIRES =
+ Boolean.valueOf(alwaysAddExpires).booleanValue();
+ }
+
+ String fwdSlashIsSeparator = System.getProperty(
+ "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR");
+ if (fwdSlashIsSeparator == null) {
+ FWD_SLASH_IS_SEPARATOR = STRICT_SERVLET_COMPLIANCE;
+ } else {
+ FWD_SLASH_IS_SEPARATOR =
+ Boolean.valueOf(fwdSlashIsSeparator).booleanValue();
+ }
+
+ /*
+ Excluding the '/' char by default violates the RFC, but
+ it looks like a lot of people put '/'
+ in unquoted values: '/': ; //47
+ '\t':9 ' ':32 '\"':34 '(':40 ')':41 ',':44 ':':58 ';':59 '<':60
+ '=':61 '>':62 '?':63 '@':64 '[':91 '\\':92 ']':93 '{':123 '}':125
+ */
+ if (CookieSupport.FWD_SLASH_IS_SEPARATOR) {
+ HTTP_SEPARATORS = new char[] { '\t', ' ', '\"', '(', ')', ',', '/',
+ ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
+ } else {
+ HTTP_SEPARATORS = new char[] { '\t', ' ', '\"', '(', ')', ',',
+ ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
+ }
+ for (int i = 0; i < 128; i++) {
+ V0_SEPARATOR_FLAGS[i] = false;
+ HTTP_SEPARATOR_FLAGS[i] = false;
+ }
+ for (int i = 0; i < V0_SEPARATORS.length; i++) {
+ V0_SEPARATOR_FLAGS[V0_SEPARATORS[i]] = true;
+ }
+ for (int i = 0; i < HTTP_SEPARATORS.length; i++) {
+ HTTP_SEPARATOR_FLAGS[HTTP_SEPARATORS[i]] = true;
+ }
+
+ }
+
+ // ----------------------------------------------------------------- Methods
+
+ /**
+ * Returns true if the byte is a separator as defined by V0 of the cookie
+ * spec.
+ */
+ public static final boolean isV0Separator(final char c) {
+ if (c < 0x20 || c >= 0x7f) {
+ if (c != 0x09) {
+ throw new IllegalArgumentException(
+ "Control character in cookie value or attribute.");
+ }
+ }
+
+ return V0_SEPARATOR_FLAGS[c];
+ }
+
+ public static boolean isV0Token(String value) {
+ if( value==null) return false;
+
+ int i = 0;
+ int len = value.length();
+
+ if (alreadyQuoted(value)) {
+ i++;
+ len--;
+ }
+
+ for (; i < len; i++) {
+ char c = value.charAt(i);
+
+ if (isV0Separator(c))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the byte is a separator as defined by V1 of the cookie
+ * spec, RFC2109.
+ * @throws IllegalArgumentException if a control character was supplied as
+ * input
+ */
+ public static final boolean isHttpSeparator(final char c) {
+ if (c < 0x20 || c >= 0x7f) {
+ if (c != 0x09) {
+ throw new IllegalArgumentException(
+ "Control character in cookie value or attribute.");
+ }
+ }
+
+ return HTTP_SEPARATOR_FLAGS[c];
+ }
+
+ public static boolean isHttpToken(String value) {
+ if( value==null) return false;
+
+ int i = 0;
+ int len = value.length();
+
+ if (alreadyQuoted(value)) {
+ i++;
+ len--;
+ }
+
+ for (; i < len; i++) {
+ char c = value.charAt(i);
+
+ if (isHttpSeparator(c))
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean alreadyQuoted (String value) {
+ if (value==null || value.length() < 2) return false;
+ return (value.charAt(0)=='\"' && value.charAt(value.length()-1)=='\"');
+ }
+
+
+
+ // ------------------------------------------------------------- Constructor
+ private CookieSupport() {
+ // Utility class. Don't allow instances to be created.
+ }
+}
Modified: trunk/java/org/apache/tomcat/util/http/Cookies.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/Cookies.java 2009-11-17 19:21:47 UTC (rev 1272)
+++ trunk/java/org/apache/tomcat/util/http/Cookies.java 2009-11-18 00:08:59 UTC (rev 1273)
@@ -19,7 +19,6 @@
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.StringTokenizer;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
@@ -47,72 +46,6 @@
MimeHeaders headers;
/**
- * If set to true, we parse cookies strictly according to the servlet,
- * cookie and HTTP specs by default.
- */
- public static final boolean STRICT_SERVLET_COMPLIANCE;
-
- /**
- * If true, cookie values are allowed to contain an equals character without
- * being quoted.
- */
- public static final boolean ALLOW_EQUALS_IN_VALUE;
-
- /**
- * If set to true, the <code>/</code> character will be treated as a
- * separator. Default is usually false. If STRICT_SERVLET_COMPLIANCE==true
- * then default is true. Explicitly setting always takes priority.
- */
- public static final boolean FWD_SLASH_IS_SEPARATOR;
-
- /*
- List of Separator Characters (see isSeparator())
- */
- public static final char SEPARATORS[];
-
- protected static final boolean separators[] = new boolean[128];
- static {
- STRICT_SERVLET_COMPLIANCE = Boolean.valueOf(System.getProperty(
- "org.apache.catalina.STRICT_SERVLET_COMPLIANCE",
- "false")).booleanValue();
-
- ALLOW_EQUALS_IN_VALUE = Boolean.valueOf(System.getProperty(
- "org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE",
- "false")).booleanValue();
-
- String fwdSlashIsSeparator = System.getProperty(
- "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR");
- if (fwdSlashIsSeparator == null) {
- FWD_SLASH_IS_SEPARATOR = STRICT_SERVLET_COMPLIANCE;
- } else {
- FWD_SLASH_IS_SEPARATOR =
- Boolean.valueOf(fwdSlashIsSeparator).booleanValue();
- }
-
- /*
- Excluding the '/' char by default violates the RFC, but
- it looks like a lot of people put '/'
- in unquoted values: '/': ; //47
- '\t':9 ' ':32 '\"':34 '(':40 ')':41 ',':44 ':':58 ';':59 '<':60
- '=':61 '>':62 '?':63 '@':64 '[':91 '\\':92 ']':93 '{':123 '}':125
- */
- if (FWD_SLASH_IS_SEPARATOR) {
- SEPARATORS = new char[] { '\t', ' ', '\"', '(', ')', ',', '/',
- ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
- } else {
- SEPARATORS = new char[] { '\t', ' ', '\"', '(', ')', ',',
- ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
- }
-
- for (int i = 0; i < 128; i++) {
- separators[i] = false;
- }
- for (int i = 0; i < SEPARATORS.length; i++) {
- separators[SEPARATORS[i]] = true;
- }
- }
-
- /**
* Construct a new cookie collection, that will extract
* the information from headers.
*
@@ -124,29 +57,6 @@
}
/**
- * Construct a new uninitialized cookie collection.
- * Use {@link #setHeaders} to initialize.
- */
- // [seguin] added so that an empty Cookies object could be
- // created, have headers set, then recycled.
- public Cookies() {
- }
-
- /**
- * Set the headers from which cookies will be pulled.
- * This has the side effect of recycling the object.
- *
- * @param headers Cookies are lazy-evaluated and will extract the
- * information from the provided headers.
- */
- // [seguin] added so that an empty Cookies object could be
- // created, have headers set, then recycled.
- public void setHeaders(MimeHeaders headers) {
- recycle();
- this.headers=headers;
- }
-
- /**
* Recycle.
*/
public void recycle() {
@@ -161,6 +71,7 @@
/**
* EXPENSIVE!!! only for debugging.
*/
+ @Override
public String toString() {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
@@ -191,11 +102,11 @@
// -------------------- Adding cookies --------------------
- /** Register a new, unitialized cookie. Cookies are recycled, and
+ /** Register a new, initialized cookie. Cookies are recycled, and
* most of the time an existing ServerCookie object is returned.
* The caller can set the name/value and attributes for the cookie
*/
- public ServerCookie addCookie() {
+ private ServerCookie addCookie() {
if( cookieCount >= scookies.length ) {
ServerCookie scookiesTmp[]=new ServerCookie[2*cookieCount];
System.arraycopy( scookies, 0, scookiesTmp, 0, cookieCount);
@@ -234,24 +145,24 @@
}
// Uncomment to test the new parsing code
- if( cookieValue.getType() == MessageBytes.T_BYTES ) {
- if(log.isDebugEnabled())
- log.debug("Cookies: Parsing b[]: " + cookieValue.toString());
- ByteChunk bc=cookieValue.getByteChunk();
- processCookieHeader( bc.getBytes(),
- bc.getOffset(),
- bc.getLength());
- } else {
- if(log.isDebugEnabled())
- log.debug("Cookies: Parsing S: " + cookieValue.toString());
- processCookieHeader( cookieValue.toString() );
+ if( cookieValue.getType() != MessageBytes.T_BYTES ) {
+ Exception e = new Exception();
+ log.warn("Cookies: Parsing cookie as String. Expected bytes.",
+ e);
+ cookieValue.toBytes();
}
+ if(log.isDebugEnabled())
+ log.debug("Cookies: Parsing b[]: " + cookieValue.toString());
+ ByteChunk bc=cookieValue.getByteChunk();
+ processCookieHeader( bc.getBytes(),
+ bc.getOffset(),
+ bc.getLength());
pos++;// search from the next position
}
}
// XXX will be refactored soon!
- public static boolean equals( String s, byte b[], int start, int end) {
+ private static boolean equals( String s, byte b[], int start, int end) {
int blen = end-start;
if (b == null || blen != s.length()) {
return false;
@@ -266,87 +177,12 @@
}
- // ---------------------------------------------------------
- // -------------------- DEPRECATED, OLD --------------------
-
- private void processCookieHeader( String cookieString )
- {
- if(log.isDebugEnabled())
- log.debug("Cookies: Parsing cookie header " + cookieString);
- // normal cookie, with a string value.
- // This is the original code, un-optimized - it shouldn't
- // happen in normal case
-
- StringTokenizer tok = new StringTokenizer(cookieString,
- ";", false);
- while (tok.hasMoreTokens()) {
- String token = tok.nextToken();
- int i = token.indexOf("=");
- if (i > -1) {
-
- // XXX
- // the trims here are a *hack* -- this should
- // be more properly fixed to be spec compliant
-
- String name = token.substring(0, i).trim();
- String value = token.substring(i+1, token.length()).trim();
- // RFC 2109 and bug
- value=stripQuote( value );
- ServerCookie cookie = addCookie();
-
- cookie.getName().setString(name);
- cookie.getValue().setString(value);
- if(log.isDebugEnabled())
- log.debug("Cookies: Add cookie " + name + "=" + value);
- } else {
- // we have a bad cookie.... just let it go
- }
- }
- }
-
/**
- *
- * Strips quotes from the start and end of the cookie string
- * This conforms to RFC 2965
- *
- * @param value a <code>String</code> specifying the cookie
- * value (possibly quoted).
- *
- * @see #setValue
- *
- */
- private static String stripQuote( String value )
- {
- // log("Strip quote from " + value );
- if (value.startsWith("\"") && value.endsWith("\"")) {
- try {
- return value.substring(1,value.length()-1);
- } catch (Exception ex) {
- }
- }
- return value;
- }
-
- /**
- * Returns true if the byte is a separator character as
- * defined in RFC2619. Since this is called often, this
- * function should be organized with the most probable
- * outcomes first.
- * JVK
- */
- public static final boolean isSeparator(final byte c) {
- if (c > 0 && c < 126)
- return separators[c];
- else
- return false;
- }
-
- /**
* Returns true if the byte is a whitespace character as
* defined in RFC2619
* JVK
*/
- public static final boolean isWhiteSpace(final byte c) {
+ private static final boolean isWhiteSpace(final byte c) {
// This switch statement is slightly slower
// for my vm than the if statement.
// Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-164)
@@ -369,12 +205,39 @@
}
/**
+ * Unescapes any double quotes in the given cookie value.
+ *
+ * @param bc The cookie value to modify
+ */
+ private static void unescapeDoubleQuotes(ByteChunk bc) {
+
+ if (bc == null || bc.getLength() == 0 || bc.indexOf('"', 0) == -1) {
+ return;
+ }
+
+ int src = bc.getStart();
+ int end = bc.getEnd();
+ int dest = src;
+ byte[] buffer = bc.getBuffer();
+
+ while (src < end) {
+ if (buffer[src] == '\\' && src < end && buffer[src+1] == '"') {
+ src++;
+ }
+ buffer[dest] = buffer[src];
+ dest ++;
+ src ++;
+ }
+ bc.setEnd(dest);
+ }
+
+ /**
* Parses a cookie header after the initial "Cookie:"
* [WS][$]token[WS]=[WS](token|QV)[;|,]
* RFC 2965
* JVK
*/
- public final void processCookieHeader(byte bytes[], int off, int len){
+ protected final void processCookieHeader(byte bytes[], int off, int len){
if( len<=0 || bytes==null ) return;
int end=off+len;
int pos=off;
@@ -393,7 +256,10 @@
// Skip whitespace and non-token characters (separators)
while (pos < end &&
- (isSeparator(bytes[pos]) || isWhiteSpace(bytes[pos])))
+ (CookieSupport.isHttpSeparator((char) bytes[pos]) &&
+ !CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 ||
+ CookieSupport.isV0Separator((char) bytes[pos]) ||
+ isWhiteSpace(bytes[pos])))
{pos++; }
if (pos >= end)
@@ -405,9 +271,9 @@
pos++;
}
- // Get the cookie name. This must be a token
+ // Get the cookie/attribute name. This must be a token
valueEnd = valueStart = nameStart = pos;
- pos = nameEnd = getTokenEndPosition(bytes,pos,end);
+ pos = nameEnd = getTokenEndPosition(bytes,pos,end,version,true);
// Skip whitespace
while (pos < end && isWhiteSpace(bytes[pos])) {pos++; }
@@ -434,7 +300,7 @@
isQuoted = true;
valueStart=pos + 1; // strip "
// getQuotedValue returns the position before
- // at the last qoute. This must be dealt with
+ // at the last quote. This must be dealt with
// when the bytes are copied into the cookie
valueEnd=getQuotedValueEndPosition(bytes,
valueStart, end);
@@ -454,19 +320,24 @@
// The position is OK (On a delimiter)
break;
default:
- if (!isSeparator(bytes[pos])) {
+ if (version == 0 &&
+ !CookieSupport.isV0Separator((char)bytes[pos]) &&
+ CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 ||
+ !CookieSupport.isHttpSeparator((char)bytes[pos]) ||
+ bytes[pos] == '=' && CookieSupport.ALLOW_EQUALS_IN_VALUE) {
// Token
valueStart=pos;
- // getToken returns the position at the delimeter
+ // getToken returns the position at the delimiter
// or other non-token character
- valueEnd=getTokenEndPosition(bytes, valueStart, end);
+ valueEnd=getTokenEndPosition(bytes, valueStart, end,
+ version, false);
// We need pos to advance
pos = valueEnd;
} else {
// INVALID COOKIE, advance to next delimiter
// The starting character of the cookie value was
// not valid.
- log.info("Cookies: Invalid cookie." +
+ log.info("Cookies: Invalid cookie. " +
"Value not a token or quoted value");
while (pos < end && bytes[pos] != ';' &&
bytes[pos] != ',')
@@ -502,23 +373,6 @@
pos++;
- /*
- if (nameEnd <= nameStart || valueEnd < valueStart ) {
- // Something is wrong, but this may be a case
- // of having two ';' characters in a row.
- // log("Cookie name/value does not conform to RFC 2965");
- // Advance to next delimiter (ignoring everything else)
- while (pos < end && bytes[pos] != ';' && bytes[pos] != ',')
- { pos++; };
- pos++;
- // Make sure no special cookies can be attributed to
- // the previous cookie by setting the current cookie
- // to null
- sc = null;
- continue;
- }
- */
-
// All checks passed. Add the cookie, start with the
// special avpairs first
if (isSpecial) {
@@ -556,14 +410,13 @@
continue;
}
-
+ // v2 cookie attributes - skip them
if (equals( "Port", bytes, nameStart, nameEnd)) {
- // sc.getPort is not currently implemented.
- // sc.getPort().setBytes( bytes,
- // valueStart,
- // valueEnd-valueStart );
continue;
}
+ if (equals( "CommentURL", bytes, nameStart, nameEnd)) {
+ continue;
+ }
// Unknown cookie, complain
log.info("Cookies: Unknown Special Cookie");
@@ -579,8 +432,7 @@
valueEnd-valueStart);
if (isQuoted) {
// We know this is a byte value so this is safe
- ServerCookie.unescapeDoubleQuotes(
- sc.getValue().getByteChunk());
+ unescapeDoubleQuotes(sc.getValue().getByteChunk());
}
} else {
// Name Only
@@ -596,11 +448,17 @@
* token, with no separator characters in between.
* JVK
*/
- public static final int getTokenEndPosition(byte bytes[], int off, int end){
+ private static final int getTokenEndPosition(byte bytes[], int off, int end,
+ int version, boolean isName){
int pos = off;
while (pos < end &&
- (!isSeparator(bytes[pos]) ||
- bytes[pos]=='=' && ALLOW_EQUALS_IN_VALUE)) {
+ (!CookieSupport.isHttpSeparator((char)bytes[pos]) ||
+ version == 0 &&
+ CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+ bytes[pos] != '=' &&
+ !CookieSupport.isV0Separator((char)bytes[pos]) ||
+ !isName && bytes[pos] == '=' &&
+ CookieSupport.ALLOW_EQUALS_IN_VALUE)) {
pos++;
}
@@ -610,11 +468,11 @@
}
/**
- * Given a starting position after an initial quote chracter, this gets
+ * Given a starting position after an initial quote character, this gets
* the position of the end quote. This escapes anything after a '\' char
* JVK RFC 2616
*/
- public static final int getQuotedValueEndPosition(byte bytes[], int off, int end){
+ private static final int getQuotedValueEndPosition(byte bytes[], int off, int end){
int pos = off;
while (pos < end) {
if (bytes[pos] == '"') {
Modified: trunk/java/org/apache/tomcat/util/http/ServerCookie.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2009-11-17 19:21:47 UTC (rev 1272)
+++ trunk/java/org/apache/tomcat/util/http/ServerCookie.java 2009-11-18 00:08:59 UTC (rev 1273)
@@ -25,7 +25,6 @@
import java.util.Locale;
import java.util.TimeZone;
-import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
@@ -40,6 +39,7 @@
*/
public class ServerCookie implements Serializable {
+ private static final long serialVersionUID = 1L;
// Version 0 (Netscape) attributes
private MessageBytes name=MessageBytes.newInstance();
@@ -59,6 +59,7 @@
"EEE, dd-MMM-yyyy HH:mm:ss z";
private static final ThreadLocal<DateFormat> OLD_COOKIE_FORMAT =
new ThreadLocal<DateFormat>() {
+ @Override
protected DateFormat initialValue() {
DateFormat df =
new SimpleDateFormat(OLD_COOKIE_PATTERN, Locale.US);
@@ -68,80 +69,21 @@
};
private static final String ancientDate;
- /**
- * If set to true, we parse cookies strictly according to the servlet,
- * cookie and HTTP specs by default.
- */
- public static final boolean STRICT_SERVLET_COMPLIANCE;
-
- /**
- * If set to false, we don't auto switch invalid v0 cookies to v1 and add
- * quotes to make them valid.
- * Default is usually true. If STRICT_SERVLET_COMPLIANCE==true then default
- * is false. Explicitly setting always takes priority.
- */
- public static final boolean ALLOW_VERSION_SWITCH;
-
- /**
- * If set to false, we don't use the IE6/7 Max-Age/Expires work around.
- * Default is usually true. If STRICT_SERVLET_COMPLIANCE==true then default
- * is false. Explicitly setting always takes priority.
- */
- public static final boolean ALWAYS_ADD_EXPIRES;
-
- /**
- * If set to true, the <code>/</code> character will be treated as a
- * separator. Default is usually false. If STRICT_SERVLET_COMPLIANCE==true
- * then default is true. Explicitly setting always takes priority.
- */
- public static final boolean FWD_SLASH_IS_SEPARATOR;
-
-
static {
ancientDate = OLD_COOKIE_FORMAT.get().format(new Date(10000));
-
- STRICT_SERVLET_COMPLIANCE = Boolean.valueOf(System.getProperty(
- "org.apache.catalina.STRICT_SERVLET_COMPLIANCE",
- "false")).booleanValue();
-
-
- String allowVersionSwitch = System.getProperty(
- "org.apache.tomcat.util.http.ServerCookie.ALLOW_VERSION_SWITCH");
- if (allowVersionSwitch == null) {
- ALLOW_VERSION_SWITCH = true;
- } else {
- ALLOW_VERSION_SWITCH =
- Boolean.valueOf(allowVersionSwitch).booleanValue();
- }
-
- String alwaysAddExpires = System.getProperty(
- "org.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES");
- if (alwaysAddExpires == null) {
- ALWAYS_ADD_EXPIRES = !STRICT_SERVLET_COMPLIANCE;
- } else {
- ALWAYS_ADD_EXPIRES =
- Boolean.valueOf(alwaysAddExpires).booleanValue();
- }
-
- String fwdSlashIsSeparator = System.getProperty(
- "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR");
- if (fwdSlashIsSeparator == null) {
- FWD_SLASH_IS_SEPARATOR = STRICT_SERVLET_COMPLIANCE;
- } else {
- FWD_SLASH_IS_SEPARATOR =
- Boolean.valueOf(fwdSlashIsSeparator).booleanValue();
- }
}
- // Note: Servlet Spec =< 2.5 only refers to Netscape and RFC2109,
+ // Note: Servlet Spec =< 3.0 only refers to Netscape and RFC2109,
// not RFC2965
- // Version 1 (RFC2965) attributes
- // TODO Add support for CommentURL
+ // Version 2 (RFC2965) attributes that would need to be added to support
+ // v2 cookies
+ // CommentURL
// Discard - implied by maxAge <0
- // TODO Add support for Port
+ // Port
public ServerCookie() {
+ // NOOP
}
public void recycle() {
@@ -203,104 +145,15 @@
// -------------------- utils --------------------
+ @Override
public String toString() {
return "Cookie " + getName() + "=" + getValue() + " ; "
+ getVersion() + " " + getPath() + " " + getDomain();
}
- private static final String tspecials = ",; ";
- private static final String tspecials2 = "()<>@,;:\\\"/[]?={} \t";
- private static final String tspecials2NoSlash = "()<>@,;:\\\"[]?={} \t";
-
- /*
- * Tests a string and returns true if the string counts as a
- * reserved token in the Java language.
- *
- * @param value the <code>String</code> to be tested
- *
- * @return <code>true</code> if the <code>String</code> is a reserved
- * token; <code>false</code> if it is not
- */
- public static boolean isToken(String value) {
- return isToken(value,null);
- }
-
- public static boolean isToken(String value, String literals) {
- String tspecials = (literals==null?ServerCookie.tspecials:literals);
- if( value==null) return true;
- int len = value.length();
-
- for (int i = 0; i < len; i++) {
- char c = value.charAt(i);
-
- if (tspecials.indexOf(c) != -1)
- return false;
- }
- return true;
- }
-
- public static boolean containsCTL(String value, int version) {
- if( value==null) return false;
- int len = value.length();
- for (int i = 0; i < len; i++) {
- char c = value.charAt(i);
- if (c < 0x20 || c >= 0x7f) {
- if (c == 0x09)
- continue; //allow horizontal tabs
- return true;
- }
- }
- return false;
- }
-
- public static boolean isToken2(String value) {
- return isToken2(value,null);
- }
-
- public static boolean isToken2(String value, String literals) {
- String tspecials2 = (literals==null?ServerCookie.tspecials2:literals);
- if( value==null) return true;
- int len = value.length();
-
- for (int i = 0; i < len; i++) {
- char c = value.charAt(i);
- if (tspecials2.indexOf(c) != -1)
- return false;
- }
- return true;
- }
-
// -------------------- Cookie parsing tools
- /**
- * Return the header name to set the cookie, based on cookie version.
- */
- public String getCookieHeaderName() {
- return getCookieHeaderName(version);
- }
-
- /**
- * Return the header name to set the cookie, based on cookie version.
- */
- public static String getCookieHeaderName(int version) {
- // TODO Re-enable logging when RFC2965 is implemented
- // log( (version==1) ? "Set-Cookie2" : "Set-Cookie");
- if (version == 1) {
- // XXX RFC2965 not referenced in Servlet Spec
- // Set-Cookie2 is not supported by Netscape 4, 6, IE 3, 5
- // Set-Cookie2 is supported by Lynx and Opera
- // Need to check on later IE and FF releases but for now...
- // RFC2109
- return "Set-Cookie";
- // return "Set-Cookie2";
- } else {
- // Old Netscape
- return "Set-Cookie";
- }
- }
-
- // TODO RFC2965 fields also need to be passed
public static void appendCookieValue( StringBuffer headerBuf,
int version,
String name,
@@ -318,41 +171,81 @@
buf.append("=");
// Servlet implementation does not check anything else
- // Switch version if allowed and a comment has been configured
- if (version == 0 && comment != null && ALLOW_VERSION_SWITCH) {
- version = 1;
+ /*
+ * The spec allows some latitude on when to send the version attribute
+ * with a Set-Cookie header. To be nice to clients, we'll make sure the
+ * version attribute is first. That means checking the various things
+ * that can cause us to switch to a v1 cookie first.
+ *
+ * Note that by checking for tokens we will also throw an exception if a
+ * control character is encountered.
+ */
+ // Start by using the version we were asked for
+ int newVersion = version;
+
+ // If it is v0, check if we need to switch
+ if (newVersion == 0 &&
+ (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+ CookieSupport.isHttpToken(value) ||
+ CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+ CookieSupport.isV0Token(value))) {
+ // HTTP token in value - need to use v1
+ newVersion = 1;
}
+
+ if (newVersion == 0 && comment != null) {
+ // Using a comment makes it a v1 cookie
+ newVersion = 1;
+ }
- version = maybeQuote2(version, buf, value,true);
+ if (newVersion == 0 &&
+ (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+ CookieSupport.isHttpToken(path) ||
+ CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+ CookieSupport.isV0Token(path))) {
+ // HTTP token in path - need to use v1
+ newVersion = 1;
+ }
+ if (newVersion == 0 &&
+ (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+ CookieSupport.isHttpToken(domain) ||
+ CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+ CookieSupport.isV0Token(domain))) {
+ // HTTP token in domain - need to use v1
+ newVersion = 1;
+ }
+
+ // Now build the cookie header
+ // Value
+ maybeQuote(buf, value);
// Add version 1 specific information
- if (version == 1) {
+ if (newVersion == 1) {
// Version=1 ... required
buf.append ("; Version=1");
// Comment=comment
if ( comment!=null ) {
buf.append ("; Comment=");
- maybeQuote2(version, buf, comment);
+ maybeQuote(buf, comment);
}
}
// Add domain information, if present
if (domain!=null) {
buf.append("; Domain=");
- maybeQuote2(version, buf, domain);
+ maybeQuote(buf, domain);
}
// Max-Age=secs ... or use old "Expires" format
- // TODO RFC2965 Discard
if (maxAge >= 0) {
- if (version > 0) {
+ if (newVersion > 0) {
buf.append ("; Max-Age=");
buf.append (maxAge);
}
// IE6, IE7 and possibly other browsers don't understand Max-Age.
// They do understand Expires, even with V1 cookies!
- if (version == 0 || ALWAYS_ADD_EXPIRES) {
+ if (newVersion == 0 || CookieSupport.ALWAYS_ADD_EXPIRES) {
// Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
buf.append ("; Expires=");
// To expire immediately we need to set the time in past
@@ -369,17 +262,7 @@
// Path=path
if (path!=null) {
buf.append ("; Path=");
- if (version==0) {
- maybeQuote2(version, buf, path);
- } else {
- if (FWD_SLASH_IS_SEPARATOR) {
- maybeQuote2(version, buf, path, ServerCookie.tspecials2,
- false);
- } else {
- maybeQuote2(version, buf, path,
- ServerCookie.tspecials2NoSlash, false);
- }
- }
+ maybeQuote(buf, path);
}
// Secure
@@ -394,51 +277,28 @@
headerBuf.append(buf);
}
- public static boolean alreadyQuoted (String value) {
- if (value==null || value.length()==0) return false;
- return (value.charAt(0)=='\"' && value.charAt(value.length()-1)=='\"');
- }
-
/**
- * Quotes values using rules that vary depending on Cookie version.
- * @param version
+ * Quotes values if required.
* @param buf
* @param value
*/
- public static int maybeQuote2 (int version, StringBuffer buf, String value) {
- return maybeQuote2(version,buf,value,false);
- }
-
- public static int maybeQuote2 (int version, StringBuffer buf, String value, boolean allowVersionSwitch) {
- return maybeQuote2(version,buf,value,null,allowVersionSwitch);
- }
-
- public static int maybeQuote2 (int version, StringBuffer buf, String value, String literals, boolean allowVersionSwitch) {
+ private static void maybeQuote (StringBuffer buf, String value) {
if (value==null || value.length()==0) {
buf.append("\"\"");
- }else if (containsCTL(value,version))
- throw new IllegalArgumentException("Control character in cookie value, consider BASE64 encoding your value");
- else if (alreadyQuoted(value)) {
+ } else if (CookieSupport.alreadyQuoted(value)) {
buf.append('"');
buf.append(escapeDoubleQuotes(value,1,value.length()-1));
buf.append('"');
- } else if (allowVersionSwitch && ALLOW_VERSION_SWITCH && version==0 && !isToken2(value, literals)) {
+ } else if (CookieSupport.isHttpToken(value) &&
+ !CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 ||
+ CookieSupport.isV0Token(value) &&
+ CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0) {
buf.append('"');
buf.append(escapeDoubleQuotes(value,0,value.length()));
buf.append('"');
- version = 1;
- } else if (version==0 && !isToken(value,literals)) {
- buf.append('"');
- buf.append(escapeDoubleQuotes(value,0,value.length()));
- buf.append('"');
- } else if (version==1 && !isToken2(value,literals)) {
- buf.append('"');
- buf.append(escapeDoubleQuotes(value,0,value.length()));
- buf.append('"');
- }else {
+ } else {
buf.append(value);
}
- return version;
}
@@ -473,31 +333,5 @@
return b.toString();
}
- /**
- * Unescapes any double quotes in the given cookie value.
- *
- * @param bc The cookie value to modify
- */
- public static void unescapeDoubleQuotes(ByteChunk bc) {
-
- if (bc == null || bc.getLength() == 0 || bc.indexOf('"', 0) == -1) {
- return;
- }
-
- int src = bc.getStart();
- int end = bc.getEnd();
- int dest = src;
- byte[] buffer = bc.getBuffer();
-
- while (src < end) {
- if (buffer[src] == '\\' && src < end && buffer[src+1] == '"') {
- src++;
- }
- buffer[dest] = buffer[src];
- dest ++;
- src ++;
- }
- bc.setEnd(dest);
- }
}
15 years, 10 months
JBossWeb SVN: r1272 - in trunk/java/javax/servlet: annotation and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-17 14:21:47 -0500 (Tue, 17 Nov 2009)
New Revision: 1272
Modified:
trunk/java/javax/servlet/AsyncContext.java
trunk/java/javax/servlet/annotation/WebServlet.java
Log:
- Javadoc update.
Modified: trunk/java/javax/servlet/AsyncContext.java
===================================================================
--- trunk/java/javax/servlet/AsyncContext.java 2009-11-17 16:19:54 UTC (rev 1271)
+++ trunk/java/javax/servlet/AsyncContext.java 2009-11-17 19:21:47 UTC (rev 1272)
@@ -341,8 +341,9 @@
/**
- * Causes the container to dispatch a thread to run the specified Runnable
- * in the {@link ServletContext} that initialized this AsyncContext.
+ * Causes the container to dispatch a thread, possibly from a managed
+ * thread pool, to run the specified <tt>Runnable</tt>. The container may
+ * propagate appropriate contextual information to the <tt>Runnable</tt>.
*
* @param run the asynchronous handler
*/
Modified: trunk/java/javax/servlet/annotation/WebServlet.java
===================================================================
--- trunk/java/javax/servlet/annotation/WebServlet.java 2009-11-17 16:19:54 UTC (rev 1271)
+++ trunk/java/javax/servlet/annotation/WebServlet.java 2009-11-17 19:21:47 UTC (rev 1272)
@@ -109,7 +109,7 @@
String description() default "";
/**
- * * The display name of the filter
+ * The display name of the servlet
*/
String displayName() default "";
15 years, 10 months
JBossWeb SVN: r1271 - branches/2.1.x/webapps/docs.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-11-17 11:19:54 -0500 (Tue, 17 Nov 2009)
New Revision: 1271
Modified:
branches/2.1.x/webapps/docs/changelog.xml
Log:
- Fix version number.
Modified: branches/2.1.x/webapps/docs/changelog.xml
===================================================================
--- branches/2.1.x/webapps/docs/changelog.xml 2009-11-17 15:46:57 UTC (rev 1270)
+++ branches/2.1.x/webapps/docs/changelog.xml 2009-11-17 16:19:54 UTC (rev 1271)
@@ -16,7 +16,7 @@
<body>
-<section name="JBoss Web 2.1.5.GA (remm)">
+<section name="JBoss Web 2.1.6.GA (remm)">
<subsection name="Coyote">
<changelog>
<fix>
15 years, 10 months