private Request buildRequest(ClientRequest req) throws IOException {
   final Request request =
       client.newRequest(req.getURI()).method(HttpMethod.fromString(req.getMethod()));
   if (req.getEntity() != null) {
     final RequestEntityWriter writer = getRequestEntityWriter(req);
     final PipedOutputStream output = new PipedOutputStream();
     final PipedInputStream input = new PipedInputStream(output);
     request.content(new InputStreamContentProvider(input));
     writer.writeRequestEntity(output);
   }
   return request;
 }
  public void configureRequest(
      final RequestBuilder requestBuilder, final ClientRequest cr, final boolean needsBody) {
    final Map<String, Object> props = cr.getProperties();

    // Set the read timeout
    final Integer readTimeout = (Integer) props.get(AhcConfig.PROPERTY_READ_TIMEOUT);
    if (readTimeout != null) {
      final PerRequestConfig c = new PerRequestConfig();
      c.setRequestTimeoutInMs(readTimeout);
      requestBuilder.setPerRequestConfig(c);
    }
    if (cr.getEntity() != null && needsBody) {
      final RequestEntityWriter re = getRequestEntityWriter(cr);

      final ByteArrayOutputStream baos = new ByteArrayOutputStream();
      try {
        re.writeRequestEntity(
            new CommittingOutputStream(baos) {
              @Override
              protected void commit() throws IOException {
                configureHeaders(cr.getHeaders(), requestBuilder);
              }
            });
      } catch (final IOException ex) {
        throw new ClientHandlerException(ex);
      }

      final byte[] content = baos.toByteArray();
      requestBuilder.setBody(
          new Request.EntityWriter() {
            @Override
            public void writeEntity(final OutputStream out) throws IOException {
              out.write(content);
            }
          });
    } else {
      configureHeaders(cr.getHeaders(), requestBuilder);
    }
  }
  @Override
  public void executeMethod(final HttpMethod method, final ClientRequest cr) {
    final Map<String, Object> props = cr.getProperties();

    method.setDoAuthentication(true);

    final HttpMethodParams methodParams = method.getParams();

    // Set the handle cookies property
    if (!cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_HANDLE_COOKIES)) {
      methodParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
    }

    // Set the interactive and credential provider properties
    if (cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_INTERACTIVE)) {
      CredentialsProvider provider =
          (CredentialsProvider) props.get(ApacheHttpClientConfig.PROPERTY_CREDENTIALS_PROVIDER);
      if (provider == null) {
        provider = DEFAULT_CREDENTIALS_PROVIDER;
      }
      methodParams.setParameter(CredentialsProvider.PROVIDER, provider);
    } else {
      methodParams.setParameter(CredentialsProvider.PROVIDER, null);
    }

    // Set the read timeout
    final Integer readTimeout = (Integer) props.get(ApacheHttpClientConfig.PROPERTY_READ_TIMEOUT);
    if (readTimeout != null) {
      methodParams.setSoTimeout(readTimeout);
    }

    if (method instanceof EntityEnclosingMethod) {
      final EntityEnclosingMethod entMethod = (EntityEnclosingMethod) method;

      if (cr.getEntity() != null) {
        final RequestEntityWriter re = getRequestEntityWriter(cr);
        final Integer chunkedEncodingSize =
            (Integer) props.get(ApacheHttpClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE);
        if (chunkedEncodingSize != null) {
          // There doesn't seems to be a way to set the chunk size.
          entMethod.setContentChunked(true);

          // It is not possible for a MessageBodyWriter to modify
          // the set of headers before writing out any bytes to
          // the OutputStream
          // This makes it impossible to use the multipart
          // writer that modifies the content type to add a boundary
          // parameter
          writeOutBoundHeaders(cr.getHeaders(), method);

          // Do not buffer the request entity when chunked encoding is
          // set
          entMethod.setRequestEntity(
              new RequestEntity() {

                @Override
                public boolean isRepeatable() {
                  return false;
                }

                @Override
                public void writeRequest(OutputStream out) throws IOException {
                  re.writeRequestEntity(out);
                }

                @Override
                public long getContentLength() {
                  return re.getSize();
                }

                @Override
                public String getContentType() {
                  return re.getMediaType().toString();
                }
              });

        } else {
          entMethod.setContentChunked(false);

          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          try {
            re.writeRequestEntity(
                new CommittingOutputStream(baos) {

                  @Override
                  protected void commit() throws IOException {
                    writeOutBoundHeaders(cr.getMetadata(), method);
                  }
                });
          } catch (IOException ex) {
            throw new ClientHandlerException(ex);
          }

          final byte[] content = baos.toByteArray();
          entMethod.setRequestEntity(
              new RequestEntity() {

                @Override
                public boolean isRepeatable() {
                  return true;
                }

                @Override
                public void writeRequest(OutputStream out) throws IOException {
                  out.write(content);
                }

                @Override
                public long getContentLength() {
                  return content.length;
                }

                @Override
                public String getContentType() {
                  return re.getMediaType().toString();
                }
              });
        }
      }
    } else {
      writeOutBoundHeaders(cr.getHeaders(), method);

      // Follow redirects
      method.setFollowRedirects(
          cr.getPropertyAsFeature(ApacheHttpClientConfig.PROPERTY_FOLLOW_REDIRECTS));
    }
    try {
      httpClient.executeMethod(
          getHostConfiguration(httpClient, props), method, getHttpState(props));
    } catch (Exception e) {
      method.releaseConnection();
      throw new ClientHandlerException(e);
    }
  }