mitm.common.net.HTTPMethodExecutorTest.java Source code

Java tutorial

Introduction

Here is the source code for mitm.common.net.HTTPMethodExecutorTest.java

Source

/*
 * Copyright (c) 2010-2011, Martijn Brinkers, Djigzo.
 * 
 * This file is part of Djigzo email encryption.
 *
 * Djigzo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License 
 * version 3, 19 November 2007 as published by the Free Software 
 * Foundation.
 *
 * Djigzo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public 
 * License along with Djigzo. If not, see <http://www.gnu.org/licenses/>
 *
 * Additional permission under GNU AGPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or 
 * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, 
 * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, 
 * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, 
 * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, 
 * wsdl4j-1.6.1.jar (or modified versions of these libraries), 
 * containing parts covered by the terms of Eclipse Public License, 
 * tyrex license, freemarker license, dom4j license, mx4j license,
 * Spice Software License, Common Development and Distribution License
 * (CDDL), Common Public License (CPL) the licensors of this Program grant 
 * you additional permission to convey the resulting work.
 */
package mitm.common.net;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URISyntaxException;
import java.security.cert.CRLException;

import mitm.common.net.HTTPMethodExecutor.ResponseHandler;
import mitm.common.scheduler.TaskScheduler;
import mitm.test.SimpleSocketServer;
import mitm.test.SocketAcceptEvent;

