| /* |
| * 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.IOException; |
| |
| import javax.servlet.ServletException; |
| import javax.servlet.http.HttpServlet; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| import org.apache.catalina.core.StandardContext; |
| import org.apache.catalina.startup.SimpleHttpClient; |
| import org.apache.catalina.startup.Tomcat; |
| import org.apache.catalina.startup.TomcatBaseTest; |
| |
| public class TestMaxConnections extends TomcatBaseTest { |
| private static final int MAX_CONNECTIONS = 3; |
| public static final int soTimeout = 5000; |
| public static final int connectTimeout = 1000; |
| |
| @Test |
| public void testConnector() throws Exception { |
| init(); |
| ConnectThread[] t = new ConnectThread[10]; |
| for (int i=0; i<t.length; i++) { |
| t[i] = new ConnectThread(); |
| t[i].setName("ConnectThread["+i+"]"); |
| } |
| for (int i=0; i<t.length; i++) { |
| t[i].start(); |
| Thread.sleep(50); |
| } |
| for (int i=0; i<t.length; i++) { |
| t[i].join(); |
| } |
| |
| Assert.assertEquals(MAX_CONNECTIONS, SimpleServlet.getMaxConnections()); |
| } |
| |
| private class ConnectThread extends Thread { |
| @Override |
| public void run() { |
| try { |
| TestClient client = new TestClient(); |
| client.doHttp10Request(); |
| } catch (Exception x) { |
| // NO-OP. Some connections are expected to fail. |
| } |
| } |
| } |
| |
| |
| private synchronized void init() throws Exception { |
| Tomcat tomcat = getTomcatInstance(); |
| StandardContext root = (StandardContext) tomcat.addContext("", SimpleHttpClient.TEMP_DIR); |
| root.setUnloadDelay(soTimeout); |
| Tomcat.addServlet(root, "Simple", new SimpleServlet()); |
| root.addServletMappingDecoded("/test", "Simple"); |
| tomcat.getConnector().setProperty("maxKeepAliveRequests", "1"); |
| tomcat.getConnector().setProperty("maxThreads", "10"); |
| tomcat.getConnector().setProperty("soTimeout", "20000"); |
| tomcat.getConnector().setProperty("keepAliveTimeout", "50000"); |
| tomcat.getConnector().setProperty( |
| "maxConnections", Integer.toString(MAX_CONNECTIONS)); |
| tomcat.getConnector().setProperty("acceptCount", "1"); |
| tomcat.start(); |
| } |
| |
| private class TestClient extends SimpleHttpClient { |
| |
| private void doHttp10Request() throws Exception { |
| setPort(getPort()); |
| |
| long start = System.currentTimeMillis(); |
| // Open connection |
| connect(connectTimeout,soTimeout); |
| |
| // Send request in two parts |
| String[] request = new String[1]; |
| request[0] = |
| "GET /test HTTP/1.0" + CRLF + CRLF; |
| setRequest(request); |
| boolean passed = false; |
| processRequest(false); // blocks until response has been read |
| long stop = System.currentTimeMillis(); |
| log.info(Thread.currentThread().getName()+" Request complete:"+(stop-start)+" ms."); |
| passed = (this.readLine()==null); |
| // Close the connection |
| disconnect(); |
| reset(); |
| Assert.assertTrue(passed); |
| } |
| |
| @Override |
| public boolean isResponseBodyOK() { |
| return true; |
| } |
| } |
| |
| |
| private static class SimpleServlet extends HttpServlet { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static int currentConnections = 0; |
| private static int maxConnections = 0; |
| |
| @Override |
| protected void service(HttpServletRequest req, HttpServletResponse resp) |
| throws ServletException, IOException { |
| |
| increment(); |
| |
| System.out.println("Processing thread: " + Thread.currentThread().getName()); |
| try { |
| Thread.sleep(TestMaxConnections.soTimeout*4/5); |
| } catch (InterruptedException x) { |
| |
| } |
| resp.setContentLength(0); |
| resp.flushBuffer(); |
| |
| decrement(); |
| } |
| |
| private static synchronized void increment() { |
| currentConnections++; |
| if (currentConnections > maxConnections) { |
| maxConnections = currentConnections; |
| } |
| } |
| |
| private static synchronized void decrement() { |
| currentConnections--; |
| } |
| |
| |
| public static synchronized int getMaxConnections() { |
| return maxConnections; |
| } |
| } |
| } |