blob: ef5132ced186fb0ab292bf136237730e8c0b4311 [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed 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.warp;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Deployer;
import org.apache.catalina.Host;
import org.apache.catalina.Wrapper;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.deploy.FilterMap;
import org.apache.catalina.deploy.SecurityCollection;
import org.apache.catalina.deploy.SecurityConstraint;
public class WarpConfigurationHandler {
private static final String DEFAULT_SERVLET =
"org.apache.catalina.servlets.DefaultServlet";
/* ==================================================================== */
/* Constructor */
/* ==================================================================== */
public WarpConfigurationHandler() {
super();
}
public boolean handle(WarpConnection connection, WarpPacket packet)
throws IOException {
WarpLogger logger=new WarpLogger(this);
logger.setContainer(connection.getConnector().getContainer());
// Prepare the Welcome packet
packet.setType(Constants.TYPE_CONF_WELCOME);
packet.writeUnsignedShort(Constants.VERS_MAJOR);
packet.writeUnsignedShort(Constants.VERS_MINOR);
packet.writeInteger(connection.getConnector().uniqueId);
connection.send(packet);
// Loop for configuration packets
while (true) {
connection.recv(packet);
switch (packet.getType()) {
case Constants.TYPE_CONF_DEPLOY: {
String appl=packet.readString();
String host=packet.readString();
int port=packet.readUnsignedShort();
String path=packet.readString();
Context context=null;
packet.reset();
if (Constants.DEBUG)
logger.log("Deploying web application \""+appl+"\" "+
"under <http://"+host+":"+port+path+">");
try {
context=deploy(connection,logger,appl,host,path);
} catch (Exception e) {
logger.log(e);
}
if (context==null) {
String msg="Error deploying web application \""+appl+
"\" under <http://"+host+":"+port+path+">";
logger.log(msg);
packet.setType(Constants.TYPE_ERROR);
packet.writeString(msg);
connection.send(packet);
break;
}
int k=connection.getConnector().applicationId(context);
packet.setType(Constants.TYPE_CONF_APPLIC);
packet.writeInteger(k);
packet.writeString(context.getDocBase());
connection.send(packet);
if (Constants.DEBUG)
logger.debug("Application \""+appl+"\" deployed "+
"under <http://"+host+":"+port+path+
"> with root="+context.getDocBase()+
" ID="+k);
break;
}
case Constants.TYPE_CONF_MAP: {
int id=packet.readInteger();
Context context=connection.getConnector()
.applicationContext(id);
if (context==null) {
String msg="Invalid application ID for mappings "+id;
logger.log(msg);
packet.reset();
packet.setType(Constants.TYPE_ERROR);
packet.writeString(msg);
connection.send(packet);
break;
}
String smap[]=context.findServletMappings();
if (smap!=null) {
for (int x=0; x<smap.length; x++) {
Container c=context.findChild(
context.findServletMapping(smap[x]));
packet.reset();
packet.setType(Constants.TYPE_CONF_MAP_DENY);
packet.writeString(smap[x]);
if (c instanceof Wrapper) {
String servlet=((Wrapper)c).getServletClass();
if (DEFAULT_SERVLET.equals(servlet)) {
packet.setType(
Constants.TYPE_CONF_MAP_ALLOW);
if (Constants.DEBUG)
logger.debug("Servlet mapping \""+
smap[x]+"\" allowed");
} else if (Constants.DEBUG) {
logger.debug("Servlet mapping \""+smap[x]+
"\" denied");
}
}
connection.send(packet);
}
}
FilterMap fmap[]=context.findFilterMaps();
if (fmap!=null) {
logger.log("Filter mappings ("+fmap.length+")");
for (int x=0; x<fmap.length; x++) {
String map=fmap[x].getURLPattern();
if (map!=null) {
if (Constants.DEBUG)
logger.debug("Filter mapping \""+map+
"\" denied");
packet.reset();
packet.setType(Constants.TYPE_CONF_MAP_DENY);
packet.writeString(map);
connection.send(packet);
}
}
}
SecurityConstraint scon[]=context.findConstraints();
if (scon!=null) {
for (int x=0; x<scon.length; x++) {
SecurityCollection col[]=scon[x].findCollections();
if (col!=null) {
for (int y=0; y<col.length; y++) {
String patt[]=col[y].findPatterns();
if (patt!=null) {
for (int q=0; q<patt.length; q++) {
packet.reset();
packet.setType(
Constants.TYPE_CONF_MAP_DENY);
packet.writeString(patt[q]);
connection.send(packet);
if (Constants.DEBUG) {
logger.debug("Seurity "+
" mapping \""+patt[q]+
"\"");
}
}
}
}
}
}
}
packet.reset();
packet.setType(Constants.TYPE_CONF_MAP_DONE);
connection.send(packet);
break;
}
case Constants.TYPE_CONF_DONE: {
return(true);
}
case Constants.TYPE_DISCONNECT: {
return(false);
}
default: {
String msg="Invalid packet with type "+packet.getType();
logger.log(msg);
packet.reset();
packet.setType(Constants.TYPE_FATAL);
packet.writeString(msg);
connection.send(packet);
return(false);
}
}
}
}
/** Deploy a web application */
private Context deploy(WarpConnection connection, WarpLogger logger,
String applName, String hostName, String applPath)
throws IOException {
synchronized (connection.getConnector()) {
Container container=connection.getConnector().getContainer();
// the hostName should be in lowewr case (setName makes a toLowerCase).
Host host=(Host)container.findChild(hostName.toLowerCase());
if (host==null) {
WarpHost whost=new WarpHost();
whost.setName(hostName);
whost.setParent(container);
whost.setAppBase(connection.getConnector().getAppBase());
whost.setDebug(connection.getConnector().getDebug());
container.addChild(whost);
host=whost;
if (Constants.DEBUG)
logger.debug("Created new host "+host.getName());
} else if (Constants.DEBUG) {
logger.debug("Reusing instance of Host \""+host.getName()+"\"");
}
// TODO: Set up mapping mechanism for performance
if (applPath.endsWith("/"))
applPath=applPath.substring(0,applPath.length()-1);
Context appl=(Context)host.findChild(applPath);
if (appl==null) {
if (Constants.DEBUG)
logger.debug("No application for \""+applPath+"\"");
Deployer deployer=(Deployer)host;
File file=new File(applName);
if (!file.isAbsolute()) {
file=new File(host.getAppBase()+File.separator+applName);
if (!file.isAbsolute()) {
file=new File(System.getProperty("catalina.base"),
host.getAppBase()+File.separator+applName);
}
}
if (!file.exists()) {
logger.log("Cannot find \""+file.getPath()+"\" for appl. \""+
applName+"\" host \""+host.getName()+"\"");
return(null);
}
String path=file.getCanonicalPath();
URL url=new URL("file",null,path);
if (path.toLowerCase().endsWith(".war"))
url=new URL("jar:"+url.toString()+"!/");
if (Constants.DEBUG)
logger.debug("Application URL \""+url.toString()+"\"");
deployer.install(applPath, url);
StandardContext context=null;
context=(StandardContext)deployer.findDeployedApp(applPath);
context.setDebug(connection.getConnector().getDebug());
return(context);
} else {
if (Constants.DEBUG)
logger.debug("Found application for \""+appl.getName()+"\"");
return(appl);
}
}
}
}