import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.PropertyConfigurator;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class HTTPMethodExecutorTest {
    private final static int SERVER_PORT = 61112;

    private static SimpleSocketServer server;

    private static class RunawaySocketHandler implements Runnable {
        private final Socket socket;

        public RunawaySocketHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    OutputStream output = socket.getOutputStream();

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                    }

                    output.write(new byte[] { 0 });
                    output.flush();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static class WaitSocketHandler implements Runnable {
        @Override
        public void run() {
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // ignore
                }
            }
        }
    }

    private static class HttpReplySocketHandler implements Runnable {
        private final Socket socket;

        public HttpReplySocketHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {

            try {
                OutputStream output = socket.getOutputStream();
                output.write("HTTP/1.1 200 OK\r\n".getBytes());
                output.write("Content-Type: text/html\r\n".getBytes());
                output.write("\r\n\r\n".getBytes());

                output.flush();

                while (true) {
                    Thread.sleep(100);

                    output.write(new byte[] { 'a' });
                    output.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static class ConsumeResponseHandler implements ResponseHandler {
        private ByteArrayOutputStream output;

        @Override
        public void handleResponse(int statusCode, HttpMethod httpMethod, TaskScheduler watchdog)
                throws IOException, HttpException {
            output = new ByteArrayOutputStream();

            IOUtils.copy(httpMethod.getResponseBodyAsStream(), output);
        }
    }

    private static class WaitResponseHandler implements ResponseHandler {
        @Override
        public void handleResponse(int statusCode, HttpMethod httpMethod, TaskScheduler watchdog)
                throws IOException, HttpException {
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // ignore
                }
            }
        }
    }

    private static class ThrowExceptionResponseHandler implements ResponseHandler {
        @Override
        public void handleResponse(int statusCode, HttpMethod httpMethod, TaskScheduler watchdog)
                throws IOException, HttpException {
            throw new IOException("Thrown on purpose");
        }
    }

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        PropertyConfigurator.configure("conf/log4j.properties");

        LogManager.getLogger(HTTPMethodExecutor.class).setLevel(org.apache.log4j.Level.DEBUG);

        startServer();
    }

    @AfterClass
    public static void setUpAfterClass() {
        server.stop();
    }

    @Before
    public void before() {
        server.setIncomingEvent(null);
    }

    private static void startServer() {
        server = new SimpleSocketServer(SERVER_PORT);

        Thread serverThread = new Thread(server);
        serverThread.setDaemon(true);
        serverThread.start();

        while (!server.isRunning()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // ignore
            }
        }
    }

    @Test(timeout = 10000)
    public void testConsumeResponseHandlerTimeout() throws URISyntaxException, CRLException, IOException {
        SocketAcceptEvent event = new SocketAcceptEvent() {
            @Override
            public void accept(Socket socket) throws IOException {
                Runnable runnable = new HttpReplySocketHandler(socket);

                new Thread(runnable).start();
            }
        };

        server.setIncomingEvent(event);

        int timeout = 2000;

        HTTPMethodExecutor executor = new HTTPMethodExecutor(timeout, null);

        HttpMethod httpMethod = new GetMethod("http://127.0.0.1:" + SERVER_PORT);

        long start = System.currentTimeMillis();

        ConsumeResponseHandler responseHandler = new ConsumeResponseHandler();

        try {
            executor.executeMethod(httpMethod, responseHandler);

            fail();
        } catch (IOException e) {
            // expected
        }

        assertNotNull(responseHandler.output);
        assertTrue(responseHandler.output.size() > 2);
        assertTrue(responseHandler.output.toString().contains("aa"));

        long diff = System.currentTimeMillis() - start;

        assertTrue(diff >= timeout);
        assertTrue(diff <= timeout * 2);
    }

    @Test(timeout = 10000)
    public void testWaitResponseHandlerTimeout() throws URISyntaxException, CRLException, IOException {
        SocketAcceptEvent event = new SocketAcceptEvent() {
            @Override
            public void accept(Socket socket) throws IOException {
                Runnable runnable = new HttpReplySocketHandler(socket);

                new Thread(runnable).start();
            }
        };

        server.setIncomingEvent(event);

        int timeout = 2000;

        HTTPMethodExecutor executor = new HTTPMethodExecutor(timeout, null);

        HttpMethod httpMethod = new GetMethod("http://127.0.0.1:" + SERVER_PORT);

        long start = System.currentTimeMillis();

        try {
            executor.executeMethod(httpMethod, new WaitResponseHandler());

            fail();
        } catch (IOException e) {
            // expected
        }

        long diff = System.currentTimeMillis() - start;

        assertTrue(diff >= timeout);
        assertTrue(diff <= timeout * 2);
    }

    @Test(timeout = 10000)
    public void testWaitSocketHandlerTimeout() throws URISyntaxException, CRLException, IOException {
        SocketAcceptEvent event = new SocketAcceptEvent() {
            @Override
            public void accept(Socket socket) throws IOException {
                Runnable runnable = new WaitSocketHandler();

                new Thread(runnable).start();
            }
        };

        server.setIncomingEvent(event);

        int timeout = 2000;

        HTTPMethodExecutor executor = new HTTPMethodExecutor(timeout, null);

        HttpMethod httpMethod = new GetMethod("http://127.0.0.1:" + SERVER_PORT);

        long start = System.currentTimeMillis();

        try {
            executor.executeMethod(httpMethod, new ThrowExceptionResponseHandler());

            fail();
        } catch (IOException e) {
            // expected
        }

        long diff = System.currentTimeMillis() - start;

        assertTrue(diff >= timeout);
        assertTrue(diff <= timeout * 2);
    }

    @Test(timeout = 10000)
    public void testRunawaySocketHandlerTimeout() throws URISyntaxException, CRLException, IOException {
        SocketAcceptEvent event = new SocketAcceptEvent() {
            @Override
            public void accept(Socket socket) throws IOException {
                Runnable runnable = new RunawaySocketHandler(socket);

                new Thread(runnable).start();
            }
        };

        server.setIncomingEvent(event);

        int timeout = 2000;

        HTTPMethodExecutor executor = new HTTPMethodExecutor(timeout, null);

        HttpMethod httpMethod = new GetMethod("http://127.0.0.1:" + SERVER_PORT);

        long start = System.currentTimeMillis();

        try {
            executor.executeMethod(httpMethod, new ThrowExceptionResponseHandler());

            fail();
        } catch (IOException e) {
            // expected
        }

        long diff = System.currentTimeMillis() - start;

        assertTrue(diff >= timeout);
        assertTrue(diff <= timeout * 2);
    }
}