add html compression
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 1m59s
Publish Docker Image / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 58s

This commit is contained in:
Lee 2024-06-02 10:20:10 +01:00
parent 2f008730f9
commit 93d491445a
2 changed files with 103 additions and 0 deletions

@ -77,6 +77,11 @@
<version>3.14.0</version> <version>3.14.0</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.googlecode.htmlcompressor</groupId>
<artifactId>htmlcompressor</artifactId>
<version>1.5.2</version>
</dependency>
<!-- Sentry --> <!-- Sentry -->
<dependency> <dependency>

@ -0,0 +1,98 @@
package cc.fascinated.backend.filter;
import com.googlecode.htmlcompressor.compressor.HtmlCompressor;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import org.springframework.stereotype.Component;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Filter to compress HTML responses using HtmlCompressor.
* Author: Fascinated (fascinated7)
*/
@Component
public class HtmlCompressionFilter implements Filter {
private final HtmlCompressor htmlCompressor = new HtmlCompressor();
/**
* Applies the HTML compression filter.
*
* @param request the ServletRequest
* @param response the ServletResponse
* @param chain the FilterChain
* @throws ServletException if an error occurs during filtering
* @throws IOException if an input or output error occurs
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
ServletResponse newResponse = response;
// Wrap the response to capture the output
if (request instanceof HttpServletRequest) {
newResponse = new CharResponseWrapper((HttpServletResponse) response);
}
// Pass the request and response along the filter chain
chain.doFilter(request, newResponse);
// Compress the captured response if it was wrapped
if (newResponse instanceof CharResponseWrapper) {
String responseContent = newResponse.toString();
if (responseContent != null) {
response.getWriter().write(htmlCompressor.compress(responseContent));
}
}
}
/**
* Wrapper for HttpServletResponse to capture the output for compression.
*/
private static class CharResponseWrapper extends HttpServletResponseWrapper {
private final CharArrayWriter charWriter = new CharArrayWriter();
private PrintWriter writer;
private boolean getOutputStreamCalled;
private boolean getWriterCalled;
/**
* Constructor to wrap the response.
* @param response the original HttpServletResponse
*/
public CharResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (getWriterCalled) {
throw new IllegalStateException("getWriter already called");
}
getOutputStreamCalled = true;
return super.getOutputStream();
}
@Override
public PrintWriter getWriter() {
if (writer != null) {
return writer;
}
if (getOutputStreamCalled) {
throw new IllegalStateException("getOutputStream already called");
}
getWriterCalled = true;
writer = new PrintWriter(charWriter);
return writer;
}
@Override
public String toString() {
return (writer != null) ? charWriter.toString() : null;
}
}
}