@Test
  public void testNoContentResponse() throws Exception {

    final int reqNo = 20;

    // Initialize the server-side request handler
    this.server.registerHandler(
        "*",
        new HttpRequestHandler() {

          public void handle(
              final HttpRequest request, final HttpResponse response, final HttpContext context)
              throws HttpException, IOException {
            response.setStatusCode(HttpStatus.SC_NO_CONTENT);
          }
        });

    this.server.start();

    final DefaultBHttpClientConnection conn = client.createConnection();
    final HttpHost host = new HttpHost("localhost", this.server.getPort());

    try {
      for (int r = 0; r < reqNo; r++) {
        if (!conn.isOpen()) {
          client.connect(host, conn);
        }

        final BasicHttpRequest get = new BasicHttpRequest("GET", "/?" + r);
        final HttpResponse response = this.client.execute(get, host, conn);
        Assert.assertNull(response.getEntity());
        if (!this.client.keepAlive(response)) {
          conn.close();
          Assert.fail("Connection expected to be re-usable");
        }
      }

      // Verify the connection metrics
      final HttpConnectionMetrics cm = conn.getMetrics();
      Assert.assertEquals(reqNo, cm.getRequestCount());
      Assert.assertEquals(reqNo, cm.getResponseCount());

    } finally {
      conn.close();
      this.server.shutdown();
    }
  }
  public void sendRequests() throws IOException, HttpException {
    this.connection.flush();
    HttpConnectionMetrics localHttpConnectionMetrics = this.connection.getMetrics();
    while (localHttpConnectionMetrics.getResponseCount()
        < localHttpConnectionMetrics.getRequestCount()) {
      HttpResponse localHttpResponse = this.connection.receiveResponseHeader();
      if (!localHttpResponse
          .getStatusLine()
          .getProtocolVersion()
          .greaterEquals(HttpVersion.HTTP_1_1)) {
        this.callbacks.pipelineModeChanged(false);
        this.canPipeline = false;
      }
      Header[] arrayOfHeader1 = localHttpResponse.getHeaders("Connection");
      if (arrayOfHeader1 != null)
        for (Header localHeader : arrayOfHeader1) {
          if (!"close".equalsIgnoreCase(localHeader.getValue())) continue;
          this.callbacks.pipelineModeChanged(false);
          this.canPipeline = false;
        }
      this.lastStatusCode = localHttpResponse.getStatusLine().getStatusCode();
      if (this.lastStatusCode != 200) {
        this.callbacks.serverError(this.lastStatusCode);
        closeConnection();
        return;
      }
      this.connection.receiveResponseEntity(localHttpResponse);
      localHttpResponse.getEntity().consumeContent();
      this.callbacks.requestSent();

      if (!this.canPipeline) {
        closeConnection();
        return;
      }
    }
  }
  /**
   * This test case executes a series of simple POST requests that do not meet the target server
   * expectations.
   */
  @Test
  public void testHttpPostsWithExpectationVerification() throws Exception {

    final int reqNo = 3;

    // Initialize the server-side request handler
    this.server.registerHandler(
        "*",
        new HttpRequestHandler() {

          public void handle(
              final HttpRequest request, final HttpResponse response, final HttpContext context)
              throws HttpException, IOException {

            final StringEntity outgoing = new StringEntity("No content");
            response.setEntity(outgoing);
          }
        });

    this.server.setExpectationVerifier(
        new HttpExpectationVerifier() {

          public void verify(
              final HttpRequest request, final HttpResponse response, final HttpContext context)
              throws HttpException {
            final Header someheader = request.getFirstHeader("Secret");
            if (someheader != null) {
              int secretNumber;
              try {
                secretNumber = Integer.parseInt(someheader.getValue());
              } catch (final NumberFormatException ex) {
                response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
                return;
              }
              if (secretNumber < 2) {
                response.setStatusCode(HttpStatus.SC_EXPECTATION_FAILED);
                final ByteArrayEntity outgoing =
                    new ByteArrayEntity(EncodingUtils.getAsciiBytes("Wrong secret number"));
                response.setEntity(outgoing);
              }
            }
          }
        });

    this.server.start();

    final DefaultBHttpClientConnection conn = client.createConnection();
    final HttpHost host = new HttpHost("localhost", this.server.getPort());

    try {
      for (int r = 0; r < reqNo; r++) {
        if (!conn.isOpen()) {
          client.connect(host, conn);
        }

        final BasicHttpEntityEnclosingRequest post =
            new BasicHttpEntityEnclosingRequest("POST", "/");
        post.addHeader("Secret", Integer.toString(r));
        final ByteArrayEntity outgoing =
            new ByteArrayEntity(EncodingUtils.getAsciiBytes("No content " + r));
        post.setEntity(outgoing);

        final HttpResponse response = this.client.execute(post, host, conn);

        final HttpEntity entity = response.getEntity();
        Assert.assertNotNull(entity);
        EntityUtils.consume(entity);

        if (r < 2) {
          Assert.assertEquals(
              HttpStatus.SC_EXPECTATION_FAILED, response.getStatusLine().getStatusCode());
        } else {
          Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
        }

        if (!this.client.keepAlive(response)) {
          conn.close();
        }
      }
      // Verify the connection metrics
      final HttpConnectionMetrics cm = conn.getMetrics();
      Assert.assertEquals(reqNo, cm.getRequestCount());
      Assert.assertEquals(reqNo, cm.getResponseCount());
    } finally {
      conn.close();
      this.server.shutdown();
    }
  }
  /**
   * This test case executes a series of simple POST requests using the 'expect: continue'
   * handshake.
   */
  @Test
  public void testHttpPostsWithExpectContinue() throws Exception {

    final int reqNo = 20;

    final Random rnd = new Random();

    // Prepare some random data
    final List<byte[]> testData = new ArrayList<byte[]>(reqNo);
    for (int i = 0; i < reqNo; i++) {
      final int size = rnd.nextInt(5000);
      final byte[] data = new byte[size];
      rnd.nextBytes(data);
      testData.add(data);
    }

    // Initialize the server-side request handler
    this.server.registerHandler(
        "*",
        new HttpRequestHandler() {

          public void handle(
              final HttpRequest request, final HttpResponse response, final HttpContext context)
              throws HttpException, IOException {

            if (request instanceof HttpEntityEnclosingRequest) {
              final HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
              final byte[] data = EntityUtils.toByteArray(incoming);

              final ByteArrayEntity outgoing = new ByteArrayEntity(data);
              outgoing.setChunked(true);
              response.setEntity(outgoing);
            } else {
              final StringEntity outgoing = new StringEntity("No content");
              response.setEntity(outgoing);
            }
          }
        });

    this.server.start();

    // Activate 'expect: continue' handshake
    final DefaultBHttpClientConnection conn = client.createConnection();
    final HttpHost host = new HttpHost("localhost", this.server.getPort());

    try {
      for (int r = 0; r < reqNo; r++) {
        if (!conn.isOpen()) {
          client.connect(host, conn);
        }

        final BasicHttpEntityEnclosingRequest post =
            new BasicHttpEntityEnclosingRequest("POST", "/");
        final byte[] data = testData.get(r);
        final ByteArrayEntity outgoing = new ByteArrayEntity(data);
        outgoing.setChunked(true);
        post.setEntity(outgoing);

        final HttpResponse response = this.client.execute(post, host, conn);
        final byte[] received = EntityUtils.toByteArray(response.getEntity());
        final byte[] expected = testData.get(r);

        Assert.assertEquals(expected.length, received.length);
        for (int i = 0; i < expected.length; i++) {
          Assert.assertEquals(expected[i], received[i]);
        }
        if (!this.client.keepAlive(response)) {
          conn.close();
        }
      }

      // Verify the connection metrics
      final HttpConnectionMetrics cm = conn.getMetrics();
      Assert.assertEquals(reqNo, cm.getRequestCount());
      Assert.assertEquals(reqNo, cm.getResponseCount());
    } finally {
      conn.close();
      this.server.shutdown();
    }
  }
  /** This test case executes a series of simple GET requests */
  @Test
  public void testSimpleBasicHttpRequests() throws Exception {

    final int reqNo = 20;

    final Random rnd = new Random();

    // Prepare some random data
    final List<byte[]> testData = new ArrayList<byte[]>(reqNo);
    for (int i = 0; i < reqNo; i++) {
      final int size = rnd.nextInt(5000);
      final byte[] data = new byte[size];
      rnd.nextBytes(data);
      testData.add(data);
    }

    // Initialize the server-side request handler
    this.server.registerHandler(
        "*",
        new HttpRequestHandler() {

          public void handle(
              final HttpRequest request, final HttpResponse response, final HttpContext context)
              throws HttpException, IOException {

            String s = request.getRequestLine().getUri();
            if (s.startsWith("/?")) {
              s = s.substring(2);
            }
            final int index = Integer.parseInt(s);
            final byte[] data = testData.get(index);
            final ByteArrayEntity entity = new ByteArrayEntity(data);
            response.setEntity(entity);
          }
        });

    this.server.start();

    final DefaultBHttpClientConnection conn = client.createConnection();
    final HttpHost host = new HttpHost("localhost", this.server.getPort());

    try {
      for (int r = 0; r < reqNo; r++) {
        if (!conn.isOpen()) {
          client.connect(host, conn);
        }

        final BasicHttpRequest get = new BasicHttpRequest("GET", "/?" + r);
        final HttpResponse response = this.client.execute(get, host, conn);
        final byte[] received = EntityUtils.toByteArray(response.getEntity());
        final byte[] expected = testData.get(r);

        Assert.assertEquals(expected.length, received.length);
        for (int i = 0; i < expected.length; i++) {
          Assert.assertEquals(expected[i], received[i]);
        }
        if (!this.client.keepAlive(response)) {
          conn.close();
        }
      }

      // Verify the connection metrics
      final HttpConnectionMetrics cm = conn.getMetrics();
      Assert.assertEquals(reqNo, cm.getRequestCount());
      Assert.assertEquals(reqNo, cm.getResponseCount());

    } finally {
      conn.close();
      this.server.shutdown();
    }
  }