Package org.littleshoot.proxy

Source Code of org.littleshoot.proxy.TestUtils

package org.littleshoot.proxy;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.littleshoot.proxy.extras.SelfSignedSslEngineSource;

public class TestUtils {

    private TestUtils() {
    }

    /**
     * Creates and starts embedded web server that is running on given port.
     * Each response has a body that indicates how many bytes were received with
     * a message like "Received x bytes\n".
     *
     * @param port
     *            The port
     * @return Instance of Server
     * @throws Exception
     *             if failed to start
     */
    public static Server startWebServer(final int port) throws Exception {
        return startWebServer(port, null);
    }

    /**
     * Creates and starts embedded web server that is running on given port,
     * including an SSL connector on the other given port. Each response has a
     * body that indicates how many bytes were received with a message like
     * "Received x bytes\n".
     *
     * @param port
     *            The port
     * @param sslPort
     *            (optional) The ssl port
     * @return Instance of Server
     * @throws Exception
     *             if failed to start
     */
    public static Server startWebServer(final int port, final Integer sslPort)
            throws Exception {
        final Server httpServer = new Server(port);
        httpServer.setHandler(new AbstractHandler() {
            public void handle(String target, Request baseRequest,
                    HttpServletRequest request, HttpServletResponse response)
                    throws IOException, ServletException {
                if (request.getRequestURI().contains("hang")) {
                    System.out.println("Hanging as requested");
                    try {
                        Thread.sleep(90000);
                    } catch (InterruptedException ie) {
                        System.out.println("Stopped hanging due to interruption");
                    }
                }
               
                long numberOfBytesRead = 0;
                InputStream in = new BufferedInputStream(request
                        .getInputStream());
                while (in.read() != -1) {
                    numberOfBytesRead += 1;
                }
                System.out.println("Done reading # of bytes: "
                        + numberOfBytesRead);
                response.setStatus(HttpServletResponse.SC_OK);
                baseRequest.setHandled(true);
                byte[] content = ("Received " + numberOfBytesRead + " bytes\n").getBytes();
                response.addHeader("Content-Length", Integer.toString(content.length));
                response.getOutputStream().write(content);
            }
        });
        if (sslPort != null) {
            // Add SSL connector
            org.eclipse.jetty.util.ssl.SslContextFactory sslContextFactory = new org.eclipse.jetty.util.ssl.SslContextFactory();

            SelfSignedSslEngineSource contextSource = new SelfSignedSslEngineSource();
            SSLContext sslContext = contextSource.getSslContext();

            sslContextFactory.setSslContext(sslContext);
            SslSocketConnector connector = new SslSocketConnector(
                    sslContextFactory);
            connector.setPort(sslPort);
            /*
             * <p>Ox: For some reason, on OS X, a non-zero timeout can causes
             * sporadic issues. <a href="http://stackoverflow.com/questions
             * /16191236/tomcat-startup-fails
             * -due-to-java-net-socketexception-invalid-argument-on-mac-o">This
             * StackOverflow thread</a> has some insights into it, but I don't
             * quite get it.</p>
             *
             * <p>This can cause problems with Jetty's SSL handshaking, so I
             * have to set the handshake timeout and the maxIdleTime to 0 so
             * that the SSLSocket has an infinite timeout.</p>
             */
            connector.setHandshakeTimeout(0);
            connector.setMaxIdleTime(0);
            httpServer.addConnector(connector);
        }
        httpServer.start();
        return httpServer;
    }

    /**
     * Creates instance HttpClient that is configured to use proxy server. The
     * proxy server should run on 127.0.0.1 and given port
     *
     * @param port
     *            the proxy port
     * @return instance of HttpClient
     */
    public static HttpClient createProxiedHttpClient(final int port)
            throws Exception {
        return createProxiedHttpClient(port, false);
    }

