diff --git a/webapp/pom.xml b/webapp/pom.xml index 8783276f6d..05a97f200a 100755 --- a/webapp/pom.xml +++ b/webapp/pom.xml @@ -585,6 +585,12 @@ compile + + com.aayushatharva.brotli4j + brotli4j + 1.17.0 + + diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/BrotliCompressionFilter.java b/webapp/src/main/java/org/apache/atlas/web/filters/BrotliCompressionFilter.java new file mode 100644 index 0000000000..f83b0b595e --- /dev/null +++ b/webapp/src/main/java/org/apache/atlas/web/filters/BrotliCompressionFilter.java @@ -0,0 +1,59 @@ +package org.apache.atlas.web.filters; + +import com.aayushatharva.brotli4j.Brotli4jLoader; +import com.aayushatharva.brotli4j.encoder.Encoder; +import com.aayushatharva.brotli4j.encoder.Encoder.Parameters; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class BrotliCompressionFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) { + Brotli4jLoader.ensureAvailability(); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + // Ensure request and response are HttpServletRequest and HttpServletResponse + if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + + String acceptEncoding = httpRequest.getHeader("Accept-Encoding"); + + // Check if the client supports Brotli compression + if (acceptEncoding != null && acceptEncoding.contains("br")) { + // Wrap the response with a Brotli compression wrapper + BrotliResponseWrapper responseWrapper = new BrotliResponseWrapper(httpResponse); + chain.doFilter(request, responseWrapper); + + // Compress the response content with Brotli + byte[] uncompressedData = responseWrapper.getOutputStreamData(); + Parameters params = new Parameters().setQuality(6); // Set Brotli quality level + byte[] compressedOutput = Encoder.compress(uncompressedData, params); + + // Write Brotli-compressed data to the actual response + httpResponse.setHeader("Content-Encoding", "br"); + httpResponse.setContentLength(compressedOutput.length); + httpResponse.getOutputStream().write(compressedOutput); + } else { + // Proceed without compression + chain.doFilter(request, response); + } + } else { + // Proceed without compression if not HTTP + chain.doFilter(request, response); + } + } + + @Override + public void destroy() { + // Optional: Add cleanup logic here if needed + } +} diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/BrotliResponseWrapper.java b/webapp/src/main/java/org/apache/atlas/web/filters/BrotliResponseWrapper.java new file mode 100644 index 0000000000..e8cdbb860b --- /dev/null +++ b/webapp/src/main/java/org/apache/atlas/web/filters/BrotliResponseWrapper.java @@ -0,0 +1,54 @@ +package org.apache.atlas.web.filters; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintWriter; + +public class BrotliResponseWrapper extends HttpServletResponseWrapper { + + private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + private ServletOutputStream servletOutputStream; + private PrintWriter writer; + + public BrotliResponseWrapper(HttpServletResponse response) { + super(response); + } + + @Override + public ServletOutputStream getOutputStream() throws IOException { + if (servletOutputStream == null) { + servletOutputStream = new ServletOutputStream() { + @Override + public void write(int b) { + outputStream.write(b); + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setWriteListener(javax.servlet.WriteListener listener) { + // No-op for this example + } + }; + } + return servletOutputStream; + } + + @Override + public PrintWriter getWriter() throws IOException { + if (writer == null) { + writer = new PrintWriter(outputStream); + } + return writer; + } + + public byte[] getOutputStreamData() { + return outputStream.toByteArray(); + } +} diff --git a/webapp/src/main/webapp/WEB-INF/web.xml b/webapp/src/main/webapp/WEB-INF/web.xml index 07092d62eb..efb26298e2 100755 --- a/webapp/src/main/webapp/WEB-INF/web.xml +++ b/webapp/src/main/webapp/WEB-INF/web.xml @@ -114,6 +114,16 @@ /api/atlas/admin/status + + brotliFilter + org.apache.atlas.web.filters.BrotliCompressionFilter + + + + brotliFilter + /* + + org.springframework.web.context.request.RequestContextListener