Source code: org/mortbay/jetty/servlet/ServletHandler.java
1 // ===========================================================================
2 // Copyright (c) 1996-2003 Mort Bay Consulting Pty. Ltd. All rights reserved.
3 // $Id: ServletHandler.java,v 1.101 2003/11/19 11:35:55 gregwilkins Exp $
4 // ---------------------------------------------------------------------------
5
6 package org.mortbay.jetty.servlet;
7
8
9 import java.io.File;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.OutputStream;
13 import java.net.MalformedURLException;
14 import java.net.URL;
15 import java.util.Collections;
16 import java.util.Enumeration;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.Map;
20 import java.util.Set;
21
22 import javax.servlet.RequestDispatcher;
23 import javax.servlet.Servlet;
24 import javax.servlet.ServletContext;
25 import javax.servlet.ServletException;
26 import javax.servlet.UnavailableException;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29 import javax.servlet.http.HttpSession;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.mortbay.http.EOFException;
34 import org.mortbay.http.HttpContext;
35 import org.mortbay.http.HttpException;
36 import org.mortbay.http.HttpFields;
37 import org.mortbay.http.HttpRequest;
38 import org.mortbay.http.HttpResponse;
39 import org.mortbay.http.PathMap;
40 import org.mortbay.http.Version;
41 import org.mortbay.http.handler.AbstractHttpHandler;
42 import org.mortbay.util.ByteArrayISO8859Writer;
43 import org.mortbay.util.LogSupport;
44 import org.mortbay.util.MultiException;
45 import org.mortbay.util.Resource;
46 import org.mortbay.util.URI;
47
48
49 /* --------------------------------------------------------------------- */
50 /** Servlet HttpHandler.
51 * This handler maps requests to servlets that implement the
52 * javax.servlet.http.HttpServlet API.
53 * <P>
54 * This handler does not implement the full J2EE features and is intended to
55 * be used when a full web application is not required. Specifically filters
56 * and request wrapping are not supported.
57 * <P>
58 * If a SessionManager is not added to the handler before it is
59 * initialized, then a HashSessionManager with a standard
60 * java.util.Random generator is created.
61 * <P>
62 * @see org.mortbay.jetty.servlet.WebApplicationHandler
63 * @version $Id: ServletHandler.java,v 1.101 2003/11/19 11:35:55 gregwilkins Exp $
64 * @author Greg Wilkins
65 */
66 public class ServletHandler extends AbstractHttpHandler
67 {
68 private static Log log = LogFactory.getLog(ServletHandler.class);
69
70 /* ------------------------------------------------------------ */
71 public static final String __DEFAULT_SERVLET="default";
72 public static final String __J_S_CONTEXT_TEMPDIR="javax.servlet.context.tempdir";
73 public static final String __J_S_ERROR_EXCEPTION="javax.servlet.error.exception";
74 public static final String __J_S_ERROR_EXCEPTION_TYPE="javax.servlet.error.exception_type";
75 public static final String __J_S_ERROR_MESSAGE="javax.servlet.error.message";
76 public static final String __J_S_ERROR_REQUEST_URI="javax.servlet.error.request_uri";
77 public static final String __J_S_ERROR_SERVLET_NAME="javax.servlet.error.servlet_name";
78 public static final String __J_S_ERROR_STATUS_CODE="javax.servlet.error.status_code";
79
80 /* ------------------------------------------------------------ */
81 private static final boolean __Slosh2Slash=File.separatorChar=='\\';
82 private static String __AllowString="GET, HEAD, POST, OPTIONS, TRACE";
83
84
85 /* ------------------------------------------------------------ */
86 private boolean _usingCookies=true;
87 private boolean _autoInitializeServlets=true;
88
89 /* ------------------------------------------------------------ */
90 protected PathMap _servletMap=new PathMap();
91 protected Map _nameMap=new HashMap();
92 protected String _formLoginPage;
93 protected String _formErrorPage;
94 protected SessionManager _sessionManager;
95
96 protected transient Context _context;
97 protected transient ClassLoader _loader;
98
99 /* ------------------------------------------------------------ */
100 /** Constructor.
101 */
102 public ServletHandler()
103 {}
104
105 /* ------------------------------------------------------------ */
106 public void initialize(HttpContext context)
107 {
108 SessionManager sessionManager=getSessionManager();
109 super.initialize(context);
110 _context=new Context();
111 sessionManager.initialize(this);
112 }
113
114 /* ------------------------------------------------------------ */
115 public void formAuthInit(String formLoginPage,
116 String formErrorPage)
117 {
118 _formLoginPage=formLoginPage;
119 _formErrorPage=formErrorPage;
120 }
121
122 /* ------------------------------------------------------------ */
123 public void setSessionManager(SessionManager sm)
124 {
125 if (isStarted())
126 throw new IllegalStateException("Started");
127
128 _sessionManager=sm;
129 }
130
131 /* ------------------------------------------------------------ */
132 public SessionManager getSessionManager()
133 {
134 if (_sessionManager==null)
135 _sessionManager = new HashSessionManager();
136 return _sessionManager;
137 }
138
139 /* ------------------------------------------------------------ */
140 public ServletContext getServletContext() { return _context; }
141
142 /* ------------------------------------------------------------ */
143 public PathMap getServletMap() { return _servletMap; }
144
145 /* ------------------------------------------------------------ */
146 public boolean isUsingCookies() { return _usingCookies; }
147
148 /* ------------------------------------------------------------ */
149 /** Set the dynamic servlet path.
150 * @deprecated Use org.mortbay.jetty.servlet.Invoker
151 */
152 public void setDynamicServletPathSpec(String dynamicServletPathSpec)
153 {
154 log.warn("setDynamicServletPathSpec is Deprecated.");
155 }
156
157 /* ------------------------------------------------------------ */
158 /** Set dynamic servlet initial parameters.
159 * @deprecated Use org.mortbay.jetty.servlet.Invoker
160 */
161 public void setDynamicInitParams(Map initParams)
162 {
163 log.warn("setDynamicInitParams is Deprecated.");
164 }
165
166 /* ------------------------------------------------------------ */
167 /** Set serving dynamic system servlets.
168 * @deprecated Use org.mortbay.jetty.servlet.Invoker
169 */
170 public void setServeDynamicSystemServlets(boolean b)
171 {
172 log.warn("setServeDynamicSystemServlets is Deprecated.");
173 }
174
175 /* ------------------------------------------------------------ */
176 public ClassLoader getClassLoader()
177 {
178 return _loader;
179 }
180
181 /* ------------------------------------------------------------ */
182 /**
183 * @param uc If true, cookies are used for sessions
184 */
185 public void setUsingCookies(boolean uc)
186 {
187 _usingCookies=uc;
188 }
189
190 /* ------------------------------------------------------------ */
191 public ServletHolder newServletHolder(String name,
192 String servletClass,
193 String forcedPath)
194 {
195 if (_nameMap.containsKey(name))
196 throw new IllegalArgumentException("Named servlet already exists: "+name);
197
198 ServletHolder holder = new ServletHolder(this,name,servletClass,forcedPath);
199 _nameMap.put(holder.getName(),holder);
200 return holder;
201 }
202
203 /* ------------------------------------------------------------ */
204 public ServletHolder newServletHolder(String name,
205 String servletClass)
206 {
207 return newServletHolder(name,servletClass,null);
208 }
209
210 /* ------------------------------------------------------------ */
211 public ServletHolder getServletHolder(String name)
212 {
213 return (ServletHolder)_nameMap.get(name);
214 }
215
216 /* ------------------------------------------------------------ */
217 public ServletHolder mapPathToServlet(String pathSpec,
218 String servletName)
219 {
220 ServletHolder holder =(ServletHolder)_nameMap.get(servletName);
221
222 if (!pathSpec.startsWith("/") && !pathSpec.startsWith("*"))
223 {
224 log.warn("pathSpec should start with '/' or '*' : "+pathSpec);
225 pathSpec="/"+pathSpec;
226 }
227
228 if (holder==null)
229 throw new IllegalArgumentException("Unknown servlet: "+servletName);
230 _servletMap.put(pathSpec,holder);
231 return holder;
232 }
233
234 /* ------------------------------------------------------------ */
235 /** Add a servlet.
236 * @param name The servlet name.
237 * @param pathSpec A path specification to map this servlet to.
238 * @param servletClass The class name of the servlet.
239 * @param forcedPath If non null, the request attribute
240 * javax.servlet.include.servlet_path will be set to this path before
241 * service is called.
242 * @return The ServletHolder for the servlet.
243 */
244 public ServletHolder addServlet(String name,
245 String pathSpec,
246 String servletClass,
247 String forcedPath)
248 {
249 ServletHolder holder = getServletHolder(name);
250 if (holder==null)
251 holder = newServletHolder(name,servletClass,forcedPath);
252 mapPathToServlet(pathSpec,name);
253 if (isStarted() && !holder.isStarted())
254 {
255 try{holder.start();}
256 catch(Exception e){log.warn(LogSupport.EXCEPTION,e);}
257 }
258 return holder;
259 }
260
261 /* ------------------------------------------------------------ */
262 /** Add a servlet.
263 * @param name The servlet name.
264 * @param pathSpec A path specification to map this servlet to.
265 * @param servletClass The class name of the servlet.
266 * @return The ServletHolder for the servlet.
267 */
268 public ServletHolder addServlet(String name,
269 String pathSpec,
270 String servletClass)
271 {
272 return addServlet(name,pathSpec,servletClass,null);
273 }
274
275
276 /* ------------------------------------------------------------ */
277 public ServletHolder addServlet(String pathSpec,
278 String servletClass)
279 {
280 return addServlet(servletClass,pathSpec,servletClass,null);
281 }
282
283 /* ------------------------------------------------------------ */
284 void addServletHolder(String pathSpec, ServletHolder holder)
285 {
286 try
287 {
288 ServletHolder existing = (ServletHolder)
289 _nameMap.get(holder.getName());
290 if (existing==null)
291 _nameMap.put(holder.getName(),holder);
292 else if (existing!=holder)
293 throw new IllegalArgumentException("Holder already exists for name: "+holder.getName());
294
295 if (isStarted() && !holder.isStarted())
296 holder.start();
297 _servletMap.put(pathSpec,holder);
298 }
299 catch(Exception e)
300 {
301 log.warn(LogSupport.EXCEPTION,e);
302 }
303 }
304
305 /* ------------------------------------------------------------ */
306 public boolean isAutoInitializeServlets()
307 {
308 return _autoInitializeServlets;
309 }
310
311 /* ------------------------------------------------------------ */
312 public void setAutoInitializeServlets(boolean b)
313 {
314 _autoInitializeServlets=b;
315 }
316
317 /* ----------------------------------------------------------------- */
318 public synchronized void start()
319 throws Exception
320 {
321 if (isStarted())
322 return;
323
324 if (_sessionManager!=null)
325 _sessionManager.start();
326
327 // Initialize classloader
328 _loader=getHttpContext().getClassLoader();
329
330 // start the handler - protected by synchronization until
331 // end of the call.
332 super.start();
333
334 if (_autoInitializeServlets)
335 initializeServlets();
336 }
337
338 /* ------------------------------------------------------------ */
339 /** Get Servlets.
340 * @return Array of defined servlets
341 */
342 public ServletHolder[] getServlets()
343 {
344 // Sort and Initialize servlets
345 HashSet holder_set = new HashSet(_nameMap.size());
346 holder_set.addAll(_nameMap.values());
347 ServletHolder holders [] = (ServletHolder [])
348 holder_set.toArray(new ServletHolder [holder_set.size()]);
349 java.util.Arrays.sort (holders);
350 return holders;
351 }
352
353 /* ------------------------------------------------------------ */
354 /** Initialize load-on-startup servlets.
355 * Called automatically from start if autoInitializeServlet is true.
356 */
357 public void initializeServlets()
358 throws Exception
359 {
360 MultiException mx = new MultiException();
361
362 // Sort and Initialize servlets
363 ServletHolder[] holders = getServlets();
364 for (int i=0; i<holders.length; i++)
365 {
366 try{holders[i].start();}
367 catch(Exception e)
368 {
369 log.debug(LogSupport.EXCEPTION,e);
370 mx.add(e);
371 }
372 }
373 mx.ifExceptionThrow();
374 }
375
376 /* ----------------------------------------------------------------- */
377 public synchronized void stop()
378 throws InterruptedException
379 {
380 // Sort and Initialize servlets
381 ServletHolder[] holders = getServlets();
382
383 super.stop();
384
385 // Stop servlets
386 for (int i=holders.length; i-->0;)
387 {
388 try
389 {
390 if (holders[i].isStarted())
391 holders[i].stop();
392 }
393 catch(Exception e){log.warn(LogSupport.EXCEPTION,e);}
394 }
395
396 // Stop the session manager
397 _sessionManager.stop();
398
399 _loader=null;
400 }
401
402 /* ------------------------------------------------------------ */
403 HttpSession getHttpSession(String id)
404 {
405 return _sessionManager.getHttpSession(id);
406 }
407
408 /* ------------------------------------------------------------ */
409 HttpSession newHttpSession(HttpServletRequest request)
410 {
411 return _sessionManager.newHttpSession(request);
412 }
413
414 /* ------------------------------------------------------------ */
415 void setSessionInactiveInterval(int seconds)
416 {
417 _sessionManager.setMaxInactiveInterval(seconds);
418 }
419
420 /* ----------------------------------------------------------------- */
421 /** Handle request.
422 * @param pathInContext
423 * @param pathParams
424 * @param httpRequest
425 * @param httpResponse
426 * @exception IOException
427 */
428 public void handle(String pathInContext,
429 String pathParams,
430 HttpRequest httpRequest,
431 HttpResponse httpResponse)
432 throws IOException
433 {
434 if (!isStarted() && _context==null)
435 return;
436
437 // Handle TRACE
438 if (HttpRequest.__TRACE.equals(httpRequest.getMethod()))
439 {
440 handleTrace(httpRequest,httpResponse);
441 return;
442 }
443
444 // Look for existing request/response objects
445 ServletHttpRequest request = (ServletHttpRequest) httpRequest.getWrapper();
446 ServletHttpResponse response = (ServletHttpResponse) httpResponse.getWrapper();
447 if (request==null)
448 {
449 // Build the request and response.
450 request = new ServletHttpRequest(this,pathInContext,httpRequest);
451 response = new ServletHttpResponse(request,httpResponse);
452 httpRequest.setWrapper(request);
453 httpResponse.setWrapper(response);
454 }
455 else
456 {
457 // Recycled request
458 request.recycle(this,pathInContext);
459 response.recycle();
460 }
461
462
463 // Look for the servlet
464 Map.Entry servlet=getHolderEntry(pathInContext);
465 ServletHolder servletHolder=servlet==null?null:(ServletHolder)servlet.getValue();
466 if(log.isDebugEnabled())log.debug("servlet="+servlet);
467
468 try
469 {
470 // Adjust request paths
471 if (servlet!=null)
472 {
473 String servletPathSpec=(String)servlet.getKey();
474 request.setServletPaths(PathMap.pathMatch(servletPathSpec,pathInContext),
475 PathMap.pathInfo(servletPathSpec,pathInContext),
476 servletHolder);
477 }
478
479 // Handle the session ID
480 request.setSessionId(pathParams);
481 HttpSession session=request.getSession(false);
482 if (session!=null)
483 ((SessionManager.Session)session).access();
484 if(log.isDebugEnabled())log.debug("session="+session);
485
486 // Do that funky filter and servlet thang!
487 if (servletHolder!=null)
488 dispatch(pathInContext,request,response,servletHolder);
489 }
490 catch(Exception e)
491 {
492 log.debug(LogSupport.EXCEPTION,e);
493
494 Throwable th=e;
495 if (e instanceof ServletException)
496 {
497 Throwable root=((ServletException)e).getRootCause();
498 while (root instanceof ServletException)
499 root=((ServletException)e).getRootCause();
500 if (root instanceof HttpException ||
501 root instanceof EOFException)
502 {
503 if(log.isDebugEnabled())log.debug("Extracting root cause from ",e);
504 th=root;
505 }
506 }
507
508 if (th instanceof HttpException)
509 throw (HttpException)th;
510 if (th instanceof EOFException)
511 throw (IOException)th;
512 else if (!log.isDebugEnabled() && th instanceof java.io.IOException)
513 log.warn("Exception for "+httpRequest.getURI()+": "+th);
514 else
515 {
516 log.warn("Exception for "+httpRequest.getURI(),th);
517 if(log.isDebugEnabled())log.debug(httpRequest);
518 }
519
520 httpResponse.getHttpConnection().forceClose();
521 if (!httpResponse.isCommitted())
522 {
523 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,th.getClass());
524 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,th);
525 response.sendError(th instanceof UnavailableException
526 ?HttpResponse.__503_Service_Unavailable
527 :HttpResponse.__500_Internal_Server_Error,
528 e.getMessage());
529 }
530 else
531 if(log.isDebugEnabled())log.debug("Response already committed for handling "+th);
532 }
533 catch(Error e)
534 {
535 log.warn("Error for "+httpRequest.getURI(),e);
536 if(log.isDebugEnabled())log.debug(httpRequest);
537
538 httpResponse.getHttpConnection().forceClose();
539 if (!httpResponse.isCommitted())
540 {
541 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,e.getClass());
542 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,e);
543 response.sendError(HttpResponse.__500_Internal_Server_Error,
544 e.getMessage());
545 }
546 else
547 if(log.isDebugEnabled())log.debug("Response already committed for handling ",e);
548 }
549 finally
550 {
551 if (servletHolder!=null)
552 {
553 response.flushBuffer();
554 if (!httpRequest.isHandled())
555 new Throwable().printStackTrace();
556 }
557 }
558 }
559
560 /* ------------------------------------------------------------ */
561 /** Dispatch to a servletHolder.
562 * This method may be specialized to insert extra handling in the
563 * dispatch of a request to a specific servlet. This is used by
564 * WebApplicatonHandler to implement dispatched filters.
565 * The default implementation simply calls
566 * ServletHolder.handle(request,response)
567 * @param pathInContext The path used to select the servlet holder.
568 * @param request
569 * @param response
570 * @param servletHolder
571 * @exception ServletException
572 * @exception UnavailableException
573 * @exception IOException
574 */
575 protected void dispatch(String pathInContext,
576 HttpServletRequest request,
577 HttpServletResponse response,
578 ServletHolder servletHolder)
579 throws ServletException,
580 UnavailableException,
581 IOException
582 {
583 servletHolder.handle(request,response);
584 }
585
586
587 /* ------------------------------------------------------------ */
588 /** ServletHolder matching path.
589 * @param pathInContext Path within context.
590 * @return PathMap Entries pathspec to ServletHolder
591 */
592 public Map.Entry getHolderEntry(String pathInContext)
593 {
594 return _servletMap.getMatch(pathInContext);
595 }
596
597
598 /* ------------------------------------------------------------ */
599 public Set getResourcePaths(String uriInContext)
600 {
601 try
602 {
603 uriInContext=URI.canonicalPath(uriInContext);
604 if (uriInContext==null)
605 return Collections.EMPTY_SET;
606 Resource resource=getHttpContext().getResource(uriInContext);
607 if (resource==null || !resource.isDirectory())
608 return Collections.EMPTY_SET;
609 String[] contents=resource.list();
610 if (contents==null || contents.length==0)
611 return Collections.EMPTY_SET;
612 HashSet set = new HashSet(contents.length*2);
613 for (int i=0;i<contents.length;i++)
614 set.add(URI.addPaths(uriInContext,contents[i]));
615 return set;
616 }
617 catch(Exception e)
618 {
619 LogSupport.ignore(log,e);
620 }
621
622 return Collections.EMPTY_SET;
623 }
624
625
626 /* ------------------------------------------------------------ */
627 /** Get a Resource.
628 * If no resource is found, resource aliases are tried.
629 * @param uriInContext
630 * @return URL of the resource.
631 * @exception MalformedURLException
632 */
633 public URL getResource(String uriInContext)
634 throws MalformedURLException
635 {
636 try{
637 Resource resource = getHttpContext().getResource(uriInContext);
638 if (resource!=null && resource.exists())
639 return resource.getURL();
640 }
641 catch(IllegalArgumentException e)
642 {
643 LogSupport.ignore(log,e);
644 }
645 catch(MalformedURLException e)
646 {
647 throw e;
648 }
649 catch(IOException e)
650 {
651 log.warn(LogSupport.EXCEPTION,e);
652 }
653 return null;
654 }
655
656 /* ------------------------------------------------------------ */
657 public InputStream getResourceAsStream(String uriInContext)
658 {
659 try
660 {
661 uriInContext=URI.canonicalPath(uriInContext);
662 URL url = getResource(uriInContext);
663 if (url!=null)
664 return url.openStream();
665 }
666 catch(MalformedURLException e) {LogSupport.ignore(log,e);}
667 catch(IOException e) {LogSupport.ignore(log,e);}
668 return null;
669 }
670
671 /* ------------------------------------------------------------ */
672 public String getRealPath(String path)
673 {
674 if(log.isDebugEnabled())log.debug("getRealPath of "+path+" in "+this);
675
676 if (__Slosh2Slash)
677 path=path.replace('\\','/');
678 path=URI.canonicalPath(path);
679 if (path==null)
680 return null;
681
682 Resource baseResource=getHttpContext().getBaseResource();
683 if (baseResource==null )
684 return null;
685
686 try{
687 Resource resource = baseResource.addPath(path);
688 File file = resource.getFile();
689
690 return (file==null)?null:(file.getAbsolutePath());
691 }
692 catch(IOException e)
693 {
694 log.warn(LogSupport.EXCEPTION,e);
695 return null;
696 }
697 }
698
699 /* ------------------------------------------------------------ */
700 public RequestDispatcher getRequestDispatcher(String uriInContext)
701 {
702 if (uriInContext == null)
703 return null;
704
705 if (!uriInContext.startsWith("/"))
706 uriInContext="/"+uriInContext;
707
708 try
709 {
710 String query=null;
711 int q=0;
712 if ((q=uriInContext.indexOf('?'))>0)
713 {
714 query=uriInContext.substring(q+1);
715 uriInContext=uriInContext.substring(0,q);
716 }
717 if ((q=uriInContext.indexOf(';'))>0)
718 uriInContext=uriInContext.substring(0,q);
719
720 String pathInContext=URI.canonicalPath(URI.decodePath(uriInContext));
721 Map.Entry entry=getHolderEntry(pathInContext);
722 if (entry!=null)
723 return new Dispatcher(ServletHandler.this,
724 uriInContext,
725 pathInContext,
726 query,
727 entry);
728 }
729 catch(Exception e)
730 {
731 LogSupport.ignore(log,e);
732 }
733 return null;
734 }
735
736 /* ------------------------------------------------------------ */
737 /** Get Named dispatcher.
738 * @param name The name of the servlet. If null or empty string, the
739 * containers default servlet is returned.
740 * @return Request dispatcher for the named servlet.
741 */
742 public RequestDispatcher getNamedDispatcher(String name)
743 {
744 if (name == null || name.length()==0)
745 name=__DEFAULT_SERVLET;
746
747 try { return new Dispatcher(ServletHandler.this,name); }
748 catch(Exception e) {LogSupport.ignore(log,e);}
749
750 return null;
751 }
752
753
754
755 /* ------------------------------------------------------------ */
756 void notFound(HttpServletRequest request,
757 HttpServletResponse response)
758 throws IOException
759 {
760 if(log.isDebugEnabled())log.debug("Not Found "+request.getRequestURI());
761 String method=request.getMethod();
762
763 // Not found special requests.
764 if (method.equals(HttpRequest.__GET) ||
765 method.equals(HttpRequest.__HEAD) ||
766 method.equals(HttpRequest.__POST))
767 {
768 response.sendError(HttpResponse.__404_Not_Found);
769 }
770 else if (method.equals(HttpRequest.__TRACE))
771 handleTrace(request,response);
772 else if (method.equals(HttpRequest.__OPTIONS))
773 handleOptions(request,response);
774 else
775 {
776 // Unknown METHOD
777 response.setHeader(HttpFields.__Allow,__AllowString);
778 response.sendError(HttpResponse.__405_Method_Not_Allowed);
779 }
780 }
781
782 /* ------------------------------------------------------------ */
783 void handleTrace(HttpServletRequest request,
784 HttpServletResponse response)
785 throws IOException
786 {
787 response.setHeader(HttpFields.__ContentType,
788 HttpFields.__MessageHttp);
789 OutputStream out = response.getOutputStream();
790 ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
791 writer.write(request.toString());
792 writer.flush();
793 response.setIntHeader(HttpFields.__ContentLength,writer.size());
794 writer.writeTo(out);
795 out.flush();
796 }
797
798 /* ------------------------------------------------------------ */
799 void handleOptions(HttpServletRequest request,
800 HttpServletResponse response)
801 throws IOException
802 {
803 // Handle OPTIONS request for entire server
804 if ("*".equals(request.getRequestURI()))
805 {
806 // 9.2
807 response.setIntHeader(HttpFields.__ContentLength,0);
808 response.setHeader(HttpFields.__Allow,__AllowString);
809 response.flushBuffer();
810 }
811 else
812 response.sendError(HttpResponse.__404_Not_Found);
813 }
814
815 /* ------------------------------------------------------------ */
816 String getErrorPage(int status,ServletHttpRequest request)
817 {
818 return null;
819 }
820
821
822
823 /* ------------------------------------------------------------ */
824 /* ------------------------------------------------------------ */
825 /* ------------------------------------------------------------ */
826 class Context implements ServletContext
827 {
828 /* -------------------------------------------------------- */
829 ServletHandler getServletHandler()
830 {
831 return ServletHandler.this;
832 }
833
834 /* -------------------------------------------------------- */
835 public ServletContext getContext(String uri)
836 {
837 ServletHandler handler= (ServletHandler)
838 getHttpContext().getHttpServer()
839 .findHandler(org.mortbay.jetty.servlet.ServletHandler.class,
840 uri,
841 getHttpContext().getVirtualHosts());
842 if (handler!=null)
843 return handler.getServletContext();
844 return null;
845 }
846
847 /* ------------------------------------------------------------ */
848 public int getMajorVersion()
849 {
850 return 2;
851 }
852
853 /* ------------------------------------------------------------ */
854 public int getMinorVersion()
855 {
856 return 3;
857 }
858
859 /* ------------------------------------------------------------ */
860 public String getMimeType(String file)
861 {
862 return getHttpContext().getMimeByExtension(file);
863 }
864
865 /* ------------------------------------------------------------ */
866 public Set getResourcePaths(String uriInContext)
867 {
868 return ServletHandler.this.getResourcePaths(uriInContext);
869 }
870
871 /* ------------------------------------------------------------ */
872 public URL getResource(String uriInContext)
873 throws MalformedURLException
874 {
875 return ServletHandler.this.getResource(uriInContext);
876 }
877
878 /* ------------------------------------------------------------ */
879 public InputStream getResourceAsStream(String uriInContext)
880 {
881 return ServletHandler.this.getResourceAsStream(uriInContext);
882 }
883
884 /* ------------------------------------------------------------ */
885 public String getRealPath(String path)
886 {
887 return ServletHandler.this.getRealPath(path);
888 }
889
890 /* ------------------------------------------------------------ */
891 public RequestDispatcher getRequestDispatcher(String uriInContext)
892 {
893 return ServletHandler.this.getRequestDispatcher(uriInContext);
894 }
895
896 /* ------------------------------------------------------------ */
897 public RequestDispatcher getNamedDispatcher(String name)
898 {
899 return ServletHandler.this.getNamedDispatcher(name);
900 }
901
902 /* ------------------------------------------------------------ */
903 /**
904 * @deprecated
905 */
906 public Servlet getServlet(String name)
907 {
908 return null;
909 }
910
911 /* ------------------------------------------------------------ */
912 /**
913 * @deprecated
914 */
915 public Enumeration getServlets()
916 {
917 return Collections.enumeration(Collections.EMPTY_LIST);
918 }
919
920 /* ------------------------------------------------------------ */
921 /**
922 * @deprecated
923 */
924 public Enumeration getServletNames()
925 {
926 return Collections.enumeration(Collections.EMPTY_LIST);
927 }
928
929 /* ------------------------------------------------------------ */
930 /** Servlet Log.
931 * Log message to servlet log. Use either the system log or a
932 * LogSinkset via the context attribute
933 * org.mortbay.jetty.servlet.Context.LogSink
934 * @param msg
935 */
936 public void log(String msg)
937 {
938 log.info(msg);
939 }
940
941 /* ------------------------------------------------------------ */
942 /**
943 * @deprecated As of Java Servlet API 2.1, use
944 * {@link #log(String message, Throwable throwable)}
945 * instead.
946 */
947 public void log(Exception e, String msg)
948 {
949 log.warn(msg,e);
950 }
951
952 /* ------------------------------------------------------------ */
953 public void log(String msg, Throwable th)
954 {
955 log.warn(msg,th);
956 }
957
958 /* ------------------------------------------------------------ */
959 public String getServerInfo()
960 {
961 return Version.__VersionImpl;
962 }
963
964
965 /* ------------------------------------------------------------ */
966 /** Get context init parameter.
967 * Delegated to HttpContext.
968 * @param param param name
969 * @return param value or null
970 */
971 public String getInitParameter(String param)
972 {
973 return getHttpContext().getInitParameter(param);
974 }
975
976 /* ------------------------------------------------------------ */
977 /** Get context init parameter names.
978 * Delegated to HttpContext.
979 * @return Enumeration of names
980 */
981 public Enumeration getInitParameterNames()
982 {
983 return getHttpContext().getInitParameterNames();
984 }
985
986
987 /* ------------------------------------------------------------ */
988 /** Get context attribute.
989 * Delegated to HttpContext.
990 * @param name attribute name.
991 * @return attribute
992 */
993 public Object getAttribute(String name)
994 {
995 if (ServletHandler.__J_S_CONTEXT_TEMPDIR.equals(name))
996 {
997 // Initialize temporary directory
998 Object t = getHttpContext().getAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR);
999
1000 if (t instanceof File)
1001 return (File)t;
1002
1003 return getHttpContext().getTempDirectory();
1004 }
1005
1006 return getHttpContext().getAttribute(name);
1007 }
1008
1009 /* ------------------------------------------------------------ */
1010 /** Get context attribute names.
1011 * Delegated to HttpContext.
1012 */
1013 public Enumeration getAttributeNames()
1014 {
1015 return getHttpContext().getAttributeNames();
1016 }
1017
1018 /* ------------------------------------------------------------ */
1019 /** Set context attribute names.
1020 * Delegated to HttpContext.
1021 * @param name attribute name.
1022 * @param value attribute value
1023 */
1024 public void setAttribute(String name, Object value)
1025 {
1026 getHttpContext().setAttribute(name,value);
1027 }
1028
1029 /* ------------------------------------------------------------ */
1030 /** Remove context attribute.
1031 * Delegated to HttpContext.
1032 * @param name attribute name.
1033 */
1034 public void removeAttribute(String name)
1035 {
1036 getHttpContext().removeAttribute(name);
1037 }
1038
1039 /* ------------------------------------------------------------ */
1040 public String getServletContextName()
1041 {
1042 if (getHttpContext() instanceof WebApplicationContext)
1043 return ((WebApplicationContext)getHttpContext()).getDisplayName();
1044 return null;
1045 }
1046
1047 /* ------------------------------------------------------------ */
1048 public String toString()
1049 {
1050 return "ServletContext["+getHttpContext()+"]";
1051 }
1052 }
1053}