// Copyright � 2002-2005 Canoo Engineering AG, Switzerland. package com.canoo.webtest.self; import java.io.IOException; import java.io.PrintWriter; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.ListIterator; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.codec.binary.Hex; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.canoo.webtest.util.HtmlConstants; /** * * @author unknown * @author Marc Guillemot */ public class FormTestServlet extends HttpServlet { private String fServletPath = "formTest"; private static final boolean DUMMY = false; // only used to compress dispatching code public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { dispatchRequest(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { dispatchRequest(request, response); } private boolean dispatchRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String action = getParameterAsString("mode", request); if ("postTest".equals(action)) return renderForm(request, response, "POST", "postTest"); if ("getTest".equals(action)) return renderForm(request, response, "GET", "getTest"); if ("invalidHtml".equals(action)) return renderInvalidHtml(request, response, "invalid HTML"); if ("demo".equals(action)) return renderDemoLoginPage(response, "Login Page"); if ("demoLogin".equals(action)) return renderDemoSuccessPage(response, "Home Page"); if ("formNestingWrong".equals(action)) return renderFormsBetweenTDs(response); if ("tableTest".equals(action)) return renderTableTest(request, response); if ("checkboxTest".equals(action)) return renderCheckboxTest(request, response); if ("linkTest".equals(action)) return renderLinkTest(request, response); if ("redirectTest".equals(action)) return renderRedirectTest(response); if ("redirectTestMeta".equals(action)) return renderRedirectTestMeta(request, response); if ("redirectTarget".equals(action)) return renderRedirectTarget(request, response); if ("redirectPage".equals(action)) return renderRedirectPage(request, response); if ("https".equals(action)) return renderHttpsPage(request, response); if ("upload".equals(action)) return renderUploadInfoPage(request, response); if ("timeoutTest".equals(action)) return renderTimeoutTestPage(request, response); return renderDefault(request, response, "Canoo WebTest", "Wusi is the greatest"); } /** * Waits the time specified in the query parameter "wait" (in seconds) * allowing to test the timeout config parameter before rendering the default page * @param request the incoming request * @param response the outgoing response * @return doesn't matter */ private boolean renderTimeoutTestPage(final HttpServletRequest request, final HttpServletResponse response) throws IOException { final String wait = request.getParameter("wait"); int waitTime = 0; if (wait != null) { try { waitTime = Integer.parseInt(wait); } catch (final NumberFormatException e) { // throw an exception to "see" it from the tests are nobody would look at it if we take a default value // ant the problem appears only in server log throw new RuntimeException("Request parameter \"wait\" should be an integer", e); } } try { Thread.sleep(1000 * waitTime); } catch (final InterruptedException e) { throw new RuntimeException("Sleep (" + waitTime + "s) interrupted", e); } return renderDefault(request, response, "Canoo WebTest", "Wusi is the greatest"); } private boolean renderRedirectPage(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter out = renderBegin(response, "Redirect Test Page"); out.println("<h3>Redirect Test Page</h3>"); out.println("<a href=\"formTest?mode=redirectTest\">Redirected link</a>"); out.println("<form method=\"post\" action=\"" + fServletPath + "\" name=\"RedirectFormPost\">"); out.println("<Input type=hidden name=\"mode\" value=\"redirectTest\" />"); out.println("<Input type=submit name=\"submitPost\" value=\"RedirectSubmitPost\" />"); out.println("</form>"); out.println("<form method=\"get\" action=\"" + fServletPath + "\" name=\"RedirectFormGet\">"); out.println("<Input type=hidden name=\"mode\" value=\"redirectTest\" />"); out.println("<Input type=submit name=\"submitGet\" value=\"RedirectSubmitGet\" />"); out.println("</form>"); printSubmittedParametersAndValues(out, request); renderEnd(out); return DUMMY; } private boolean renderHttpsPage(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter out = renderBegin(response, "Https Test Page"); out.println("<pre>"); if (request.getUserPrincipal() == null){ out.println("no user principal"); }else{ out.println("user principal name = "+request.getUserPrincipal().getName()); } out.println("authentication type = "+request.getAuthType()); out.println("</pre>"); printSubmittedParametersAndValues(out, request); renderEnd(out); return DUMMY; } private boolean renderRedirectTarget(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter out = renderBegin(response, "Redirect AbstractTargetAction"); out.println("<h3>Redirect AbstractTargetAction Page</h3>"); printSubmittedParametersAndValues(out, request); printHeadersAndValues(out, request); renderEnd(out); return DUMMY; } private boolean renderRedirectTest(HttpServletResponse response) throws IOException { response.sendRedirect(fServletPath + "?mode=redirectTarget"); return DUMMY; } private boolean renderRedirectTestMeta(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); StringBuffer reqURL = request.getRequestURL(); out.println("<meta http-equiv=\"refresh\" content=\"0;url=" + reqURL + "?mode=redirectTarget\" />"); out.println("</head>"); out.println("<body></body>"); out.println("</html>"); return DUMMY; } private void appendCheckBox(PrintWriter out, String name, String value, boolean checked) { out.println("<br>"); out.println("<br>Check box name=" + name + ":"); String htmlCodeBegin = "<br><input type=\""+ HtmlConstants.CHECKBOX + "\" " + (checked ? "CHECKED" : "") + " name=" + name; if (value == null) { out.println(htmlCodeBegin + ">Box [no value]"); return; } out.println(htmlCodeBegin + " value=\"" + value + "\">Box " + value); } private void appendLink(PrintWriter out, String label, String attributes) { String parameters = ""; if (attributes != null && !"".equals(attributes.trim())) { parameters = "?" + attributes; } out.println("<br>"); out.println("<a href=\"" + fServletPath + parameters + "\">" + label + "</a>"); } private void appendRadioButtons(PrintWriter out, String name) { out.println("<br>"); out.println("<br>Radio buttons name=" + name + ":"); out.println("<br>"); String beginTag = "<input type=\"" + HtmlConstants.RADIO + "\" name=" + name; out.println(beginTag + " value=r1 checked>Radio r1"); out.println(beginTag + " value=r2>Radio r2"); out.println(beginTag + " value=r3>Radio r3"); } private void appendSelectBox(PrintWriter out, String name, boolean isMultiSelection, List selectedValues) { out.println("<br>"); out.println("<br>Select name=" + name + ":"); out.print("<br><select name=" + name + " size=3 "); if (isMultiSelection) { out.print("multiple"); } out.println(">"); for (int i = 1; i < 5; i++) { appendSelectOption(out, "v" + i, "Name for v" + i, selectedValues.contains("v" + i)); } out.println("</select>"); } private void appendSelectOption(PrintWriter out, String value, String text, boolean isSelected) { out.print("<option value=\"" + value + "\" "); if (isSelected) { out.print("selected"); } out.println(">" + text + "</option>"); } private String getParameterAsString(String parameterName, HttpServletRequest request) { String result = request.getParameter(parameterName); return result != null ? result : ""; } private List getValuesForParameter(String parameterName, HttpServletRequest request) { String[] result = request.getParameterValues(parameterName); return result != null ? Arrays.asList(result) : new ArrayList(); } private void printMultipleFormsIfNeeded(PrintWriter out, HttpServletRequest request, String type) { if ("multiple".equals(getParameterAsString("forms", request))) { out.println("<hr>"); out.println("Second form: name=2"); out.println("<form method=" + type + " action=\"" + fServletPath + "\" name=\"2\">"); out.println("<Input type=\"" + HtmlConstants.HIDDEN + "\" name=Dummy value=\"A Dummy Value\">"); out.println("Text: <Input type=\"" + HtmlConstants.TEXT + "\" name=field1 value=\"" + getParameterAsString("field1", request) + "\" >"); List selectedValues = new ArrayList(); selectedValues.add("v1"); appendSelectBox(out, "select1", false, selectedValues); appendRadioButtons(out, "radio"); appendCheckBox(out, "check", "c1", false); appendLink(out, "link", "link=l1&radio=r1"); appendLink(out, "link", "link=l2&radio=r1"); out.println("<br>"); out.println("<a href=\"ReadMe.pdf\">pdf document</a>"); out.println("<br>"); out.println("<a href=\"WebTest.doc\">word document</a>"); out.println("<br>"); out.println("<br><Input type=submit name=first value=doItAgain>"); out.println("<br><Input type=submit name=second value=doItAgain></form>"); out.println("<hr>"); out.println("Third form: name=3"); out.println("<form method=" + type + " action=\"" + fServletPath + "\" name=\"3\">"); out.println("<Input type=hidden name=Dummy value=\"A Dummy Value\">"); out.println("<Input type=hidden name=mode value=getTest>"); out.println("Text: <Input type=text name=field2 value=\"" + getParameterAsString("field2", request) + "\" >"); appendSelectBox(out, "select1", false, new ArrayList()); out.println("<br><Input type=submit name=third value=doItAgain>"); out.println("<br><Input type=submit value=doItAgain3></form>"); } } private void printSubmittedParametersAndValues(PrintWriter out, HttpServletRequest request) { printSubTitle(out, "Submitted parameter names and values:"); Enumeration en = request.getParameterNames(); while (en.hasMoreElements()) { String name = getAndPrintNextKey(en, out); for (int i = 0; i < request.getParameterValues(name).length; i++) { out.print(" " + request.getParameterValues(name)[i]); } out.println("<br>"); } String fillSession = getParameterAsString("fillsession", request); if (fillSession != null && fillSession.length() > 0) { request.getSession().setAttribute(fillSession, fillSession); } String withSession = getParameterAsString("session", request); if (!"YES".equalsIgnoreCase(withSession)) { return; } printSubTitle(out, "Session values"); en = request.getSession().getAttributeNames(); while (en.hasMoreElements()) { String name = getAndPrintNextKey(en, out); out.print(" " + request.getSession().getAttribute(name)); } } private void printHeadersAndValues(PrintWriter out, HttpServletRequest request) { printSubTitle(out, "Header names and values"); Enumeration en = request.getHeaderNames(); while (en.hasMoreElements()) { String name = getAndPrintNextKey(en, out); Enumeration values = request.getHeaders(name); while (values.hasMoreElements()) { out.print(" " + values.nextElement().toString()); } out.println("<br>"); } } private String getAndPrintNextKey(Enumeration en, PrintWriter out) { String name = (String) en.nextElement(); out.print(name + " ="); return name; } private void printSubTitle(PrintWriter out, String subtitle) { out.println("<hr>"); out.println(subtitle); out.println(": "); out.println("<br>"); out.println("<br>"); } private boolean renderCheckboxTest(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter out = renderBegin(response, "CheckboxTest"); out.println("<form method=POST name=\"checkboxForm\" action=\"" + fServletPath + "?mode=checkboxTest\">"); out.println("<INPUT value=\"Testfield without Type\" style=\" HEIGHT: 22px\" maxLength=\"30\" size=\"34\" name=\"input\"><BR>"); appendCheckBox(out, "c1", "check1", getParameterAsString("c1", request).length() > 0); appendCheckBox(out, "c2", "check2", getValuesForParameter("c2", request).contains("check2")); appendCheckBox(out, "c2", "check3", getValuesForParameter("c2", request).contains("check3")); appendCheckBox(out, "c3NoValue", null, getParameterAsString("c3NoValue", request).length() > 0); out.println("<BR/><H2>The Multiselection list</H2>"); String selectName = "MultiSelect"; List selectedValues = getMultiValueParameterList(request, selectName); appendSelectBox(out, selectName, true, selectedValues); out.println("<BR/><H2>The Single Selection list</H2>"); selectName = "CBoxSelect"; selectedValues = getMultiValueParameterList(request, selectName); appendSelectBox(out, selectName, true, selectedValues); out.println("<br><Input type=submit value=doIt>"); out.println("</form>"); printSubmittedParametersAndValues(out, request); renderEnd(out); return DUMMY; } private List getMultiValueParameterList(HttpServletRequest request, String parameterName) { if (request.getParameterValues(parameterName) != null) { return Arrays.asList(request.getParameterValues(parameterName)); } return new ArrayList(); } private boolean renderLinkTest(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter out = renderBegin(response, "LinkTest"); String linkStatus = getParameterAsString("linkStatus", request); if ("startGood".equals(linkStatus)) { appendLink(out, "Page with good Link", "mode=linkTest&linkStatus=stillGood"); } if ("stillGood".equals(linkStatus)) { appendLink(out, "Page with bad Link", "mode=linkTest&linkStatus=bad"); } if ("bad".equals(linkStatus)) { out.println("<A HREF=\"youwillnotfindthis.htm\">Bad Link</A>"); } if ("external".equals(linkStatus)) { out.println("<A HREF=\"http://www.canoo.com\">Canoo.com</A>"); } if ("special".equals(linkStatus)) { out.println("<A HREF=\"ftp://youwillnotfindthisserver.com\">Bad FTP Address</A><BR>"); out.println("<A HREF= \"mailto:feedback-online@canoo.com\">Canoo-Mail</A>"); } printSubmittedParametersAndValues(out, request); renderEnd(out); return DUMMY; } private boolean renderTableTest(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter out = renderBegin(response, "TableTest"); out.println("<table id=\"test\" border=\"1\">"); for (int i = 0; i < 3; i++) { out.println("<tr>"); for (int j = 0; j < 3; j++) { out.println("<td>"); out.println("" + i + ":" + j); out.println("</td>"); } out.println("</tr>"); } out.println("</table>"); printSubmittedParametersAndValues(out, request); renderEnd(out); return DUMMY; } private boolean renderDemoSuccessPage(HttpServletResponse response, String title) throws IOException { PrintWriter out = renderBegin(response, title); out.println("<h1>Welcome to my home page!</h1>"); renderEnd(out); return DUMMY; } private boolean renderDemoLoginPage(HttpServletResponse response, String title) throws IOException { PrintWriter out = renderBegin(response, title); // Render form with image buttons out.println("<h1>Please login</h1>"); out.println("<form method=POST action=\"" + fServletPath + "\">"); out.println("<Input type=hidden name=\"mode\" value=\"demoLogin\">"); out.println("<br>Username:<Input type=text value=\"\" name=\"username\" >"); out.println("<br>Password:<Input type=password value=\"\" name=\"password\" >"); out.println("<br> <br><Input type=submit value=Login></form>"); renderEnd(out); return DUMMY; } // private void writeButtonTestImage(PrintWriter out, String value, String buttonNr, String formNr) { // out.println("<Input type=image src=\"seibertec.jpg\" value=\"" + value + "\" name=\"imageButton" + buttonNr + "\" " + // "alt=\"value=" + value + " name=imageButton" + buttonNr + " form=form" + formNr + "\" />"); // } private boolean renderInvalidHtml(HttpServletRequest request, HttpServletResponse response, String title) throws IOException { PrintWriter out = renderBegin(response, title); // Invalid HTML with tr/td outside of table out.println("<tr><td><INPUT type=text name=field1 value=\"TD in body\">"); out.println("<form method=POST action=\"" + fServletPath + "\">"); out.println("<br>Text (valid): <Input type=text name=field2 value=\"" + getParameterAsString("field1", request) + "\" >"); out.println("<br><Input type=submit value=doIt></form>"); printSubmittedParametersAndValues(out, request); renderEnd(out); return DUMMY; } private boolean renderDefault(HttpServletRequest request, HttpServletResponse response, String title, String text) throws IOException { PrintWriter out = renderBegin(response, title); out.println("<h1>" + text + "</h1>"); appendLink(out, "MyLink", "mode=getTest&field1=MyLink"); appendLink(out, "<img src=\"seibertec.jpg\" alt=\"imagelink\">", "image=clicked"); out.println("<br>"); appendLink(out, "Multiple forms", "mode=getTest&forms=multiple"); out.println("<br>"); out.println("<br>"); out.println("<form action=\"\">"); out.println("<textarea name=\"theArea\">"); out.println("Wusi was here ..."); out.println("</textarea>"); out.println("<br>"); out.println("<textarea name=\"theOtherArea\">"); out.println("and here."); out.println("</textarea>"); out.println("<br>"); out.println("<textarea name=\"theOtherArea\" id=\"textarea2\">"); out.print("Wusi was here as well..."); out.println("</textarea>"); out.println("</form>"); printSubmittedParametersAndValues(out, request); out.print("<br><a href=\""); String sessionUrlEncodedLink = request.getContextPath() + request.getServletPath() + "?" + request.getQueryString(); out.print(response.encodeRedirectURL(sessionUrlEncodedLink)); out.println("\">Url encoded back link</a>"); printHeadersAndValues(out, request); if ("true".equals(request.getParameter("brokenlink"))) { out.println("<br><a href=\"youwillnotfindthis.html\">a broken link</a><br>"); } renderEnd(out); return DUMMY; } private boolean renderForm(HttpServletRequest request, HttpServletResponse response, String type, String nextMode) throws IOException { PrintWriter out = renderBegin(response, "SelfTest"); out.println("<h1>SelfTest</h1>"); out.println("<form method=" + type + " action=\"" + fServletPath + "\">"); out.println("<Input type=hidden name=mode value=" + nextMode + ">"); out.println("<Input type=hidden name=Dummy value=\"A Dummy Value\">"); out.println("<br>Text: <Input type=text name=field1 value=\"" + getParameterAsString("field1", request) + "\" >"); out.println("<br><Input type=submit value=doIt></form>"); printMultipleFormsIfNeeded(out, request, type); renderEnd(out); return DUMMY; } private boolean renderFormsBetweenTDs(HttpServletResponse response) throws IOException { PrintWriter out = renderBegin(response, "SelfTest"); out.println("<h1>SelfTest</h1>"); out.println("<table><tr><td>first form with button named bla : </td>"); out.println("<form method=GET action=\"" + fServletPath + "\">"); out.println("<td><Input type=submit name=bla value=doIt></td></form>"); // JTidy reads one form with both buttons until here (but there should only be one) out.println("<br> second form with button named clickme: <form method=GET action=\"" + fServletPath + "\">"); out.println("<br><Input type=submit name=clickme value=doIt></form>"); renderEnd(out); return DUMMY; } private void renderEnd(PrintWriter out) { out.println("</body>"); out.println("</html>"); } private PrintWriter renderBegin(HttpServletResponse response, String title) throws IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>" + title + "</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1 id=\"headingId\">title</h1>"); return out; } /** * Renders information on the uploaded file */ private boolean renderUploadInfoPage(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { final PrintWriter out = renderBegin(response, "Upload Test Page"); out.println("<h3>Upload Test Page</h3>"); final boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (!isMultipart) { out.println("Request is not multipart"); renderEnd(out); return DUMMY; } // Create a factory for disk-based file items final FileItemFactory factory = new DiskFileItemFactory(); // Create a new file upload handler final ServletFileUpload upload = new ServletFileUpload(factory); // Parse the request final List items; try { items = upload.parseRequest(request); } catch (final FileUploadException e) { throw new ServletException(e); } out.println(items.size() + " uploaded file(s):"); out.println("<ul>"); for (final ListIterator iter = items.listIterator(); iter.hasNext();) { final FileItem item = (FileItem) iter.next(); if (item.isFormField()) continue; // normal form field, not an uploaed file final String idSuffix = item.getFieldName(); out.println("<li id='file_" + idSuffix + "'>"); renderLineWithSpan(out, "Content type", "cntType_" + idSuffix, item.getContentType()); renderLineWithSpan(out, "Field name", "fieldName_" + idSuffix, item.getFieldName()); renderLineWithSpan(out, "File name", "fileName_" + idSuffix, item.getName()); renderLineWithSpan(out, "File size", "fileSize_" + idSuffix, String.valueOf(item.getSize())); renderLineWithSpan(out, "MD5", "md5_" + idSuffix, computeMD5(item.get())); out.println("</li>"); } out.println("</ul>"); renderEnd(out); return DUMMY; } private void renderLineWithSpan(final PrintWriter _out, final String _label, final String _id, final String _value) { _out.println(_label + ": <span id='" + _id + "'>" + _value + "</span>"); } private String computeMD5(final byte[] _bs) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); } catch (final NoSuchAlgorithmException e) { throw new RuntimeException(e); } digest.update(_bs); final byte[] md5 = digest.digest(); return new String(Hex.encodeHex(md5)); } }