package com.github.kristofa.test.http.client; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.entity.ByteArrayEntity; import com.github.kristofa.test.http.FullHttpRequest; import com.github.kristofa.test.http.HttpMessageHeader; import com.github.kristofa.test.http.Method; /** * {@link HttpClient} implementation that uses <a href="http://hc.apache.org/httpcomponents-client-ga/">Apache HTTP * client</a> as 'lower level' library. * * @author kristof */ public class ApacheHttpClientImpl implements HttpClient { public ApacheHttpClientImpl() { } /** * {@inheritDoc} */ @Override public HttpClientResponse<InputStream> execute(final FullHttpRequest request) throws HttpRequestException { if (request.getMethod().equals(Method.GET)) { final HttpGet httpGet = new HttpGet(request.getUrl()); populateHeader(request, httpGet); try { return execute(httpGet); } catch (final IOException e1) { throw new GetException(e1); } } else if (request.getMethod().equals(Method.PUT)) { final HttpPut httpPut = new HttpPut(request.getUrl()); populateHeader(request, httpPut); try { return execute(httpPut, request.getContent()); } catch (final IOException e1) { throw new PutException(e1); } } else if (request.getMethod().equals(Method.POST)) { final HttpPost httpPost = new HttpPost(request.getUrl()); populateHeader(request, httpPost); try { return execute(httpPost, request.getContent()); } catch (final IOException e1) { throw new PostException(e1); } } else if (request.getMethod().equals(Method.DELETE)) { final HttpDelete httpDelete = new HttpDelete(request.getUrl()); populateHeader(request, httpDelete); try { return execute(httpDelete); } catch (final IOException e1) { throw new GetException(e1); } } throw new HttpRequestException("Unsupported operation: " + request.getMethod()); } /** * Gets a new HTTPClient instance. Introduced to facilitate testing. * * @return A new HTTPClient instance. */ /* package */org.apache.http.client.HttpClient getClient() { // We use a Custom implementation because we don't want to modify the requests/responses. return new CustomHttpClient(); } private void populateHeader(final FullHttpRequest request, final HttpRequestBase apacheRequest) { for (final HttpMessageHeader header : request.getHttpMessageHeaders()) { apacheRequest.addHeader(header.getName(), header.getValue()); } } private HttpClientResponse<InputStream> execute(final HttpEntityEnclosingRequestBase request, final byte[] content) throws IOException { if (content != null) { request.setEntity(new ByteArrayEntity(content)); } return execute(request); } private HttpClientResponse<InputStream> execute(final HttpRequestBase request) throws IOException { final org.apache.http.client.HttpClient client = getClient(); try { final HttpResponse httpResponse = client.execute(request); return buildResponse(client, httpResponse); } catch (final IOException e) { client.getConnectionManager().shutdown(); // In case of exception we should close connection manager here. throw e; } } private HttpClientResponse<InputStream> buildResponse(final org.apache.http.client.HttpClient client, final HttpResponse response) throws IOException { final int status = response.getStatusLine().getStatusCode(); final ApacheHttpClientResponseImpl<InputStream> httpResponse = new ApacheHttpClientResponseImpl<InputStream>(status, client); httpResponse.setResponseEntity(response.getEntity().getContent()); if (response.getEntity().getContentType() != null) { httpResponse.setContentType(response.getEntity().getContentType().getValue()); } if (status < 200 || status > 299) { // In this case response will be the error message. httpResponse.setErrorMessage("Got HTTP return code " + status); } return httpResponse; } }