<commit_before>/*
 * Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 * The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * The Apache License v2.0 is available at
 * http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */

package org.eclipse.jetty.client;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.io.IOException;
import java.net.SocketTimeoutException;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 */
public abstract class AbstractHttpExchangeCancelTest
{
    private static final Logger LOG = Log.getLogger(AbstractHttpExchangeCancelTest.TestHttpExchange.class);
    
    private Server server;
    private Connector connector;

    @Before
    public void setUp() throws Exception
    {
        server = new Server();
        connector = new SelectChannelConnector();
        server.addConnector(connector);
        server.setHandler(new EmptyHandler());
        server.start();
    }

    @After
    public void tearDown() throws Exception
    {
        server.stop();
        server.join();
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnSend1() throws Exception
    {
        // One of the first things that HttpClient.send() does
        // is to change the status of the exchange
        // We exploit that to be sure the exchange is canceled
        // without race conditions
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            boolean setStatus(int status)
            {
                // Cancel before setting the new status
                if (getStatus() == HttpExchange.STATUS_START &&
                    status == STATUS_WAITING_FOR_CONNECTION)
                    cancel();
                return super.setStatus(status);
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);
        // Cancelling here is wrong and makes the test fail spuriously
        // due to a race condition with send(): the send() can complete
        // before the exchange is canceled so it will be in STATUS_COMPLETE
        // which will fail the test.
//        exchange.cancel();

        int status = exchange.waitForDone();
        assertEquals(HttpExchange.STATUS_CANCELLED, status);
        assertFalse(exchange.isResponseCompleted());
        assertFalse(exchange.isFailed());
        assertFalse(exchange.isAssociated());
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnSend2() throws Exception
    {
        // One of the first things that HttpClient.send() does
        // is to change the status of the exchange
        // We exploit that to be sure the exchange is canceled
        // without race conditions
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            boolean setStatus(int status)
            {
                // Cancel after setting the new status
                int oldStatus = getStatus();
                boolean set = super.setStatus(status);
                if (oldStatus == STATUS_START &&
                    getStatus() == HttpExchange.STATUS_WAITING_FOR_CONNECTION)
                    cancel();
                return set;
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);
        // Cancelling here is wrong and makes the test fail spuriously
        // due to a race condition with send(): the send() can complete
        // before the exchange is canceled so it will be in STATUS_COMPLETE
        // which will fail the test.
//        exchange.cancel();

        int status = exchange.waitForDone();
        assertEquals(HttpExchange.STATUS_CANCELLED, status);
        assertFalse(exchange.isResponseCompleted());
        assertFalse(exchange.isFailed());
        assertFalse(exchange.isAssociated());
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnRequestCommitted() throws Exception
    {
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            protected void onRequestCommitted() throws IOException
            {
                super.onRequestCommitted();
                cancel();
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);

        int status = exchange.waitForDone();
        assertEquals(HttpExchange.STATUS_CANCELLED, status);
        assertFalse(exchange.isResponseCompleted());
        assertFalse(exchange.isFailed());
        assertFalse(exchange.isAssociated());
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnRequestComplete() throws Exception
    {
        LOG.setDebugEnabled(true);
        
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            protected void onRequestComplete() throws IOException
            {
                super.onRequestComplete();
                cancel();
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);

        int status = exchange.waitForDone();
        assertThat("Exchange Status", status, is(HttpExchange.STATUS_CANCELLED));
        assertThat("Exchange.isResponseCompleted", exchange.isResponseCompleted(), is(false));
        assertThat("Exchange.isFailed", exchange.isFailed(), is(false));
        assertThat("Exchange.isAssociated", exchange.isAssociated(), is(false));
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnResponseStatus() throws Exception
    {
        TestHttpExchange exchange = new TestHttpExchange()<commit_msg>only handle early EOF if exchange is not done<commit_after>/*
 * Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 * The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * The Apache License v2.0 is available at
 * http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */

package org.eclipse.jetty.client;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.io.IOException;
import java.net.SocketTimeoutException;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 */
public abstract class AbstractHttpExchangeCancelTest
{
    private static final Logger LOG = Log.getLogger(AbstractHttpExchangeCancelTest.TestHttpExchange.class);
    
    private Server server;
    private Connector connector;

    @Before
    public void setUp() throws Exception
    {
        server = new Server();
        connector = new SelectChannelConnector();
        server.addConnector(connector);
        server.setHandler(new EmptyHandler());
        server.start();
    }

    @After
    public void tearDown() throws Exception
    {
        server.stop();
        server.join();
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnSend1() throws Exception
    {
        // One of the first things that HttpClient.send() does
        // is to change the status of the exchange
        // We exploit that to be sure the exchange is canceled
        // without race conditions
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            boolean setStatus(int status)
            {
                // Cancel before setting the new status
                if (getStatus() == HttpExchange.STATUS_START &&
                    status == STATUS_WAITING_FOR_CONNECTION)
                    cancel();
                return super.setStatus(status);
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);
        // Cancelling here is wrong and makes the test fail spuriously
        // due to a race condition with send(): the send() can complete
        // before the exchange is canceled so it will be in STATUS_COMPLETE
        // which will fail the test.
//        exchange.cancel();

        int status = exchange.waitForDone();
        assertEquals(HttpExchange.STATUS_CANCELLED, status);
        assertFalse(exchange.isResponseCompleted());
        assertFalse(exchange.isFailed());
        assertFalse(exchange.isAssociated());
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnSend2() throws Exception
    {
        // One of the first things that HttpClient.send() does
        // is to change the status of the exchange
        // We exploit that to be sure the exchange is canceled
        // without race conditions
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            boolean setStatus(int status)
            {
                // Cancel after setting the new status
                int oldStatus = getStatus();
                boolean set = super.setStatus(status);
                if (oldStatus == STATUS_START &&
                    getStatus() == HttpExchange.STATUS_WAITING_FOR_CONNECTION)
                    cancel();
                return set;
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);
        // Cancelling here is wrong and makes the test fail spuriously
        // due to a race condition with send(): the send() can complete
        // before the exchange is canceled so it will be in STATUS_COMPLETE
        // which will fail the test.
//        exchange.cancel();

        int status = exchange.waitForDone();
        assertEquals(HttpExchange.STATUS_CANCELLED, status);
        assertFalse(exchange.isResponseCompleted());
        assertFalse(exchange.isFailed());
        assertFalse(exchange.isAssociated());
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnRequestCommitted() throws Exception
    {
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            protected void onRequestCommitted() throws IOException
            {
                super.onRequestCommitted();
                cancel();
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);

        int status = exchange.waitForDone();
        assertEquals(HttpExchange.STATUS_CANCELLED, status);
        assertFalse(exchange.isResponseCompleted());
        assertFalse(exchange.isFailed());
        assertFalse(exchange.isAssociated());
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnRequestComplete() throws Exception
    {
        TestHttpExchange exchange = new TestHttpExchange()
        {
            @Override
            protected void onRequestComplete() throws IOException
            {
                super.onRequestComplete();
                cancel();
            }
        };
        exchange.setAddress(newAddress());
        exchange.setRequestURI("/");

        getHttpClient().send(exchange);

        int status = exchange.waitForDone();
        assertThat("Exchange Status", status, is(HttpExchange.STATUS_CANCELLED));
        assertThat("Exchange.isResponseCompleted", exchange.isResponseCompleted(), is(false));
        assertThat("Exchange.isFailed", exchange.isFailed(), is(false));
        assertThat("Exchange.isAssociated", exchange.isAssociated(), is(false));
    }

    /* ------------------------------------------------------------ */
    @Test
    public void testHttpExchangeCancelOnResponseStatus() throws Exception
    {
        TestHttpExchange exchange = new TestHttpExchange()
{'fraction_non_alphanumeric': 0.13182914715481767, 'fraction_numerical': 0.0028380871292748686, 'mean_word_length': 2.103258476442096, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3440903', 'n_tokens_mistral': 3460, 'n_tokens_neox': 3295, 'n_words': 900}