diff --git a/apps/jetty/java/src/org/mortbay/http/HttpContext.java b/apps/jetty/java/src/org/mortbay/http/HttpContext.java
deleted file mode 100644
index 1ae1a08b6e..0000000000
--- a/apps/jetty/java/src/org/mortbay/http/HttpContext.java
+++ /dev/null
@@ -1,2198 +0,0 @@
-// ========================================================================
-// $Id: HttpContext.java,v 1.136 2006/02/21 09:47:43 gregwilkins Exp $
-// Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// 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.mortbay.http;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.Socket;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.UnknownHostException;
-import java.security.Permission;
-import java.security.PermissionCollection;
-import java.security.Permissions;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.apache.commons.logging.Log;
-import org.mortbay.log.LogFactory;
-import org.mortbay.http.ResourceCache.ResourceMetaData;
-import org.mortbay.http.handler.ErrorPageHandler;
-import org.mortbay.util.Container;
-import org.mortbay.util.EventProvider;
-import org.mortbay.util.IO;
-import org.mortbay.util.LazyList;
-import org.mortbay.util.LifeCycle;
-import org.mortbay.util.LogSupport;
-import org.mortbay.util.MultiException;
-import org.mortbay.util.Resource;
-import org.mortbay.util.URI;
-
-
-/* ------------------------------------------------------------ */
-/** Context for a collection of HttpHandlers.
- * HTTP Context provides an ordered container for HttpHandlers
- * that share the same path prefix, filebase, resourcebase and/or
- * classpath.
- *
- * A HttpContext is analagous to a ServletContext in the
- * Servlet API, except that it may contain other types of handler
- * other than servlets.
- *
- * A ClassLoader is created for the context and it uses
- * Thread.currentThread().getContextClassLoader(); as it's parent loader.
- * The class loader is initialized during start(), when a derived
- * context calls initClassLoader() or on the first call to loadClass()
- *
- *
- * Note. that order is important when configuring a HttpContext.
- * For example, if resource serving is enabled before servlets, then resources
- * take priority.
- *
- * @see HttpServer
- * @see HttpHandler
- * @see org.mortbay.jetty.servlet.ServletHttpContext
- * @version $Id: HttpContext.java,v 1.136 2006/02/21 09:47:43 gregwilkins Exp $
- * @author Greg Wilkins (gregw)
- */
-public class HttpContext extends Container
- implements LifeCycle,
- HttpHandler,
- EventProvider,
- Serializable
-{
- private static Log log = LogFactory.getLog(HttpContext.class);
-
- /* ------------------------------------------------------------ */
- /** File class path attribute.
- * If this name is set as a context init parameter, then the attribute
- * name given will be used to set the file classpath for the context as a
- * context attribute.
- */
- public final static String __fileClassPathAttr=
- "org.mortbay.http.HttpContext.FileClassPathAttribute";
-
- public final static String __ErrorHandler=
- "org.mortbay.http.ErrorHandler";
-
-
- /* ------------------------------------------------------------ */
- /* ------------------------------------------------------------ */
- // These attributes are serialized by WebApplicationContext, which needs
- // to be updated if you add to these
- private String _contextPath;
- private List _vhosts=new ArrayList(2);
- private List _hosts=new ArrayList(2);
- private List _handlers=new ArrayList(3);
- private Map _attributes = new HashMap(3);
- private boolean _redirectNullPath=true;
- private boolean _statsOn=false;
- private PermissionCollection _permissions;
- private boolean _classLoaderJava2Compliant=true;
- private ResourceCache _resources;
- private String[] _systemClasses=new String [] {"java.","javax.servlet.","javax.xml.","org.mortbay.","org.xml.","org.w3c.","org.apache.commons.logging."};
- private String[] _serverClasses = new String[] {"-org.mortbay.http.PathMap","-org.mortbay.jetty.servlet.Invoker","-org.mortbay.jetty.servlet.JSR154Filter","-org.mortbay.jetty.servlet.Default","org.mortbay.jetty.Server","org.mortbay.http.","org.mortbay.start.","org.mortbay.stop."};
-
- /* ------------------------------------------------------------ */
- private String _contextName;
- private String _classPath;
- private Map _initParams = new HashMap(11);
- private UserRealm _userRealm;
- private String _realmName;
- private PathMap _constraintMap=new PathMap();
- private Authenticator _authenticator;
- private RequestLog _requestLog;
-
-
- private String[] _welcomes=
- {
- "welcome.html",
- "index.html",
- "index.htm",
- "index.jsp"
- };
-
-
- /* ------------------------------------------------------------ */
- private transient boolean _gracefulStop;
- private transient ClassLoader _parent;
- private transient ClassLoader _loader;
- private transient HttpServer _httpServer;
- private transient File _tmpDir;
- private transient HttpHandler[] _handlersArray;
- private transient String[] _vhostsArray;
-
-
- /* ------------------------------------------------------------ */
- transient Object _statsLock=new Object[0];
- transient long _statsStartedAt;
- transient int _requests;
- transient int _requestsActive;
- transient int _requestsActiveMax;
- transient int _responses1xx; // Informal
- transient int _responses2xx; // Success
- transient int _responses3xx; // Redirection
- transient int _responses4xx; // Client Error
- transient int _responses5xx; // Server Error
-
-
- /* ------------------------------------------------------------ */
- /** Constructor.
- */
- public HttpContext()
- {
- setAttribute(__ErrorHandler, new ErrorPageHandler());
- _resources=new ResourceCache();
- addComponent(_resources);
- }
-
- /* ------------------------------------------------------------ */
- /** Constructor.
- * @param httpServer
- * @param contextPathSpec
- */
- public HttpContext(HttpServer httpServer,String contextPathSpec)
- {
- this();
- setHttpServer(httpServer);
- setContextPath(contextPathSpec);
- }
-
- /* ------------------------------------------------------------ */
- private void readObject(java.io.ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
- _statsLock=new Object[0];
- getHandlers();
- for (int i=0;i<_handlersArray.length;i++)
- _handlersArray[i].initialize(this);
- }
-
- /* ------------------------------------------------------------ */
- /** Get the ThreadLocal HttpConnection.
- * Get the HttpConnection for current thread, if any. This method is
- * not static in order to control access.
- * @return HttpConnection for this thread.
- */
- public HttpConnection getHttpConnection()
- {
- return HttpConnection.getHttpConnection();
- }
-
- /* ------------------------------------------------------------ */
- void setHttpServer(HttpServer httpServer)
- {
- _httpServer=httpServer;
- _contextName=null;
-
- }
-
- /* ------------------------------------------------------------ */
- public HttpServer getHttpServer()
- {
- return _httpServer;
- }
-
- /* ------------------------------------------------------------ */
- public void setStopGracefully(boolean graceful)
- {
- _gracefulStop=graceful;
- }
-
- /* ------------------------------------------------------------ */
- public boolean getStopGracefully()
- {
- return _gracefulStop;
- }
-
-
- /* ------------------------------------------------------------ */
- public static String canonicalContextPathSpec(String contextPathSpec)
- {
- // check context path
- if (contextPathSpec==null ||
- contextPathSpec.indexOf(',')>=0 ||
- contextPathSpec.startsWith("*"))
- throw new IllegalArgumentException ("Illegal context spec:"+contextPathSpec);
-
- if(!contextPathSpec.startsWith("/"))
- contextPathSpec='/'+contextPathSpec;
-
- if (contextPathSpec.length()>1)
- {
- if (contextPathSpec.endsWith("/"))
- contextPathSpec+="*";
- else if (!contextPathSpec.endsWith("/*"))
- contextPathSpec+="/*";
- }
-
- return contextPathSpec;
- }
-
- /* ------------------------------------------------------------ */
- public void setContextPath(String contextPathSpec)
- {
- if (_httpServer!=null)
- _httpServer.removeMappings(this);
-
- contextPathSpec=canonicalContextPathSpec(contextPathSpec);
-
- if (contextPathSpec.length()>1)
- _contextPath=contextPathSpec.substring(0,contextPathSpec.length()-2);
- else
- _contextPath="/";
-
- _contextName=null;
-
- if (_httpServer!=null)
- _httpServer.addMappings(this);
- }
-
-
- /* ------------------------------------------------------------ */
- /**
- * @return The context prefix
- */
- public String getContextPath()
- {
- return _contextPath;
- }
-
-
- /* ------------------------------------------------------------ */
- /** Add a virtual host alias to this context.
- * @see #setVirtualHosts
- * @param hostname A hostname. A null host name means any hostname is
- * acceptable. Host names may String representation of IP addresses.
- */
- public void addVirtualHost(String hostname)
- {
- // Note that null hosts are also added.
- if (!_vhosts.contains(hostname))
- {
- _vhosts.add(hostname);
- _contextName=null;
-
- if (_httpServer!=null)
- {
- if (_vhosts.size()==1)
- _httpServer.removeMapping(null,this);
- _httpServer.addMapping(hostname,this);
- }
- _vhostsArray=null;
- }
- }
-
- /* ------------------------------------------------------------ */
- /** remove a virtual host alias to this context.
- * @see #setVirtualHosts
- * @param hostname A hostname. A null host name means any hostname is
- * acceptable. Host names may String representation of IP addresses.
- */
- public void removeVirtualHost(String hostname)
- {
- // Note that null hosts are also added.
- if (_vhosts.remove(hostname))
- {
- _contextName=null;
- if (_httpServer!=null)
- {
- _httpServer.removeMapping(hostname,this);
- if (_vhosts.size()==0)
- _httpServer.addMapping(null,this);
- }
- _vhostsArray=null;
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Set the virtual hosts for the context.
- * Only requests that have a matching host header or fully qualified
- * URL will be passed to that context with a virtual host name.
- * A context with no virtual host names or a null virtual host name is
- * available to all requests that are not served by a context with a
- * matching virtual host name.
- * @param hosts Array of virtual hosts that this context responds to. A
- * null host name or null/empty array means any hostname is acceptable.
- * Host names may String representation of IP addresses.
- */
- public void setVirtualHosts(String[] hosts)
- {
- List old = new ArrayList(_vhosts);
-
- if (hosts!=null)
- {
- for (int i=0;i0)
- buf.append(File.pathSeparator);
- buf.append(iter.next().toString());
- }
-
- if (log.isDebugEnabled()) log.debug("fileClassPath="+buf);
- return buf.toString();
- }
-
- /* ------------------------------------------------------------ */
- /** Sets the class path for the context.
- * A class path is only required for a context if it uses classes
- * that are not in the system class path.
- * @param classPath a comma or ';' separated list of class
- * resources. These may be jar files, directories or URLs to jars
- * or directories.
- */
- public void setClassPath(String classPath)
- {
- _classPath=classPath;
- if (isStarted())
- log.warn("classpath set while started");
- }
-
- /* ------------------------------------------------------------ */
- /** Add the class path element to the context.
- * A class path is only required for a context if it uses classes
- * that are not in the system class path.
- * @param classPath a comma or ';' separated list of class
- * resources. These may be jar files, directories or URLs to jars
- * or directories.
- */
- public void addClassPath(String classPath)
- {
- if (_classPath==null || _classPath.length()==0)
- _classPath=classPath;
- else
- _classPath+=","+classPath;
-
- if (isStarted())
- log.warn("classpath set while started");
- }
-
- /* ------------------------------------------------------------ */
- /** Add elements to the class path for the context from the jar and zip files found
- * in the specified resource.
- * @param lib the resource that contains the jar and/or zip files.
- * @param append true if the classpath entries are to be appended to any
- * existing classpath, or false if they replace the existing classpath.
- * @see #setClassPath(String)
- */
- public void addClassPaths(Resource lib)
- {
- if (isStarted())
- log.warn("classpaths set while started");
-
- if (lib.exists() && lib.isDirectory())
- {
- String[] files=lib.list();
- for (int f=0;files!=null && f0)
- {
- Object o = request.getHttpConnection().getConnection();
- if (o instanceof Socket)
- {
- Socket s=(Socket)o;
- if (!_hosts.contains(s.getLocalAddress()))
- {
- if(log.isDebugEnabled())log.debug(s.getLocalAddress()+" not in "+_hosts);
- return;
- }
- }
- }
-
- // handle stats
- if (_statsOn)
- {
- synchronized(_statsLock)
- {
- _requests++;
- _requestsActive++;
- if (_requestsActive>_requestsActiveMax)
- _requestsActiveMax=_requestsActive;
- }
- }
-
- String pathInContext = URI.canonicalPath(request.getPath());
- if (pathInContext==null)
- {
- // Must be a bad request.
- throw new HttpException(HttpResponse.__400_Bad_Request);
- }
-
- if (_contextPath.length()>1)
- pathInContext=pathInContext.substring(_contextPath.length());
-
- if (_redirectNullPath && (pathInContext==null ||
- pathInContext.length()==0))
- {
- StringBuffer buf=request.getRequestURL();
- buf.append("/");
- String q=request.getQuery();
- if (q!=null&&q.length()!=0)
- buf.append("?"+q);
-
- response.sendRedirect(buf.toString());
- if (log.isDebugEnabled())
- log.debug(this+" consumed all of path "+
- request.getPath()+
- ", redirect to "+buf.toString());
- return;
- }
-
- String pathParams=null;
- int semi = pathInContext.lastIndexOf(';');
- if (semi>=0)
- {
- int pl = pathInContext.length()-semi;
- String ep=request.getEncodedPath();
- if(';'==ep.charAt(ep.length()-pl))
- {
- pathParams=pathInContext.substring(semi+1);
- pathInContext=pathInContext.substring(0,semi);
- }
- }
-
- try
- {
- handle(pathInContext,pathParams,request,response);
- }
- finally
- {
- if (_userRealm!=null && request.hasUserPrincipal())
- _userRealm.disassociate(request.getUserPrincipal());
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Handler request.
- * Call each HttpHandler until request is handled.
- * @param pathInContext Path in context
- * @param pathParams Path parameters such as encoded Session ID
- * @param request
- * @param response
- * @return True if the request has been handled.
- * @exception HttpException
- * @exception IOException
- */
- public void handle(String pathInContext,
- String pathParams,
- HttpRequest request,
- HttpResponse response)
- throws HttpException, IOException
- {
- Object old_scope= null;
- try
- {
- old_scope= enterContextScope(request,response);
- HttpHandler[] handlers= getHandlers();
- for (int k= 0; k < handlers.length; k++)
- {
- HttpHandler handler= handlers[k];
- if (handler == null)
- {
- handlers= getHandlers();
- k= -1;
- continue;
- }
- if (!handler.isStarted())
- {
- if (log.isDebugEnabled())
- log.debug(handler + " not started in " + this);
- continue;
- }
- if (log.isDebugEnabled())
- log.debug("Handler " + handler);
- handler.handle(pathInContext, pathParams, request, response);
- if (request.isHandled())
- {
- if (log.isDebugEnabled())
- log.debug("Handled by " + handler);
- return;
- }
- }
- return;
- }
- finally
- {
- leaveContextScope(request, response, old_scope);
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Enter the context scope.
- * This method is called (by handle or servlet dispatchers) to indicate that
- * request handling is entering the scope of this context. The opaque scope object
- * returned, should be passed to the leaveContextScope method.
- */
- public Object enterContextScope(HttpRequest request, HttpResponse response)
- {
- // Save the thread context loader
- Thread thread = Thread.currentThread();
- ClassLoader cl=thread.getContextClassLoader();
- HttpContext c=response.getHttpContext();
-
- Scope scope=null;
- if (cl!=HttpContext.class.getClassLoader() || c!=null)
- {
- scope=new Scope();
- scope._classLoader=cl;
- scope._httpContext=c;
- }
-
- if (_loader!=null)
- thread.setContextClassLoader(_loader);
- response.setHttpContext(this);
-
- return scope;
- }
-
- /* ------------------------------------------------------------ */
- /** Leave the context scope.
- * This method is called (by handle or servlet dispatchers) to indicate that
- * request handling is leaveing the scope of this context. The opaque scope object
- * returned by enterContextScope should be passed in.
- */
- public void leaveContextScope(HttpRequest request, HttpResponse response,Object oldScope)
- {
- if (oldScope==null)
- {
- Thread.currentThread()
- .setContextClassLoader(HttpContext.class.getClassLoader());
- response.setHttpContext(null);
- }
- else
- {
- Scope old = (Scope)oldScope;
- Thread.currentThread().setContextClassLoader(old._classLoader);
- response.setHttpContext(old._httpContext);
- }
- }
-
-
- /* ------------------------------------------------------------ */
- public String getHttpContextName()
- {
- if (_contextName==null)
- _contextName = (_vhosts.size()>1?(_vhosts.toString()+":"):"")+_contextPath;
- return _contextName;
- }
-
- /* ------------------------------------------------------------ */
- public void setHttpContextName(String s)
- {
- _contextName=s;
- }
-
- /* ------------------------------------------------------------ */
- public String toString()
- {
- return "HttpContext["+getContextPath()+","+getHttpContextName()+"]";
- }
-
- /* ------------------------------------------------------------ */
- public String toString(boolean detail)
- {
- return "HttpContext["+getContextPath()+","+getHttpContextName()+"]" +
- (detail?("="+_handlers):"");
- }
-
-
- /* ------------------------------------------------------------ */
- protected synchronized void doStart()
- throws Exception
- {
- if (isStarted())
- return;
-
- if (_httpServer.getServerClasses()!=null)
- _serverClasses=_httpServer.getServerClasses();
- if (_httpServer.getSystemClasses()!=null)
- _systemClasses=_httpServer.getSystemClasses();
-
- _resources.start();
-
- statsReset();
-
- if (_httpServer==null)
- throw new IllegalStateException("No server for "+this);
-
- // start the context itself
- _resources.getMimeMap();
- _resources.getEncodingMap();
-
- // Setup realm
- if (_userRealm==null && _authenticator!=null)
- {
- _userRealm=_httpServer.getRealm(_realmName);
- if (_userRealm==null)
- log.warn("No Realm: "+_realmName);
- }
-
- // setup the context loader
- initClassLoader(false);
-
- // Set attribute if needed
- String attr = getInitParameter(__fileClassPathAttr);
- if (attr!=null && attr.length()>0)
- setAttribute(attr,getFileClassPath());
-
- // Start the handlers
- Thread thread = Thread.currentThread();
- ClassLoader lastContextLoader=thread.getContextClassLoader();
- try
- {
- if (_loader!=null)
- thread.setContextClassLoader(_loader);
-
- if (_requestLog!=null)
- _requestLog.start();
-
- startHandlers();
- }
- finally
- {
- thread.setContextClassLoader(lastContextLoader);
- getHandlers();
- }
-
- }
-
- /* ------------------------------------------------------------ */
- /** Start the handlers.
- * This is called by start after the classloader has been
- * initialized and set as the thread context loader.
- * It may be specialized to provide custom handling
- * before any handlers are started.
- * @exception Exception
- */
- protected void startHandlers()
- throws Exception
- {
- // Prepare a multi exception
- MultiException mx = new MultiException();
-
- Iterator handlers = _handlers.iterator();
- while(handlers.hasNext())
- {
- HttpHandler handler=(HttpHandler)handlers.next();
- if (!handler.isStarted())
- try{handler.start();}catch(Exception e){mx.add(e);}
- }
- mx.ifExceptionThrow();
- }
-
- /* ------------------------------------------------------------ */
- /** Stop the context.
- * @param graceful If true and statistics are on, then this method will wait
- * for requestsActive to go to zero before calling stop()
- */
- public void stop(boolean graceful)
- throws InterruptedException
- {
- boolean gs=_gracefulStop;
- try
- {
- _gracefulStop=true;
-
- // wait for all requests to complete.
- while (graceful && _statsOn && _requestsActive>0 && _httpServer!=null)
- try {Thread.sleep(100);}
- catch (InterruptedException e){throw e;}
- catch (Exception e){LogSupport.ignore(log,e);}
-
- stop();
- }
- finally
- {
- _gracefulStop=gs;
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Stop the context.
- */
- protected void doStop()
- throws Exception
- {
- if (_httpServer==null)
- throw new InterruptedException("Destroy called");
-
- synchronized(this)
- {
- // Notify the container for the stop
- Thread thread = Thread.currentThread();
- ClassLoader lastContextLoader=thread.getContextClassLoader();
- try
- {
- if (_loader!=null)
- thread.setContextClassLoader(_loader);
- Iterator handlers = _handlers.iterator();
- while(handlers.hasNext())
- {
- HttpHandler handler=(HttpHandler)handlers.next();
- if (handler.isStarted())
- {
- try{handler.stop();}
- catch(Exception e){log.warn(LogSupport.EXCEPTION,e);}
- }
- }
-
- if (_requestLog!=null)
- _requestLog.stop();
- }
- finally
- {
- thread.setContextClassLoader(lastContextLoader);
- }
-
- // TODO this is a poor test
- if (_loader instanceof ContextLoader)
- {
- ((ContextLoader)_loader).destroy();
- LogFactory.release(_loader);
- }
-
- _loader=null;
- }
- _resources.flushCache();
- _resources.stop();
- }
-
-
- /* ------------------------------------------------------------ */
- /** Destroy a context.
- * Destroy a context and remove it from the HttpServer. The
- * HttpContext must be stopped before it can be destroyed.
- */
- public void destroy()
- {
- if (isStarted())
- throw new IllegalStateException("Started");
-
- if (_httpServer!=null)
- _httpServer.removeContext(this);
-
- _httpServer=null;
-
- if (_handlers!=null)
- _handlers.clear();
-
- _handlers=null;
- _parent=null;
- _loader=null;
- if (_attributes!=null)
- _attributes.clear();
- _attributes=null;
- if (_initParams!=null)
- _initParams.clear();
- _initParams=null;
- if (_vhosts!=null)
- _vhosts.clear();
- _vhosts=null;
- _hosts=null;
- _tmpDir=null;
-
- _permissions=null;
-
- removeComponent(_resources);
- if (_resources!=null)
- {
- _resources.flushCache();
- if (_resources.isStarted())
- try{_resources.stop();}catch(Exception e){LogSupport.ignore(log,e);}
- _resources.destroy();
- }
- _resources=null;
-
- super.destroy();
-
- }
-
-
- /* ------------------------------------------------------------ */
- /** Set the request log.
- * @param log RequestLog to use.
- */
- public void setRequestLog(RequestLog log)
- {
- _requestLog=log;
- }
-
- /* ------------------------------------------------------------ */
- public RequestLog getRequestLog()
- {
- return _requestLog;
- }
-
-
- /* ------------------------------------------------------------ */
- /** Send an error response.
- * This method may be specialized to provide alternative error handling for
- * errors generated by the container. The default implemenation calls HttpResponse.sendError
- * @param response the response to send
- * @param code The error code
- * @param msg The message for the error or null for the default
- * @throws IOException Problem sending response.
- */
- public void sendError(HttpResponse response,int code,String msg)
- throws IOException
- {
- response.sendError(code,msg);
- }
-
- /* ------------------------------------------------------------ */
- /** Send an error response.
- * This method obtains the responses context and call sendError for context specific
- * error handling.
- * @param response the response to send
- * @param code The error code
- * @param msg The message for the error or null for the default
- * @throws IOException Problem sending response.
- */
- public static void sendContextError(HttpResponse response,int code,String msg)
- throws IOException
- {
- HttpContext context = response.getHttpContext();
- if (context!=null)
- context.sendError(response,code,msg);
- else
- response.sendError(code,msg);
- }
-
- /* ------------------------------------------------------------ */
- /** True set statistics recording on for this context.
- * @param on If true, statistics will be recorded for this context.
- */
- public void setStatsOn(boolean on)
- {
- log.info("setStatsOn "+on+" for "+this);
- _statsOn=on;
- statsReset();
- }
-
- /* ------------------------------------------------------------ */
- public boolean getStatsOn() {return _statsOn;}
-
- /* ------------------------------------------------------------ */
- public long getStatsOnMs()
- {return _statsOn?(System.currentTimeMillis()-_statsStartedAt):0;}
-
- /* ------------------------------------------------------------ */
- public void statsReset()
- {
- synchronized(_statsLock)
- {
- if (_statsOn)
- _statsStartedAt=System.currentTimeMillis();
- _requests=0;
- _requestsActiveMax=_requestsActive;
- _responses1xx=0;
- _responses2xx=0;
- _responses3xx=0;
- _responses4xx=0;
- _responses5xx=0;
- }
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return Get the number of requests handled by this context
- * since last call of statsReset(). If setStatsOn(false) then this
- * is undefined.
- */
- public int getRequests() {return _requests;}
-
- /* ------------------------------------------------------------ */
- /**
- * @return Number of requests currently active.
- * Undefined if setStatsOn(false).
- */
- public int getRequestsActive() {return _requestsActive;}
-
- /* ------------------------------------------------------------ */
- /**
- * @return Maximum number of active requests
- * since statsReset() called. Undefined if setStatsOn(false).
- */
- public int getRequestsActiveMax() {return _requestsActiveMax;}
-
- /* ------------------------------------------------------------ */
- /**
- * @return Get the number of responses with a 2xx status returned
- * by this context since last call of statsReset(). Undefined if
- * if setStatsOn(false).
- */
- public int getResponses1xx() {return _responses1xx;}
-
- /* ------------------------------------------------------------ */
- /**
- * @return Get the number of responses with a 100 status returned
- * by this context since last call of statsReset(). Undefined if
- * if setStatsOn(false).
- */
- public int getResponses2xx() {return _responses2xx;}
-
- /* ------------------------------------------------------------ */
- /**
- * @return Get the number of responses with a 3xx status returned
- * by this context since last call of statsReset(). Undefined if
- * if setStatsOn(false).
- */
- public int getResponses3xx() {return _responses3xx;}
-
- /* ------------------------------------------------------------ */
- /**
- * @return Get the number of responses with a 4xx status returned
- * by this context since last call of statsReset(). Undefined if
- * if setStatsOn(false).
- */
- public int getResponses4xx() {return _responses4xx;}
-
- /* ------------------------------------------------------------ */
- /**
- * @return Get the number of responses with a 5xx status returned
- * by this context since last call of statsReset(). Undefined if
- * if setStatsOn(false).
- */
- public int getResponses5xx() {return _responses5xx;}
-
-
- /* ------------------------------------------------------------ */
- /** Log a request and response.
- * Statistics are also collected by this method.
- * @param request
- * @param response
- */
- public void log(HttpRequest request,
- HttpResponse response,
- int length)
- {
- if (_statsOn)
- {
- synchronized(_statsLock)
- {
- if (--_requestsActive<0)
- _requestsActive=0;
-
- if (response!=null)
- {
- switch(response.getStatus()/100)
- {
- case 1: _responses1xx++;break;
- case 2: _responses2xx++;break;
- case 3: _responses3xx++;break;
- case 4: _responses4xx++;break;
- case 5: _responses5xx++;break;
- }
- }
- }
- }
-
- if (_requestLog!=null &&
- request!=null &&
- response!=null)
- _requestLog.log(request,response,length);
- else if (_httpServer!=null)
- _httpServer.log(request,response,length);
- }
-
-
-
- /* ------------------------------------------------------------ */
- /* Class to save scope of nested context calls
- */
- private static class Scope
- {
- ClassLoader _classLoader;
- HttpContext _httpContext;
- }
-
- /*
- * @see org.mortbay.http.HttpHandler#getName()
- */
- public String getName()
- {
- return this.getContextPath();
- }
-
- /*
- * @see org.mortbay.http.HttpHandler#getHttpContext()
- */
- public HttpContext getHttpContext()
- {
- return this;
- }
-
- /*
- * @see org.mortbay.http.HttpHandler#initialize(org.mortbay.http.HttpContext)
- */
- public void initialize(HttpContext context)
- {
- throw new UnsupportedOperationException();
- }
-
-
- /**
- * @return
- */
- public Resource getBaseResource()
- {
- return _resources.getBaseResource();
- }
- /**
- * @param type
- * @return
- */
- public String getEncodingByMimeType(String type)
- {
- return _resources.getEncodingByMimeType(type);
- }
- /**
- * @return
- */
- public Map getEncodingMap()
- {
- return _resources.getEncodingMap();
- }
- /**
- * @return
- */
- public int getMaxCachedFileSize()
- {
- return _resources.getMaxCachedFileSize();
- }
- /**
- * @return
- */
- public int getMaxCacheSize()
- {
- return _resources.getMaxCacheSize();
- }
- /**
- * @param filename
- * @return
- */
- public String getMimeByExtension(String filename)
- {
- return _resources.getMimeByExtension(filename);
- }
- /**
- * @return
- */
- public Map getMimeMap()
- {
- return _resources.getMimeMap();
- }
- /**
- * @param pathInContext
- * @return
- * @throws IOException
- */
- public Resource getResource(String pathInContext) throws IOException
- {
- return _resources.getResource(pathInContext);
- }
- /**
- * @return
- */
- public String getResourceBase()
- {
- return _resources.getResourceBase();
- }
- /**
- * @param resource
- * @return
- */
- public ResourceMetaData getResourceMetaData(Resource resource)
- {
- return _resources.getResourceMetaData(resource);
- }
- /**
- * @param base
- */
- public void setBaseResource(Resource base)
- {
- _resources.setBaseResource(base);
- }
- /**
- * @param encodingMap
- */
- public void setEncodingMap(Map encodingMap)
- {
- _resources.setEncodingMap(encodingMap);
- }
- /**
- * @param maxCachedFileSize
- */
- public void setMaxCachedFileSize(int maxCachedFileSize)
- {
- _resources.setMaxCachedFileSize(maxCachedFileSize);
- }
- /**
- * @param maxCacheSize
- */
- public void setMaxCacheSize(int maxCacheSize)
- {
- _resources.setMaxCacheSize(maxCacheSize);
- }
- /**
- * @param mimeMap
- */
- public void setMimeMap(Map mimeMap)
- {
- _resources.setMimeMap(mimeMap);
- }
- /**
- * @param extension
- * @param type
- */
- public void setMimeMapping(String extension, String type)
- {
- _resources.setMimeMapping(extension, type);
- }
- /**
- * @param resourceBase
- */
- public void setResourceBase(String resourceBase)
- {
- _resources.setResourceBase(resourceBase);
- }
- /**
- * @param mimeType
- * @param encoding
- */
- public void setTypeEncoding(String mimeType, String encoding)
- {
- _resources.setTypeEncoding(mimeType, encoding);
- }
-}
diff --git a/apps/jetty/java/src/org/mortbay/http/NCSARequestLog.java b/apps/jetty/java/src/org/mortbay/http/NCSARequestLog.java
deleted file mode 100644
index a898624eaa..0000000000
--- a/apps/jetty/java/src/org/mortbay/http/NCSARequestLog.java
+++ /dev/null
@@ -1,505 +0,0 @@
-// ========================================================================
-// $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
-// Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// 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.mortbay.http;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import javax.servlet.http.Cookie;
-
-import org.apache.commons.logging.Log;
-import org.mortbay.log.LogFactory;
-import org.mortbay.util.DateCache;
-import org.mortbay.util.LogSupport;
-import org.mortbay.util.RolloverFileOutputStream;
-import org.mortbay.util.StringUtil;
-
-
-/* ------------------------------------------------------------ */
-/** NCSA HTTP Request Log.
- * NCSA common or NCSA extended (combined) request log.
- *
- * Taken from 5.1.12 source and modded to change some private vars to protected
- * so we can extend it for I2P.
- *
- * @version $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
- * @author Tony Thompson
- * @author Greg Wilkins
- */
-public class NCSARequestLog implements RequestLog
-{
- protected static Log log = LogFactory.getLog(NCSARequestLog.class);
-
- private String _filename;
- private boolean _extended;
- private boolean _append;
- private int _retainDays;
- private boolean _closeOut;
- private boolean _preferProxiedForAddress;
- private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss ZZZ";
- private Locale _logLocale=Locale.getDefault();
- private String _logTimeZone=TimeZone.getDefault().getID();
- private String[] _ignorePaths;
- private boolean _logLatency=false;
- private boolean _logCookies=false;
-
- protected transient OutputStream _out;
- protected transient OutputStream _fileOut;
- protected transient DateCache _logDateCache;
- protected transient PathMap _ignorePathMap;
- protected transient Writer _writer;
-
- /* ------------------------------------------------------------ */
- /** Constructor.
- */
- public NCSARequestLog()
- {
- _extended=true;
- _append=true;
- _retainDays=31;
- }
-
- /* ------------------------------------------------------------ */
- /** Constructor.
- * @param filename Filename, which can be in
- * rolloverFileOutputStream format
- * @see org.mortbay.util.RolloverFileOutputStream
- * @exception IOException
- */
- public NCSARequestLog(String filename)
- throws IOException
- {
- _extended=true;
- _append=true;
- _retainDays=31;
- setFilename(filename);
- }
-
- /* ------------------------------------------------------------ */
- /** Set the log filename.
- * @see NCSARequestLog#setRetainDays(int)
- * @param filename The filename to use. If the filename contains the
- * string "yyyy_mm_dd", then a RolloverFileOutputStream is used and the
- * log is rolled over nightly and aged according setRetainDays. If no
- * filename is set or a null filename
- * passed, then requests are logged to System.err.
- */
- public void setFilename(String filename)
- {
- if (filename!=null)
- {
- filename=filename.trim();
- if (filename.length()==0)
- filename=null;
- }
- _filename=filename;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the log filename.
- * @see NCSARequestLog#getDatedFilename()
- * @return The log filename without any date expansion.
- */
- public String getFilename()
- {
- return _filename;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the dated log filename.
- * @see NCSARequestLog#getFilename()
- * @return The log filename with any date encoding expanded.
- */
- public String getDatedFilename()
- {
- if (_fileOut instanceof RolloverFileOutputStream)
- return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
- return null;
- }
-
-
- /* ------------------------------------------------------------ */
- /**
- * @param format The date format to use within the log file.
- */
- public void setLogDateFormat(String format)
- {
- _logDateFormat=format;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return The date format to use within the log file.
- */
- public String getLogDateFormat()
- {
- return _logDateFormat;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param tz The date format timezone to use within the log file.
- */
- public void setLogTimeZone(String tz)
- {
- _logTimeZone=tz;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return The date format timezone to use within the log file.
- */
- public String getLogTimeZone()
- {
- return _logTimeZone;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return The number of days to retain rollovered log files.
- */
- public int getRetainDays()
- {
- return _retainDays;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param retainDays The number of days to retain rollovered log files.
- */
- public void setRetainDays(int retainDays)
- {
- _retainDays = retainDays;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if NCSA extended format is to be used.
- */
- public boolean isExtended()
- {
- return _extended;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param e True if NCSA extended format is to be used.
- */
- public void setExtended(boolean e)
- {
- _extended=e;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if logs are appended to existing log files.
- */
- public boolean isAppend()
- {
- return _append;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param a True if logs are appended to existing log files.
- */
- public void setAppend(boolean a)
- {
- _append=a;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @deprecated ignored
- */
- public void setBuffered(boolean b)
- {}
-
- /* ------------------------------------------------------------ */
- /** Set which paths to ignore.
- *
- * @param ignorePaths Array of path specifications to ignore
- */
- public void setIgnorePaths(String[] ignorePaths)
- {
- // Contributed by Martin Vilcans (martin@jadestone.se)
- _ignorePaths = ignorePaths;
- }
-
- /* ------------------------------------------------------------ */
- public String[] getIgnorePaths()
- {
- return _ignorePaths;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return Returns the logCookies.
- */
- public boolean getLogCookies()
- {
- return _logCookies;
- }
- /* ------------------------------------------------------------ */
- /**
- * @param logCookies The logCookies to set.
- */
- public void setLogCookies(boolean logCookies)
- {
- _logCookies = logCookies;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return Returns true if logging latency
- */
- public boolean getLogLatency()
- {
- return _logLatency;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param logLatency If true, latency is logged at the end of the log line
- */
- public void setLogLatency(boolean logLatency)
- {
- _logLatency = logLatency;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Prefer to log the proxied-for IP address (if present in
- * the request header) over the native requester IP address.
- * Useful in reverse-proxy situations when you'd rather see
- * the IP address of the host before the most recent proxy
- * server, as opposed to your own proxy server(s) every time.
- *
- * jlrobins@socialserve.com, March 2004.
- **/
- public void setPreferProxiedForAddress(boolean value)
- {
- _preferProxiedForAddress = value;
- }
-
- /* ------------------------------------------------------------ */
- public void start()
- throws Exception
- {
- _logDateCache=new DateCache(_logDateFormat,_logLocale);
- _logDateCache.setTimeZoneID(_logTimeZone);
-
- if (_filename != null)
- {
- _fileOut=new RolloverFileOutputStream(_filename,_append,_retainDays);
- _closeOut=true;
- }
- else
- _fileOut=System.err;
-
- _out=_fileOut;
-
- if (_ignorePaths!=null && _ignorePaths.length>0)
- {
- _ignorePathMap=new PathMap();
- for (int i=0;i<_ignorePaths.length;i++)
- _ignorePathMap.put(_ignorePaths[i],_ignorePaths[i]);
- }
- else
- _ignorePathMap=null;
-
- _writer=new OutputStreamWriter(_out);
- }
-
- /* ------------------------------------------------------------ */
- public boolean isStarted()
- {
- return _fileOut!=null;
- }
-
- /* ------------------------------------------------------------ */
- public void stop()
- {
- try{if (_writer!=null)_writer.flush();} catch (IOException e){LogSupport.ignore(log,e);}
- if (_out!=null && _closeOut)
- try{_out.close();}catch(IOException e){LogSupport.ignore(log,e);}
- _out=null;
- _fileOut=null;
- _closeOut=false;
- _logDateCache=null;
- _writer=null;
- }
-
- /* ------------------------------------------------------------ */
- /** Log a request.
- * @param request The request
- * @param response The response to this request.
- * @param responseLength The bytes written to the response.
- */
- public void log(HttpRequest request,
- HttpResponse response,
- int responseLength)
- {
- try{
- // ignore ignorables
- if (_ignorePathMap != null &&
- _ignorePathMap.getMatch(request.getPath()) != null)
- return;
-
- // log the rest
- if (_fileOut==null)
- return;
-
- StringBuffer buf = new StringBuffer(160);
-
- String addr = null;
- if(_preferProxiedForAddress)
- {
- // If header is not present, addr will remain null ...
- addr = request.getField(HttpFields.__XForwardedFor);
- }
- if(addr == null)
- addr = request.getRemoteAddr();
- buf.append(addr);
-
- buf.append(" - ");
- String user = request.getAuthUser();
- buf.append((user==null)?"-":user);
- buf.append(" [");
- buf.append(_logDateCache.format(request.getTimeStamp()));
- buf.append("] \"");
- buf.append(request.getMethod());
- buf.append(' ');
- buf.append(request.getURI());
- buf.append(' ');
- buf.append(request.getVersion());
- buf.append("\" ");
- int status=response.getStatus();
- buf.append((char)('0'+((status/100)%10)));
- buf.append((char)('0'+((status/10)%10)));
- buf.append((char)('0'+(status%10)));
- if (responseLength>=0)
- {
- buf.append(' ');
- if (responseLength>99999)
- buf.append(Integer.toString(responseLength));
- else
- {
- if (responseLength>9999)
- buf.append((char)('0'+((responseLength/10000)%10)));
- if (responseLength>999)
- buf.append((char)('0'+((responseLength/1000)%10)));
- if (responseLength>99)
- buf.append((char)('0'+((responseLength/100)%10)));
- if (responseLength>9)
- buf.append((char)('0'+((responseLength/10)%10)));
- buf.append((char)('0'+(responseLength%10)));
- }
- buf.append(' ');
- }
- else
- buf.append(" - ");
-
- String log =buf.toString();
- synchronized(_writer)
- {
- _writer.write(log);
- if (_extended)
- {
- logExtended(request,response,_writer);
- if (!_logCookies)
- _writer.write(" -");
- }
-
- if (_logCookies)
- {
- Cookie[] cookies = request.getCookies();
- if (cookies==null || cookies.length==0)
- _writer.write(" -");
- else
- {
- _writer.write(" \"");
- for (int i=0;i0)
- b.append(',');
- b.append(methods[i]);
- }
- _allowed=b.toString();
- }
-
- /* ------------------------------------------------------------ */
- public boolean isMethodAllowed(String method)
- {
- return _methodMap.get(method)!=null;
- }
-
- /* ------------------------------------------------------------ */
- public String getAllowedString()
- {
- return _allowed;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isDirAllowed()
- {
- return _dirAllowed;
- }
-
- /* ------------------------------------------------------------ */
- public void setDirAllowed(boolean dirAllowed)
- {
- _dirAllowed = dirAllowed;
- }
-
- /* ------------------------------------------------------------ */
- public boolean isAcceptRanges()
- {
- return _acceptRanges;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if welcome files are redirected to. False if forward is used.
- */
- public boolean getRedirectWelcome()
- {
- return _redirectWelcomeFiles;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param redirectWelcome True if welcome files are redirected to. False
- * if forward is used.
- */
- public void setRedirectWelcome(boolean redirectWelcome)
- {
- _redirectWelcomeFiles = redirectWelcome;
- }
-
- /* ------------------------------------------------------------ */
- /** Set if the handler accepts range requests.
- * Default is false;
- * @param ar True if the handler should accept ranges
- */
- public void setAcceptRanges(boolean ar)
- {
- _acceptRanges=ar;
- }
-
- /* ------------------------------------------------------------ */
- /** Get minimum content length for GZIP encoding.
- * @return Minimum length of content for gzip encoding or -1 if disabled.
- */
- public int getMinGzipLength()
- {
- return _minGzipLength;
- }
-
- /* ------------------------------------------------------------ */
- /** Set minimum content length for GZIP encoding.
- * @param minGzipLength If set to a positive integer, then static content
- * larger than this will be served as gzip content encoded
- * if a matching resource is found ending with ".gz"
- */
- public void setMinGzipLength(int minGzipLength)
- {
- _minGzipLength = minGzipLength;
- }
-
-
- /* ------------------------------------------------------------ */
- /** get Resource to serve.
- * Map a path to a resource. The default implementation calls
- * HttpContext.getResource but derived handers may provide
- * their own mapping.
- * @param pathInContext The path to find a resource for.
- * @return The resource to serve.
- */
- protected Resource getResource(String pathInContext)
- throws IOException
- {
- return getHttpContext().getResource(pathInContext);
- }
-
- /* ------------------------------------------------------------ */
- public void handle(String pathInContext,
- String pathParams,
- HttpRequest request,
- HttpResponse response)
- throws HttpException, IOException
- {
- Resource resource = getResource(pathInContext);
- if (resource==null)
- return;
-
- // Is the method allowed?
- if (!isMethodAllowed(request.getMethod()))
- {
- if(log.isDebugEnabled())log.debug("Method not allowed: "+request.getMethod());
- if (resource.exists())
- {
- setAllowHeader(response);
- response.sendError(HttpResponse.__405_Method_Not_Allowed);
- }
- return;
- }
-
- // Handle the request
- try
- {
- if(log.isDebugEnabled())log.debug("PATH="+pathInContext+" RESOURCE="+resource);
-
- // check filename
- String method=request.getMethod();
- if (method.equals(HttpRequest.__GET) ||
- method.equals(HttpRequest.__POST) ||
- method.equals(HttpRequest.__HEAD))
- handleGet(request, response, pathInContext, pathParams, resource);
- else if (method.equals(HttpRequest.__PUT))
- handlePut(request, response, pathInContext, resource);
- else if (method.equals(HttpRequest.__DELETE))
- handleDelete(request, response, pathInContext, resource);
- else if (method.equals(HttpRequest.__OPTIONS))
- handleOptions(response, pathInContext);
- else if (method.equals(HttpRequest.__MOVE))
- handleMove(request, response, pathInContext, resource);
- else if (method.equals(HttpRequest.__TRACE))
- handleTrace(request, response);
- else
- {
- if(log.isDebugEnabled())log.debug("Unknown action:"+method);
- // anything else...
- try{
- if (resource.exists())
- response.sendError(HttpResponse.__501_Not_Implemented);
- }
- catch(Exception e) {LogSupport.ignore(log,e);}
- }
- }
- catch(IllegalArgumentException e)
- {
- LogSupport.ignore(log,e);
- }
- finally
- {
- if (resource!=null && !(resource instanceof CachedResource))
- resource.release();
- }
- }
-
- /* ------------------------------------------------------------------- */
- public void handleGet(HttpRequest request,
- HttpResponse response,
- String pathInContext,
- String pathParams,
- Resource resource)
- throws IOException
- {
- if(log.isDebugEnabled())log.debug("Looking for "+resource);
-
- if (resource!=null && resource.exists())
- {
- // check if directory
- if (resource.isDirectory())
- {
- if (!pathInContext.endsWith("/") && !pathInContext.equals("/"))
- {
- log.debug("Redirect to directory/");
-
- String q=request.getQuery();
-
- // Properly fix URI
- URI urifix = new URI(request.getRequestURL().toString());
- urifix.setPath(urifix.getPath());
- StringBuffer buf = new StringBuffer(urifix.toString());
- urifix = null;
-
- if (q!=null&&q.length()!=0)
- {
- buf.append('?');
- buf.append(q);
- }
- response.setField(HttpFields.__Location, URI.addPaths(buf.toString(),"/"));
- response.setStatus(302);
- request.setHandled(true);
- return;
- }
-
- // See if index file exists
- String welcome=getHttpContext().getWelcomeFile(resource);
- if (welcome!=null)
- {
- // Forward to the index
- String ipath=URI.addPaths(pathInContext,welcome);
- if (_redirectWelcomeFiles)
- {
- // Redirect to the index
- ipath=URI.addPaths(getHttpContext().getContextPath(),ipath);
- response.setContentLength(0);
- response.sendRedirect(ipath);
- }
- else
- {
- URI uri=request.getURI();
- uri.setPath(URI.addPaths(uri.getPath(),welcome));
- getHttpContext().handle(ipath,pathParams,request,response);
- }
- return;
- }
-
- // Check modified dates
- if (!passConditionalHeaders(request,response,resource))
- return;
- // If we got here, no forward to index took place
- sendDirectory(request,response,resource,pathInContext.length()>1);
- }
- // check if it is a file
- else if (resource.exists())
- {
- // Check modified dates
- if (!passConditionalHeaders(request,response,resource))
- return;
- sendData(request,response,pathInContext,resource,true);
- }
- else
- // don't know what it is
- log.warn("Unknown file type");
- }
- }
-
-
- /* ------------------------------------------------------------ */
- /* Check modification date headers.
- */
- private boolean passConditionalHeaders(HttpRequest request,
- HttpResponse response,
- Resource resource)
- throws IOException
- {
- if (!request.getMethod().equals(HttpRequest.__HEAD))
- {
- // If we have meta data for the file
- // Try a direct match for most common requests. Avoids
- // parsing the date.
- ResourceCache.ResourceMetaData metaData =
- (ResourceCache.ResourceMetaData)resource.getAssociate();
- if (metaData!=null)
- {
- String ifms=request.getField(HttpFields.__IfModifiedSince);
- String mdlm=metaData.getLastModified();
- if (ifms!=null && mdlm!=null && ifms.equals(mdlm))
- {
- response.setStatus(HttpResponse.__304_Not_Modified);
- request.setHandled(true);
- return false;
- }
- }
-
-
- long date=0;
- // Parse the if[un]modified dates and compare to resource
-
- if ((date=request.getDateField(HttpFields.__IfUnmodifiedSince))>0)
- {
- if (resource.lastModified()/1000 > date/1000)
- {
- response.sendError(HttpResponse.__412_Precondition_Failed);
- return false;
- }
- }
-
- if ((date=request.getDateField(HttpFields.__IfModifiedSince))>0)
- {
-
- if (resource.lastModified()/1000 <= date/1000)
- {
- response.setStatus(HttpResponse.__304_Not_Modified);
- request.setHandled(true);
- return false;
- }
- }
-
- }
- return true;
- }
-
-
- /* ------------------------------------------------------------ */
- void handlePut(HttpRequest request,
- HttpResponse response,
- String pathInContext,
- Resource resource)
- throws IOException
- {
- if(log.isDebugEnabled())log.debug("PUT "+pathInContext+" in "+resource);
-
- boolean exists=resource!=null && resource.exists();
- if (exists &&
- !passConditionalHeaders(request,response,resource))
- return;
-
- if (pathInContext.endsWith("/"))
- {
- if (!exists)
- {
- if (!resource.getFile().mkdirs())
- response.sendError(HttpResponse.__403_Forbidden, "Directories could not be created");
- else
- {
- request.setHandled(true);
- response.setStatus(HttpResponse.__201_Created);
- response.commit();
- }
- }
- else
- {
- request.setHandled(true);
- response.setStatus(HttpResponse.__200_OK);
- response.commit();
- }
- }
- else
- {
- try
- {
- int toRead = request.getContentLength();
- InputStream in = request.getInputStream();
- OutputStream out = resource.getOutputStream();
- if (toRead>=0)
- IO.copy(in,out,toRead);
- else
- IO.copy(in,out);
- out.close();
- request.setHandled(true);
- response.setStatus(exists
- ?HttpResponse.__200_OK
- :HttpResponse.__201_Created);
- response.commit();
- }
- catch (Exception ex)
- {
- log.warn(LogSupport.EXCEPTION,ex);
- response.sendError(HttpResponse.__403_Forbidden,
- ex.getMessage());
- }
- }
- }
-
- /* ------------------------------------------------------------ */
- void handleDelete(HttpRequest request,
- HttpResponse response,
- String pathInContext,
- Resource resource)
- throws IOException
- {
- if(log.isDebugEnabled())log.debug("DELETE "+pathInContext+" from "+resource);
-
- if (!resource.exists() ||
- !passConditionalHeaders(request,response,resource))
- return;
-
- try
- {
- // delete the file
- if (resource.delete())
- response.setStatus(HttpResponse.__204_No_Content);
- else
- response.sendError(HttpResponse.__403_Forbidden);
-
- // Send response
- request.setHandled(true);
- }
- catch (SecurityException sex)
- {
- log.warn(LogSupport.EXCEPTION,sex);
- response.sendError(HttpResponse.__403_Forbidden, sex.getMessage());
- }
- }
-
-
- /* ------------------------------------------------------------ */
- void handleMove(HttpRequest request,
- HttpResponse response,
- String pathInContext,
- Resource resource)
- throws IOException
- {
- if (!resource.exists() || !passConditionalHeaders(request,response,resource))
- return;
-
-
- String newPath = URI.canonicalPath(request.getField("New-uri"));
- if (newPath==null)
- {
- response.sendError(HttpResponse.__405_Method_Not_Allowed,
- "Bad new uri");
- return;
- }
-
- String contextPath = getHttpContext().getContextPath();
- if (contextPath!=null && !newPath.startsWith(contextPath))
- {
- response.sendError(HttpResponse.__405_Method_Not_Allowed,
- "Not in context");
- return;
- }
-
-
- // Find path
- try
- {
- // TODO - Check this
- String newInfo=newPath;
- if (contextPath!=null)
- newInfo=newInfo.substring(contextPath.length());
- Resource newFile = getHttpContext().getBaseResource().addPath(newInfo);
-
- if(log.isDebugEnabled())log.debug("Moving "+resource+" to "+newFile);
- resource.renameTo(newFile);
-
- response.setStatus(HttpResponse.__204_No_Content);
- request.setHandled(true);
- }
- catch (Exception ex)
- {
- log.warn(LogSupport.EXCEPTION,ex);
- setAllowHeader(response);
- response.sendError(HttpResponse.__405_Method_Not_Allowed,
- "Error:"+ex);
- return;
- }
- }
-
- /* ------------------------------------------------------------ */
- void handleOptions(HttpResponse response, String pathInContext)
- throws IOException
- {
- if ("*".equals(pathInContext))
- return;
- setAllowHeader(response);
- response.commit();
- }
-
- /* ------------------------------------------------------------ */
- void setAllowHeader(HttpResponse response)
- {
- response.setField(HttpFields.__Allow, getAllowedString());
- }
-
- /* ------------------------------------------------------------ */
- public void writeHeaders(HttpResponse response,Resource resource, long count)
- throws IOException
- {
- ResourceCache.ResourceMetaData metaData =
- (ResourceCache.ResourceMetaData)resource.getAssociate();
-
- response.setContentType(metaData.getMimeType());
- if (count != -1)
- {
- if (count==resource.length())
- response.setField(HttpFields.__ContentLength,metaData.getLength());
- else
- response.setContentLength((int)count);
- }
-
- response.setField(HttpFields.__LastModified,metaData.getLastModified());
-
- if (_acceptRanges && response.getHttpRequest().getDotVersion()>0)
- response.setField(HttpFields.__AcceptRanges,"bytes");
- }
-
- /* ------------------------------------------------------------ */
- public void sendData(HttpRequest request,
- HttpResponse response,
- String pathInContext,
- Resource resource,
- boolean writeHeaders)
- throws IOException
- {
- long resLength=resource.length();
-
- // see if there are any range headers
- Enumeration reqRanges =
- request.getDotVersion()>0
- ?request.getFieldValues(HttpFields.__Range)
- :null;
-
- if (!writeHeaders || reqRanges == null || !reqRanges.hasMoreElements())
- {
- // look for a gziped content.
- Resource data=resource;
- if (_minGzipLength>0)
- {
- String accept=request.getField(HttpFields.__AcceptEncoding);
- if (accept!=null && resLength>_minGzipLength &&
- !pathInContext.endsWith(".gz"))
- {
- Resource gz = getHttpContext().getResource(pathInContext+".gz");
- if (gz.exists() && accept.indexOf("gzip")>=0)
- {
- if(log.isDebugEnabled())log.debug("gzip="+gz);
- response.setField(HttpFields.__ContentEncoding,"gzip");
- data=gz;
- resLength=data.length();
- }
- }
- }
- writeHeaders(response,resource,resLength);
-
- request.setHandled(true);
- OutputStream out = response.getOutputStream();
- data.writeTo(out,0,resLength);
- return;
- }
-
- // Parse the satisfiable ranges
- List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,resLength);
- if(log.isDebugEnabled())log.debug("ranges: " + reqRanges + " == " + ranges);
-
- // if there are no satisfiable ranges, send 416 response
- if (ranges==null || ranges.size()==0)
- {
- log.debug("no satisfiable ranges");
- writeHeaders(response, resource, resLength);
- response.setStatus(HttpResponse.__416_Requested_Range_Not_Satisfiable);
- response.setReason((String)HttpResponse.__statusMsg
- .get(TypeUtil.newInteger(HttpResponse.__416_Requested_Range_Not_Satisfiable)));
-
- response.setField(HttpFields.__ContentRange,
- InclusiveByteRange.to416HeaderRangeString(resLength));
-
- OutputStream out = response.getOutputStream();
- resource.writeTo(out,0,resLength);
- request.setHandled(true);
- return;
- }
-
-
- // if there is only a single valid range (must be satisfiable
- // since were here now), send that range with a 216 response
- if ( ranges.size()== 1)
- {
- InclusiveByteRange singleSatisfiableRange =
- (InclusiveByteRange)ranges.get(0);
- if(log.isDebugEnabled())log.debug("single satisfiable range: " + singleSatisfiableRange);
- long singleLength = singleSatisfiableRange.getSize(resLength);
- writeHeaders(response,resource,singleLength);
- response.setStatus(HttpResponse.__206_Partial_Content);
- response.setReason((String)HttpResponse.__statusMsg
- .get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
- response.setField(HttpFields.__ContentRange,
- singleSatisfiableRange.toHeaderRangeString(resLength));
- OutputStream out = response.getOutputStream();
- resource.writeTo(out,
- singleSatisfiableRange.getFirst(resLength),
- singleLength);
- request.setHandled(true);
- return;
- }
-
-
- // multiple non-overlapping valid ranges cause a multipart
- // 216 response which does not require an overall
- // content-length header
- //
- ResourceCache.ResourceMetaData metaData =
- (ResourceCache.ResourceMetaData)resource.getAssociate();
- String encoding = metaData.getMimeType();
- MultiPartResponse multi = new MultiPartResponse(response);
- response.setStatus(HttpResponse.__206_Partial_Content);
- response.setReason((String)HttpResponse.__statusMsg
- .get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
-
- // If the request has a "Request-Range" header then we need to
- // send an old style multipart/x-byteranges Content-Type. This
- // keeps Netscape and acrobat happy. This is what Apache does.
- String ctp;
- if (request.containsField(HttpFields.__RequestRange))
- ctp = "multipart/x-byteranges; boundary=";
- else
- ctp = "multipart/byteranges; boundary=";
- response.setContentType(ctp+multi.getBoundary());
-
- InputStream in=(resource instanceof CachedResource)
- ?null:resource.getInputStream();
- OutputStream out = response.getOutputStream();
- long pos=0;
-
- for (int i=0;i0)
- throw new java.net.UnknownHostException("Bad [] syntax");
- if (b==0) // IPV6
- {
- int b2 = inetAddrPort.indexOf(']');
- if (b2<2)
- throw new java.net.UnknownHostException("Bad [] syntax");
- String addr=inetAddrPort.substring(1,b2);
- if (addr.indexOf('/')>0)
- addr=addr.substring(addr.indexOf('/')+1);
- inetAddrPort=inetAddrPort.substring(b2+1);
- int c = inetAddrPort.indexOf(':');
- if (c>0)
- throw new java.net.UnknownHostException("Bad [] syntax");
- if (c==0)
- inetAddrPort=inetAddrPort.substring(1);
-
- if (addr.length()>0 && ! __0_0_0_0.equals(addr))
- {
- _addrIsHost=!Character.isDigit((addr.charAt(0)));
- this._addr=InetAddress.getByName(addr);
- }
- } else { // IPV4
- int c = inetAddrPort.indexOf(':');
- if (c>=0)
- {
- String addr=inetAddrPort.substring(0,c);
- if (addr.indexOf('/')>0)
- addr=addr.substring(addr.indexOf('/')+1);
- inetAddrPort=inetAddrPort.substring(c+1);
-
- if (addr.length()>0 && ! __0_0_0_0.equals(addr))
- {
- _addrIsHost=!Character.isDigit((addr.charAt(0)));
- this._addr=InetAddress.getByName(addr);
- }
- }
- }
-
- _port = Integer.parseInt(inetAddrPort);
- }
-
- /* ------------------------------------------------------------ */
- /** Constructor.
- * @param address InetAddrPort top copy.
- */
- public InetAddrPort(InetAddrPort address)
- {
- if (address!=null)
- {
- _addr=address._addr;
- _port=address._port;
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Get the Host.
- * @return The IP address
- */
- public String getHost()
- {
- if (_addr==null)
- return __0_0_0_0;
-
- return _addrIsHost?_addr.getHostName():_addr.getHostAddress();
- }
-
- /* ------------------------------------------------------------ */
- /** Set the Host.
- * @param host
- * @exception java.net.UnknownHostException
- */
- public void setHost(String host)
- throws java.net.UnknownHostException
- {
- _addr=null;
- if (host!=null)
- {
- if (host.indexOf('/')>0)
- host=host.substring(0,host.indexOf('/'));
- _addrIsHost=!Character.isDigit((host.charAt(0)));
- _addr=InetAddress.getByName(host);
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Get the IP address.
- * @return The IP address
- */
- public InetAddress getInetAddress()
- {
- return _addr;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the IP address.
- * @param addr The IP address
- */
- public void setInetAddress(InetAddress addr)
- {
- _addrIsHost=false;
- _addr=addr;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the port.
- * @return The port number
- */
- public int getPort()
- {
- return _port;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the port.
- * @param port The port number
- */
- public void setPort(int port)
- {
- _port=port;
- }
-
-
- /* ------------------------------------------------------------------- */
- public String toString()
- {
- return getHost()+':'+_port;
- }
-
- /* ------------------------------------------------------------ */
- /** Clone the InetAddrPort.
- * @return A new instance.
- */
- public Object clone()
- {
- return new InetAddrPort(this);
- }
-
- /* ------------------------------------------------------------ */
- /** Hash Code.
- * @return hash Code.
- */
- public int hashCode()
- {
- return _port+((_addr==null)?0:_addr.hashCode());
- }
-
- /* ------------------------------------------------------------ */
- /** Equals.
- * @param o
- * @return True if is the same address and port.
- */
- public boolean equals(Object o)
- {
- if (o==null)
- return false;
- if (o==this)
- return true;
- if (o instanceof InetAddrPort)
- {
- InetAddrPort addr=(InetAddrPort)o;
- return addr._port==_port &&
- ( addr._addr==_addr ||
- addr._addr!=null && addr._addr.equals(_addr));
- }
- return false;
- }
-}
-
-
-
-
-
-
diff --git a/apps/jetty/java/src/org/mortbay/util/Resource.java b/apps/jetty/java/src/org/mortbay/util/Resource.java
deleted file mode 100644
index ed992cfd55..0000000000
--- a/apps/jetty/java/src/org/mortbay/util/Resource.java
+++ /dev/null
@@ -1,431 +0,0 @@
-// ========================================================================
-// $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
-// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// 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.mortbay.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.text.DateFormat;
-import java.util.Arrays;
-import java.util.Date;
-
-import org.apache.commons.logging.Log;
-import org.mortbay.log.LogFactory;
-
-
-/* ------------------------------------------------------------ */
-/** Abstract resource class.
- *
- * @version $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
- * @author Nuno Preguica
- * @author Greg Wilkins (gregw)
- */
-public abstract class Resource implements Serializable
-{
- private static Log log = LogFactory.getLog(Resource.class);
-
- Object _associate;
-
- /* ------------------------------------------------------------ */
- /** Construct a resource from a url.
- * @param url A URL.
- * @return A Resource object.
- */
- public static Resource newResource(URL url)
- throws IOException
- {
- if (url==null)
- return null;
-
- String urls=url.toExternalForm();
- if( urls.startsWith( "file:"))
- {
- try
- {
- FileResource fileResource= new FileResource(url);
- return fileResource;
- }
- catch(Exception e)
- {
- log.debug(LogSupport.EXCEPTION,e);
- return new BadResource(url,e.toString());
- }
- }
- else if( urls.startsWith( "jar:file:"))
- {
- return new JarFileResource(url);
- }
- else if( urls.startsWith( "jar:"))
- {
- return new JarResource(url);
- }
-
- return new URLResource(url,null);
- }
-
- /* ------------------------------------------------------------ */
- /** Construct a resource from a string.
- * @param resource A URL or filename.
- * @return A Resource object.
- */
- public static Resource newResource(String resource)
- throws MalformedURLException, IOException
- {
- URL url=null;
- try
- {
- // Try to format as a URL?
- url = new URL(resource);
- }
- catch(MalformedURLException e)
- {
- if(!resource.startsWith("ftp:") &&
- !resource.startsWith("file:") &&
- !resource.startsWith("jar:"))
- {
- try
- {
- // It's a file.
- if (resource.startsWith("./"))
- resource=resource.substring(2);
-
- File file=new File(resource).getCanonicalFile();
- url=file.toURI().toURL();
-
- URLConnection connection=url.openConnection();
- FileResource fileResource= new FileResource(url,connection,file);
- return fileResource;
- }
- catch(Exception e2)
- {
- log.debug(LogSupport.EXCEPTION,e2);
- throw e;
- }
- }
- else
- {
- log.warn("Bad Resource: "+resource);
- throw e;
- }
- }
-
- String nurl=url.toString();
- if (nurl.length()>0 &&
- nurl.charAt(nurl.length()-1)!=
- resource.charAt(resource.length()-1))
- {
- if ((nurl.charAt(nurl.length()-1)!='/' ||
- nurl.charAt(nurl.length()-2)!=resource.charAt(resource.length()-1))
- &&
- (resource.charAt(resource.length()-1)!='/' ||
- resource.charAt(resource.length()-2)!=nurl.charAt(nurl.length()-1)
- ))
- {
- return new BadResource(url,"Trailing special characters stripped by URL in "+resource);
- }
- }
- return newResource(url);
- }
-
- /* ------------------------------------------------------------ */
- /** Construct a system resource from a string.
- * The resource is tried as classloader resource before being
- * treated as a normal resource.
- */
- public static Resource newSystemResource(String resource)
- throws IOException
- {
- URL url=null;
- // Try to format as a URL?
- ClassLoader
- loader=Thread.currentThread().getContextClassLoader();
- if (loader!=null)
- {
- url=loader.getResource(resource);
- if (url==null && resource.startsWith("/"))
- url=loader.getResource(resource.substring(1));
- }
- if (url==null)
- {
- loader=Resource.class.getClassLoader();
- if (loader!=null)
- {
- url=loader.getResource(resource);
- if (url==null && resource.startsWith("/"))
- url=loader.getResource(resource.substring(1));
- }
- }
-
- if (url==null)
- {
- url=ClassLoader.getSystemResource(resource);
- if (url==null && resource.startsWith("/"))
- url=loader.getResource(resource.substring(1));
- }
-
- if (url==null)
- return null;
-
- return newResource(url);
- }
-
- /* ------------------------------------------------------------ */
- protected void finalize()
- {
- release();
- }
-
- /* ------------------------------------------------------------ */
- /** Release any resources held by the resource.
- */
- public abstract void release();
-
-
- /* ------------------------------------------------------------ */
- /**
- * Returns true if the respresened resource exists.
- */
- public abstract boolean exists();
-
-
- /* ------------------------------------------------------------ */
- /**
- * Returns true if the respresenetd resource is a container/directory.
- * If the resource is not a file, resources ending with "/" are
- * considered directories.
- */
- public abstract boolean isDirectory();
-
- /* ------------------------------------------------------------ */
- /**
- * Returns the last modified time
- */
- public abstract long lastModified();
-
-
- /* ------------------------------------------------------------ */
- /**
- * Return the length of the resource
- */
- public abstract long length();
-
-
- /* ------------------------------------------------------------ */
- /**
- * Returns an URL representing the given resource
- */
- public abstract URL getURL();
-
-
- /* ------------------------------------------------------------ */
- /**
- * Returns an File representing the given resource or NULL if this
- * is not possible.
- */
- public abstract File getFile()
- throws IOException;
-
-
- /* ------------------------------------------------------------ */
- /**
- * Returns the name of the resource
- */
- public abstract String getName();
-
-
- /* ------------------------------------------------------------ */
- /**
- * Returns an input stream to the resource
- */
- public abstract InputStream getInputStream()
- throws java.io.IOException;
-
- /* ------------------------------------------------------------ */
- /**
- * Returns an output stream to the resource
- */
- public abstract OutputStream getOutputStream()
- throws java.io.IOException, SecurityException;
-
- /* ------------------------------------------------------------ */
- /**
- * Deletes the given resource
- */
- public abstract boolean delete()
- throws SecurityException;
-
- /* ------------------------------------------------------------ */
- /**
- * Rename the given resource
- */
- public abstract boolean renameTo( Resource dest)
- throws SecurityException;
-
- /* ------------------------------------------------------------ */
- /**
- * Returns a list of resource names contained in the given resource
- * The resource names are not URL encoded.
- */
- public abstract String[] list();
-
- /* ------------------------------------------------------------ */
- /**
- * Returns the resource contained inside the current resource with the
- * given name.
- * @param path The path segment to add, which should be encoded by the
- * encode method.
- */
- public abstract Resource addPath(String path)
- throws IOException,MalformedURLException;
-
-
- /* ------------------------------------------------------------ */
- /** Encode according to this resource type.
- * The default implementation calls URI.encodePath(uri)
- * @param uri
- * @return String encoded for this resource type.
- */
- public String encode(String uri)
- {
- return URI.encodePath(uri);
- }
-
-
- /* ------------------------------------------------------------ */
- public Object getAssociate()
- {
- return _associate;
- }
-
- /* ------------------------------------------------------------ */
- public void setAssociate(Object o)
- {
- _associate=o;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return The canonical Alias of this resource or null if none.
- */
- public URL getAlias()
- {
- return null;
- }
-
-
- /* ------------------------------------------------------------ */
- public CachedResource cache()
- throws IOException
- {
- return new CachedResource(this);
- }
-
- /* ------------------------------------------------------------ */
- /** Get the resource list as a HTML directory listing.
- * @param base The base URL
- * @param parent True if the parent directory should be included
- * @return String of HTML
- */
- public String getListHTML(String base,
- boolean parent)
- throws IOException
- {
- if (!isDirectory())
- return null;
-
-
- String[] ls = list();
- if (ls==null)
- return null;
- Arrays.sort(ls);
-
- String title = "Directory: "+URI.decodePath(base);
- title=StringUtil.replace(StringUtil.replace(title,"<","<"),">",">");
- StringBuffer buf=new StringBuffer(4096);
- buf.append("");
- buf.append(title);
- buf.append("\n");
- buf.append(title);
- buf.append("
");
-
- if (parent)
- {
- buf.append("Parent Directory | | |
\n");
- }
-
- DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
- DateFormat.MEDIUM);
- for (int i=0 ; i< ls.length ; i++)
- {
- String encoded=URI.encodePath(ls[i]);
- // bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times)
- // http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
- // See resource.diff attachment
- //Resource item = addPath(encoded);
- Resource item = addPath(ls[i]);
-
- buf.append("");
- buf.append(StringUtil.replace(StringUtil.replace(ls[i],"<","<"),">",">"));
- buf.append(" ");
- buf.append(" | ");
- buf.append(item.length());
- buf.append(" bytes | ");
- buf.append(dfmt.format(new Date(item.lastModified())));
- buf.append(" |
\n");
- }
- buf.append("
\n");
- buf.append("\n");
-
- return buf.toString();
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param out
- * @param start First byte to write
- * @param count Bytes to write or -1 for all of them.
- */
- public void writeTo(OutputStream out,long start,long count)
- throws IOException
- {
- InputStream in = getInputStream();
- try
- {
- in.skip(start);
- if (count<0)
- IO.copy(in,out);
- else
- IO.copy(in,out,(int)count);
- }
- finally
- {
- in.close();
- }
- }
-}
diff --git a/apps/jetty/java/src/org/mortbay/util/URI.java b/apps/jetty/java/src/org/mortbay/util/URI.java
deleted file mode 100644
index 867ef19f40..0000000000
--- a/apps/jetty/java/src/org/mortbay/util/URI.java
+++ /dev/null
@@ -1,1010 +0,0 @@
-// ========================================================================
-// $Id: URI.java,v 1.40 2009/05/16 02:02:00 gregwilkins Exp $
-// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// 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.mortbay.util;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.mortbay.log.LogFactory;
-
-/* ------------------------------------------------------------ */
-/** URI Holder.
- * This class assists with the decoding and encoding or HTTP URI's.
- * It differs from the java.net.URL class as it does not provide
- * communications ability, but it does assist with query string
- * formatting.
- * ISO_8859_1 encoding is used by default for % encoded characters. This
- * may be overridden with the org.mortbay.util.URI.charset system property.
- * @see UrlEncoded
- * @version $Id: URI.java,v 1.40 2009/05/16 02:02:00 gregwilkins Exp $
- * @author Greg Wilkins (gregw)
- */
-public class URI
- implements Cloneable
-{
- private static Log log = LogFactory.getLog(URI.class);
-
- public static final String __CHARSET=System.getProperty("org.mortbay.util.URI.charset",StringUtil.__UTF_8);
- public static final boolean __CHARSET_IS_DEFAULT=__CHARSET.equals(StringUtil.__UTF_8);
-
- /* ------------------------------------------------------------ */
- private String _uri;
- private String _scheme;
- private String _host;
- private int _port;
- private String _path;
- private String _encodedPath;
- private String _query;
- private UrlEncoded _parameters;
- private boolean _dirty;
- private static String unreserved = "/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.~";
- private static String reserved = "!*'();:@&=+$,?%#[]";
- private static String hexchars = "0123456789ABCDEF";
-
- /* ------------------------------------------------------------ */
- /** Copy Constructor .
- * @param uri
- */
- public URI(URI uri)
- throws IllegalArgumentException
- {
- _uri=uri.toString();
- _scheme=uri._scheme;
- _host=uri._host;
- _port=uri._port;
- _path=uri._path;
- _encodedPath=uri._encodedPath;
- _query=uri._query;
- if (uri._parameters!=null)
- _parameters=(UrlEncoded)uri._parameters.clone();
- _dirty=false;
- }
-
- /* ------------------------------------------------------------ */
- /** Construct from a String.
- * The string must contain a URI path, but optionaly may contain a
- * scheme, host, port and query string.
- *
- * @param uri [scheme://host[:port]]/path[?query]
- */
- public URI(String uri)
- throws IllegalArgumentException
- {
- setURI(uri);
- }
-
- /* ------------------------------------------------------------ */
- public void setURI(String uri)
- throws IllegalArgumentException
- {
- try
- {
- _uri=uri;
- _scheme=null;
- _host=null;
- _port=0;
- _path=null;
- _encodedPath=null;
- _query=null;
- if (_parameters!=null)
- _parameters.clear();
-
- // Scan _uri for host, port, path & query
- int maxi=uri.length()-1;
- int mark=0;
- int state=0;
- int i=0;
-
- if (maxi==0 || uri.charAt(0)=='/' && uri.charAt(1)!='/')
- {
- state=3;
- _scheme=null;
- _host=null;
- _port=0;
- }
- else
- {
- for (i=0;state<3 && i<=maxi;i++)
- {
- char c=uri.charAt(i);
- switch(state)
- {
- case 0: // looking for scheme or path
- if (c==':' &&
- uri.charAt(i+1)=='/' &&
- uri.charAt(i+2)=='/')
- {
- // found end of scheme & start of host
- _scheme=uri.substring(mark,i);
- i+=2;
- mark=i+1;
- state=1;
- }
- else if (i==0 && c=='/')
- {
- // Found path
- state=3;
- }
- else if (i==0 && c=='*')
- {
- state=5;
- _path="*";
- _encodedPath="*";
- }
- continue;
-
- case 1: // Get host & look for port or path
- if (c==':')
- {
- // found port
- _host=uri.substring(mark,i);
- mark=i+1;
- state=2;
- }
- else if (c=='/')
- {
- // found path
- _host=uri.substring(mark,i);
- mark=i;
- state=3;
- }
- continue;
-
- case 2: // Get port & look for path
- if (c=='/')
- {
- _port=TypeUtil.parseInt(uri,mark,i-mark,10);
- mark=i;
- state=3;
- }
- continue;
- }
- }
- }
-
- // State 3 - Get path & look for query
- _query=null;
- for (i++;i<=maxi;i++)
- {
- char c=uri.charAt(i);
- if (c=='?')
- {
- // Found query
- _encodedPath=uri.substring(mark,i);
- _path=decodePath(_encodedPath);
-
- mark=i+1;
- state=4;
- break;
- }
- }
-
- // complete last state
- switch(state)
- {
- case 0:
- _dirty=false;
- _encodedPath=_uri;
- _path=decodePath(_encodedPath);
- break;
-
- case 1:
- _dirty=true;
- _encodedPath="/";
- _path=_encodedPath;
- _host=uri.substring(mark);
- break;
-
- case 2:
- _dirty=true;
- _encodedPath="/";
- _path=_encodedPath;
- _port=TypeUtil.parseInt(uri,mark,-1,10);
- break;
- case 3:
- _dirty=(mark==maxi);
- _encodedPath=uri.substring(mark);
- _path=decodePath(_encodedPath);
- break;
-
- case 4:
- _dirty=false;
- if (mark<=maxi)
- _query=uri.substring(mark);
- break;
-
- case 5:
- _dirty=false;
- }
-
- if (_query!=null && _query.length()>0)
- {
- if (_parameters==null)
- _parameters= new UrlEncoded();
- else
- _parameters.clear();
- _parameters.decode(_query,__CHARSET);
-
- }
- else
- _query=null;
- }
- catch (Exception e)
- {
- LogSupport.ignore(log,e);
- throw new IllegalArgumentException("Malformed URI '"+uri+
- "' : "+e.toString());
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Is the URI an absolute URL?
- * @return True if the URI has a scheme or host
- */
- public boolean isAbsolute()
- {
- return _scheme!=null || _host!=null;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the uri scheme.
- * @return the URI scheme
- */
- public String getScheme()
- {
- return _scheme;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the uri scheme.
- * @param scheme the uri scheme
- */
- public void setScheme(String scheme)
- {
- _scheme=scheme;
- _dirty=true;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the uri host.
- * @return the URI host
- */
- public String getHost()
- {
- return _host;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the uri host.
- * @param host the uri host
- */
- public void setHost(String host)
- {
- _host=host;
- _dirty=true;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the uri port.
- * @return the URI port
- */
- public int getPort()
- {
- return _port;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the uri port.
- * A port of 0 implies use the default port.
- * @param port the uri port
- */
- public void setPort(int port)
- {
- _port=port;
- _dirty=true;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the uri path.
- * @return the URI path
- */
- public String getPath()
- {
- return _path;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the encoded uri path.
- * @return the URI path
- */
- public String getEncodedPath()
- {
- return _encodedPath;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the uri path.
- * @param path the URI path
- */
- public void setPath(String path)
- {
- _path=path;
- _encodedPath=encodePath(_path);
- _dirty=true;
- }
-
-
- /* ------------------------------------------------------------ */
- /** Get the uri query String.
- * @return the URI query string
- */
- public String getQuery()
- {
- if (_dirty && _parameters!=null)
- {
- _query = _parameters.encode(__CHARSET);
- if (_query!=null && _query.length()==0)
- _query=null;
- }
- return _query;
- }
-
- /* ------------------------------------------------------------ */
- /** Set the uri query String.
- * @param query the URI query string
- */
- public void setQuery(String query)
- {
- _query=query;
-
- if (_parameters!=null)
- _parameters.clear();
- else if (query!=null)
- _parameters=new UrlEncoded();
-
- if (query!=null)
- _parameters.decode(query,__CHARSET);
-
- cleanURI();
- }
-
- /* ------------------------------------------------------------ */
- /** Get the uri query _parameters names.
- * @return Unmodifiable set of URI query _parameters names
- */
- public Set getParameterNames()
- {
- if (_parameters==null)
- return Collections.EMPTY_SET;
- return _parameters.keySet();
- }
-
- /* ------------------------------------------------------------ */
- /** Get the uri query _parameters.
- * @return the URI query _parameters
- */
- public MultiMap getParameters()
- {
- if (_parameters==null)
- _parameters=new UrlEncoded();
- _dirty=true;
- return _parameters;
- }
-
- /* ------------------------------------------------------------ */
- /** Get the uri query _parameters.
- * @return the URI query _parameters in an unmodifiable map.
- */
- public Map getUnmodifiableParameters()
- {
- if (_parameters==null)
- return Collections.EMPTY_MAP;
- return Collections.unmodifiableMap(_parameters);
- }
-
- /* ------------------------------------------------------------ */
- /** Add the uri query _parameters to a MultiMap
- */
- public void putParametersTo(MultiMap map)
- {
- if (_parameters!=null && _parameters.size()>0)
- map.putAll(_parameters);
- }
-
- /* ------------------------------------------------------------ */
- /** Clear the URI _parameters.
- */
- public void clearParameters()
- {
- if (_parameters!=null)
- {
- _dirty=true;
- _parameters.clear();
- }
- }
-
- /* ------------------------------------------------------------ */
- /** Add encoded _parameters.
- * @param encoded A HTTP encoded string of _parameters: e.g.. "a=1&b=2"
- */
- public void put(String encoded)
- {
- UrlEncoded params = new UrlEncoded(encoded);
- put(params);
- }
-
- /* ------------------------------------------------------------ */
- /** Add name value pair to the uri query _parameters.
- * @param name name of value
- * @param value The value, which may be a multi valued list or
- * String array.
- */
- public Object put(Object name, Object value)
- {
- return getParameters().put(name,value);
- }
-
- /* ------------------------------------------------------------ */
- /** Add dictionary to the uri query _parameters.
- */
- public void put(Map values)
- {
- getParameters().putAll(values);
- }
-
- /* ------------------------------------------------------------ */
- /** Get named value
- */
- public String get(String name)
- {
- if (_parameters==null)
- return null;
- return (String)_parameters.get(name);
- }
-
- /* ------------------------------------------------------------ */
- /** Get named multiple values.
- * @param name The parameter name
- * @return Umodifiable list of values or null
- */
- public List getValues(String name)
- {
- if (_parameters==null)
- return null;
- return _parameters.getValues(name);
- }
-
- /* ------------------------------------------------------------ */
- /** Remove named value
- */
- public void remove(String name)
- {
- if (_parameters!=null)
- {
- _dirty=
- _parameters.remove(name)!=null;
- }
- }
-
- /* ------------------------------------------------------------ */
- /** @return the URI string encoded.
- */
- public String toString()
- {
- if (_dirty)
- {
- getQuery();
- cleanURI();
- }
- return _uri;
- }
-
- /* ------------------------------------------------------------ */
- private void cleanURI()
- {
- StringBuffer buf = new StringBuffer(_uri.length()*2);
- synchronized(buf)
- {
- if (_scheme!=null)
- {
- buf.append(_scheme);
- buf.append("://");
- buf.append(_host);
- if (_port>0)
- {
- buf.append(':');
- buf.append(_port);
- }
- }
-
- buf.append(_encodedPath);
-
- if (_query!=null && _query.length()>0)
- {
- buf.append('?');
- buf.append(_query);
- }
- _uri=buf.toString();
- _dirty=false;
- }
- }
-
-
- /* ------------------------------------------------------------ */
- /** Encode a URI path.
- * This is the same encoding offered by URLEncoder, except that
- * the '/' character is not encoded.
- * @param path The path the encode
- * @return The encoded path
- */
- public static String encodePath(String path)
- {
- if (path==null || path.length()==0)
- return path;
-
- StringBuffer buf = encodePath(null,path);
- return buf==null?path:buf.toString();
- }
-
- /* ------------------------------------------------------------ */
- /** Encode a URI path.
- * @param path The path the encode
- * @param buf StringBuffer to encode path into (or null)
- * @return The StringBuffer or null if no substitutions required.
- */
- public static StringBuffer encodePath(StringBuffer buf, String path)
- {
- /* Convert path to native character set not __CHARSET.
- * This is important to do this way because the path
- * contains *OS specific characters* and __CHARSET could
- * be wrong and not encode/decode the path correctly.
- */
- byte[] b = null;
- /*
- Keep commented out unless you can prove that this does the right thing.
- try {
- b = path.getBytes(__CHARSET);
- } catch(UnsupportedEncodingException ex) {
- return null; // Shouldn't be possible.
- }
- */
- b = path.getBytes();
- StringBuffer x = new StringBuffer(b.length);
- for(int i=0; i> 8) & 0xff));
- buf.append(gethex(c & 0xff));
- }
- */
- buf.append(gethex(c & 0xff));
- } else {
- buf.append(c);
- }
- }
- }
-
- return buf;
- }
-
- /**
- *
- * @param decimal value not greater than 255.
- * @return a percent sign followed by two hexadecimal digits.
- */
- private static String gethex(int decimal) {
- return new String("%" + hexchars.charAt(decimal >> 4) + hexchars.charAt(decimal & 0xF));
- }
- /* ------------------------------------------------------------ */
- /** Encode a URI path.
- * @param path The path the encode
- * @param buf StringBuffer to encode path into (or null)
- * @param encode String of characters to encode. % is always encoded.
- * @return The StringBuffer or null if no substitutions required.
- */
- public static StringBuffer encodeString(StringBuffer buf,
- String path,
- String encode)
- {
- if (buf==null)
- {
- loop:
- for (int i=0;i=0)
- {
- buf=new StringBuffer(path.length()<<1);
- break loop;
- }
- }
- if (buf==null)
- return null;
- }
-
- synchronized(buf)
- {
- for (int i=0;i=0)
- {
- buf.append('%');
- StringUtil.append(buf,(byte)(0xff&c),16);
- }
- else
- buf.append(c);
- }
- }
-
- return buf;
- }
-
- /* ------------------------------------------------------------ */
- /* Decode a URI path.
- * @param path The path the encode
- * @param buf StringBuffer to encode path into
- */
- public static String decodePath(String path)
- {
- int len=path.length();
- byte[] bytes=null;
- int n=0;
- boolean noDecode=true;
-
- for (int i=0;i=0)
- return p.substring(0,slash+1);
- return null;
- }
-
- /* ------------------------------------------------------------ */
- /** Strip parameters from a path.
- * Return path upto any semicolon parameters.
- */
- public static String stripPath(String path)
- {
- if (path==null)
- return null;
- int semi=path.indexOf(';');
- if (semi<0)
- return path;
- return path.substring(0,semi);
- }
-
- /* ------------------------------------------------------------ */
- /** Convert a path to a cananonical form.
- * All instances of "." and ".." are factored out. Null is returned
- * if the path tries to .. above it's root.
- * @param path
- * @return path or null.
- */
- public static String canonicalPath(String path)
- {
- if (path==null || path.length()==0)
- return path;
-
- int end=path.length();
- int start = path.lastIndexOf('/', end);
-
- search:
- while (end>0)
- {
- switch(end-start)
- {
- case 2: // possible single dot
- if (path.charAt(start+1)!='.')
- break;
- break search;
- case 3: // possible double dot
- if (path.charAt(start+1)!='.' || path.charAt(start+2)!='.')
- break;
- break search;
- }
-
- end=start;
- start=path.lastIndexOf('/',end-1);
- }
-
- // If we have checked the entire string
- if (start>=end)
- return path;
-
- StringBuffer buf = new StringBuffer(path);
- int delStart=-1;
- int delEnd=-1;
- int skip=0;
-
- while (end>0)
- {
- switch(end-start)
- {
- case 2: // possible single dot
- if (buf.charAt(start+1)!='.')
- {
- if (skip>0 && --skip==0)
- {
- delStart=start>=0?start:0;
- if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
- delStart++;
- }
- break;
- }
-
- if(start<0 && buf.length()>2 && buf.charAt(1)=='/' && buf.charAt(2)=='/')
- break;
-
- if(delEnd<0)
- delEnd=end;
- delStart=start;
- if (delStart<0 || delStart==0&&buf.charAt(delStart)=='/')
- {
- delStart++;
- if (delEnd=0 && buf.charAt(start)!='/')
- start--;
- continue;
-
- case 3: // possible double dot
- if (buf.charAt(start+1)!='.' || buf.charAt(start+2)!='.')
- {
- if (skip>0 && --skip==0)
- { delStart=start>=0?start:0;
- if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
- delStart++;
- }
- break;
- }
-
- delStart=start;
- if (delEnd<0)
- delEnd=end;
-
- skip++;
- end=start--;
- while (start>=0 && buf.charAt(start)!='/')
- start--;
- continue;
-
- default:
- if (skip>0 && --skip==0)
- {
- delStart=start>=0?start:0;
- if(delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
- delStart++;
- }
- }
-
- // Do the delete
- if (skip<=0 && delStart>=0 && delStart>=0)
- {
- buf.delete(delStart,delEnd);
- delStart=delEnd=-1;
- if (skip>0)
- delEnd=end;
- }
-
- end=start--;
- while (start>=0 && buf.charAt(start)!='/')
- start--;
- }
-
- // Too many ..
- if (skip>0)
- return null;
-
- // Do the delete
- if (delEnd>=0)
- buf.delete(delStart,delEnd);
-
- return buf.toString();
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param uri URI
- * @return True if the uri has a scheme
- */
- public static boolean hasScheme(String uri)
- {
- for (int i=0;i='a'&&c<='z' ||
- c>='A'&&c<='Z' ||
- (i>0 &&(c>='0'&&c<='9' ||
- c=='.' ||
- c=='+' ||
- c=='-'))
- ))
- break;
- }
- return false;
- }
-
-}
-
-
-
diff --git a/apps/routerconsole/java/build.xml b/apps/routerconsole/java/build.xml
index f49153486c..0ce64a59d0 100644
--- a/apps/routerconsole/java/build.xml
+++ b/apps/routerconsole/java/build.xml
@@ -21,7 +21,11 @@
+
+
+
+
@@ -53,7 +57,11 @@
+
+
+
+
@@ -233,6 +241,7 @@
+
@@ -266,6 +275,10 @@
+
+
+
+
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
index eb28a4b90e..07e65d4d65 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java
@@ -14,7 +14,7 @@ import net.i2p.router.client.ClientManagerFacadeImpl;
import net.i2p.router.startup.ClientAppConfig;
import net.i2p.router.startup.LoadClientAppsJob;
-import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.ContextHandlerCollection;
/**
* Saves changes to clients.config or webapps.config
@@ -286,7 +286,7 @@ public class ConfigClientsHandler extends FormHandler {
* requested and add the .war to that one
*/
private void startWebApp(String app) {
- Server s = WebAppStarter.getConsoleServer();
+ ContextHandlerCollection s = WebAppStarter.getConsoleServer();
if (s != null) {
try {
File path = new File(_context.getBaseDir(), "webapps");
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java
index b7a892587b..98050bce2f 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/LocaleWebAppHandler.java
@@ -4,11 +4,13 @@ import java.io.IOException;
import java.util.Locale;
import java.util.Map;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
import net.i2p.I2PAppContext;
-import org.mortbay.http.HttpRequest;
-import org.mortbay.http.HttpResponse;
-import org.mortbay.jetty.servlet.WebApplicationHandler;
+import org.mortbay.jetty.webapp.WebAppContext;
/**
* Convert foo.jsp to foo_xx.jsp for language xx.
@@ -19,12 +21,12 @@ import org.mortbay.jetty.servlet.WebApplicationHandler;
*
* @author zzz
*/
-public class LocaleWebAppHandler extends WebApplicationHandler
+public class LocaleWebAppHandler extends WebAppContext
{
private final I2PAppContext _context;
- public LocaleWebAppHandler(I2PAppContext ctx) {
- super();
+ public LocaleWebAppHandler(I2PAppContext ctx, String path, String warPath) {
+ super(warPath, path);
_context = ctx;
}
@@ -36,13 +38,13 @@ public class LocaleWebAppHandler extends WebApplicationHandler
*/
@Override
public void handle(String pathInContext,
- String pathParams,
- HttpRequest httpRequest,
- HttpResponse httpResponse)
- throws IOException
+ HttpServletRequest httpRequest,
+ HttpServletResponse httpResponse,
+ int dispatch)
+ throws IOException, ServletException
{
// Handle OPTIONS (nothing to override)
- if (HttpRequest.__OPTIONS.equals(httpRequest.getMethod()))
+ if ("OPTIONS".equals(httpRequest.getMethod()))
{
handleOptions(httpRequest, httpResponse);
return;
@@ -74,7 +76,9 @@ public class LocaleWebAppHandler extends WebApplicationHandler
if (lang != null && lang.length() > 0 && !lang.equals("en")) {
String testPath = pathInContext.substring(0, len - 4) + '_' + lang + ".jsp";
// Do we have a servlet for the new path that isn't the catchall *.jsp?
- Map.Entry servlet = getHolderEntry(testPath);
+ //Map.Entry servlet = getHolderEntry(testPath);
+///////////////////////////////
+ Map.Entry servlet = null;
if (servlet != null) {
String servletPath = (String) servlet.getKey();
if (servletPath != null && !servletPath.startsWith("*")) {
@@ -87,7 +91,7 @@ public class LocaleWebAppHandler extends WebApplicationHandler
}
}
//System.err.println("New path: " + newPath);
- super.handle(newPath, pathParams, httpRequest, httpResponse);
+ super.handle(newPath, httpRequest, httpResponse, dispatch);
//System.err.println("Was handled? " + httpRequest.isHandled());
}
@@ -95,22 +99,24 @@ public class LocaleWebAppHandler extends WebApplicationHandler
* Overrides method in ServletHandler
* @since 0.8
*/
+/**** not in Jetty 6
@Override
- public void handleTrace(HttpRequest request,
- HttpResponse response)
+ public void handleTrace(HttpServletRequest request,
+ HttpServletResponse response)
throws IOException
{
- response.sendError(HttpResponse.__405_Method_Not_Allowed);
+ response.sendError(405);
}
+****/
/**
* Not an override
* @since 0.8
*/
- public void handleOptions(HttpRequest request,
- HttpResponse response)
+ public void handleOptions(HttpServletRequest request,
+ HttpServletResponse response)
throws IOException
{
- response.sendError(HttpResponse.__405_Method_Not_Allowed);
+ response.sendError(405);
}
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java
index 959b8b7974..4ebf32f9df 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java
@@ -5,14 +5,14 @@ import java.util.List;
import net.i2p.util.FileUtil;
-import org.mortbay.http.Version;
+import org.mortbay.jetty.Server;
public class LogsHelper extends HelperBase {
public LogsHelper() {}
/** @since 0.8.11 */
public String getJettyVersion() {
- return Version.getImplVersion();
+ return Server.getVersion();
}
public String getLogs() {
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
index d1835a3206..614f52c976 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
@@ -28,7 +28,7 @@ import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.Translate;
-import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.ContextHandlerCollection;
/**
@@ -120,7 +120,7 @@ public class PluginStarter implements Runnable {
}
// start console webapps in console/webapps
- Server server = WebAppStarter.getConsoleServer();
+ ContextHandlerCollection server = WebAppStarter.getConsoleServer();
if (server != null) {
File consoleDir = new File(pluginDir, "console");
Properties props = RouterConsoleRunner.webAppProperties(consoleDir.getAbsolutePath());
@@ -221,8 +221,8 @@ public class PluginStarter implements Runnable {
}
// stop console webapps in console/webapps
- Server server = WebAppStarter.getConsoleServer();
- if (server != null) {
+ //ContextHandlerCollection server = WebAppStarter.getConsoleServer();
+ //if (server != null) {
/*
File consoleDir = new File(pluginDir, "console");
Properties props = RouterConsoleRunner.webAppProperties(consoleDir.getAbsolutePath());
@@ -242,11 +242,11 @@ public class PluginStarter implements Runnable {
Iterator wars = pluginWars.get(appName).iterator();
while (wars.hasNext()) {
String warName = wars.next();
- WebAppStarter.stopWebApp(server, warName);
+ WebAppStarter.stopWebApp(warName);
}
pluginWars.get(appName).clear();
}
- }
+ //}
// remove summary bar link
Properties props = pluginProperties(ctx, appName);
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
index 15c7f76f5f..93f549d5ea 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
@@ -9,6 +9,7 @@ import java.security.KeyStore;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
+import java.util.concurrent.TimeUnit;
import net.i2p.I2PAppContext;
import net.i2p.apps.systray.SysTray;
@@ -24,25 +25,39 @@ import net.i2p.util.SecureFileOutputStream;
import net.i2p.util.ShellCommand;
import net.i2p.util.VersionComparator;
-import org.mortbay.http.DigestAuthenticator;
-import org.mortbay.http.HashUserRealm;
-import org.mortbay.http.NCSARequestLog;
-import org.mortbay.http.SecurityConstraint;
-import org.mortbay.http.SocketListener;
-import org.mortbay.http.SslListener;
-import org.mortbay.http.handler.SecurityHandler;
+import org.mortbay.jetty.AbstractConnector;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.NCSARequestLog;
import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.WebApplicationContext;
-import org.mortbay.jetty.servlet.WebApplicationHandler;
-import org.mortbay.util.InetAddrPort;
+import org.mortbay.jetty.handler.ContextHandlerCollection;
+import org.mortbay.jetty.handler.DefaultHandler;
+import org.mortbay.jetty.handler.HandlerCollection;
+import org.mortbay.jetty.handler.RequestLogHandler;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.security.DigestAuthenticator;
+import org.mortbay.jetty.security.HashUserRealm;
+import org.mortbay.jetty.security.Constraint;
+import org.mortbay.jetty.security.ConstraintMapping;
+import org.mortbay.jetty.security.SecurityHandler;
+import org.mortbay.jetty.security.SslSelectChannelConnector;
+import org.mortbay.jetty.servlet.ServletHandler;
+import org.mortbay.jetty.servlet.SessionHandler;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.thread.QueuedThreadPool;
+import org.mortbay.thread.concurrent.ThreadPool;
+/**
+ * Start the router console.
+ */
public class RouterConsoleRunner {
- private Server _server;
+ private static Server _server;
private String _listenPort;
private String _listenHost;
private String _sslListenPort;
private String _sslListenHost;
private String _webAppsDir;
+
private static final String PROP_WEBAPP_CONFIG_FILENAME = "router.webappsConfigFile";
private static final String DEFAULT_WEBAPP_CONFIG_FILENAME = "webapps.config";
private static final DigestAuthenticator authenticator = new DigestAuthenticator();
@@ -57,6 +72,10 @@ public class RouterConsoleRunner {
private static final String DEFAULT_WEBAPPS_DIR = "./webapps/";
private static final String USAGE = "Bad RouterConsoleRunner arguments, check clientApp.0.args in your clients.config file! " +
"Usage: [[port host[,host]] [-s sslPort [host[,host]]] [webAppsDir]]";
+
+ private static final int MIN_THREADS = 1;
+ private static final int MAX_THREADS = 24;
+ private static final int MAX_IDLE_TIME = 90*1000;
static {
System.setProperty("org.mortbay.http.Version.paranoid", "true");
@@ -135,6 +154,15 @@ public class RouterConsoleRunner {
runner.startConsole();
}
+ /**
+ * SInce _server is now static
+ * @return may be null or stopped perhaps
+ * @since Jetty 6 since it doesn't have Server.getServers()
+ */
+ static Server getConsoleServer() {
+ return _server;
+ }
+
private static void startTrayApp() {
try {
//TODO: move away from routerconsole into a separate application.
@@ -158,6 +186,23 @@ public class RouterConsoleRunner {
}
}
+ /**
+ * http://irc.codehaus.org/display/JETTY/Porting+to+jetty6
+ *
+ *
+ * Server
+ * HandlerCollection
+ * ContextHandlerCollection
+ * WebAppContext (i.e. ContextHandler)
+ * SessionHandler
+ * SecurityHandler
+ * ServletHandler
+ * WebAppContext
+ * ...
+ * DefaultHandler
+ * RequestLogHandler (opt)
+ *
+ */
public void startConsole() {
File workDir = new SecureDirectory(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work");
boolean workDirRemoved = FileUtil.rmdir(workDir, false);
@@ -171,14 +216,34 @@ public class RouterConsoleRunner {
System.setProperty("jetty.class.path", I2PAppContext.getGlobalContext().getBaseDir() + "/lib/routerconsole.jar");
_server = new Server();
+ /**** this doesn't work with NIO maybe?
+ try {
+ _server.setThreadPool(new ThreadPool(MIN_THREADS, MAX_THREADS, MAX_IDLE_TIME, TimeUnit.MILLISECONDS));
+ } catch (Throwable t) {
+ // class not found...
+ System.out.println("INFO: Jetty concurrent ThreadPool unavailable, using QueuedThreadPool");
+ QueuedThreadPool qtp = new QueuedThreadPool(MAX_THREADS);
+ qtp.setMinThreads(MIN_THREADS);
+ qtp.setMaxIdleTimeMs(MAX_IDLE_TIME);
+ _server.setThreadPool(qtp);
+ }
+ ****/
+ HandlerCollection hColl = new HandlerCollection();
+ ContextHandlerCollection chColl = new ContextHandlerCollection();
+ _server.addHandler(hColl);
+ hColl.addHandler(chColl);
+ hColl.addHandler(new DefaultHandler());
+
String log = I2PAppContext.getGlobalContext().getProperty("routerconsole.log");
if (log != null) {
File logFile = new File(log);
if (!logFile.isAbsolute())
logFile = new File(I2PAppContext.getGlobalContext().getLogDir(), "logs/" + log);
try {
- _server.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
- } catch (IOException ioe) {
+ RequestLogHandler rhl = new RequestLogHandler();
+ rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
+ hColl.addHandler(rhl);
+ } catch (Exception ioe) {
System.err.println("ERROR: Unable to create Jetty log: " + ioe);
}
}
@@ -202,7 +267,7 @@ public class RouterConsoleRunner {
_webAppsDir += '/';
List notStarted = new ArrayList();
- WebApplicationHandler baseHandler = null;
+ WebAppContext baseHandler = null;
try {
int boundAddresses = 0;
@@ -217,17 +282,17 @@ public class RouterConsoleRunner {
// _server.addListener('[' + host + "]:" + _listenPort);
//else
// _server.addListener(host + ':' + _listenPort);
- InetAddrPort iap = new InetAddrPort(host, lport);
- SocketListener lsnr = new SocketListener(iap);
- lsnr.setMinThreads(1); // default 2
- lsnr.setMaxThreads(24); // default 256
- lsnr.setMaxIdleTimeMs(90*1000); // default 10 sec
+ // Use AbstractConnector instead of Connector so we can do setName()
+ AbstractConnector lsnr = new SelectChannelConnector();
+ lsnr.setHost(host);
+ lsnr.setPort(lport);
+ lsnr.setMaxIdleTime(90*1000); // default 10 sec
lsnr.setName("ConsoleSocket"); // all with same name will use the same thread pool
- _server.addListener(lsnr);
+ _server.addConnector(lsnr);
boundAddresses++;
} catch (NumberFormatException nfe) {
System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ' ' + nfe);
- } catch (IOException ioe) { // this doesn't seem to work, exceptions don't happen until start() below
+ } catch (Exception ioe) { // this doesn't seem to work, exceptions don't happen until start() below
System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ' ' + ioe);
}
}
@@ -252,19 +317,20 @@ public class RouterConsoleRunner {
while (tok.hasMoreTokens()) {
String host = tok.nextToken().trim();
// doing it this way means we don't have to escape an IPv6 host with []
- InetAddrPort iap = new InetAddrPort(host, sslPort);
try {
- SslListener ssll = new SslListener(iap);
+ // TODO if class not found use SslChannelConnector
+ // Sadly there's no common base class with the ssl methods in it
+ SslSelectChannelConnector ssll = new SslSelectChannelConnector();
+ ssll.setHost(host);
+ ssll.setPort(sslPort);
// the keystore path and password
ssll.setKeystore(keyStore.getAbsolutePath());
ssll.setPassword(ctx.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD));
// the X.509 cert password (if not present, verifyKeyStore() returned false)
ssll.setKeyPassword(ctx.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
- ssll.setMinThreads(1); // default 2
- ssll.setMaxThreads(24); // default 256
- ssll.setMaxIdleTimeMs(90*1000); // default 10 sec
+ ssll.setMaxIdleTime(90*1000); // default 10 sec
ssll.setName("ConsoleSocket"); // all with same name will use the same thread pool
- _server.addListener(ssll);
+ _server.addConnector(ssll);
boundAddresses++;
} catch (Exception e) { // probably no exceptions at this point
System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
@@ -280,15 +346,18 @@ public class RouterConsoleRunner {
System.err.println("Unable to bind routerconsole to any address on port " + _listenPort + (sslPort > 0 ? (" or SSL port " + sslPort) : ""));
return;
}
- _server.setRootWebApp(ROUTERCONSOLE);
- WebApplicationContext wac = _server.addWebApplication("/", _webAppsDir + ROUTERCONSOLE + ".war");
+
+ baseHandler = new LocaleWebAppHandler(I2PAppContext.getGlobalContext(),
+ "/", _webAppsDir + ROUTERCONSOLE + ".war");
File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" +
(_listenPort != null ? _listenPort : _sslListenPort));
tmpdir.mkdir();
- wac.setTempDirectory(tmpdir);
- baseHandler = new LocaleWebAppHandler(I2PAppContext.getGlobalContext());
- wac.addHandler(0, baseHandler);
- initialize(wac);
+ baseHandler.setTempDirectory(tmpdir);
+ baseHandler.setSessionHandler(new SessionHandler());
+ baseHandler.setServletHandler(new ServletHandler());
+ initialize(baseHandler);
+ chColl.addHandler(baseHandler);
+
File dir = new File(_webAppsDir);
String fileNames[] = dir.list(WarFilenameFilter.instance());
if (fileNames != null) {
@@ -300,7 +369,7 @@ public class RouterConsoleRunner {
String path = new File(dir, fileNames[i]).getCanonicalPath();
tmpdir = new SecureDirectory(workDir, appName + "-" +
(_listenPort != null ? _listenPort : _sslListenPort));
- WebAppStarter.addWebApp(I2PAppContext.getGlobalContext(), _server, appName, path, tmpdir);
+ WebAppStarter.addWebApp(I2PAppContext.getGlobalContext(), chColl, appName, path, tmpdir);
if (enabled == null) {
// do this so configclients.jsp knows about all apps from reading the config
@@ -315,12 +384,14 @@ public class RouterConsoleRunner {
}
}
}
- } catch (IOException ioe) {
+ } catch (Exception ioe) {
ioe.printStackTrace();
}
+
if (rewrite)
storeWebAppProperties(props);
try {
+ // start does a mapContexts()
_server.start();
} catch (Throwable me) {
// NoClassFoundDefError from a webapp is a throwable, not an exception
@@ -337,8 +408,9 @@ public class RouterConsoleRunner {
// map each not-started webapp to the error page
for (int i = 0; i < notStarted.size(); i++) {
try {
- baseHandler.mapPathToServlet('/' + notStarted.get(i) + "/*",
- "net.i2p.router.web.jsp.nowebapp_jsp");
+/////////////////////////////////////////////////
+ //baseHandler.mapPathToServlet('/' + notStarted.get(i) + "/*",
+ // "net.i2p.router.web.jsp.nowebapp_jsp");
} catch (Throwable me) {
System.err.println(me);
}
@@ -454,18 +526,22 @@ public class RouterConsoleRunner {
return success;
}
- static void initialize(WebApplicationContext context) {
+ static void initialize(WebAppContext context) {
+ SecurityHandler sec = new SecurityHandler();
+ List constraints = new ArrayList(4);
String password = getPassword();
if (password != null) {
HashUserRealm realm = new HashUserRealm("i2prouter");
realm.put("admin", password);
realm.addUserToRole("admin", "routerAdmin");
- context.setRealm(realm);
- context.setAuthenticator(authenticator);
- context.addHandler(0, new SecurityHandler());
- SecurityConstraint constraint = new SecurityConstraint("admin", "routerAdmin");
+ sec.setUserRealm(realm);
+ sec.setAuthenticator(authenticator);
+ Constraint constraint = new Constraint("admin", "routerAdmin");
constraint.setAuthenticate(true);
- context.addSecurityConstraint("/", constraint);
+ ConstraintMapping cm = new ConstraintMapping();
+ cm.setConstraint(constraint);
+ cm.setPathSpec("/");
+ constraints.add(cm);
}
// This forces a '403 Forbidden' response for TRACE and OPTIONS unless the
@@ -477,12 +553,27 @@ public class RouterConsoleRunner {
// The other strange methods - PUT, DELETE, MOVE - are disabled by default
// See also:
// http://old.nabble.com/Disable-HTTP-TRACE-in-Jetty-5.x-td12412607.html
- SecurityConstraint sc = new SecurityConstraint();
- sc.setName("No trace or options");
- sc.addMethod("TRACE");
- sc.addMethod("OPTIONS");
- sc.setAuthenticate(true);
- context.addSecurityConstraint("/*", sc) ;
+
+ Constraint sc = new Constraint();
+ sc.setName("No trace");
+ ConstraintMapping cm = new ConstraintMapping();
+ cm.setMethod("TRACE");
+ cm.setConstraint(sc);
+ cm.setPathSpec("/");
+ constraints.add(cm);
+
+ sc = new Constraint();
+ sc.setName("No options");
+ cm = new ConstraintMapping();
+ cm.setMethod("OPTIONS");
+ cm.setConstraint(sc);
+ cm.setPathSpec("/");
+ constraints.add(cm);
+
+ ConstraintMapping cmarr[] = constraints.toArray(new ConstraintMapping[constraints.size()]);
+ sec.setConstraintMappings(cmarr);
+
+ context.setSecurityHandler(sec);
}
static String getPassword() {
@@ -507,11 +598,11 @@ public class RouterConsoleRunner {
}
/** @since 0.8.8 */
- private class ServerShutdown implements Runnable {
+ private static class ServerShutdown implements Runnable {
public void run() {
try {
_server.stop();
- } catch (InterruptedException ie) {}
+ } catch (Exception ie) {}
}
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java b/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java
index 0943ea4177..249ae4582e 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/WebAppConfiguration.java
@@ -6,7 +6,8 @@ import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
-import org.mortbay.jetty.servlet.WebApplicationContext;
+import org.mortbay.jetty.webapp.Configuration;
+import org.mortbay.jetty.webapp.WebAppContext;
/**
@@ -31,16 +32,16 @@ import org.mortbay.jetty.servlet.WebApplicationContext;
* @since 0.7.12
* @author zzz
*/
-public class WebAppConfiguration implements WebApplicationContext.Configuration {
- private WebApplicationContext _wac;
+public class WebAppConfiguration implements Configuration {
+ private WebAppContext _wac;
private static final String CLASSPATH = ".classpath";
- public void setWebApplicationContext(WebApplicationContext context) {
+ public void setWebAppContext(WebAppContext context) {
_wac = context;
}
- public WebApplicationContext getWebApplicationContext() {
+ public WebAppContext getWebAppContext() {
return _wac;
}
@@ -87,10 +88,16 @@ public class WebAppConfiguration implements WebApplicationContext.Configuration
else
path = dir.getAbsolutePath() + '/' + elem;
System.err.println("Adding " + path + " to classpath for " + appName);
- _wac.addClassPath(path);
+ _wac.setExtraClasspath(path);
}
}
public void configureDefaults() {}
public void configureWebApp() {}
+
+ /** @since Jetty 6 */
+ public void deconfigureWebApp() {}
+
+ /** @since Jetty 6 */
+ public void configureClassLoader() {}
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java
index 9c47190c14..0c4d7ac473 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java
@@ -14,10 +14,12 @@ import net.i2p.util.Log;
import net.i2p.util.SecureDirectory;
import net.i2p.util.PortMapper;
-import org.mortbay.http.HttpContext;
-import org.mortbay.http.HttpListener;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.WebApplicationContext;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.jetty.handler.ContextHandler;
+import org.mortbay.jetty.handler.ContextHandlerCollection;
/**
@@ -49,9 +51,10 @@ public class WebAppStarter {
* adds and starts
* @throws just about anything, caller would be wise to catch Throwable
*/
- static void startWebApp(I2PAppContext ctx, Server server, String appName, String warPath) throws Exception {
+ static void startWebApp(I2PAppContext ctx, ContextHandlerCollection server,
+ String appName, String warPath) throws Exception {
File tmpdir = new SecureDirectory(ctx.getTempDir(), "jetty-work-" + appName + ctx.random().nextInt());
- WebApplicationContext wac = addWebApp(ctx, server, appName, warPath, tmpdir);
+ WebAppContext wac = addWebApp(ctx, server, appName, warPath, tmpdir);
_log.debug("Loading war from: " + warPath);
wac.start();
}
@@ -61,12 +64,13 @@ public class WebAppStarter {
* This is used only by RouterConsoleRunner, which adds all the webapps first
* and then starts all at once.
*/
- static WebApplicationContext addWebApp(I2PAppContext ctx, Server server, String appName, String warPath, File tmpdir) throws IOException {
+ static WebAppContext addWebApp(I2PAppContext ctx, ContextHandlerCollection server,
+ String appName, String warPath, File tmpdir) throws IOException {
// Jetty will happily load one context on top of another without stopping
// the first one, so we remove any previous one here
try {
- stopWebApp(server, appName);
+ stopWebApp(appName);
} catch (Throwable t) {}
// To avoid ZipErrors from JarURLConnetion caching,
@@ -91,7 +95,7 @@ public class WebAppStarter {
warPath = tmpPath;
}
- WebApplicationContext wac = server.addWebApplication("/"+ appName, warPath);
+ WebAppContext wac = new WebAppContext(warPath, "/"+ appName);
tmpdir.mkdir();
wac.setTempDirectory(tmpdir);
@@ -101,12 +105,14 @@ public class WebAppStarter {
// see WebAppConfiguration for info
- String[] classNames = server.getWebApplicationConfigurationClassNames();
+ String[] classNames = wac.getConfigurationClasses();
String[] newClassNames = new String[classNames.length + 1];
for (int j = 0; j < classNames.length; j++)
newClassNames[j] = classNames[j];
newClassNames[classNames.length] = WebAppConfiguration.class.getName();
- wac.setConfigurationClassNames(newClassNames);
+ wac.setConfigurationClasses(newClassNames);
+ server.addHandler(wac);
+ server.mapContexts();
return wac;
}
@@ -114,38 +120,55 @@ public class WebAppStarter {
* stop it and remove the context
* @throws just about anything, caller would be wise to catch Throwable
*/
- static void stopWebApp(Server server, String appName) {
- // this will return a new context if one does not exist
- HttpContext wac = server.getContext('/' + appName);
+ static void stopWebApp(String appName) {
+ ContextHandler wac = getWebApp(appName);
+ if (wac == null)
+ return;
try {
- // false -> not graceful
- wac.stop(false);
- } catch (InterruptedException ie) {}
+ // not graceful is default in Jetty 6?
+ wac.stop();
+ } catch (Exception ie) {}
+ ContextHandlerCollection server = getConsoleServer();
+ if (server == null)
+ return;
try {
- server.removeContext(wac);
+ server.removeHandler(wac);
+ server.mapContexts();
} catch (IllegalStateException ise) {}
}
static boolean isWebAppRunning(String appName) {
- Server server = WebAppStarter.getConsoleServer();
- if (server == null)
+ ContextHandler wac = getWebApp(appName);
+ if (wac == null)
return false;
- // this will return a new context if one does not exist
- HttpContext wac = server.getContext('/' + appName);
return wac.isStarted();
}
- /** see comments in ConfigClientsHandler */
- static Server getConsoleServer() {
- Collection c = Server.getHttpServers();
- for (int i = 0; i < c.size(); i++) {
- Server s = (Server) c.toArray()[i];
- HttpListener[] hl = s.getListeners();
- for (int j = 0; j < hl.length; j++) {
- if (hl[j].getPort() == I2PAppContext.getGlobalContext().portMapper().getPort(PortMapper.SVC_CONSOLE))
- return s;
- }
+ /** @since Jetty 6 */
+ static ContextHandler getWebApp(String appName) {
+ ContextHandlerCollection server = getConsoleServer();
+ if (server == null)
+ return null;
+ Handler handlers[] = server.getHandlers();
+ if (handlers == null)
+ return null;
+ String path = '/'+ appName;
+ for (int i = 0; i < handlers.length; i++) {
+ ContextHandler ch = (ContextHandler) handlers[i];
+ if (appName.equals(ch.getContextPath()))
+ return ch;
}
return null;
}
+
+ /** see comments in ConfigClientsHandler */
+ static ContextHandlerCollection getConsoleServer() {
+ Server s = RouterConsoleRunner.getConsoleServer();
+ if (s == null)
+ return null;
+ Handler h = s.getChildHandlerByClass(ContextHandlerCollection.class);
+ if (h == null)
+ return null;
+ return (ContextHandlerCollection) h;
+ }
}
diff --git a/apps/susidns/src/build.xml b/apps/susidns/src/build.xml
index d287e5a4d0..156492ea58 100644
--- a/apps/susidns/src/build.xml
+++ b/apps/susidns/src/build.xml
@@ -17,6 +17,7 @@
+
diff --git a/apps/susimail/build.xml b/apps/susimail/build.xml
index 8a8d33c4ad..b660be49e3 100644
--- a/apps/susimail/build.xml
+++ b/apps/susimail/build.xml
@@ -19,6 +19,7 @@
+
diff --git a/apps/susimail/src/WEB-INF/web.xml b/apps/susimail/src/WEB-INF/web.xml
index bab239ed07..e3f93d229f 100644
--- a/apps/susimail/src/WEB-INF/web.xml
+++ b/apps/susimail/src/WEB-INF/web.xml
@@ -15,4 +15,26 @@
15
-
+
+
+
+-
diff --git a/apps/susimail/src/src/i2p/susi/webmail/RequestWrapper.java b/apps/susimail/src/src/i2p/susi/webmail/RequestWrapper.java
index 98350708ca..c02aae599f 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/RequestWrapper.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/RequestWrapper.java
@@ -35,6 +35,19 @@ import javax.servlet.http.HttpSession;
import org.mortbay.servlet.MultiPartRequest;
/**
+ * Required major changes for Jetty 6
+ * to support change from MultiPartRequest to MultiPartFilter.
+ * See http://docs.codehaus.org/display/JETTY/File+Upload+in+jetty6
+ * Unfortunately, Content-type not available until Jetty 8
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=349110
+ *
+ * So we could either extend and fix MultiPartFilter, and rewrite everything here,
+ * or copy MultiParRequest into our war and fix it so it compiles with Jetty 6.
+ * We do the latter.
+ *
+ * The filter would have been added in web.xml,
+ * see that file, where it's commented out.
+ *
* @author user
*/
public class RequestWrapper {
diff --git a/build.properties b/build.properties
index 9ae4afb969..2f7920cba8 100644
--- a/build.properties
+++ b/build.properties
@@ -10,6 +10,6 @@
# Javadocs
# Note: Include the trailing slash! Don't surround the URL in quotes!
javasedocs.url=http://docs.oracle.com/javase/6/docs/api/
-jettydocs.url=http://docs.i2p2.de/jetty/javadoc/
+jettydocs.url=http://jetty.codehaus.org/jetty/jetty-6/apidocs/
jrobindocs.url=http://docs.i2p-projekt.de/jrobin/javadoc/
wrapperdocs.url=http://wrapper.tanukisoftware.com/jdoc/
diff --git a/build.xml b/build.xml
index 51715be3fd..4efacca7a9 100644
--- a/build.xml
+++ b/build.xml
@@ -194,12 +194,9 @@
-
-
-
-
-
-
+
+
+
@@ -391,9 +388,10 @@
+
-
+
@@ -412,10 +410,16 @@
+
+
+
+
+
+
@@ -670,14 +674,12 @@
-
-
-
-
-
+
+
+
+
-
@@ -724,20 +726,13 @@
-
-
-
-
-
-
-
-
+
+
-
@@ -931,14 +926,18 @@
+
-
-
-
-
-
-
+
+
+
+
+
diff --git a/installer/resources/clients.config b/installer/resources/clients.config
index 08c6c62ba8..8d408cb17a 100644
--- a/installer/resources/clients.config
+++ b/installer/resources/clients.config
@@ -40,7 +40,7 @@ clientApp.2.args=i2ptunnel.config
clientApp.2.startOnLoad=true
# run our own eepsite with a seperate jetty instance
-clientApp.3.main=org.mortbay.jetty.Server
+clientApp.3.main=org.mortbay.start.Main
clientApp.3.name=I2P webserver (eepsite)
clientApp.3.args="eepsite/jetty.xml"
clientApp.3.delay=30
diff --git a/installer/resources/eepsite/contexts/base-context.xml b/installer/resources/eepsite/contexts/base-context.xml
new file mode 100644
index 0000000000..1eac073303
--- /dev/null
+++ b/installer/resources/eepsite/contexts/base-context.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ /
+ ./eepsite/docroot/
+
+
+
+
+ - index.html
+
+
+ max-age=3600,public
+
+
+
+
diff --git a/installer/resources/eepsite/contexts/cgi-context.xml b/installer/resources/eepsite/contexts/cgi-context.xml
new file mode 100644
index 0000000000..68ffa38aad
--- /dev/null
+++ b/installer/resources/eepsite/contexts/cgi-context.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ /cgi-bin
+
+
+ ./eepsite/cgi-bin/
+
+
+
+
diff --git a/installer/resources/eepsite.help/help/index.html b/installer/resources/eepsite/docroot/help/index.html
similarity index 100%
rename from installer/resources/eepsite.help/help/index.html
rename to installer/resources/eepsite/docroot/help/index.html
diff --git a/installer/resources/eepsite.help/help/index_de.html b/installer/resources/eepsite/docroot/help/index_de.html
similarity index 100%
rename from installer/resources/eepsite.help/help/index_de.html
rename to installer/resources/eepsite/docroot/help/index_de.html
diff --git a/installer/resources/eepsite.help/help/index_fr.html b/installer/resources/eepsite/docroot/help/index_fr.html
similarity index 100%
rename from installer/resources/eepsite.help/help/index_fr.html
rename to installer/resources/eepsite/docroot/help/index_fr.html
diff --git a/installer/resources/eepsite.help/help/index_na.html b/installer/resources/eepsite/docroot/help/index_na.html
similarity index 100%
rename from installer/resources/eepsite.help/help/index_na.html
rename to installer/resources/eepsite/docroot/help/index_na.html
diff --git a/installer/resources/eepsite.help/help/index_nl.html b/installer/resources/eepsite/docroot/help/index_nl.html
similarity index 100%
rename from installer/resources/eepsite.help/help/index_nl.html
rename to installer/resources/eepsite/docroot/help/index_nl.html
diff --git a/installer/resources/eepsite.help/help/index_ru.html b/installer/resources/eepsite/docroot/help/index_ru.html
similarity index 100%
rename from installer/resources/eepsite.help/help/index_ru.html
rename to installer/resources/eepsite/docroot/help/index_ru.html
diff --git a/installer/resources/eepsite.help/help/index_sv.html b/installer/resources/eepsite/docroot/help/index_sv.html
similarity index 100%
rename from installer/resources/eepsite.help/help/index_sv.html
rename to installer/resources/eepsite/docroot/help/index_sv.html
diff --git a/installer/resources/eepsite.help/help/lib/bg.png b/installer/resources/eepsite/docroot/help/lib/bg.png
similarity index 100%
rename from installer/resources/eepsite.help/help/lib/bg.png
rename to installer/resources/eepsite/docroot/help/lib/bg.png
diff --git a/installer/resources/eepsite.help/help/lib/brown.png b/installer/resources/eepsite/docroot/help/lib/brown.png
similarity index 100%
rename from installer/resources/eepsite.help/help/lib/brown.png
rename to installer/resources/eepsite/docroot/help/lib/brown.png
diff --git a/installer/resources/eepsite.help/help/lib/eepsite.css b/installer/resources/eepsite/docroot/help/lib/eepsite.css
similarity index 100%
rename from installer/resources/eepsite.help/help/lib/eepsite.css
rename to installer/resources/eepsite/docroot/help/lib/eepsite.css
diff --git a/installer/resources/eepsite.help/help/lib/h2bg.png b/installer/resources/eepsite/docroot/help/lib/h2bg.png
similarity index 100%
rename from installer/resources/eepsite.help/help/lib/h2bg.png
rename to installer/resources/eepsite/docroot/help/lib/h2bg.png
diff --git a/installer/resources/eepsite.help/help/lib/itoopie.png b/installer/resources/eepsite/docroot/help/lib/itoopie.png
similarity index 100%
rename from installer/resources/eepsite.help/help/lib/itoopie.png
rename to installer/resources/eepsite/docroot/help/lib/itoopie.png
diff --git a/installer/resources/eepsite.help/help/pagetemplate.html b/installer/resources/eepsite/docroot/help/pagetemplate.html
similarity index 100%
rename from installer/resources/eepsite.help/help/pagetemplate.html
rename to installer/resources/eepsite/docroot/help/pagetemplate.html
diff --git a/installer/resources/eepsite.help/index.html b/installer/resources/eepsite/docroot/index.html
similarity index 100%
rename from installer/resources/eepsite.help/index.html
rename to installer/resources/eepsite/docroot/index.html
diff --git a/installer/resources/eepsite.help/robots.txt b/installer/resources/eepsite/docroot/robots.txt
similarity index 100%
rename from installer/resources/eepsite.help/robots.txt
rename to installer/resources/eepsite/docroot/robots.txt
diff --git a/installer/resources/eepsite/etc/realm.properties b/installer/resources/eepsite/etc/realm.properties
new file mode 100644
index 0000000000..f9e4e7fa3c
--- /dev/null
+++ b/installer/resources/eepsite/etc/realm.properties
@@ -0,0 +1,21 @@
+#
+# This file defines users passwords and roles for a HashUserRealm
+#
+# The format is
+# : [, ...]
+#
+# Passwords may be clear text, obfuscated or checksummed. The class
+# org.mortbay.util.Password should be used to generate obfuscated
+# passwords or password checksums
+#
+# If DIGEST Authentication is used, the password must be in a recoverable
+# format, either plain text or OBF:.
+#
+jetty: MD5:164c88b302622e17050af52c89945d44,user
+admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin
+other: OBF:1xmk1w261u9r1w1c1xmq
+plain: plain
+user: password
+
+# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
+digest: MD5:6e120743ad67abfbc385bc2bb754e297
diff --git a/installer/resources/eepsite/jetty.xml b/installer/resources/eepsite/jetty.xml
new file mode 100644
index 0000000000..632c54afa0
--- /dev/null
+++ b/installer/resources/eepsite/jetty.xml
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 127.0.0.1
+ 7658
+ 60000
+ 2
+ false
+ 8443
+ 5000
+ 5000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./eepsite/contexts
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [
+
+
+ ./eepsite/logs/yyyy_mm_dd.request.log
+ yyyy_MM_dd
+ 90
+ true
+ false
+ false
+ GMT
+
+
+ ]
+
+
+
+
+ true
+ false
+ true
+ 1000
+
+
diff --git a/installer/resources/jetty.xml b/installer/resources/jetty.xml
deleted file mode 100644
index a5072d8d75..0000000000
--- a/installer/resources/jetty.xml
+++ /dev/null
@@ -1,238 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 127.0.0.1
- 7658
-
-
- 1
- 16
- 60000
- 1000
- 8443
- 8443
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- root
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /
- ./eepsite/docroot
-
-
-
- FALSE
-
-
-
- - GET
- - HEAD
- - POST
-
-
-
-
-
-
-
-
-
-
- /cgi-bin/*
- ./eepsite/cgi-bin
-
- Common Gateway Interface
- /
- org.mortbay.servlet.CGI
- /usr/local/bin:/usr/ucb:/bin:/usr/bin
-
-
-
-
-
-
-
-
- ./eepsite/logs/yyyy_mm_dd.request.log
- 90
- true
- false
- false
- GMT
-
-
-
-
-
-
- 2000
-
-
-
diff --git a/router/java/src/net/i2p/router/startup/WorkingDir.java b/router/java/src/net/i2p/router/startup/WorkingDir.java
index a1f414ac29..648b2ff0c8 100644
--- a/router/java/src/net/i2p/router/startup/WorkingDir.java
+++ b/router/java/src/net/i2p/router/startup/WorkingDir.java
@@ -147,7 +147,9 @@ public class WorkingDir {
System.err.println("Setting up new user directory " + rv);
boolean success = migrate(MIGRATE_BASE, oldDirf, dirf);
// this one must be after MIGRATE_BASE
- success &= migrateJettyXml(oldDirf, dirf);
+ success &= migrateJettyXml(oldDirf, dirf, "jetty.xml");
+ success &= migrateJettyXml(oldDirf, dirf, "contexts/base-context.xml");
+ success &= migrateJettyXml(oldDirf, dirf, "contexts/cgi-context.xml");
success &= migrateClientsConfig(oldDirf, dirf);
// for later news.xml updates (we don't copy initialNews.xml over anymore)
success &= (new SecureDirectory(dirf, "docs")).mkdir();
@@ -258,11 +260,11 @@ public class WorkingDir {
* It was already copied over once in migrate(), throw that out and
* do it again with modifications.
*/
- private static boolean migrateJettyXml(File olddir, File todir) {
+ private static boolean migrateJettyXml(File olddir, File todir, String filename) {
File eepsite1 = new File(olddir, "eepsite");
- File oldFile = new File(eepsite1, "jetty.xml");
+ File oldFile = new File(eepsite1, filename);
File eepsite2 = new File(todir, "eepsite");
- File newFile = new File(eepsite2, "jetty.xml");
+ File newFile = new File(eepsite2, filename);
FileInputStream in = null;
PrintWriter out = null;
try {
@@ -276,11 +278,11 @@ public class WorkingDir {
out.println(s);
}
out.println("");
- System.err.println("Copied jetty.xml with modifications");
+ System.err.println("Copied " + filename + " with modifications");
return true;
} catch (IOException ioe) {
if (in != null) {
- System.err.println("FAILED copy jetty.xml");
+ System.err.println("FAILED copy " + filename);
return false;
}
return false;