View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package com.acme;
20  import java.io.BufferedWriter;
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.io.OutputStreamWriter;
26  import java.io.PrintWriter;
27  import java.io.Reader;
28  import java.lang.reflect.Array;
29  import java.lang.reflect.Field;
30  import java.net.URL;
31  import java.util.Collections;
32  import java.util.Collection;
33  import java.util.Date;
34  import java.util.Enumeration;
35  import java.util.Locale;
36  import java.util.Timer;
37  import java.util.TimerTask;
38  
39  import javax.servlet.ServletConfig;
40  import javax.servlet.ServletContext;
41  import javax.servlet.ServletException;
42  import javax.servlet.ServletRequest;
43  import javax.servlet.ServletRequestWrapper;
44  import javax.servlet.ServletResponse;
45  import javax.servlet.ServletResponseWrapper;
46  import javax.servlet.UnavailableException;
47  import javax.servlet.http.Cookie;
48  import javax.servlet.http.HttpServlet;
49  import javax.servlet.http.HttpServletRequest;
50  import javax.servlet.http.HttpServletRequestWrapper;
51  import javax.servlet.http.HttpServletResponse;
52  import javax.servlet.http.HttpServletResponseWrapper;
53  
54  import org.eclipse.jetty.continuation.Continuation;
55  import org.eclipse.jetty.continuation.ContinuationListener;
56  import org.eclipse.jetty.continuation.ContinuationSupport;
57  import org.eclipse.jetty.http.HttpHeaders;
58  import org.eclipse.jetty.util.IO;
59  import org.eclipse.jetty.util.StringUtil;
60  import org.eclipse.jetty.util.log.Log;
61  import org.eclipse.jetty.util.log.Logger;
62  
63  
64  
65  /* ------------------------------------------------------------ */
66  /** Dump Servlet Request.
67   * 
68   */
69  public class Dump extends HttpServlet
70  {
71      private static final Logger LOG = Log.getLogger(Dump.class);
72  
73      boolean fixed;
74      Timer _timer;
75      
76      /* ------------------------------------------------------------ */
77      @Override
78      public void init(ServletConfig config) throws ServletException
79      {
80      	super.init(config);
81      	
82      	if (config.getInitParameter("unavailable")!=null && !fixed)
83      	{
84      	    
85      	    fixed=true;
86      	    throw new UnavailableException("Unavailable test",Integer.parseInt(config.getInitParameter("unavailable")));
87      	}
88      	
89      	_timer=new Timer(true);
90      }
91  
92      /* ------------------------------------------------------------ */
93      @Override
94      public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
95      {
96          doGet(request, response);
97      }
98  
99      /* ------------------------------------------------------------ */
100     @Override
101     public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
102     {
103         byte[] buffer = new byte[8192];
104         int len=request.getContentLength();
105         int c=0;
106         InputStream in=request.getInputStream();
107         while (c<len)
108         {
109             int l = in.read(buffer);
110             if (l<0)
111                 break;
112             c+=l;
113         }
114         request.setAttribute("PUT",c+"bytes");
115         doGet(request, response);
116     }
117 
118     /* ------------------------------------------------------------ */
119     @Override
120     public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
121     {
122         // Handle a dump of data
123         final String data= request.getParameter("data");
124         final String chars= request.getParameter("chars");
125         final String block= request.getParameter("block");
126         final String dribble= request.getParameter("dribble");
127         final boolean flush= request.getParameter("flush")!=null?Boolean.parseBoolean(request.getParameter("flush")):false;
128 
129         
130         if(request.getPathInfo()!=null && request.getPathInfo().toLowerCase(Locale.ENGLISH).indexOf("script")!=-1)
131         {
132             response.sendRedirect(response.encodeRedirectURL(getServletContext().getContextPath() + "/dump/info"));
133             return;
134         }
135             
136         request.setCharacterEncoding("UTF-8");
137         
138         if (request.getParameter("busy")!=null)
139         {
140             long end = System.currentTimeMillis()+Long.parseLong(request.getParameter("busy"));
141             while(System.currentTimeMillis()<end)
142             {}
143         }
144         
145         if (request.getParameter("empty")!=null)
146         {
147             response.setStatus(200);
148             response.flushBuffer();
149             return;
150         }
151         
152         if (request.getParameter("sleep")!=null)
153         {
154             try
155             {
156                 long s = Long.parseLong(request.getParameter("sleep"));
157                 if (request.getHeader(HttpHeaders.EXPECT)!=null &&request.getHeader(HttpHeaders.EXPECT).indexOf("102")>=0)
158                 {
159                     Thread.sleep(s/2);
160                     response.sendError(102);
161                     Thread.sleep(s/2);
162                 }
163                 else
164                     Thread.sleep(s);
165             }
166             catch (InterruptedException e)
167             {
168                 return;
169             }
170             catch (Exception e)
171             {
172                 throw new ServletException(e);
173             }
174         }
175 
176         if (request.getAttribute("RESUME")==null && request.getParameter("resume")!=null)
177         {
178             request.setAttribute("RESUME",Boolean.TRUE);
179 
180             final long resume=Long.parseLong(request.getParameter("resume"));
181             final Continuation continuation = ContinuationSupport.getContinuation(request);
182             _timer.schedule(new TimerTask()
183             {
184                 @Override
185                 public void run()
186                 {
187                     continuation.resume();
188                 }
189             },resume);
190   
191         }
192 
193         if (request.getParameter("complete")!=null)
194         {
195             final long complete=Long.parseLong(request.getParameter("complete"));
196             _timer.schedule(new TimerTask()
197             {
198                 @Override
199                 public void run()
200                 {
201                     try
202                     {
203                         response.setContentType("text/html");
204                         response.getOutputStream().println("<h1>COMPLETED</h1>"); 
205                         Continuation continuation = ContinuationSupport.getContinuation(request);
206                         continuation.complete();
207                     }
208                     catch(Exception e)
209                     {
210                         e.printStackTrace();
211                     }
212                 }
213             },complete);
214         }
215         
216         if (request.getParameter("suspend")!=null && request.getAttribute("SUSPEND")!=Boolean.TRUE)
217         {
218             request.setAttribute("SUSPEND",Boolean.TRUE);
219             try
220             {
221                 Continuation continuation = ContinuationSupport.getContinuation(request);
222                 continuation.setTimeout(Long.parseLong(request.getParameter("suspend")));
223                 continuation.suspend();
224                 
225                 continuation.addContinuationListener(new ContinuationListener()
226                 {   
227                     public void onTimeout(Continuation continuation)
228                     {
229                         response.addHeader("Dump","onTimeout");
230                         try
231                         {
232                             if (!dump(response,data,chars,block,dribble,flush))
233                             {
234                                 response.setContentType("text/plain");
235                                 response.getOutputStream().println("EXPIRED");
236                             }
237                             continuation.complete();
238                         }
239                         catch (IOException e)
240                         {
241                             LOG.ignore(e);
242                         }
243                     }
244                     
245                     public void onComplete(Continuation continuation)
246                     {
247                         response.addHeader("Dump","onComplete");
248                     }
249                 });
250                 
251                 continuation.undispatch();
252             }
253             catch(Exception e)
254             {
255                 throw new ServletException(e);
256             }
257         }        
258             
259         request.setAttribute("Dump", this);
260         getServletContext().setAttribute("Dump",this);
261         // getServletContext().log("dump "+request.getRequestURI());
262 
263         // Force a content length response
264         String length= request.getParameter("length");
265         if (length != null && length.length() > 0)
266         {
267             response.setContentLength(Integer.parseInt(length));
268         }
269 
270         // Handle a dump of data
271         if (dump(response,data,chars,block,dribble,flush))
272             return;
273         
274         // handle an exception
275         String info= request.getPathInfo();
276         if (info != null && info.endsWith("Exception"))
277         {
278             try
279             {
280                 throw (Throwable) Thread.currentThread().getContextClassLoader().loadClass(info.substring(1)).newInstance();
281             }
282             catch (Throwable th)
283             {
284                 throw new ServletException(th);
285             }
286         }
287 
288         // test a reset
289         String reset= request.getParameter("reset");
290         if (reset != null && reset.length() > 0)
291         {
292             response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
293             response.setHeader("SHOULD_NOT","BE SEEN");
294             response.reset();
295         }
296         
297         
298         // handle an redirect
299         String redirect= request.getParameter("redirect");
300         if (redirect != null && redirect.length() > 0)
301         {
302             response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
303             response.sendRedirect(response.encodeRedirectURL(redirect));
304             try
305             {
306                 response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
307             }
308             catch(IOException e)
309             {
310                 // ignored as stream is closed.
311             }
312             return;
313         }
314 
315         // handle an error
316         String error= request.getParameter("error");
317         if (error != null && error.length() > 0 && request.getAttribute("javax.servlet.error.status_code")==null)
318         {
319             response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
320             response.sendError(Integer.parseInt(error));
321             try
322             {
323                 response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
324             }
325             catch(IllegalStateException e)
326             {
327                 try
328                 {
329                     response.getWriter().println("NOR THIS!!"); 
330                 }
331                 catch(IOException e2){}
332             }
333             catch(IOException e){}
334             return;
335         }
336 
337         // Handle a extra headers 
338         String headers= request.getParameter("headers");
339         if (headers != null && headers.length() > 0)
340         {
341             long h=Long.parseLong(headers);
342             for (int i=0;i<h;i++)
343                 response.addHeader("Header"+i,"Value"+i);
344         }
345 
346         String buffer= request.getParameter("buffer");
347         if (buffer != null && buffer.length() > 0)
348             response.setBufferSize(Integer.parseInt(buffer));
349 
350         String charset= request.getParameter("charset");
351         if (charset==null)
352             charset="UTF-8";
353         response.setCharacterEncoding(charset);
354         response.setContentType("text/html");
355 
356         if (info != null && info.indexOf("Locale/") >= 0)
357         {
358             try
359             {
360                 String locale_name= info.substring(info.indexOf("Locale/") + 7);
361                 Field f= java.util.Locale.class.getField(locale_name);
362                 response.setLocale((Locale)f.get(null));
363             }
364             catch (Exception e)
365             {
366                 e.printStackTrace();
367                 response.setLocale(Locale.getDefault());
368             }
369         }
370 
371         String cn= request.getParameter("cookie");
372         String cv=request.getParameter("cookiev");
373         if (cn!=null && cv!=null)
374         {
375             Cookie cookie= new Cookie(cn, cv);
376             if (request.getParameter("version")!=null)
377                 cookie.setVersion(Integer.parseInt(request.getParameter("version")));
378             cookie.setComment("Cookie from dump servlet");
379             response.addCookie(cookie);
380         }
381 
382         String pi= request.getPathInfo();
383         if (pi != null && pi.startsWith("/ex"))
384         {
385             OutputStream out= response.getOutputStream();
386             out.write("</H1>This text should be reset</H1>".getBytes());
387             if ("/ex0".equals(pi))
388                 throw new ServletException("test ex0", new Throwable());
389             else if ("/ex1".equals(pi))
390                 throw new IOException("test ex1");
391             else if ("/ex2".equals(pi))
392                 throw new UnavailableException("test ex2");
393             else if (pi.startsWith("/ex3/"))
394                 throw new UnavailableException("test ex3",Integer.parseInt(pi.substring(5)));
395             throw new RuntimeException("test");
396         }
397 
398         if ("true".equals(request.getParameter("close")))
399             response.setHeader("Connection","close");
400 
401         String buffered= request.getParameter("buffered");
402         
403         PrintWriter pout=null;
404         
405         try
406         {
407             pout =response.getWriter();
408         }
409         catch(IllegalStateException e)
410         {
411             pout=new PrintWriter(new OutputStreamWriter(response.getOutputStream(),charset));
412         }
413         if (buffered!=null)
414             pout = new PrintWriter(new BufferedWriter(pout,Integer.parseInt(buffered)));
415         
416         try
417         {
418             pout.write("<html>\n<body>\n");
419             pout.write("<h1>Dump Servlet</h1>\n");
420             pout.write("<table width=\"95%\">");
421             pout.write("<tr>\n");
422             pout.write("<th align=\"right\">getMethod:&nbsp;</th>");
423             pout.write("<td>" + notag(request.getMethod())+"</td>");
424             pout.write("</tr><tr>\n");
425             pout.write("<th align=\"right\">getContentLength:&nbsp;</th>");
426             pout.write("<td>"+Integer.toString(request.getContentLength())+"</td>");
427             pout.write("</tr><tr>\n");
428             pout.write("<th align=\"right\">getContentType:&nbsp;</th>");
429             pout.write("<td>"+notag(request.getContentType())+"</td>");
430             pout.write("</tr><tr>\n");
431             pout.write("<th align=\"right\">getRequestURI:&nbsp;</th>");
432             pout.write("<td>"+notag(request.getRequestURI())+"</td>");
433             pout.write("</tr><tr>\n");
434             pout.write("<th align=\"right\">getRequestURL:&nbsp;</th>");
435             pout.write("<td>"+notag(request.getRequestURL().toString())+"</td>");
436             pout.write("</tr><tr>\n");
437             pout.write("<th align=\"right\">getContextPath:&nbsp;</th>");
438             pout.write("<td>"+request.getContextPath()+"</td>");
439             pout.write("</tr><tr>\n");
440             pout.write("<th align=\"right\">getServletPath:&nbsp;</th>");
441             pout.write("<td>"+notag(request.getServletPath())+"</td>");
442             pout.write("</tr><tr>\n");
443             pout.write("<th align=\"right\">getPathInfo:&nbsp;</th>");
444             pout.write("<td>"+notag(request.getPathInfo())+"</td>");
445             pout.write("</tr><tr>\n");
446             pout.write("<th align=\"right\">getPathTranslated:&nbsp;</th>");
447             pout.write("<td>"+notag(request.getPathTranslated())+"</td>");
448             pout.write("</tr><tr>\n");
449             pout.write("<th align=\"right\">getQueryString:&nbsp;</th>");
450             pout.write("<td>"+notag(request.getQueryString())+"</td>");
451             pout.write("</tr><tr>\n");
452             
453             pout.write("<th align=\"right\">getProtocol:&nbsp;</th>");
454             pout.write("<td>"+request.getProtocol()+"</td>");
455             pout.write("</tr><tr>\n");
456             pout.write("<th align=\"right\">getScheme:&nbsp;</th>");
457             pout.write("<td>"+request.getScheme()+"</td>");
458             pout.write("</tr><tr>\n");
459             pout.write("<th align=\"right\">getServerName:&nbsp;</th>");
460             pout.write("<td>"+notag(request.getServerName())+"</td>");
461             pout.write("</tr><tr>\n");
462             pout.write("<th align=\"right\">getServerPort:&nbsp;</th>");
463             pout.write("<td>"+Integer.toString(request.getServerPort())+"</td>");
464             pout.write("</tr><tr>\n");
465             pout.write("<th align=\"right\">getLocalName:&nbsp;</th>");
466             pout.write("<td>"+request.getLocalName()+"</td>");
467             pout.write("</tr><tr>\n");
468             pout.write("<th align=\"right\">getLocalAddr:&nbsp;</th>");
469             pout.write("<td>"+request.getLocalAddr()+"</td>");
470             pout.write("</tr><tr>\n");
471             pout.write("<th align=\"right\">getLocalPort:&nbsp;</th>");
472             pout.write("<td>"+Integer.toString(request.getLocalPort())+"</td>");
473             pout.write("</tr><tr>\n");
474             pout.write("<th align=\"right\">getRemoteUser:&nbsp;</th>");
475             pout.write("<td>"+request.getRemoteUser()+"</td>");
476             pout.write("</tr><tr>\n");
477             pout.write("<th align=\"right\">getUserPrincipal:&nbsp;</th>");
478             pout.write("<td>"+request.getUserPrincipal()+"</td>");
479             pout.write("</tr><tr>\n");
480             pout.write("<th align=\"right\">getRemoteAddr:&nbsp;</th>");
481             pout.write("<td>"+request.getRemoteAddr()+"</td>");
482             pout.write("</tr><tr>\n");
483             pout.write("<th align=\"right\">getRemoteHost:&nbsp;</th>");
484             pout.write("<td>"+request.getRemoteHost()+"</td>");
485             pout.write("</tr><tr>\n");
486             pout.write("<th align=\"right\">getRemotePort:&nbsp;</th>");
487             pout.write("<td>"+request.getRemotePort()+"</td>");
488             pout.write("</tr><tr>\n");
489             pout.write("<th align=\"right\">getRequestedSessionId:&nbsp;</th>");
490             pout.write("<td>"+request.getRequestedSessionId()+"</td>");
491             pout.write("</tr><tr>\n");
492             pout.write("<th align=\"right\">isSecure():&nbsp;</th>");
493             pout.write("<td>"+request.isSecure()+"</td>");
494 
495             pout.write("</tr><tr>\n");
496             pout.write("<th align=\"right\">isUserInRole(admin):&nbsp;</th>");
497             pout.write("<td>"+request.isUserInRole("admin")+"</td>");
498 
499             pout.write("</tr><tr>\n");
500             pout.write("<th align=\"right\">getLocale:&nbsp;</th>");
501             pout.write("<td>"+request.getLocale()+"</td>");
502             
503             Enumeration locales= request.getLocales();
504             while (locales.hasMoreElements())
505             {
506                 pout.write("</tr><tr>\n");
507                 pout.write("<th align=\"right\">getLocales:&nbsp;</th>");
508                 pout.write("<td>"+locales.nextElement()+"</td>");
509             }
510             pout.write("</tr><tr>\n");
511             
512             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Other HTTP Headers:</big></th>");
513             Enumeration h= request.getHeaderNames();
514             String name;
515             while (h.hasMoreElements())
516             {
517                 name= (String)h.nextElement();
518 
519                 Enumeration h2= request.getHeaders(name);
520                 while (h2.hasMoreElements())
521                 {
522                     String hv= (String)h2.nextElement();
523                     pout.write("</tr><tr>\n");
524                     pout.write("<th align=\"right\">"+notag(name)+":&nbsp;</th>");
525                     pout.write("<td>"+notag(hv)+"</td>");
526                 }
527             }
528 
529             pout.write("</tr><tr>\n");
530             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Request Parameters:</big></th>");
531             h= request.getParameterNames();
532             while (h.hasMoreElements())
533             {
534                 name= (String)h.nextElement();
535                 pout.write("</tr><tr>\n");
536                 pout.write("<th align=\"right\">"+notag(name)+":&nbsp;</th>");
537                 pout.write("<td>"+notag(request.getParameter(name))+"</td>");
538                 String[] values= request.getParameterValues(name);
539                 if (values == null)
540                 {
541                     pout.write("</tr><tr>\n");
542                     pout.write("<th align=\"right\">"+notag(name)+" Values:&nbsp;</th>");
543                     pout.write("<td>"+"NULL!"+"</td>");
544                 }
545                 else if (values.length > 1)
546                 {
547                     for (int i= 0; i < values.length; i++)
548                     {
549                         pout.write("</tr><tr>\n");
550                         pout.write("<th align=\"right\">"+notag(name)+"["+i+"]:&nbsp;</th>");
551                         pout.write("<td>"+notag(values[i])+"</td>");
552                     }
553                 }
554             }
555 
556             pout.write("</tr><tr>\n");
557             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Cookies:</big></th>");
558             Cookie[] cookies = request.getCookies();
559             for (int i=0; cookies!=null && i<cookies.length;i++)
560             {
561                 Cookie cookie = cookies[i];
562 
563                 pout.write("</tr><tr>\n");
564                 pout.write("<th align=\"right\">"+notag(cookie.getName())+":&nbsp;</th>");
565                 pout.write("<td>"+notag(cookie.getValue())+"</td>");
566             }
567             
568             String content_type=request.getContentType();
569             if (content_type!=null &&
570                 !content_type.startsWith("application/x-www-form-urlencoded") &&
571                 !content_type.startsWith("multipart/form-data"))
572             {
573                 pout.write("</tr><tr>\n");
574                 pout.write("<th align=\"left\" valign=\"top\" colspan=\"2\"><big><br/>Content:</big></th>");
575                 pout.write("</tr><tr>\n");
576                 pout.write("<td><pre>");
577                 char[] content= new char[4096];
578                 int len;
579                 try{
580                     Reader in=request.getReader();
581                     
582                     while((len=in.read(content))>=0)
583                         pout.write(notag(new String(content,0,len)));
584                 }
585                 catch(IOException e)
586                 {
587                     pout.write(e.toString());
588                 }
589                 
590                 pout.write("</pre></td>");
591             }
592             
593             pout.write("</tr><tr>\n");
594             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Request Attributes:</big></th>");
595             Enumeration a= request.getAttributeNames();
596             while (a.hasMoreElements())
597             {
598                 name= (String)a.nextElement();
599                 pout.write("</tr><tr>\n");
600                 pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+":&nbsp;</th>");
601                 Object value=request.getAttribute(name);
602                 if (value instanceof File)
603                 {
604                     File file = (File)value;
605                     pout.write("<td>"+"<pre>" + file.getName()+" ("+file.length()+" "+new Date(file.lastModified())+ ")</pre>"+"</td>");
606                 }
607                 else
608                     pout.write("<td>"+"<pre>" + toString(request.getAttribute(name)) + "</pre>"+"</td>");
609             }
610             request.setAttribute("org.eclipse.jetty.servlet.MultiPartFilter.files",null);
611 
612             
613             pout.write("</tr><tr>\n");
614             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Servlet InitParameters:</big></th>");
615             a= getInitParameterNames();
616             while (a.hasMoreElements())
617             {
618                 name= (String)a.nextElement();
619                 pout.write("</tr><tr>\n");
620                 pout.write("<th align=\"right\">"+name+":&nbsp;</th>");
621                 pout.write("<td>"+ toString(getInitParameter(name)) +"</td>");
622             }
623 
624             pout.write("</tr><tr>\n");
625             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Context InitParameters:</big></th>");
626             a= getServletContext().getInitParameterNames();
627             while (a.hasMoreElements())
628             {
629                 name= (String)a.nextElement();
630                 pout.write("</tr><tr>\n");
631                 pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+":&nbsp;</th>");
632                 pout.write("<td>"+ toString(getServletContext().getInitParameter(name)) + "</td>");
633             }
634 
635             pout.write("</tr><tr>\n");
636             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Context Attributes:</big></th>");
637             a= getServletContext().getAttributeNames();
638             while (a.hasMoreElements())
639             {
640                 name= (String)a.nextElement();
641                 pout.write("</tr><tr>\n");
642                 pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+":&nbsp;</th>");
643                 pout.write("<td>"+"<pre>" + toString(getServletContext().getAttribute(name)) + "</pre>"+"</td>");
644             }
645 
646             String res= request.getParameter("resource");
647             if (res != null && res.length() > 0)
648             {
649                 pout.write("</tr><tr>\n");
650                 pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Get Resource: \""+res+"\"</big></th>");
651 
652                 pout.write("</tr><tr>\n");
653                 pout.write("<th align=\"right\">getServletContext().getResource(...):&nbsp;</th>");
654                 try{pout.write("<td>"+getServletContext().getResource(res)+"</td>");}
655                 catch(Exception e) {pout.write("<td>"+"" +e+"</td>");}
656                 
657                 pout.write("</tr><tr>\n");
658                 pout.write("<th align=\"right\">getServletContext().getResourcePaths(...):&nbsp;</th>");
659                 try{pout.write("<td>"+getServletContext().getResourcePaths(res)+"</td>");}
660                 catch(Exception e) {pout.write("<td>"+"" +e+"</td>");}
661                 
662                 pout.write("</tr><tr>\n");
663                 pout.write("<th align=\"right\">getServletContext().getContext(...):&nbsp;</th>");
664                 
665                 ServletContext context = getServletContext().getContext(res);
666                 pout.write("<td>"+context+"</td>");
667                 
668                 if (context!=null)
669                 {
670                     pout.write("</tr><tr>\n");
671                     pout.write("<th align=\"right\">getServletContext().getContext(...).getResource(...):&nbsp;</th>");
672                     try{pout.write("<td>"+context.getResource(res)+"</td>");}
673                     catch(Exception e) {pout.write("<td>"+"" +e+"</td>");}
674                     
675                     pout.write("</tr><tr>\n");
676                     pout.write("<th align=\"right\">getServletContext().getContext(...).getResourcePaths(...):&nbsp;</th>");
677                     try{pout.write("<td>"+context.getResourcePaths(res)+"</td>");}
678                     catch(Exception e) {pout.write("<td>"+"" +e+"</td>");}
679                     
680                     String cp=context.getContextPath();
681                     if (cp==null || "/".equals(cp))
682                         cp="";
683                     pout.write("</tr><tr>\n");
684                     pout.write("<th align=\"right\">getServletContext().getContext(...),getRequestDispatcher(...):&nbsp;</th>");
685                     pout.write("<td>"+getServletContext().getContext(res).getRequestDispatcher(res.substring(cp.length()))+"</td>");
686                 }
687 
688                 pout.write("</tr><tr>\n");
689                 pout.write("<th align=\"right\">this.getClass().getResource(...):&nbsp;</th>");
690                 pout.write("<td>"+this.getClass().getResource(res)+"</td>");
691 
692                 pout.write("</tr><tr>\n");
693                 pout.write("<th align=\"right\">this.getClass().getClassLoader().getResource(...):&nbsp;</th>");
694                 pout.write("<td>"+this.getClass().getClassLoader().getResource(res)+"</td>");
695 
696                 pout.write("</tr><tr>\n");
697                 pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResource(...):&nbsp;</th>");
698                 pout.write("<td>"+Thread.currentThread().getContextClassLoader().getResource(res)+"</td>");
699                 pout.write("</tr><tr>\n");
700                 pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResources(...):&nbsp;</th>");
701                 Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(res);
702                 if (urls==null)
703                     pout.write("<td>null</td>");
704                 else
705                     pout.write("<td>"+Collections.list(urls)+"</td>");
706 
707             }
708             
709             pout.write("</tr></table>\n");
710 
711             /* ------------------------------------------------------------ */
712             pout.write("<h2>Request Wrappers</h2>\n");
713             ServletRequest rw=request;
714             int w=0;
715             while (rw !=null)
716             {
717                 pout.write((w++)+": "+rw.getClass().getName()+"<br/>");
718                 if (rw instanceof HttpServletRequestWrapper)
719                     rw=((HttpServletRequestWrapper)rw).getRequest();
720                 else if (rw instanceof ServletRequestWrapper)
721                     rw=((ServletRequestWrapper)rw).getRequest();
722                 else
723                     rw=null;
724             }
725 
726             /* ------------------------------------------------------------ */
727             pout.write("<h2>Response Wrappers</h2>\n");
728             ServletResponse rsw=response;
729             w=0;
730             while (rsw !=null)
731             {
732                 pout.write((w++)+": "+rsw.getClass().getName()+"<br/>");
733                 if (rsw instanceof HttpServletResponseWrapper)
734                     rsw=((HttpServletResponseWrapper)rsw).getResponse();
735                 else if (rsw instanceof ServletResponseWrapper)
736                     rsw=((ServletResponseWrapper)rsw).getResponse();
737                 else
738                     rsw=null;
739             }
740             
741             pout.write("<br/>");
742             pout.write("<h2>International Characters (UTF-8)</h2>");
743             pout.write("LATIN LETTER SMALL CAPITAL AE<br/>\n");
744             pout.write("Directly uni encoded(\\u1d01): \u1d01<br/>");
745             pout.write("HTML reference (&amp;AElig;): &AElig;<br/>");
746             pout.write("Decimal (&amp;#7425;): &#7425;<br/>");
747             pout.write("Javascript unicode (\\u1d01) : <script language='javascript'>document.write(\"\u1d01\");</script><br/>");
748             pout.write("<br/>");
749             pout.write("<h2>Form to generate GET content</h2>");
750             pout.write("<form method=\"GET\" action=\""+response.encodeURL(getURI(request))+"\">");
751             pout.write("TextField: <input type=\"text\" name=\"TextField\" value=\"value\"/><br/>\n");
752             pout.write("<input type=\"submit\" name=\"Action\" value=\"Submit\">");
753             pout.write("</form>");
754 
755             pout.write("<br/>");
756             
757             pout.write("<h2>Form to generate POST content</h2>");
758             pout.write("<form method=\"POST\" accept-charset=\"utf-8\" action=\""+response.encodeURL(getURI(request))+"\">");
759             pout.write("TextField: <input type=\"text\" name=\"TextField\" value=\"value\"/><br/>\n");
760             pout.write("Select: <select multiple name=\"Select\">\n");
761             pout.write("<option>ValueA</option>");
762             pout.write("<option>ValueB1,ValueB2</option>");
763             pout.write("<option>ValueC</option>");
764             pout.write("</select><br/>");
765             pout.write("<input type=\"submit\" name=\"Action\" value=\"Submit\"><br/>");
766             pout.write("</form>");
767             pout.write("<br/>");
768             
769             pout.write("<h2>Form to generate UPLOAD content</h2>");
770             pout.write("<form method=\"POST\" enctype=\"multipart/form-data\" accept-charset=\"utf-8\" action=\""+
771                     response.encodeURL(getURI(request))+(request.getQueryString()==null?"":("?"+request.getQueryString()))+
772                     "\">");
773             pout.write("TextField: <input type=\"text\" name=\"TextField\" value=\"comment\"/><br/>\n");
774             pout.write("File 1: <input type=\"file\" name=\"file1\" /><br/>\n");
775             pout.write("File 2: <input type=\"file\" name=\"file2\" /><br/>\n");
776             pout.write("<input type=\"submit\" name=\"Action\" value=\"Submit\"><br/>");
777             pout.write("</form>");
778 
779             pout.write("<h2>Form to set Cookie</h2>");
780             pout.write("<form method=\"POST\" action=\""+response.encodeURL(getURI(request))+"\">");
781             pout.write("cookie: <input type=\"text\" name=\"cookie\" /><br/>\n");
782             pout.write("value: <input type=\"text\" name=\"cookiev\" /><br/>\n");
783             pout.write("<input type=\"submit\" name=\"Action\" value=\"setCookie\">");
784             pout.write("</form>\n");
785             
786             pout.write("<h2>Form to get Resource</h2>");
787             pout.write("<form method=\"POST\" action=\""+response.encodeURL(getURI(request))+"\">");
788             pout.write("resource: <input type=\"text\" name=\"resource\" /><br/>\n");
789             pout.write("<input type=\"submit\" name=\"Action\" value=\"getResource\">");
790             pout.write("</form>\n");
791         }
792         catch (Exception e)
793         {
794             getServletContext().log("dump "+e);
795         }
796         
797         String lines= request.getParameter("lines");
798         if (lines!=null)
799         {
800             char[] line = "<span>A line of characters. Blah blah blah blah.  blooble blooble</span></br>\n".toCharArray();
801             for (int l=Integer.parseInt(lines);l-->0;)
802             {
803                 pout.write("<span>"+l+" </span>");
804                 pout.write(line);
805             }
806         }
807         
808         pout.write("</body>\n</html>\n");
809         
810         pout.close();
811 
812         if (pi != null)
813         {
814             if ("/ex4".equals(pi))
815                 throw new ServletException("test ex4", new Throwable());
816             if ("/ex5".equals(pi))
817                 throw new IOException("test ex5");
818             if ("/ex6".equals(pi))
819                 throw new UnavailableException("test ex6");
820         }
821 
822 
823     }
824 
825 
826     /* ------------------------------------------------------------ */
827     @Override
828     public String getServletInfo()
829     {
830         return "Dump Servlet";
831     }
832 
833     /* ------------------------------------------------------------ */
834     @Override
835     public synchronized void destroy()
836     {
837         _timer.cancel();
838     }
839 
840     /* ------------------------------------------------------------ */
841     private String getURI(HttpServletRequest request)
842     {
843         String uri= (String)request.getAttribute("javax.servlet.forward.request_uri");
844         if (uri == null)
845             uri= request.getRequestURI();
846         return uri;
847     }
848 
849     /* ------------------------------------------------------------ */
850     private static String toString(Object o)
851     {
852         if (o == null)
853             return null;
854 
855         try
856         {
857             if (o.getClass().isArray())
858             {
859                 StringBuffer sb = new StringBuffer();
860                 if (!o.getClass().getComponentType().isPrimitive())
861                 {
862                     Object[] array= (Object[])o;
863                     for (int i= 0; i < array.length; i++)
864                     {
865                         if (i > 0)
866                             sb.append("\n");
867                         sb.append(array.getClass().getComponentType().getName());
868                         sb.append("[");
869                         sb.append(i);
870                         sb.append("]=");
871                         sb.append(toString(array[i]));
872                     }
873                     return sb.toString();
874                 }
875                 else
876                 { 
877                     int length = Array.getLength(o);
878                     for (int i=0;i<length;i++)
879                     {
880                         if (i > 0)
881                             sb.append("\n");
882                         sb.append(o.getClass().getComponentType().getName()); 
883                         sb.append("[");
884                         sb.append(i);
885                         sb.append("]=");
886                         sb.append(toString(Array.get(o, i)));
887                     }
888                     return sb.toString();
889                 }
890             }
891             else
892                 return o.toString();
893         }
894         catch (Exception e)
895         {
896             return e.toString();
897         }
898     }
899 
900     private boolean dump(HttpServletResponse response, String data, String chars, String block, String dribble, boolean flush) throws IOException
901     {
902         if (data != null && data.length() > 0)
903         {
904             long d=Long.parseLong(data);
905             int b=(block!=null&&block.length()>0)?Integer.parseInt(block):50;
906             byte[] buf=new byte[b];
907             for (int i=0;i<b;i++)
908             {
909                 
910                 buf[i]=(byte)('0'+(i%10));
911                 if (i%10==9)
912                     buf[i]=(byte)'\n';
913             }
914             buf[0]='o';
915             OutputStream out=response.getOutputStream();
916             response.setContentType("text/plain");
917             while (d > 0)
918             {
919                 if (b==1)
920                 {
921                     out.write(d%80==0?'\n':'.');
922                     d--;
923                 }
924                 else if (d>=b)
925                 {
926                     out.write(buf);
927                     d=d-b;
928                 }
929                 else
930                 {
931                     out.write(buf,0,(int)d);
932                     d=0;
933                 }
934                 
935                 if (dribble!=null)
936                 {
937                     out.flush();
938                     try
939                     {
940                         Thread.sleep(Long.parseLong(dribble));
941                     }
942                     catch (Exception e)
943                     {
944                         e.printStackTrace();
945                         break;
946                     }
947                 }
948                 
949             }
950             
951             if (flush)
952                 out.flush();
953             
954             return true;
955         }
956 
957         // Handle a dump of data
958         if (chars != null && chars.length() > 0)
959         {
960             long d=Long.parseLong(chars);
961             int b=(block!=null&&block.length()>0)?Integer.parseInt(block):50;
962             char[] buf=new char[b];
963             for (int i=0;i<b;i++)
964             {
965                 buf[i]=(char)('0'+(i%10));
966                 if (i%10==9)
967                     buf[i]='\n';
968             }
969             buf[0]='o';
970             response.setContentType("text/plain");
971             PrintWriter out=response.getWriter();
972             while (d > 0 && !out.checkError())
973             {
974                 if (b==1)
975                 {
976                     out.write(d%80==0?'\n':'.');
977                     d--;
978                 }
979                 else if (d>=b)
980                 {
981                     out.write(buf);
982                     d=d-b;
983                 }
984                 else
985                 {
986                     out.write(buf,0,(int)d);
987                     d=0;
988                 }
989             }
990             return true;
991         }    
992         return false;
993     }
994     
995     private String notag(String s)
996     {
997         if (s==null)
998             return "null";
999         s=StringUtil.replace(s,"&","&amp;");
1000         s=StringUtil.replace(s,"<","&lt;");
1001         s=StringUtil.replace(s,">","&gt;");
1002         return s;
1003     }
1004 }