Author: markt Date: Tue Jun 16 20:18:14 2009 New Revision: 785369 URL: http://svn.apache.org/viewvc?rev=785369&view=rev Log: Test case for bug 37794. The generic code will move out of this class if it turns out to be useful for other test cases
Added: tomcat/trunk/test/org/apache/catalina/connector/ tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java (with props) Added: tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java?rev=785369&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java (added) +++ tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java Tue Jun 16 20:18:14 2009 @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.catalina.connector; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.Tomcat; + +import junit.framework.TestCase; + +/** + * Test case for {...@link Request}. + */ +public class TestRequest extends TestCase { + /** + * Test case for https://issues.apache.org/bugzilla/show_bug.cgi?id=37794 + * POST parameters are not returned from a call to + * any of the {...@link HttpServletRequest} getParameterXXX() methods. + * @throws Exception + */ + public void testBug37794() throws Exception { + Bug37794Client client = new Bug37794Client(); + + // Edge cases around zero + client.doRequest(-1); // Unlimited + assertTrue(client.isResponse200()); + assertTrue(client.isResponseBodyOK()); + client.reset(); + client.doRequest(0); // Unlimited + assertTrue(client.isResponse200()); + assertTrue(client.isResponseBodyOK()); + client.reset(); + client.doRequest(1); // 1 byte - too small should fail + assertTrue(client.isResponse500()); + + client.reset(); + + // Edge cases around actual content length + client.reset(); + client.doRequest(6); // Too small should fail + assertTrue(client.isResponse500()); + client.reset(); + client.doRequest(7); // Just enough should pass + assertTrue(client.isResponse200()); + assertTrue(client.isResponseBodyOK()); + client.reset(); + client.doRequest(8); // 1 extra - should pass + assertTrue(client.isResponse200()); + assertTrue(client.isResponseBodyOK()); + + // Much larger + client.reset(); + client.doRequest(8096); // Plenty of space - should pass + assertTrue(client.isResponse200()); + assertTrue(client.isResponseBodyOK()); + } + + private static class Bug37794Servlet extends HttpServlet { + + /** + * Only interested in the parameters and values for POST requests. + */ + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + // Just echo the parameters and values back as plain text + resp.setContentType("text/plain"); + + PrintWriter out = resp.getWriter(); + + // Assume one value per attribute + Enumeration<String> names = req.getParameterNames(); + while (names.hasMoreElements()) { + String name = names.nextElement(); + out.println(name + "=" + req.getParameter(name)); + } + } + } + + /** + * Bug 37794 test client. + */ + private static class Bug37794Client extends SimpleHttpClient { + private Exception doRequest(int postLimit) { + Tomcat tomcat = new Tomcat(); + try { + StandardContext root = tomcat.addContext("", TEMP_DIR); + Tomcat.addServlet(root, "Bug37794", new Bug37794Servlet()); + root.addServletMapping("/test", "Bug37794"); + tomcat.getConnector().setMaxPostSize(postLimit); + tomcat.start(); + + // Open connection + connect(); + + // Send request in two parts + String[] request = new String[2]; + request[0] = + "POST http://localhost:8080/test HTTP/1.1" + CRLF + + "content-type: application/x-www-form-urlencoded" + CRLF + + "Transfer-Encoding: chunked" + CRLF + + "Connection: close" + CRLF + + CRLF + + "3" + CRLF + + "a=1" + CRLF; + request[1] = + "4" + CRLF + + "&b=2" + CRLF + + "0" + CRLF + + CRLF; + + setRequest(request); + processRequest(); // blocks until response has been read + + // Close the connection + disconnect(); + } catch (Exception e) { + return e; + } finally { + try { + tomcat.stop(); + } catch (Exception e) { + // Ignore + } + } + return null; + } + + public boolean isResponseBodyOK() { + if (getResponseBody() == null) { + return false; + } + if (!getResponseBody().contains("a=1")) { + return false; + } + if (!getResponseBody().contains("b=2")) { + return false; + } + return true; + } + + } + + /** + * Simple client for unit testing. It isn't robust, it isn't secure and + * should not be used as the basis for production code. Its only purpose + * is to do the bare minimum for the unit tests. + */ + private abstract static class SimpleHttpClient { + public static final String TEMP_DIR = + System.getProperty("java.io.tmpdir"); + + public static final String CRLF = "\r\n"; + + public static final String OK_200 = "HTTP/1.1 200"; + public static final String FAIL_500 = "HTTP/1.1 500"; + + private Socket socket; + private Writer writer; + private BufferedReader reader; + + private String[] request; + private int requestPause = 1000; + + private String responseLine; + private List<String> responseHeaders = new ArrayList<String>(); + private String responseBody; + + public void setRequest(String[] theRequest) { + request = theRequest; + } + + public void setRequestPause(int theRequestPause) { + requestPause = theRequestPause; + } + + public String getResponseLine() { + return responseLine; + } + + public List<String> getResponseHeaders() { + return responseHeaders; + } + + public String getResponseBody() { + return responseBody; + } + + public void connect() throws UnknownHostException, IOException { + socket = new Socket("localhost", 8080); + OutputStream os = socket.getOutputStream(); + writer = new OutputStreamWriter(os); + InputStream is = socket.getInputStream(); + Reader r = new InputStreamReader(is); + reader = new BufferedReader(r); + } + + public void processRequest() throws IOException, InterruptedException { + // Send the request + boolean first = true; + for (String requestPart : request) { + if (first) { + first = false; + } else { + Thread.sleep(requestPause); + } + writer.write(requestPart); + writer.flush(); + } + + // Read the response + responseLine = readLine(); + + // Put the headers into the map + String line = readLine(); + while (line.length() > 0) { + responseHeaders.add(line); + line = readLine(); + } + + // Read the body, if any + StringBuilder builder = new StringBuilder(); + line = readLine(); + while (line != null && line.length() > 0) { + builder.append(line); + line = readLine(); + } + responseBody = builder.toString(); + + } + + public String readLine() throws IOException { + return reader.readLine(); + } + + public void disconnect() throws IOException { + writer.close(); + reader.close(); + socket.close(); + } + + public void reset() { + socket = null; + writer = null; + reader = null; + + request = null; + requestPause = 1000; + + responseLine = null; + responseHeaders = new ArrayList<String>(); + responseBody = null; + } + + public boolean isResponse200() { + return getResponseLine().startsWith(OK_200); + } + + public boolean isResponse500() { + return getResponseLine().startsWith(FAIL_500); + } + + public abstract boolean isResponseBodyOK(); + } +} Propchange: tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org