diff --git a/ezyhttp-client/pom.xml b/ezyhttp-client/pom.xml index 900c9d7c..4cc493ad 100644 --- a/ezyhttp-client/pom.xml +++ b/ezyhttp-client/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-client diff --git a/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/HttpClient.java b/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/HttpClient.java index b7d4ad48..e2d21078 100644 --- a/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/HttpClient.java +++ b/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/HttpClient.java @@ -14,10 +14,7 @@ import com.tvd12.ezyhttp.core.codec.BodyDeserializer; import com.tvd12.ezyhttp.core.codec.BodySerializer; import com.tvd12.ezyhttp.core.codec.DataConverters; -import com.tvd12.ezyhttp.core.constant.ContentTypes; -import com.tvd12.ezyhttp.core.constant.Headers; -import com.tvd12.ezyhttp.core.constant.HttpMethod; -import com.tvd12.ezyhttp.core.constant.StatusCodes; +import com.tvd12.ezyhttp.core.constant.*; import com.tvd12.ezyhttp.core.data.MultiValueMap; import com.tvd12.ezyhttp.core.exception.*; import com.tvd12.ezyhttp.core.json.ObjectMapperBuilder; @@ -35,10 +32,13 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.zip.GZIPInputStream; import static com.tvd12.ezyfox.io.EzyStrings.isBlank; import static com.tvd12.ezyfox.util.EzyFileUtil.getFileExtension; import static com.tvd12.ezyhttp.client.concurrent.DownloadCancellationToken.ALWAYS_RUN; +import static com.tvd12.ezyhttp.core.constant.Headers.ACCEPT_ENCODING; +import static com.tvd12.ezyhttp.core.constant.Headers.CONTENT_ENCODING; public class HttpClient extends EzyLoggable { @@ -83,7 +83,8 @@ public ResponseEntity request( String url, RequestEntity entity, Map> responseTypes, - int connectTimeout, int readTimeout + int connectTimeout, + int readTimeout ) throws Exception { if (url == null) { throw new IllegalArgumentException("url can not be null"); @@ -115,6 +116,12 @@ public ResponseEntity request( ); } } + if (connection.getRequestProperty(ACCEPT_ENCODING) == null) { + connection.setRequestProperty( + ACCEPT_ENCODING, + ContentEncoding.GZIP.getValue() + ); + } Object requestBody = null; if (method != HttpMethod.GET && entity != null) { requestBody = entity.getBody(); @@ -156,9 +163,12 @@ public ResponseEntity request( if (responseContentType == null) { responseContentType = ContentTypes.APPLICATION_JSON; } - InputStream inputStream = responseCode >= 400 - ? connection.getErrorStream() - : connection.getInputStream(); + InputStream inputStream = decorateInputStream( + connection, + responseCode >= 400 + ? connection.getErrorStream() + : connection.getInputStream() + ); Object responseBody = null; if (inputStream != null) { try { @@ -197,7 +207,8 @@ protected byte[] serializeRequestBody( protected Object deserializeResponseBody( String contentType, int contentLength, - InputStream inputStream, Class responseType + InputStream inputStream, + Class responseType ) throws IOException { BodyDeserializer deserializer = dataConverters.getBodyDeserializer(contentType); Object body; @@ -365,7 +376,12 @@ private String download( Files.deleteIfExists(downloadingFilePath); Files.createFile(downloadingFilePath); - try (InputStream inputStream = connection.getInputStream()) { + try ( + InputStream inputStream = decorateInputStream( + connection, + connection.getInputStream() + ) + ) { try (FileOutputStream outputStream = new FileOutputStream(downloadingFile)) { int bytesRead; byte[] buffer = new byte[1024]; @@ -467,7 +483,12 @@ private void download( if (responseCode >= 400) { throw processDownloadError(connection, fileURL, responseCode); } - try (InputStream inputStream = connection.getInputStream()) { + try ( + InputStream inputStream = decorateInputStream( + connection, + connection.getInputStream() + ) + ) { int bytesRead; byte[] buffer = new byte[1024]; while ((bytesRead = inputStream.read(buffer)) != -1) { @@ -587,8 +608,11 @@ private DownloadFileResult download( .toFile(); EzyFileUtil.createFileIfNotExists(storeFile); try ( - InputStream inputStream = connection.getInputStream(); - OutputStream outputStream = new FileOutputStream(storeFile) + InputStream inputStream = decorateInputStream( + connection, + connection.getInputStream() + ); + OutputStream outputStream = Files.newOutputStream(storeFile.toPath()) ) { int bytesRead; byte[] buffer = new byte[1024]; @@ -625,12 +649,37 @@ private void decorateConnection( } } + private InputStream decorateInputStream( + HttpURLConnection connection, + InputStream inputStream + ) throws Exception { + return decorateInputStream( + connection.getHeaderField(CONTENT_ENCODING), + inputStream + ); + } + + private InputStream decorateInputStream( + String contentEncoding, + InputStream inputStream + ) throws IOException { + ContentEncoding contentEncodingEnum = ContentEncoding + .ofValue(contentEncoding); + if (contentEncodingEnum == ContentEncoding.GZIP) { + return new GZIPInputStream(inputStream); + } + return inputStream; + } + private Exception processDownloadError( HttpURLConnection connection, String fileURL, int responseCode ) throws Exception { - InputStream inputStream = connection.getErrorStream(); + InputStream inputStream = decorateInputStream( + connection, + connection.getErrorStream() + ); Object responseBody = ""; if (inputStream != null) { try { diff --git a/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/request/RequestEntity.java b/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/request/RequestEntity.java index 70c1dc2d..0af2bfc6 100644 --- a/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/request/RequestEntity.java +++ b/ezyhttp-client/src/main/java/com/tvd12/ezyhttp/client/request/RequestEntity.java @@ -110,6 +110,10 @@ public Builder headers(Map headers) { return this; } + public Builder accept(String contentEncoding) { + return header(Headers.ACCEPT_ENCODING, contentEncoding); + } + public Builder contentType(String contentType) { return header(Headers.CONTENT_TYPE, contentType); } diff --git a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/HttpClientTest.java b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/HttpClientTest.java index b77ebfa6..dde49007 100644 --- a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/HttpClientTest.java +++ b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/HttpClientTest.java @@ -14,6 +14,7 @@ import com.tvd12.ezyhttp.core.codec.BodyDeserializer; import com.tvd12.ezyhttp.core.codec.SingletonStringDeserializer; import com.tvd12.ezyhttp.core.codec.TextBodyConverter; +import com.tvd12.ezyhttp.core.constant.ContentEncoding; import com.tvd12.ezyhttp.core.constant.ContentTypes; import com.tvd12.ezyhttp.core.constant.StatusCodes; import com.tvd12.ezyhttp.core.exception.*; @@ -140,6 +141,38 @@ public void callTest() throws Exception { Asserts.assertEquals(expectation, actual); } + @Test + public void callAcceptGzipTest() throws Exception { + // given + HttpClient sut = HttpClient.builder() + .objectMapper(new Object()) + .objectMapper(new ObjectMapper()) + .build(); + + String who = RandomUtil.randomAlphabetString(128); + PostRequest request = new PostRequest() + .setConnectTimeout(-1) + .setReadTimeout(1500000) + .setEntity( + RequestEntity.builder() + .body(new TestRequest(who)) + .header("hello", "world") + .header("foo", "bar") + .accept(ContentEncoding.GZIP.getValue()) + .build() + ) + .setResponseType(TestResponse.class) + .setResponseType(StatusCodes.OK, TestResponse.class) + .setURL(URI.create("http://127.0.0.1:18081/greet")); + + // when + TestResponse actual = sut.call(request); + + // then + TestResponse expectation = new TestResponse("Greet " + who + "!"); + Asserts.assertEquals(expectation, actual); + } + @Test public void callPostFormTest() throws Exception { // given diff --git a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/request/DownloadRequestTest.java b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/request/DownloadRequestTest.java index 49f9ddd8..4a8cd3c4 100644 --- a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/request/DownloadRequestTest.java +++ b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/request/DownloadRequestTest.java @@ -17,18 +17,18 @@ public void test() throws Exception { String fileURL = "https://youngmonkeys.org"; int readTimeout = RandomUtil.randomInt(); int connectionTimeout = RandomUtil.randomInt(); - DownloadRequest sut = new DownloadRequest(); MultiValueMap headers = MultiValueMap.builder() .setValue("hello", "world") .build(); - sut.setFileURL(fileURL); - sut.setFileURL(new URL(fileURL)); - sut.setFileURL(URI.create(fileURL)); - sut.setReadTimeout(readTimeout); - sut.setConnectTimeout(connectionTimeout); - sut.setHeaders(headers); + DownloadRequest sut = new DownloadRequest() + .setFileURL(fileURL) + .setFileURL(new URL(fileURL)) + .setFileURL(URI.create(fileURL)) + .setReadTimeout(readTimeout) + .setConnectTimeout(connectionTimeout) + .setHeaders(headers); // when // then diff --git a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestApplicationBootstrap.java b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestApplicationBootstrap.java index 89b4515d..6e8c0854 100644 --- a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestApplicationBootstrap.java +++ b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestApplicationBootstrap.java @@ -7,8 +7,10 @@ import lombok.AccessLevel; import lombok.Setter; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.gzip.GzipHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -65,7 +67,10 @@ public void start() { List connectors = new ArrayList<>(); connectors.add(connector); server.setConnectors(connectors.toArray(new Connector[0])); - ServletContextHandler servletHandler = newServletHandler(); + Handler servletHandler = newServletHandler(); + GzipHandler gzipHandler = newGzipHandler(); + gzipHandler.setHandler(servletHandler); + servletHandler = gzipHandler; server.setHandler(servletHandler); EzyProcessor.processSilently(server::start); logger.info("http server started on: {}:{}", host, port); @@ -83,4 +88,11 @@ protected ServletContextHandler newServletHandler() { )); return servletHandler; } + + protected GzipHandler newGzipHandler() { + GzipHandler gzipHandler = new GzipHandler(); + gzipHandler.setMinGzipSize(128); + gzipHandler.setIncludedMethods("GET", "POST"); + return gzipHandler; + } } diff --git a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestBlockingServlet.java b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestBlockingServlet.java index 9055d0a3..6225cbbd 100644 --- a/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestBlockingServlet.java +++ b/ezyhttp-client/src/test/java/com/tvd12/ezyhttp/client/test/server/TestBlockingServlet.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.tvd12.ezyfox.io.EzyStrings; import com.tvd12.ezyhttp.core.codec.JsonBodyConverter; +import com.tvd12.ezyhttp.core.constant.ContentTypes; import com.tvd12.ezyhttp.core.constant.StatusCodes; import javax.servlet.ServletException; @@ -57,6 +58,7 @@ protected void doHandle(HttpServletRequest req, HttpServletResponse resp) throws } String message = "{\"message\":\"Greet " + who + "!\"}"; + resp.setContentType(ContentTypes.APPLICATION_JSON); resp.getOutputStream().write(message.getBytes()); resp.setStatus(StatusCodes.OK); break; diff --git a/ezyhttp-core/pom.xml b/ezyhttp-core/pom.xml index 263745d5..5c279dda 100644 --- a/ezyhttp-core/pom.xml +++ b/ezyhttp-core/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-core diff --git a/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/codec/BodyDeserializer.java b/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/codec/BodyDeserializer.java index 01a06b53..5151207d 100644 --- a/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/codec/BodyDeserializer.java +++ b/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/codec/BodyDeserializer.java @@ -7,6 +7,8 @@ import com.tvd12.ezyfox.stream.EzyInputStreams; import com.tvd12.ezyhttp.core.data.BodyData; +import static com.tvd12.ezyfox.stream.EzyInputStreams.DEFAULT_BUFFER_SIZE; + public interface BodyDeserializer { default T deserialize( @@ -34,15 +36,10 @@ default String deserializeToString( InputStream inputStream, int contentLength ) throws IOException { - byte[] bytes; - int readBytes; - if (contentLength > 0) { - bytes = new byte[contentLength]; - readBytes = inputStream.read(bytes); - } else { - bytes = EzyInputStreams.toByteArray(inputStream); - readBytes = bytes.length; - } - return new String(bytes, 0, readBytes, StandardCharsets.UTF_8); + byte[] bytes = EzyInputStreams.toByteArray( + inputStream, + contentLength > 0 ? contentLength : DEFAULT_BUFFER_SIZE + ); + return new String(bytes, StandardCharsets.UTF_8); } } diff --git a/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/ContentEncoding.java b/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/ContentEncoding.java index f0e08e5b..9388bdff 100644 --- a/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/ContentEncoding.java +++ b/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/ContentEncoding.java @@ -12,14 +12,24 @@ public enum ContentEncoding { private final String mimeType; private final String value; - + private static final Map VALUE_BY_MIME_TYPE = EzyEnums.enumMap(ContentEncoding.class, it -> it.mimeType); + private static final Map VALUE_BY_VALUE_LOWERCASE = + EzyEnums.enumMap(ContentEncoding.class, it -> it.value.toLowerCase()); + ContentEncoding(String mimeType, String value) { this.mimeType = mimeType; this.value = value; } + + public static ContentEncoding ofValue(String value) { + if (value == null) { + return null; + } + return VALUE_BY_VALUE_LOWERCASE.get(value.toLowerCase()); + } public static ContentEncoding ofMimeType(String mimeType) { return VALUE_BY_MIME_TYPE.get(mimeType); diff --git a/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/Headers.java b/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/Headers.java index d089b095..a33e8d6e 100644 --- a/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/Headers.java +++ b/ezyhttp-core/src/main/java/com/tvd12/ezyhttp/core/constant/Headers.java @@ -2,6 +2,7 @@ public final class Headers { + public static final String ACCEPT_ENCODING = "Accept-Encoding"; public static final String ACCEPT_RANGES = "accept-ranges"; public static final String CONTENT_ENCODING = "Content-Encoding"; public static final String CONTENT_RANGE = "Content-Range"; diff --git a/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/codec/BodyDeserializerTest.java b/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/codec/BodyDeserializerTest.java index a4936458..02668aef 100644 --- a/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/codec/BodyDeserializerTest.java +++ b/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/codec/BodyDeserializerTest.java @@ -36,7 +36,7 @@ public void deserializeToStringWithContentLengthTest() throws Exception { String actual = sut.deserializeToString(inputStream, contentLength); // then - Asserts.assertEquals("ab", actual); + Asserts.assertEquals("abc", actual); } @Test diff --git a/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/constant/ContentEncodingTest.java b/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/constant/ContentEncodingTest.java index 2f476994..601e3e83 100644 --- a/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/constant/ContentEncodingTest.java +++ b/ezyhttp-core/src/test/java/com/tvd12/ezyhttp/core/test/constant/ContentEncodingTest.java @@ -29,4 +29,17 @@ public void getterTest() { ContentType.GZIP.getMimeType() ); } + + @Test + public void ofValueNullTest() { + Asserts.assertNull(ContentEncoding.ofValue(null)); + } + + @Test + public void offNonNullValueTest() { + Asserts.assertEquals( + ContentEncoding.ofValue("gzip"), + ContentEncoding.GZIP + ); + } } diff --git a/ezyhttp-server-boot/pom.xml b/ezyhttp-server-boot/pom.xml index b6e3d04b..04765854 100644 --- a/ezyhttp-server-boot/pom.xml +++ b/ezyhttp-server-boot/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-server-boot diff --git a/ezyhttp-server-core/pom.xml b/ezyhttp-server-core/pom.xml index 68fd24b2..6432657d 100644 --- a/ezyhttp-server-core/pom.xml +++ b/ezyhttp-server-core/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-server-core diff --git a/ezyhttp-server-core/src/main/java/com/tvd12/ezyhttp/server/core/servlet/BlockingServlet.java b/ezyhttp-server-core/src/main/java/com/tvd12/ezyhttp/server/core/servlet/BlockingServlet.java index 9f8d7a7c..b3848d1b 100644 --- a/ezyhttp-server-core/src/main/java/com/tvd12/ezyhttp/server/core/servlet/BlockingServlet.java +++ b/ezyhttp-server-core/src/main/java/com/tvd12/ezyhttp/server/core/servlet/BlockingServlet.java @@ -89,7 +89,7 @@ public void init() throws ServletException { protected void doGet( HttpServletRequest request, HttpServletResponse response - ) throws ServletException, IOException { + ) throws IOException { doHandleRequest(HttpMethod.GET, request, response); } @@ -97,7 +97,7 @@ protected void doGet( protected void doPost( HttpServletRequest request, HttpServletResponse response - ) throws ServletException, IOException { + ) throws IOException { doHandleRequest(HttpMethod.POST, request, response); } @@ -113,7 +113,7 @@ protected void doPut( protected void doDelete( HttpServletRequest request, HttpServletResponse response - ) throws ServletException, IOException { + ) throws IOException { doHandleRequest(HttpMethod.DELETE, request, response); } diff --git a/ezyhttp-server-graphql/pom.xml b/ezyhttp-server-graphql/pom.xml index 26769b46..d7e5a588 100644 --- a/ezyhttp-server-graphql/pom.xml +++ b/ezyhttp-server-graphql/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-server-graphql diff --git a/ezyhttp-server-jetty/pom.xml b/ezyhttp-server-jetty/pom.xml index dc296899..5fb78ac0 100644 --- a/ezyhttp-server-jetty/pom.xml +++ b/ezyhttp-server-jetty/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-server-jetty diff --git a/ezyhttp-server-management/pom.xml b/ezyhttp-server-management/pom.xml index f3d32625..64b54ec6 100644 --- a/ezyhttp-server-management/pom.xml +++ b/ezyhttp-server-management/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-server-management ezyhttp-server-management diff --git a/ezyhttp-server-thymeleaf/pom.xml b/ezyhttp-server-thymeleaf/pom.xml index 53fde80e..0eb042bc 100644 --- a/ezyhttp-server-thymeleaf/pom.xml +++ b/ezyhttp-server-thymeleaf/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-server-thymeleaf diff --git a/ezyhttp-server-tomcat/pom.xml b/ezyhttp-server-tomcat/pom.xml index 5c1c4fa2..5904ec7a 100644 --- a/ezyhttp-server-tomcat/pom.xml +++ b/ezyhttp-server-tomcat/pom.xml @@ -5,7 +5,7 @@ com.tvd12 ezyhttp - 1.2.3 + 1.2.4 ezyhttp-server-tomcat diff --git a/pom.xml b/pom.xml index f0d98a21..c9f71b85 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 1.0.6 ezyhttp - 1.2.3 + 1.2.4 pom ezyhttp