From e903734bc8fdb195a7e3f7af0948087c2f24f088 Mon Sep 17 00:00:00 2001 From: Mihai Andronache Date: Sun, 4 Feb 2018 19:38:54 +0200 Subject: [PATCH 1/2] Implemented and tested headers() --- .../com/amihaiemil/docker/SocketResponse.java | 28 +++- .../docker/SocketResponseTestCase.java | 120 +++++++++++++++--- 2 files changed, 126 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/amihaiemil/docker/SocketResponse.java b/src/main/java/com/amihaiemil/docker/SocketResponse.java index 351425b3..acd0a51d 100644 --- a/src/main/java/com/amihaiemil/docker/SocketResponse.java +++ b/src/main/java/com/amihaiemil/docker/SocketResponse.java @@ -28,15 +28,17 @@ import com.jcabi.http.Request; import com.jcabi.http.Response; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * HTTP Response comming from the Unix Socket. * @author Mihai Andronache (amihaiemil@gmail.com) * @version $Id$ * @since 0.0.1 - * @todo #14:30min Implement and test the headers() method. * @todo #14:30min Refine the body reading logic. Have to take into account * the Transfer-Encoding header and cover the empty body case. */ @@ -85,7 +87,29 @@ public String reason() { @Override public Map> headers() { - return null; + final int endHeaders; + if(this.response.indexOf("\n\n") != -1) { + endHeaders = this.response.indexOf("\n\n"); + } else { + endHeaders = this.response.length(); + } + final String hdrs = this.response.substring( + this.response.indexOf("\n"), endHeaders + ); + final Map> headers; + if(hdrs.trim().isEmpty()) { + headers = new HashMap<>(); + } else { + headers = Arrays.asList( + hdrs.trim().split("\n") + ).stream().collect( + Collectors.toMap( + h -> h.split(":")[0], + h -> Arrays.asList(h.split(":")[1].trim().split(", ")) + ) + ); + } + return headers; } @Override diff --git a/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java b/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java index c81afb20..9d4fbd5b 100644 --- a/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java +++ b/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java @@ -26,17 +26,19 @@ package com.amihaiemil.docker; import com.jcabi.http.Response; +import com.sun.org.apache.xerces.internal.impl.xpath.regex.Match; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Test; +import java.util.List; +import java.util.Map; + /** * Unit tests for SocketResponse. * @author Mihai Andronache (amihaiemil@gmail.com) * @version $Id$ * @since 0.0.1 - * @checkstyle RegexpSingleline (200 lines) - * @checkstyle OperatorWrap (200 lines) */ public final class SocketResponseTestCase { @@ -45,15 +47,15 @@ public final class SocketResponseTestCase { */ @Test public void hasStatus() { - final String responseString = "HTTP/1.1 200 OK\n" + - "Api-Version: 1.35\n" + - "Content-Type: application/json\n" + - "Docker-Experimental: false\n" + - "Ostype: linux\n" + - "Server: Docker/17.12.0-ce (linux)\n" + - "Date: Sun, 04 Feb 2018 09:07:13 GMT\n" + - "Connection: close\n" + - "Content-Length: 0"; + final String responseString = "HTTP/1.1 200 OK\n" + + "Api-Version: 1.35\n" + + "Content-Type: application/json\n" + + "Docker-Experimental: false\n" + + "Ostype: linux\n" + + "Server: Docker/17.12.0-ce (linux)\n" + + "Date: Sun, 04 Feb 2018 09:07:13 GMT\n" + + "Connection: close\n" + + "Content-Length: 0"; final Response resp = new SocketResponse(null, responseString); MatcherAssert.assertThat(resp.status(), Matchers.is(200)); } @@ -63,16 +65,94 @@ public void hasStatus() { */ @Test public void hasReason() { - final String responseString = "HTTP/1.1 200 OK\n" + - "Api-Version: 1.35\n" + - "Content-Type: application/json\n" + - "Docker-Experimental: false\n" + - "Ostype: linux\n" + - "Server: Docker/17.12.0-ce (linux)\n" + - "Date: Sun, 04 Feb 2018 09:07:13 GMT\n" + - "Connection: close\n" + - "Content-Length: 0"; + final String responseString = "HTTP/1.1 200 OK\n" + + "Api-Version: 1.35\n" + + "Content-Type: application/json\n" + + "Docker-Experimental: false\n" + + "Ostype: linux\n" + + "Server: Docker/17.12.0-ce (linux)\n" + + "Date: Sun, 04 Feb 2018 09:07:13 GMT\n" + + "Connection: close\n" + + "Content-Length: 0"; final Response resp = new SocketResponse(null, responseString); MatcherAssert.assertThat(resp.reason(), Matchers.equalTo("OK")); } + + /** + * A SocketResponse can return its headers if there is no body afterwards. + */ + @Test + public void headersWithNoContent() { + final String responseString = "HTTP/1.1 200 OK\n" + + "Api-Version: 1.35\n" + + "Content-Type: application/json\n" + + "Docker-Experimental: false\n" + + "Ostype: linux\n" + + "Server: Docker/17.12.0-ce (linux)\n" + + "Date: Sun, 04 Feb 2018 09:07:13 GMT\n" + + "Connection: close\n" + + "Content-Length: 0"; + final Response resp = new SocketResponse(null, responseString); + final Map> headers = resp.headers(); + MatcherAssert.assertThat(headers.size(), Matchers.is(8)); + headers.forEach((key, value) -> { + MatcherAssert.assertThat( + key, Matchers.not(Matchers.isEmptyOrNullString()) + ); + MatcherAssert.assertThat( + value.size() > 0, Matchers.is(Boolean.TRUE) + ); + }); + } + + /** + * A SocketResponse can return its headers if there is a body afterwards. + */ + @Test + public void headersWithontent() { + final String responseString = "HTTP/1.1 200 OK\n" + + "Api-Version: 1.35\n" + + "Content-Type: application/json\n" + + "Docker-Experimental: false\n" + + "Connection: close\n" + + "Content-Length: 2\n\n" + + "OK"; + final Response resp = new SocketResponse(null, responseString); + final Map> headers = resp.headers(); + MatcherAssert.assertThat(headers.size(), Matchers.is(5)); + headers.forEach((key, value) -> { + MatcherAssert.assertThat( + key, Matchers.not(Matchers.isEmptyOrNullString()) + ); + MatcherAssert.assertThat( + value.size() == 1, Matchers.is(Boolean.TRUE) + ); + }); + MatcherAssert.assertThat(headers.get( + "Api-Version").get(0), Matchers.equalTo("1.35") + ); + MatcherAssert.assertThat(headers.get( + "Content-Type").get(0), Matchers.equalTo("application/json") + ); + MatcherAssert.assertThat(headers.get( + "Docker-Experimental").get(0), Matchers.equalTo("false") + ); + MatcherAssert.assertThat(headers.get( + "Connection").get(0), Matchers.equalTo("close") + ); + MatcherAssert.assertThat(headers.get( + "Content-Length").get(0), Matchers.equalTo("2") + ); + } + + /** + * A SocketResponse returns an empty Map when there are no headers. + */ + @Test + public void noHeaders() { + final String responseString = "HTTP/1.1 200 OK\n"; + final Response resp = new SocketResponse(null, responseString); + final Map> headers = resp.headers(); + MatcherAssert.assertThat(headers.isEmpty(), Matchers.is(Boolean.TRUE)); + } } From 080c5789f2f8ff38735923cbb50e37b7a79a0f89 Mon Sep 17 00:00:00 2001 From: Mihai Andronache Date: Sun, 4 Feb 2018 19:44:07 +0200 Subject: [PATCH 2/2] checkstyle fixes --- src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java b/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java index 9d4fbd5b..88a6dc20 100644 --- a/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java +++ b/src/test/java/com/amihaiemil/docker/SocketResponseTestCase.java @@ -26,7 +26,6 @@ package com.amihaiemil.docker; import com.jcabi.http.Response; -import com.sun.org.apache.xerces.internal.impl.xpath.regex.Match; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Test;