103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.server.handler; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.OutputStream; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URL; 2403928aee4356845252ac6b662d5c72c29903813eJake Slack 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletException; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletRequest; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletResponse; 2803928aee4356845252ac6b662d5c72c29903813eJake Slack 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpHeaders; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpMethods; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.MimeTypes; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Handler; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Request; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Server; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.ByteArrayISO8859Writer; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.IO; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.Resource; 4003928aee4356845252ac6b662d5c72c29903813eJake Slack 4103928aee4356845252ac6b662d5c72c29903813eJake Slack 4203928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */ 4303928aee4356845252ac6b662d5c72c29903813eJake Slack/** Default Handler. 4403928aee4356845252ac6b662d5c72c29903813eJake Slack * 4503928aee4356845252ac6b662d5c72c29903813eJake Slack * This handle will deal with unhandled requests in the server. 4603928aee4356845252ac6b662d5c72c29903813eJake Slack * For requests for favicon.ico, the Jetty icon is served. 4703928aee4356845252ac6b662d5c72c29903813eJake Slack * For reqests to '/' a 404 with a list of known contexts is served. 4803928aee4356845252ac6b662d5c72c29903813eJake Slack * For all other requests a normal 404 is served. 4903928aee4356845252ac6b662d5c72c29903813eJake Slack * TODO Implement OPTIONS and TRACE methods for the server. 5003928aee4356845252ac6b662d5c72c29903813eJake Slack * 5103928aee4356845252ac6b662d5c72c29903813eJake Slack * 5203928aee4356845252ac6b662d5c72c29903813eJake Slack * @org.apache.xbean.XBean 5303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 5403928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class DefaultHandler extends AbstractHandler 5503928aee4356845252ac6b662d5c72c29903813eJake Slack{ 5603928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(DefaultHandler.class); 5703928aee4356845252ac6b662d5c72c29903813eJake Slack 5803928aee4356845252ac6b662d5c72c29903813eJake Slack final long _faviconModified=(System.currentTimeMillis()/1000)*1000L; 5903928aee4356845252ac6b662d5c72c29903813eJake Slack byte[] _favicon; 6003928aee4356845252ac6b662d5c72c29903813eJake Slack boolean _serveIcon=true; 6103928aee4356845252ac6b662d5c72c29903813eJake Slack boolean _showContexts=true; 6203928aee4356845252ac6b662d5c72c29903813eJake Slack 6303928aee4356845252ac6b662d5c72c29903813eJake Slack public DefaultHandler() 6403928aee4356845252ac6b662d5c72c29903813eJake Slack { 6503928aee4356845252ac6b662d5c72c29903813eJake Slack try 6603928aee4356845252ac6b662d5c72c29903813eJake Slack { 6703928aee4356845252ac6b662d5c72c29903813eJake Slack URL fav = this.getClass().getClassLoader().getResource("org/eclipse/jetty/favicon.ico"); 6803928aee4356845252ac6b662d5c72c29903813eJake Slack if (fav!=null) 6903928aee4356845252ac6b662d5c72c29903813eJake Slack { 7003928aee4356845252ac6b662d5c72c29903813eJake Slack Resource r = Resource.newResource(fav); 7103928aee4356845252ac6b662d5c72c29903813eJake Slack _favicon=IO.readBytes(r.getInputStream()); 7203928aee4356845252ac6b662d5c72c29903813eJake Slack } 7303928aee4356845252ac6b662d5c72c29903813eJake Slack } 7403928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 7503928aee4356845252ac6b662d5c72c29903813eJake Slack { 7603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 7703928aee4356845252ac6b662d5c72c29903813eJake Slack } 7803928aee4356845252ac6b662d5c72c29903813eJake Slack } 7903928aee4356845252ac6b662d5c72c29903813eJake Slack 8003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 8103928aee4356845252ac6b662d5c72c29903813eJake Slack /* 8203928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) 8303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 8403928aee4356845252ac6b662d5c72c29903813eJake Slack public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 8503928aee4356845252ac6b662d5c72c29903813eJake Slack { 8603928aee4356845252ac6b662d5c72c29903813eJake Slack if (response.isCommitted() || baseRequest.isHandled()) 8703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 8803928aee4356845252ac6b662d5c72c29903813eJake Slack 8903928aee4356845252ac6b662d5c72c29903813eJake Slack baseRequest.setHandled(true); 9003928aee4356845252ac6b662d5c72c29903813eJake Slack 9103928aee4356845252ac6b662d5c72c29903813eJake Slack String method=request.getMethod(); 9203928aee4356845252ac6b662d5c72c29903813eJake Slack 9303928aee4356845252ac6b662d5c72c29903813eJake Slack // little cheat for common request 9403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_serveIcon && _favicon!=null && method.equals(HttpMethods.GET) && request.getRequestURI().equals("/favicon.ico")) 9503928aee4356845252ac6b662d5c72c29903813eJake Slack { 9603928aee4356845252ac6b662d5c72c29903813eJake Slack if (request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE)==_faviconModified) 9703928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 9803928aee4356845252ac6b662d5c72c29903813eJake Slack else 9903928aee4356845252ac6b662d5c72c29903813eJake Slack { 10003928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_OK); 10103928aee4356845252ac6b662d5c72c29903813eJake Slack response.setContentType("image/x-icon"); 10203928aee4356845252ac6b662d5c72c29903813eJake Slack response.setContentLength(_favicon.length); 10303928aee4356845252ac6b662d5c72c29903813eJake Slack response.setDateHeader(HttpHeaders.LAST_MODIFIED, _faviconModified); 10403928aee4356845252ac6b662d5c72c29903813eJake Slack response.setHeader(HttpHeaders.CACHE_CONTROL,"max-age=360000,public"); 10503928aee4356845252ac6b662d5c72c29903813eJake Slack response.getOutputStream().write(_favicon); 10603928aee4356845252ac6b662d5c72c29903813eJake Slack } 10703928aee4356845252ac6b662d5c72c29903813eJake Slack return; 10803928aee4356845252ac6b662d5c72c29903813eJake Slack } 10903928aee4356845252ac6b662d5c72c29903813eJake Slack 11003928aee4356845252ac6b662d5c72c29903813eJake Slack 11103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!method.equals(HttpMethods.GET) || !request.getRequestURI().equals("/")) 11203928aee4356845252ac6b662d5c72c29903813eJake Slack { 11303928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_NOT_FOUND); 11403928aee4356845252ac6b662d5c72c29903813eJake Slack return; 11503928aee4356845252ac6b662d5c72c29903813eJake Slack } 11603928aee4356845252ac6b662d5c72c29903813eJake Slack 11703928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_NOT_FOUND); 11803928aee4356845252ac6b662d5c72c29903813eJake Slack response.setContentType(MimeTypes.TEXT_HTML); 11903928aee4356845252ac6b662d5c72c29903813eJake Slack 12003928aee4356845252ac6b662d5c72c29903813eJake Slack ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500); 12103928aee4356845252ac6b662d5c72c29903813eJake Slack 12203928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("<HTML>\n<HEAD>\n<TITLE>Error 404 - Not Found"); 12303928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("</TITLE>\n<BODY>\n<H2>Error 404 - Not Found.</H2>\n"); 12403928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("No context on this server matched or handled this request.<BR>"); 12503928aee4356845252ac6b662d5c72c29903813eJake Slack 12603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_showContexts) 12703928aee4356845252ac6b662d5c72c29903813eJake Slack { 12803928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("Contexts known to this server are: <ul>"); 12903928aee4356845252ac6b662d5c72c29903813eJake Slack 13003928aee4356845252ac6b662d5c72c29903813eJake Slack Server server = getServer(); 13103928aee4356845252ac6b662d5c72c29903813eJake Slack Handler[] handlers = server==null?null:server.getChildHandlersByClass(ContextHandler.class); 13203928aee4356845252ac6b662d5c72c29903813eJake Slack 13303928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;handlers!=null && i<handlers.length;i++) 13403928aee4356845252ac6b662d5c72c29903813eJake Slack { 13503928aee4356845252ac6b662d5c72c29903813eJake Slack ContextHandler context = (ContextHandler)handlers[i]; 13603928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.isRunning()) 13703928aee4356845252ac6b662d5c72c29903813eJake Slack { 13803928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("<li><a href=\""); 13903928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0) 14003928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("http://"+context.getVirtualHosts()[0]+":"+request.getLocalPort()); 14103928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(context.getContextPath()); 14203928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getContextPath().length()>1 && context.getContextPath().endsWith("/")) 14303928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("/"); 14403928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("\">"); 14503928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(context.getContextPath()); 14603928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0) 14703928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(" @ "+context.getVirtualHosts()[0]+":"+request.getLocalPort()); 14803928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(" ---> "); 14903928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(context.toString()); 15003928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("</a></li>\n"); 15103928aee4356845252ac6b662d5c72c29903813eJake Slack } 15203928aee4356845252ac6b662d5c72c29903813eJake Slack else 15303928aee4356845252ac6b662d5c72c29903813eJake Slack { 15403928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("<li>"); 15503928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(context.getContextPath()); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0) 15703928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(" @ "+context.getVirtualHosts()[0]+":"+request.getLocalPort()); 15803928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(" ---> "); 15903928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(context.toString()); 16003928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.isFailed()) 16103928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(" [failed]"); 16203928aee4356845252ac6b662d5c72c29903813eJake Slack if (context.isStopped()) 16303928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write(" [stopped]"); 16403928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("</li>\n"); 16503928aee4356845252ac6b662d5c72c29903813eJake Slack } 16603928aee4356845252ac6b662d5c72c29903813eJake Slack } 16703928aee4356845252ac6b662d5c72c29903813eJake Slack } 16803928aee4356845252ac6b662d5c72c29903813eJake Slack 16903928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;i<10;i++) 17003928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("\n<!-- Padding for IE -->"); 17103928aee4356845252ac6b662d5c72c29903813eJake Slack 17203928aee4356845252ac6b662d5c72c29903813eJake Slack writer.write("\n</BODY>\n</HTML>\n"); 17303928aee4356845252ac6b662d5c72c29903813eJake Slack writer.flush(); 17403928aee4356845252ac6b662d5c72c29903813eJake Slack response.setContentLength(writer.size()); 17503928aee4356845252ac6b662d5c72c29903813eJake Slack OutputStream out=response.getOutputStream(); 17603928aee4356845252ac6b662d5c72c29903813eJake Slack writer.writeTo(out); 17703928aee4356845252ac6b662d5c72c29903813eJake Slack out.close(); 17803928aee4356845252ac6b662d5c72c29903813eJake Slack } 17903928aee4356845252ac6b662d5c72c29903813eJake Slack 18003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 18103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 18203928aee4356845252ac6b662d5c72c29903813eJake Slack * @return Returns true if the handle can server the jetty favicon.ico 18303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 18403928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean getServeIcon() 18503928aee4356845252ac6b662d5c72c29903813eJake Slack { 18603928aee4356845252ac6b662d5c72c29903813eJake Slack return _serveIcon; 18703928aee4356845252ac6b662d5c72c29903813eJake Slack } 18803928aee4356845252ac6b662d5c72c29903813eJake Slack 18903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 19003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 19103928aee4356845252ac6b662d5c72c29903813eJake Slack * @param serveIcon true if the handle can server the jetty favicon.ico 19203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 19303928aee4356845252ac6b662d5c72c29903813eJake Slack public void setServeIcon(boolean serveIcon) 19403928aee4356845252ac6b662d5c72c29903813eJake Slack { 19503928aee4356845252ac6b662d5c72c29903813eJake Slack _serveIcon = serveIcon; 19603928aee4356845252ac6b662d5c72c29903813eJake Slack } 19703928aee4356845252ac6b662d5c72c29903813eJake Slack 19803928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean getShowContexts() 19903928aee4356845252ac6b662d5c72c29903813eJake Slack { 20003928aee4356845252ac6b662d5c72c29903813eJake Slack return _showContexts; 20103928aee4356845252ac6b662d5c72c29903813eJake Slack } 20203928aee4356845252ac6b662d5c72c29903813eJake Slack 20303928aee4356845252ac6b662d5c72c29903813eJake Slack public void setShowContexts(boolean show) 20403928aee4356845252ac6b662d5c72c29903813eJake Slack { 20503928aee4356845252ac6b662d5c72c29903813eJake Slack _showContexts = show; 20603928aee4356845252ac6b662d5c72c29903813eJake Slack } 20703928aee4356845252ac6b662d5c72c29903813eJake Slack 20803928aee4356845252ac6b662d5c72c29903813eJake Slack} 209