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