001: // ========================================================================
002: // Copyright 1999-2005 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014:
015: package org.mortbay.jetty.handler;
016:
017: import java.io.IOException;
018: import java.io.OutputStream;
019: import java.net.URL;
020:
021: import javax.servlet.ServletException;
022: import javax.servlet.http.HttpServletRequest;
023: import javax.servlet.http.HttpServletResponse;
024:
025: import org.mortbay.jetty.Handler;
026: import org.mortbay.jetty.HttpConnection;
027: import org.mortbay.jetty.HttpHeaders;
028: import org.mortbay.jetty.HttpMethods;
029: import org.mortbay.jetty.MimeTypes;
030: import org.mortbay.jetty.Request;
031: import org.mortbay.jetty.Server;
032: import org.mortbay.log.Log;
033: import org.mortbay.util.ByteArrayISO8859Writer;
034: import org.mortbay.util.IO;
035: import org.mortbay.util.StringUtil;
036:
037: /* ------------------------------------------------------------ */
038: /** Default Handler.
039: *
040: * This handle will deal with unhandled requests in the server.
041: * For requests for favicon.ico, the Jetty icon is served.
042: * For reqests to '/' a 404 with a list of known contexts is served.
043: * For all other requests a normal 404 is served.
044: * TODO Implement OPTIONS and TRACE methods for the server.
045: *
046: * @author Greg Wilkins (gregw)
047: * @org.apache.xbean.XBean
048: */
049: public class DefaultHandler extends AbstractHandler {
050: long _faviconModified = (System.currentTimeMillis() / 1000) * 1000;
051: byte[] _favicon;
052: boolean _serveIcon = true;
053:
054: public DefaultHandler() {
055: try {
056: URL fav = this .getClass().getClassLoader().getResource(
057: "org/mortbay/jetty/favicon.ico");
058: if (fav != null)
059: _favicon = IO.readBytes(fav.openStream());
060: } catch (Exception e) {
061: Log.warn(e);
062: }
063: }
064:
065: /* ------------------------------------------------------------ */
066: /*
067: * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
068: */
069: public void handle(String target, HttpServletRequest request,
070: HttpServletResponse response, int dispatch)
071: throws IOException, ServletException {
072: Request base_request = request instanceof Request ? (Request) request
073: : HttpConnection.getCurrentConnection().getRequest();
074:
075: if (response.isCommitted() || base_request.isHandled())
076: return;
077: base_request.setHandled(true);
078:
079: String method = request.getMethod();
080:
081: // little cheat for common request
082: if (_serveIcon && _favicon != null
083: && method.equals(HttpMethods.GET)
084: && request.getRequestURI().equals("/favicon.ico")) {
085: if (request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE) == _faviconModified)
086: response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
087: else {
088: response.setStatus(HttpServletResponse.SC_OK);
089: response.setContentType("image/x-icon");
090: response.setContentLength(_favicon.length);
091: response.setDateHeader(HttpHeaders.LAST_MODIFIED,
092: _faviconModified);
093: response.getOutputStream().write(_favicon);
094: }
095: return;
096: }
097:
098: if (!method.equals(HttpMethods.GET)
099: || !request.getRequestURI().equals("/")) {
100: response.sendError(HttpServletResponse.SC_NOT_FOUND);
101: return;
102: }
103:
104: response.setStatus(HttpServletResponse.SC_NOT_FOUND);
105: response.setContentType(MimeTypes.TEXT_HTML);
106:
107: ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500);
108:
109: String uri = request.getRequestURI();
110: uri = StringUtil.replace(uri, "<", "<");
111: uri = StringUtil.replace(uri, ">", ">");
112:
113: writer.write("<HTML>\n<HEAD>\n<TITLE>Error 404 - Not Found");
114: writer
115: .write("</TITLE>\n<BODY>\n<H2>Error 404 - Not Found.</H2>\n");
116: writer
117: .write("No context on this server matched or handled this request.<BR>");
118: writer.write("Contexts known to this server are: <ul>");
119:
120: Server server = getServer();
121: Handler[] handlers = server == null ? null : server
122: .getChildHandlersByClass(ContextHandler.class);
123:
124: for (int i = 0; handlers != null && i < handlers.length; i++) {
125: ContextHandler context = (ContextHandler) handlers[i];
126: if (context.isRunning()) {
127: writer.write("<li><a href=\"");
128: if (context.getVirtualHosts() != null
129: && context.getVirtualHosts().length > 0)
130: writer.write("http://"
131: + context.getVirtualHosts()[0] + ":"
132: + request.getLocalPort());
133: writer.write(context.getContextPath());
134: if (context.getContextPath().length() > 1
135: && context.getContextPath().endsWith("/"))
136: writer.write("/");
137: writer.write("\">");
138: writer.write(context.getContextPath());
139: if (context.getVirtualHosts() != null
140: && context.getVirtualHosts().length > 0)
141: writer.write(" @ "
142: + context.getVirtualHosts()[0] + ":"
143: + request.getLocalPort());
144: writer.write(" ---> ");
145: writer.write(context.toString());
146: writer.write("</a></li>\n");
147: } else {
148: writer.write("<li>");
149: writer.write(context.getContextPath());
150: if (context.getVirtualHosts() != null
151: && context.getVirtualHosts().length > 0)
152: writer.write(" @ "
153: + context.getVirtualHosts()[0] + ":"
154: + request.getLocalPort());
155: writer.write(" ---> ");
156: writer.write(context.toString());
157: if (context.isFailed())
158: writer.write(" [failed]");
159: if (context.isStopped())
160: writer.write(" [stopped]");
161: writer.write("</li>\n");
162: }
163: }
164:
165: for (int i = 0; i < 10; i++)
166: writer.write("\n<!-- Padding for IE -->");
167:
168: writer.write("\n</BODY>\n</HTML>\n");
169: writer.flush();
170: response.setContentLength(writer.size());
171: OutputStream out = response.getOutputStream();
172: writer.writeTo(out);
173: out.close();
174:
175: return;
176: }
177:
178: /* ------------------------------------------------------------ */
179: /**
180: * @return Returns true if the handle can server the jetty favicon.ico
181: */
182: public boolean getServeIcon() {
183: return _serveIcon;
184: }
185:
186: /* ------------------------------------------------------------ */
187: /**
188: * @param serveIcon true if the handle can server the jetty favicon.ico
189: */
190: public void setServeIcon(boolean serveIcon) {
191: _serveIcon = serveIcon;
192: }
193:
194: }
|