Skip to content

Commit

Permalink
[KNOX-2622] Support Deflate Encoding for the Inbound Response (apache…
Browse files Browse the repository at this point in the history
  • Loading branch information
xuzikun2003 authored Jun 22, 2021
1 parent cb48e0f commit 1ef048f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.InflaterInputStream;

import static org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteUtil.getRewriteFilterConfig;
import static org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteUtil.pickFirstRuleWithEqualsIgnoreCasePathMatch;
Expand Down Expand Up @@ -90,6 +92,7 @@ public class UrlRewriteResponse extends GatewayResponseWrapper implements Params
private String xForwardedHostname;
private String xForwardedPort;
private String xForwardedScheme;
private String contentEncoding;

public UrlRewriteResponse( FilterConfig config, HttpServletRequest request, HttpServletResponse response ) {
super( response );
Expand All @@ -102,6 +105,7 @@ public UrlRewriteResponse( FilterConfig config, HttpServletRequest request, Http
this.bodyFilterName = config.getInitParameter( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM );
this.headersFilterName = config.getInitParameter( UrlRewriteServletFilter.RESPONSE_HEADERS_FILTER_PARAM );
this.headersFilterConfig = getRewriteFilterConfig( rewriter.getConfig(), headersFilterName, UrlRewriteServletFilter.HEADERS_MIME_TYPE );
this.contentEncoding = "";
}

protected boolean ignoreHeader( String name ) {
Expand All @@ -121,11 +125,18 @@ private String rewriteValue( String value, String rule ) {
return value;
}

private void setContentEncoding(String name, String value) {
if ("Content-Encoding".equalsIgnoreCase(name)) {
contentEncoding = value;
}
}

// Ignore the Content-Length from the dispatch respond since the respond body may be rewritten.
@Override
public void setHeader( String name, String value ) {
if( !ignoreHeader( name) ) {
value = rewriteValue( value, pickFirstRuleWithEqualsIgnoreCasePathMatch( headersFilterConfig, name ) );
setContentEncoding(name, value);
super.setHeader( name, value );
}
}
Expand All @@ -136,6 +147,7 @@ public void addHeader( String name, String value ) {
if( !ignoreHeader( name ) ) {
String rule = pickFirstRuleWithEqualsIgnoreCasePathMatch( headersFilterConfig, name );
value = rewriteValue( value, rule );
setContentEncoding(name, value);
super.addHeader( name, value );
}
}
Expand Down Expand Up @@ -175,14 +187,18 @@ public void streamResponse( InputStream input, OutputStream output ) throws IOEx
inBuffer.reset();

final InputStream unFilteredStream;
if(isGzip) {
if(isGzip || "gzip".equalsIgnoreCase(contentEncoding)) {
unFilteredStream = new GzipCompressorInputStream(inBuffer, true);
outStream = new GZIPOutputStream(output, STREAM_BUFFER_SIZE);
} else if ("deflate".equalsIgnoreCase(contentEncoding)) {
unFilteredStream = new InflaterInputStream(inBuffer);
outStream = new DeflaterOutputStream(output);
} else {
unFilteredStream = inBuffer;
outStream = output;
}
String charset = MimeTypes.getCharset( mimeType, StandardCharsets.UTF_8.name() );
inStream = filter.filter( unFilteredStream, charset, rewriter, this, UrlRewriter.Direction.OUT, filterContentConfig );
outStream = (isGzip) ? new GZIPOutputStream(output, STREAM_BUFFER_SIZE) : output;
} else {
inStream = input;
outStream = output;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.InflaterInputStream;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -135,7 +137,7 @@ public void testStreamXmlUnicodeResponse() throws IOException {

UrlRewriteResponse rewriteResponse = new UrlRewriteResponse(config, request, response);
String content = "<?xml version=\"1.0\" standalone=\"no\"?><data>abc-大数据</data>";
testStreamResponse(content, rewriteResponse, false);
testStreamResponse(content, rewriteResponse, "");
}

@Test
Expand All @@ -158,16 +160,19 @@ public void testStreamResponse() throws IOException {
UrlRewriteResponse rewriteResponse = new UrlRewriteResponse( config, request, response );

String content = "content to test gzip streaming";
testStreamResponse(content, rewriteResponse, false);
testStreamResponse(content, rewriteResponse, true);
testStreamResponse(content, rewriteResponse, "");
testStreamResponse(content, rewriteResponse, "gzip");
testStreamResponse(content, rewriteResponse, "deflate");
}

private void testStreamResponse(String content, UrlRewriteResponse rewriteResponse, boolean isGzip) throws IOException {
private void testStreamResponse(String content, UrlRewriteResponse rewriteResponse, String contentType) throws IOException {
Path inputFile = Files.createTempFile("input", "test");
Path outputFile = Files.createTempFile("output", "test");
try {
try(OutputStream outputStream = Files.newOutputStream(inputFile);
OutputStream outStream = isGzip ? new GZIPOutputStream( outputStream ) : outputStream) {
OutputStream outStream = "gzip".equalsIgnoreCase(contentType) ?
new GZIPOutputStream( outputStream ) :
"deflate".equalsIgnoreCase(contentType) ? new DeflaterOutputStream( outputStream ) : outputStream) {
outStream.write(content.getBytes(StandardCharsets.UTF_8));
}

Expand All @@ -177,7 +182,9 @@ private void testStreamResponse(String content, UrlRewriteResponse rewriteRespon
}

try(InputStream inputStream = Files.newInputStream(outputFile);
InputStream inStream = isGzip ? new GZIPInputStream(inputStream) : inputStream) {
InputStream inStream = "gzip".equalsIgnoreCase(contentType) ?
new GZIPInputStream(inputStream) :
"deflate".equalsIgnoreCase(contentType) ? new InflaterInputStream(inputStream) : inputStream) {
assertThat(String.valueOf(IOUtils.toCharArray(inStream, StandardCharsets.UTF_8)), is(content));
}
} finally {
Expand Down

0 comments on commit 1ef048f

Please sign in to comment.