    /**
     * Creates instance HttpClient that is configured to use proxy server. The
     * proxy server should run on 127.0.0.1 and given port
     *
     * @param port
     *            the proxy port
     * @param supportSSL
     *            if true, client will support SSL connections to servers using
     *            self-signed certificates
     * @return instance of HttpClient
     */
    public static HttpClient createProxiedHttpClient(final int port,
            final boolean supportSSL) throws Exception {
        final HttpClient httpclient = new DefaultHttpClient();
        // Note: we use 127.0.0.1 here because on OS X, using straight up
        // localhost yields a connect exception.
        final HttpHost proxy = new HttpHost("127.0.0.1", port, "http");
        httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
                proxy);
        if (supportSSL) {
            SSLSocketFactory sf = new SSLSocketFactory(
                    new TrustSelfSignedStrategy(),
                    new X509HostnameVerifier() {
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }

                public void verify(String host, String[] cns,
                        String[] subjectAlts) throws SSLException {
                }

                public void verify(String host, X509Certificate cert)
                        throws SSLException {
                }

                public void verify(String host, SSLSocket ssl)
                        throws IOException {
                }
            });
            Scheme scheme = new Scheme("https", 443, sf);
            httpclient.getConnectionManager().getSchemeRegistry()
                    .register(scheme);
        }
        return httpclient;
    }

    public static int randomPort() {
        final SecureRandom secureRandom = new SecureRandom();
        for (int i = 0; i < 20; i++) {
            // The +1 on the random int is because
            // Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE -- caught
            // by FindBugs.
            final int randomPort = 1024 + (Math.abs(secureRandom.nextInt() + 1) % 60000);
            ServerSocket sock = null;
            try {
                sock = new ServerSocket();
                sock.bind(new InetSocketAddress("127.0.0.1", randomPort));
                final int port = sock.getLocalPort();
                return port;
            } catch (final IOException e) {
            } finally {
                if (sock != null) {
                    try {
                        sock.close();
                    } catch (IOException e) {
                    }
                }
            }
        }

        // If we can't grab one of our securely chosen random ports, use
        // whatever port the OS assigns.
        ServerSocket sock = null;
        try {
            sock = new ServerSocket();
            sock.bind(null);
            final int port = sock.getLocalPort();
            return port;
        } catch (final IOException e) {
            return 1024 + (Math.abs(secureRandom.nextInt() + 1) % 60000);
        } finally {
            if (sock != null) {
                try {
                    sock.close();
                } catch (IOException e) {
                }
            }
        }
    }
   
    public static long getOpenFileDescriptorsAndPrintMemoryUsage() throws Exception {
        // Below courtesy of:
        // http://stackoverflow.com/questions/10999076/programmatically-print-the-heap-usage-that-is-typically-printed-on-jvm-exit-when
        MemoryUsage mu = ManagementFactory.getMemoryMXBean()
                .getHeapMemoryUsage();
        MemoryUsage muNH = ManagementFactory.getMemoryMXBean()
                .getNonHeapMemoryUsage();
        System.out.println("Init :" + mu.getInit() + "\nMax :" + mu.getMax()
                + "\nUsed :" + mu.getUsed() + "\nCommitted :"
                + mu.getCommitted() + "\nInit NH :" + muNH.getInit()
                + "\nMax NH :" + muNH.getMax() + "\nUsed NH:" + muNH.getUsed()
                + "\nCommitted NH:" + muNH.getCommitted());

        // Below courtesy of:
        // http://neopatel.blogspot.com/2011/05/java-count-open-file-handles.html
        OperatingSystemMXBean osStats = ManagementFactory
                .getOperatingSystemMXBean();
        long numberOfOpenFileDescriptors = 0;
        if (osStats.getClass().getName()
                .equals("com.sun.management.UnixOperatingSystem")) {
            Method method = osStats.getClass().getDeclaredMethod(
                    "getOpenFileDescriptorCount");
            method.setAccessible(true);
            numberOfOpenFileDescriptors = (Long) method.invoke(osStats);
            System.out.println("Open File Descriptors: "
                    + numberOfOpenFileDescriptors);
            method.setAccessible(false);
        }
        return numberOfOpenFileDescriptors;
    }
}
TOP

Related Classes of org.littleshoot.proxy.TestUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.