Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;

import org.apache.http.HttpEntity;
Expand All @@ -36,7 +38,6 @@
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import org.springframework.boot.buildpack.platform.io.Content;
import org.springframework.boot.buildpack.platform.io.IOConsumer;
Expand All @@ -46,6 +47,7 @@
* {@link Http} implementation backed by a {@link HttpClient}.
*
* @author Phillip Webb
* @author Mike Smithson
*/
class HttpClientHttp implements Http {

Expand All @@ -66,21 +68,19 @@ class HttpClientHttp implements Http {
* Perform a HTTP GET operation.
* @param uri the destination URI
* @return the operation response
* @throws IOException on IO error
*/
@Override
public Response get(URI uri) throws IOException {
public Response get(URI uri) {
return execute(new HttpGet(uri));
}

/**
* Perform a HTTP POST operation.
* @param uri the destination URI
* @return the operation response
* @throws IOException on IO error
*/
@Override
public Response post(URI uri) throws IOException {
public Response post(URI uri) {
return execute(new HttpPost(uri));
}

Expand All @@ -90,11 +90,10 @@ public Response post(URI uri) throws IOException {
* @param contentType the content type to write
* @param writer a content writer
* @return the operation response
* @throws IOException on IO error
*/

@Override
public Response post(URI uri, String contentType, IOConsumer<OutputStream> writer) throws IOException {
public Response post(URI uri, String contentType, IOConsumer<OutputStream> writer) {
return execute(new HttpPost(uri), contentType, writer);
}

Expand All @@ -104,51 +103,55 @@ public Response post(URI uri, String contentType, IOConsumer<OutputStream> write
* @param contentType the content type to write
* @param writer a content writer
* @return the operation response
* @throws IOException on IO error
*/

@Override
public Response put(URI uri, String contentType, IOConsumer<OutputStream> writer) throws IOException {
public Response put(URI uri, String contentType, IOConsumer<OutputStream> writer) {
return execute(new HttpPut(uri), contentType, writer);
}

/**
* Perform a HTTP DELETE operation.
* @param uri the destination URI
* @return the operation response
* @throws IOException on IO error
*/

@Override
public Response delete(URI uri) throws IOException {
public Response delete(URI uri) {
return execute(new HttpDelete(uri));
}

private Response execute(HttpEntityEnclosingRequestBase request, String contentType,
IOConsumer<OutputStream> writer) throws IOException {
IOConsumer<OutputStream> writer) {
request.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
request.setEntity(new WritableHttpEntity(writer));
return execute(request);
}

private Response execute(HttpUriRequest request) throws IOException {
CloseableHttpResponse response = this.client.execute(request);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
HttpEntity entity = response.getEntity();
if (statusCode >= 200 && statusCode < 300) {
return new HttpClientResponse(response);
}
Errors errors = null;
if (statusCode >= 400 && statusCode < 500) {
try {
errors = SharedObjectMapper.get().readValue(entity.getContent(), Errors.class);
private Response execute(HttpUriRequest request) {
CloseableHttpResponse response;
try {
response = this.client.execute(request);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
HttpEntity entity = response.getEntity();

if (statusCode >= 400 && statusCode < 500) {
Errors errors = SharedObjectMapper.get().readValue(entity.getContent(), Errors.class);
throw new DockerException(request.getURI(), statusCode, statusLine.getReasonPhrase(), errors);
}
catch (Exception ex) {
if (statusCode == 500) {
throw new DockerException(request.getURI(), statusCode, statusLine.getReasonPhrase(), null);
}
}
EntityUtils.consume(entity);
throw new DockerException(request.getURI(), statusCode, statusLine.getReasonPhrase(), errors);
catch (IOException ioe) {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
ioe.printStackTrace(printWriter);
throw new DockerException(request.getURI(), 500, stringWriter.toString(), null);
}

return new HttpClientResponse(response);
}

/**
Expand All @@ -175,7 +178,7 @@ public long getContentLength() {
}

@Override
public InputStream getContent() throws IOException, UnsupportedOperationException {
public InputStream getContent() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHeaders;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
Expand Down Expand Up @@ -54,6 +53,7 @@
* Tests for {@link HttpClientHttp}.
*
* @author Phillip Webb
* @author Mike Smithson
*/
class HttpClientHttpTests {

Expand Down Expand Up @@ -132,7 +132,7 @@ void postWithContentShouldExecuteHttpPost() throws Exception {
assertThat(entity.isRepeatable()).isFalse();
assertThat(entity.getContentLength()).isEqualTo(-1);
assertThat(entity.isStreaming()).isTrue();
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> entity.getContent());
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
assertThat(writeToString(entity)).isEqualTo("test");
assertThat(response.getContent()).isSameAs(this.content);
}
Expand All @@ -152,7 +152,7 @@ void putWithContentShouldExecuteHttpPut() throws Exception {
assertThat(entity.isRepeatable()).isFalse();
assertThat(entity.getContentLength()).isEqualTo(-1);
assertThat(entity.isStreaming()).isTrue();
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> entity.getContent());
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
assertThat(writeToString(entity)).isEqualTo("test");
assertThat(response.getContent()).isSameAs(this.content);
}
Expand All @@ -171,20 +171,28 @@ void deleteShouldExecuteHttpDelete() throws IOException {
}

@Test
void executeWhenResposeIsIn400RangeShouldThrowDockerException() throws ClientProtocolException, IOException {
void executeWhenResposeIsIn400RangeShouldThrowDockerException() throws IOException {
given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("errors.json"));
given(this.statusLine.getStatusCode()).willReturn(404);
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
.satisfies((ex) -> assertThat(ex.getErrors()).hasSize(2));
}

@Test
void executeWhenResposeIsIn500RangeShouldThrowDockerException() throws ClientProtocolException, IOException {
void executeWhenResposeIsIn500RangeShouldThrowDockerException() {
given(this.statusLine.getStatusCode()).willReturn(500);
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
.satisfies((ex) -> assertThat(ex.getErrors()).isNull());
}

@Test
void executeWhenClientExecutesRequestThrowsIOExceptionRethrowsAsDockerException() throws IOException {
given(this.client.execute(any())).willThrow(IOException.class);
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
.satisfies((ex) -> assertThat(ex.getErrors()).isNull()).satisfies(DockerException::getStatusCode)
.withMessageContaining("500").satisfies((ex) -> assertThat(ex.getReasonPhrase())).isNotNull();
}

private String writeToString(HttpEntity entity) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
entity.writeTo(out);
Expand Down