1   // ========================================================================
2   // Copyright 1996-2005 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at 
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  
15  package com.acme;
16  import java.io.BufferedWriter;
17  import java.io.IOException;
18  import java.io.OutputStream;
19  import java.io.OutputStreamWriter;
20  import java.io.PrintWriter;
21  import java.io.Reader;
22  import java.lang.reflect.Array;
23  import java.lang.reflect.Field;
24  import java.util.Enumeration;
25  import java.util.Locale;
26  
27  import javax.servlet.ServletConfig;
28  import javax.servlet.ServletException;
29  import javax.servlet.ServletRequest;
30  import javax.servlet.ServletRequestWrapper;
31  import javax.servlet.UnavailableException;
32  import javax.servlet.http.Cookie;
33  import javax.servlet.http.HttpServlet;
34  import javax.servlet.http.HttpServletRequest;
35  import javax.servlet.http.HttpServletRequestWrapper;
36  import javax.servlet.http.HttpServletResponse;
37  
38  import org.mortbay.util.StringUtil;
39  import org.mortbay.util.ajax.Continuation;
40  import org.mortbay.util.ajax.ContinuationSupport;
41  
42  
43  
44  /* ------------------------------------------------------------ */
45  /** Dump Servlet Request.
46   * 
47   */
48  public class Dump extends HttpServlet
49  {
50      static boolean fixed;
51      /* ------------------------------------------------------------ */
52      public void init(ServletConfig config) throws ServletException
53      {
54      	super.init(config);
55      	
56      	if (config.getInitParameter("unavailable")!=null && !fixed)
57      	{
58      	    
59      	    fixed=true;
60      	    throw new UnavailableException("Unavailable test",Integer.parseInt(config.getInitParameter("unavailable")));
61      	}
62      }
63  
64      /* ------------------------------------------------------------ */
65      public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
66      {
67          doGet(request, response);
68      }
69  
70      /* ------------------------------------------------------------ */
71      public void doGet(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
72      {
73          if(request.getPathInfo()!=null && request.getPathInfo().toLowerCase().indexOf("script")!=-1)
74          {
75              response.sendRedirect(getServletContext().getContextPath() + "/dump/info");
76              return;
77          }
78              
79          request.setCharacterEncoding("UTF-8");
80          
81          if (request.getParameter("empty")!=null)
82          {
83              response.setStatus(200);
84              response.flushBuffer();
85              return;
86          }
87          
88          if (request.getParameter("sleep")!=null)
89          {
90              try
91              {
92                  long s = Long.parseLong(request.getParameter("sleep"));
93                  Thread.sleep(s/2);
94                  response.sendError(102);
95                  Thread.sleep(s/2);
96              }
97              catch (InterruptedException e)
98              {
99                  return;
100             }
101             catch (Exception e)
102             {
103                 throw new ServletException(e);
104             }
105         }
106         
107         if (request.getParameter("continue")!=null)
108         {
109             try
110             {
111                 Continuation continuation = ContinuationSupport.getContinuation(request, null);
112                 continuation.suspend(Long.parseLong(request.getParameter("continue")));
113             }
114             catch(Exception e)
115             {
116                 throw new ServletException(e);
117             }
118         }
119 
120         if (request.isInitial() && request.getParameter("resume")!=null)
121         {
122             final long resume=Long.parseLong(request.getParameter("resume"));
123             new Thread(new Runnable()
124             {
125                 public void run()
126                 {
127                     try
128                     {
129                         Thread.sleep(resume);
130                     }
131                     catch (InterruptedException e)
132                     {
133                         e.printStackTrace();
134                     }
135                     request.resume();
136                 }
137                 
138             }).start();
139         }
140         
141         if (request.isInitial() && request.getParameter("complete")!=null)
142         {
143             final long complete=Long.parseLong(request.getParameter("complete"));
144             new Thread(new Runnable()
145             {
146                 public void run()
147                 {
148                     try
149                     {
150                         Thread.sleep(complete);
151                     }
152                     catch (InterruptedException e)
153                     {
154                         e.printStackTrace();
155                     }
156                     try
157                     {
158                         HttpServletResponse response = (HttpServletResponse) request.getServletResponse();
159                         response.setContentType("text/html");
160                         response.getOutputStream().println("<h1>COMPLETED</h1>"); 
161                         request.complete();
162                     }
163                     catch (IOException e)
164                     {
165                         e.printStackTrace();
166                     }
167                 }
168                 
169             }).start();
170         }
171         
172         if (request.getAttribute("Dump"+this.hashCode())==null && request.getParameter("suspend")!=null)
173         {
174             request.setAttribute("Dump"+this.hashCode(),Boolean.TRUE);
175             final long suspend=Long.parseLong(request.getParameter("suspend"));
176             request.suspend(suspend);
177             return;
178         }
179             
180         request.setAttribute("Dump", this);
181         getServletContext().setAttribute("Dump",this);
182         // getServletContext().log("dump "+request.getRequestURI());
183 
184         // Force a content length response
185         String length= request.getParameter("length");
186         if (length != null && length.length() > 0)
187         {
188             response.setContentLength(Integer.parseInt(length));
189         }
190 
191         // Handle a dump of data
192         String data= request.getParameter("data");
193         String block= request.getParameter("block");
194         String dribble= request.getParameter("dribble");
195         boolean flush= request.getParameter("flush")!=null?Boolean.parseBoolean(request.getParameter("flush")):false;
196         if (data != null && data.length() > 0)
197         {
198             int d=Integer.parseInt(data);
199             int b=(block!=null&&block.length()>0)?Integer.parseInt(block):50;
200             byte[] buf=new byte[b];
201             for (int i=0;i<b;i++)
202             {
203                 
204                 buf[i]=(byte)('0'+(i%10));
205                 if (i%10==9)
206                     buf[i]=(byte)'\n';
207             }
208             buf[0]='o';
209             OutputStream out=response.getOutputStream();
210             response.setContentType("text/plain");
211             while (d > 0)
212             {
213                 if (b==1)
214                 {
215                     out.write(d%80==0?'\n':'.');
216                     d--;
217                 }
218                 else if (d>=b)
219                 {
220                     out.write(buf);
221                     d=d-b;
222                 }
223                 else
224                 {
225                     out.write(buf,0,d);
226                     d=0;
227                 }
228                 
229                 if (dribble!=null)
230                 {
231                     out.flush();
232                     try
233                     {
234                         Thread.sleep(Long.parseLong(dribble));
235                     }
236                     catch (Exception e)
237                     {
238                         e.printStackTrace();
239                         break;
240                     }
241                 }
242                 
243             }
244             
245             if (flush)
246                 out.flush();
247             
248             return;
249         }
250         
251         
252         // handle an exception
253         String info= request.getPathInfo();
254         if (info != null && info.endsWith("Exception"))
255         {
256             try
257             {
258                 throw (Throwable) Thread.currentThread().getContextClassLoader().loadClass(info.substring(1)).newInstance();
259             }
260             catch (Throwable th)
261             {
262                 throw new ServletException(th);
263             }
264         }
265 
266         // test a reset
267         String reset= request.getParameter("reset");
268         if (reset != null && reset.length() > 0)
269         {
270             response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
271             response.setHeader("SHOULD_NOT","BE SEEN");
272             response.reset();
273         }
274         
275         
276         // handle an redirect
277         String redirect= request.getParameter("redirect");
278         if (redirect != null && redirect.length() > 0)
279         {
280             response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
281             response.sendRedirect(redirect);
282             try
283             {
284                 response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
285             }
286             catch(IOException e)
287             {
288                 // ignored as stream is closed.
289             }
290             return;
291         }
292 
293         // handle an error
294         String error= request.getParameter("error");
295         if (error != null && error.length() > 0 && request.getAttribute("javax.servlet.error.status_code")==null)
296         {
297             response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
298             response.sendError(Integer.parseInt(error));
299             try
300             {
301                 response.getOutputStream().println("THIS SHOULD NOT BE SEEN!");
302             }
303             catch(IllegalStateException e)
304             {
305                 try
306                 {
307                     response.getWriter().println("NOR THIS!!"); 
308                 }
309                 catch(IOException e2){}
310             }
311             catch(IOException e){}
312             return;
313         }
314 
315 
316         String buffer= request.getParameter("buffer");
317         if (buffer != null && buffer.length() > 0)
318             response.setBufferSize(Integer.parseInt(buffer));
319 
320         String charset= request.getParameter("charset");
321         if (charset==null)
322             charset="UTF-8";
323         response.setCharacterEncoding(charset);
324         response.setContentType("text/html");
325 
326         if (info != null && info.indexOf("Locale/") >= 0)
327         {
328             try
329             {
330                 String locale_name= info.substring(info.indexOf("Locale/") + 7);
331                 Field f= java.util.Locale.class.getField(locale_name);
332                 response.setLocale((Locale)f.get(null));
333             }
334             catch (Exception e)
335             {
336                 e.printStackTrace();
337                 response.setLocale(Locale.getDefault());
338             }
339         }
340 
341         String cn= request.getParameter("cookie");
342         String cv=request.getParameter("cookiev");
343         if (cn!=null && cv!=null)
344         {
345             Cookie cookie= new Cookie(cn, cv);
346             if (request.getParameter("version")!=null)
347                 cookie.setVersion(Integer.parseInt(request.getParameter("version")));
348             cookie.setComment("Cookie from dump servlet");
349             response.addCookie(cookie);
350         }
351 
352         String pi= request.getPathInfo();
353         if (pi != null && pi.startsWith("/ex"))
354         {
355             OutputStream out= response.getOutputStream();
356             out.write("</H1>This text should be reset</H1>".getBytes());
357             if ("/ex0".equals(pi))
358                 throw new ServletException("test ex0", new Throwable());
359             else if ("/ex1".equals(pi))
360                 throw new IOException("test ex1");
361             else if ("/ex2".equals(pi))
362                 throw new UnavailableException("test ex2");
363             else if (pi.startsWith("/ex3/"))
364                 throw new UnavailableException("test ex3",Integer.parseInt(pi.substring(5)));
365             throw new RuntimeException("test");
366         }
367 
368         if ("true".equals(request.getParameter("close")))
369             response.setHeader("Connection","close");
370 
371         String buffered= request.getParameter("buffered");
372         
373         PrintWriter pout=null;
374         
375         try
376         {
377             pout =response.getWriter();
378         }
379         catch(IllegalStateException e)
380         {
381             pout=new PrintWriter(new OutputStreamWriter(response.getOutputStream(),charset));
382         }
383         if (buffered!=null)
384             pout = new PrintWriter(new BufferedWriter(pout,Integer.parseInt(buffered)));
385         
386         try
387         {
388             pout.write("<html>\n<body>\n");
389             pout.write("<h1>Dump Servlet</h1>\n");
390             pout.write("<table width=\"95%\">");
391             pout.write("<tr>\n");
392             pout.write("<th align=\"right\">getMethod:&nbsp;</th>");
393             pout.write("<td>" + notag(request.getMethod())+"</td>");
394             pout.write("</tr><tr>\n");
395             pout.write("<th align=\"right\">getContentLength:&nbsp;</th>");
396             pout.write("<td>"+Integer.toString(request.getContentLength())+"</td>");
397             pout.write("</tr><tr>\n");
398             pout.write("<th align=\"right\">getContentType:&nbsp;</th>");
399             pout.write("<td>"+notag(request.getContentType())+"</td>");
400             pout.write("</tr><tr>\n");
401             pout.write("<th align=\"right\">getRequestURI:&nbsp;</th>");
402             pout.write("<td>"+notag(request.getRequestURI())+"</td>");
403             pout.write("</tr><tr>\n");
404             pout.write("<th align=\"right\">getRequestURL:&nbsp;</th>");
405             pout.write("<td>"+notag(request.getRequestURL().toString())+"</td>");
406             pout.write("</tr><tr>\n");
407             pout.write("<th align=\"right\">getContextPath:&nbsp;</th>");
408             pout.write("<td>"+request.getContextPath()+"</td>");
409             pout.write("</tr><tr>\n");
410             pout.write("<th align=\"right\">getServletPath:&nbsp;</th>");
411             pout.write("<td>"+notag(request.getServletPath())+"</td>");
412             pout.write("</tr><tr>\n");
413             pout.write("<th align=\"right\">getPathInfo:&nbsp;</th>");
414             pout.write("<td>"+notag(request.getPathInfo())+"</td>");
415             pout.write("</tr><tr>\n");
416             pout.write("<th align=\"right\">getPathTranslated:&nbsp;</th>");
417             pout.write("<td>"+notag(request.getPathTranslated())+"</td>");
418             pout.write("</tr><tr>\n");
419             pout.write("<th align=\"right\">getQueryString:&nbsp;</th>");
420             pout.write("<td>"+notag(request.getQueryString())+"</td>");
421             pout.write("</tr><tr>\n");
422 
423             pout.write("<th align=\"right\">isInitial:&nbsp;</th>");
424             pout.write("<td>"+request.isInitial()+"</td>");
425             pout.write("</tr><tr>\n");
426             pout.write("<th align=\"right\">isTimeout:&nbsp;</th>");
427             pout.write("<td>"+request.isTimeout()+"</td>");
428             pout.write("</tr><tr>\n");
429             pout.write("<th align=\"right\">isResumed:&nbsp;</th>");
430             pout.write("<td>"+request.isResumed()+"</td>");
431             pout.write("</tr><tr>\n");
432             pout.write("<th align=\"right\">isSuspended:&nbsp;</th>");
433             pout.write("<td>"+request.isSuspended()+"</td>");
434             pout.write("</tr><tr>\n");
435             
436             pout.write("<th align=\"right\">getProtocol:&nbsp;</th>");
437             pout.write("<td>"+request.getProtocol()+"</td>");
438             pout.write("</tr><tr>\n");
439             pout.write("<th align=\"right\">getScheme:&nbsp;</th>");
440             pout.write("<td>"+request.getScheme()+"</td>");
441             pout.write("</tr><tr>\n");
442             pout.write("<th align=\"right\">getServerName:&nbsp;</th>");
443             pout.write("<td>"+notag(request.getServerName())+"</td>");
444             pout.write("</tr><tr>\n");
445             pout.write("<th align=\"right\">getServerPort:&nbsp;</th>");
446             pout.write("<td>"+Integer.toString(request.getServerPort())+"</td>");
447             pout.write("</tr><tr>\n");
448             pout.write("<th align=\"right\">getLocalName:&nbsp;</th>");
449             pout.write("<td>"+request.getLocalName()+"</td>");
450             pout.write("</tr><tr>\n");
451             pout.write("<th align=\"right\">getLocalAddr:&nbsp;</th>");
452             pout.write("<td>"+request.getLocalAddr()+"</td>");
453             pout.write("</tr><tr>\n");
454             pout.write("<th align=\"right\">getLocalPort:&nbsp;</th>");
455             pout.write("<td>"+Integer.toString(request.getLocalPort())+"</td>");
456             pout.write("</tr><tr>\n");
457             pout.write("<th align=\"right\">getRemoteUser:&nbsp;</th>");
458             pout.write("<td>"+request.getRemoteUser()+"</td>");
459             pout.write("</tr><tr>\n");
460             pout.write("<th align=\"right\">getRemoteAddr:&nbsp;</th>");
461             pout.write("<td>"+request.getRemoteAddr()+"</td>");
462             pout.write("</tr><tr>\n");
463             pout.write("<th align=\"right\">getRemoteHost:&nbsp;</th>");
464             pout.write("<td>"+request.getRemoteHost()+"</td>");
465             pout.write("</tr><tr>\n");
466             pout.write("<th align=\"right\">getRemotePort:&nbsp;</th>");
467             pout.write("<td>"+request.getRemotePort()+"</td>");
468             pout.write("</tr><tr>\n");
469             pout.write("<th align=\"right\">getRequestedSessionId:&nbsp;</th>");
470             pout.write("<td>"+request.getRequestedSessionId()+"</td>");
471             pout.write("</tr><tr>\n");
472             pout.write("<th align=\"right\">isSecure():&nbsp;</th>");
473             pout.write("<td>"+request.isSecure()+"</td>");
474 
475             pout.write("</tr><tr>\n");
476             pout.write("<th align=\"right\">isUserInRole(admin):&nbsp;</th>");
477             pout.write("<td>"+request.isUserInRole("admin")+"</td>");
478 
479             pout.write("</tr><tr>\n");
480             pout.write("<th align=\"right\">getLocale:&nbsp;</th>");
481             pout.write("<td>"+request.getLocale()+"</td>");
482             
483             Enumeration locales= request.getLocales();
484             while (locales.hasMoreElements())
485             {
486                 pout.write("</tr><tr>\n");
487                 pout.write("<th align=\"right\">getLocales:&nbsp;</th>");
488                 pout.write("<td>"+locales.nextElement()+"</td>");
489             }
490             pout.write("</tr><tr>\n");
491             
492             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Other HTTP Headers:</big></th>");
493             Enumeration h= request.getHeaderNames();
494             String name;
495             while (h.hasMoreElements())
496             {
497                 name= (String)h.nextElement();
498 
499                 Enumeration h2= request.getHeaders(name);
500                 while (h2.hasMoreElements())
501                 {
502                     String hv= (String)h2.nextElement();
503                     pout.write("</tr><tr>\n");
504                     pout.write("<th align=\"right\">"+notag(name)+":&nbsp;</th>");
505                     pout.write("<td>"+notag(hv)+"</td>");
506                 }
507             }
508 
509             pout.write("</tr><tr>\n");
510             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Request Parameters:</big></th>");
511             h= request.getParameterNames();
512             while (h.hasMoreElements())
513             {
514                 name= (String)h.nextElement();
515                 pout.write("</tr><tr>\n");
516                 pout.write("<th align=\"right\">"+notag(name)+":&nbsp;</th>");
517                 pout.write("<td>"+notag(request.getParameter(name))+"</td>");
518                 String[] values= request.getParameterValues(name);
519                 if (values == null)
520                 {
521                     pout.write("</tr><tr>\n");
522                     pout.write("<th align=\"right\">"+notag(name)+" Values:&nbsp;</th>");
523                     pout.write("<td>"+"NULL!"+"</td>");
524                 }
525                 else if (values.length > 1)
526                 {
527                     for (int i= 0; i < values.length; i++)
528                     {
529                         pout.write("</tr><tr>\n");
530                         pout.write("<th align=\"right\">"+notag(name)+"["+i+"]:&nbsp;</th>");
531                         pout.write("<td>"+notag(values[i])+"</td>");
532                     }
533                 }
534             }
535 
536             pout.write("</tr><tr>\n");
537             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Cookies:</big></th>");
538             Cookie[] cookies = request.getCookies();
539             for (int i=0; cookies!=null && i<cookies.length;i++)
540             {
541                 Cookie cookie = cookies[i];
542 
543                 pout.write("</tr><tr>\n");
544                 pout.write("<th align=\"right\">"+notag(cookie.getName())+":&nbsp;</th>");
545                 pout.write("<td>"+notag(cookie.getValue())+"</td>");
546             }
547             
548             String content_type=request.getContentType();
549             if (content_type!=null &&
550                 !content_type.startsWith("application/x-www-form-urlencoded") &&
551                 !content_type.startsWith("multipart/form-data"))
552             {
553                 pout.write("</tr><tr>\n");
554                 pout.write("<th align=\"left\" valign=\"top\" colspan=\"2\"><big><br/>Content:</big></th>");
555                 pout.write("</tr><tr>\n");
556                 pout.write("<td><pre>");
557                 char[] content= new char[4096];
558                 int len;
559                 try{
560                     Reader in=request.getReader();
561                     
562                     while((len=in.read(content))>=0)
563                         pout.write(notag(new String(content,0,len)));
564                 }
565                 catch(IOException e)
566                 {
567                     pout.write(e.toString());
568                 }
569                 
570                 pout.write("</pre></td>");
571             }
572             
573             
574             pout.write("</tr><tr>\n");
575             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Request Attributes:</big></th>");
576             Enumeration a= request.getAttributeNames();
577             while (a.hasMoreElements())
578             {
579                 name= (String)a.nextElement();
580                 pout.write("</tr><tr>\n");
581                 pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+":&nbsp;</th>");
582                 pout.write("<td>"+"<pre>" + toString(request.getAttribute(name)) + "</pre>"+"</td>");
583             }            
584 
585             
586             pout.write("</tr><tr>\n");
587             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Servlet InitParameters:</big></th>");
588             a= getInitParameterNames();
589             while (a.hasMoreElements())
590             {
591                 name= (String)a.nextElement();
592                 pout.write("</tr><tr>\n");
593                 pout.write("<th align=\"right\">"+name+":&nbsp;</th>");
594                 pout.write("<td>"+ toString(getInitParameter(name)) +"</td>");
595             }
596 
597             pout.write("</tr><tr>\n");
598             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Context InitParameters:</big></th>");
599             a= getServletContext().getInitParameterNames();
600             while (a.hasMoreElements())
601             {
602                 name= (String)a.nextElement();
603                 pout.write("</tr><tr>\n");
604                 pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+":&nbsp;</th>");
605                 pout.write("<td>"+ toString(getServletContext().getInitParameter(name)) + "</td>");
606             }
607 
608             pout.write("</tr><tr>\n");
609             pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Context Attributes:</big></th>");
610             a= getServletContext().getAttributeNames();
611             while (a.hasMoreElements())
612             {
613                 name= (String)a.nextElement();
614                 pout.write("</tr><tr>\n");
615                 pout.write("<th align=\"right\" valign=\"top\">"+name.replace("."," .")+":&nbsp;</th>");
616                 pout.write("<td>"+"<pre>" + toString(getServletContext().getAttribute(name)) + "</pre>"+"</td>");
617             }
618 
619 
620             String res= request.getParameter("resource");
621             if (res != null && res.length() > 0)
622             {
623                 pout.write("</tr><tr>\n");
624                 pout.write("<th align=\"left\" colspan=\"2\"><big><br/>Get Resource: \""+res+"\"</big></th>");
625                 
626                 pout.write("</tr><tr>\n");
627                 pout.write("<th align=\"right\">this.getClass().getResource(...):&nbsp;</th>");
628                 pout.write("<td>"+this.getClass().getResource(res)+"</td>");
629 
630                 pout.write("</tr><tr>\n");
631                 pout.write("<th align=\"right\">this.getClass().getClassLoader().getResource(...):&nbsp;</th>");
632                 pout.write("<td>"+this.getClass().getClassLoader().getResource(res)+"</td>");
633 
634                 pout.write("</tr><tr>\n");
635                 pout.write("<th align=\"right\">Thread.currentThread().getContextClassLoader().getResource(...):&nbsp;</th>");
636                 pout.write("<td>"+Thread.currentThread().getContextClassLoader().getResource(res)+"</td>");
637 
638                 pout.write("</tr><tr>\n");
639                 pout.write("<th align=\"right\">getServletContext().getResource(...):&nbsp;</th>");
640                 try{pout.write("<td>"+getServletContext().getResource(res)+"</td>");}
641                 catch(Exception e) {pout.write("<td>"+"" +e+"</td>");}
642             }
643             
644             pout.write("</tr></table>\n");
645 
646             /* ------------------------------------------------------------ */
647             pout.write("<h2>Request Wrappers</h2>\n");
648             ServletRequest rw=request;
649             int w=0;
650             while (rw !=null)
651             {
652                 pout.write((w++)+": "+rw.getClass().getName()+"<br/>");
653                 if (rw instanceof HttpServletRequestWrapper)
654                     rw=((HttpServletRequestWrapper)rw).getRequest();
655                 else if (rw  instanceof ServletRequestWrapper)
656                     rw=((ServletRequestWrapper)rw).getRequest();
657                 else
658                     rw=null;
659             }
660             
661             pout.write("<br/>");
662             pout.write("<h2>International Characters (UTF-8)</h2>");
663             pout.write("LATIN LETTER SMALL CAPITAL AE<br/>\n");
664             pout.write("Directly uni encoded(\\u1d01): \u1d01<br/>");
665             pout.write("HTML reference (&amp;AElig;): &AElig;<br/>");
666             pout.write("Decimal (&amp;#7425;): &#7425;<br/>");
667             pout.write("Javascript unicode (\\u1d01) : <script language='javascript'>document.write(\"\u1d01\");</script><br/>");
668             pout.write("<br/>");
669             pout.write("<h2>Form to generate GET content</h2>");
670             pout.write("<form method=\"GET\" action=\""+response.encodeURL(getURI(request))+"\">");
671             pout.write("TextField: <input type=\"text\" name=\"TextField\" value=\"value\"/><br/>\n");
672             pout.write("<input type=\"submit\" name=\"Action\" value=\"Submit\">");
673             pout.write("</form>");
674 
675             pout.write("<br/>");
676             
677             pout.write("<h2>Form to generate POST content</h2>");
678             pout.write("<form method=\"POST\" accept-charset=\"utf-8\" action=\""+response.encodeURL(getURI(request))+"\">");
679             pout.write("TextField: <input type=\"text\" name=\"TextField\" value=\"value\"/><br/>\n");
680             pout.write("Select: <select multiple name=\"Select\">\n");
681             pout.write("<option>ValueA</option>");
682             pout.write("<option>ValueB1,ValueB2</option>");
683             pout.write("<option>ValueC</option>");
684             pout.write("</select><br/>");
685             pout.write("<input type=\"submit\" name=\"Action\" value=\"Submit\"><br/>");
686             pout.write("</form>");
687             pout.write("<br/>");
688             
689             pout.write("<h2>Form to generate UPLOAD content</h2>");
690             pout.write("<form method=\"POST\" enctype=\"multipart/form-data\" accept-charset=\"utf-8\" action=\""+response.encodeURL(getURI(request))+"\">");
691             pout.write("TextField: <input type=\"text\" name=\"TextField\" value=\"comment\"/><br/>\n");
692             pout.write("File 1: <input type=\"file\" name=\"file1\" /><br/>\n");
693             pout.write("File 2: <input type=\"file\" name=\"file2\" /><br/>\n");
694             pout.write("<input type=\"submit\" name=\"Action\" value=\"Submit\"><br/>");
695             pout.write("</form>");
696 
697             pout.write("<h2>Form to set Cookie</h2>");
698             pout.write("<form method=\"POST\" action=\""+response.encodeURL(getURI(request))+"\">");
699             pout.write("cookie: <input type=\"text\" name=\"cookie\" /><br/>\n");
700             pout.write("value: <input type=\"text\" name=\"cookiev\" /><br/>\n");
701             pout.write("<input type=\"submit\" name=\"Action\" value=\"setCookie\">");
702             pout.write("</form>\n");
703             
704             pout.write("<h2>Form to get Resource</h2>");
705             pout.write("<form method=\"POST\" action=\""+response.encodeURL(getURI(request))+"\">");
706             pout.write("resource: <input type=\"text\" name=\"resource\" /><br/>\n");
707             pout.write("<input type=\"submit\" name=\"Action\" value=\"getResource\">");
708             pout.write("</form>\n");
709             
710 
711         }
712         catch (Exception e)
713         {
714             getServletContext().log("dump", e);
715         }
716 
717         
718         if (request.getParameter("stream")!=null)
719         {
720             pout.flush();
721             Continuation continuation = ContinuationSupport.getContinuation(request, null);
722             continuation.suspend(Long.parseLong(request.getParameter("stream")));
723         }
724 
725         String lines= request.getParameter("lines");
726         if (lines!=null)
727         {
728             char[] line = "<span>A line of characters. Blah blah blah blah.  blooble blooble</span></br>\n".toCharArray();
729             for (int l=Integer.parseInt(lines);l-->0;)
730             {
731                 pout.write("<span>"+l+" </span>");
732                 pout.write(line);
733             }
734         }
735         
736         pout.write("</body>\n</html>\n");
737         
738         pout.close();
739 
740         if (pi != null)
741         {
742             if ("/ex4".equals(pi))
743                 throw new ServletException("test ex4", new Throwable());
744             if ("/ex5".equals(pi))
745                 throw new IOException("test ex5");
746             if ("/ex6".equals(pi))
747                 throw new UnavailableException("test ex6");
748         }
749 
750 
751     }
752 
753     /* ------------------------------------------------------------ */
754     public String getServletInfo()
755     {
756         return "Dump Servlet";
757     }
758 
759     /* ------------------------------------------------------------ */
760     public synchronized void destroy()
761     {
762     }
763 
764     /* ------------------------------------------------------------ */
765     private String getURI(HttpServletRequest request)
766     {
767         String uri= (String)request.getAttribute("javax.servlet.forward.request_uri");
768         if (uri == null)
769             uri= request.getRequestURI();
770         return uri;
771     }
772 
773     /* ------------------------------------------------------------ */
774     private static String toString(Object o)
775     {
776         if (o == null)
777             return null;
778 
779         try
780         {
781             if (o.getClass().isArray())
782             {
783                 StringBuffer sb = new StringBuffer();
784                 if (!o.getClass().getComponentType().isPrimitive())
785                 {
786                     Object[] array= (Object[])o;
787                     for (int i= 0; i < array.length; i++)
788                     {
789                         if (i > 0)
790                             sb.append("\n");
791                         sb.append(array.getClass().getComponentType().getName());
792                         sb.append("[");
793                         sb.append(i);
794                         sb.append("]=");
795                         sb.append(toString(array[i]));
796                     }
797                     return sb.toString();
798                 }
799                 else
800                 { 
801                     int length = Array.getLength(o);
802                     for (int i=0;i<length;i++)
803                     {
804                         if (i > 0)
805                             sb.append("\n");
806                         sb.append(o.getClass().getComponentType().getName()); 
807                         sb.append("[");
808                         sb.append(i);
809                         sb.append("]=");
810                         sb.append(toString(Array.get(o, i)));
811                     }
812                     return sb.toString();
813                 }
814             }
815             else
816                 return o.toString();
817         }
818         catch (Exception e)
819         {
820             return e.toString();
821         }
822     }
823 
824     private String notag(String s)
825     {
826         if (s==null)
827             return "null";
828         s=StringUtil.replace(s,"&","&amp;");
829         s=StringUtil.replace(s,"<","&lt;");
830         s=StringUtil.replace(s,">","&gt;");
831         return s;
832     }
833 }