Skip to content

Commit

Permalink
Merge pull request #5016 from fishface60/develop
Browse files Browse the repository at this point in the history
Add deflate as a supported REST response encoding
  • Loading branch information
cwisniew authored Nov 5, 2024
2 parents 3163585 + 61307e0 commit cf668a3
Showing 1 changed file with 75 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.Inflater;
import net.rptools.maptool.client.AppPreferences;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.language.I18N;
Expand All @@ -33,11 +35,17 @@
import net.rptools.parser.VariableResolver;
import net.rptools.parser.function.AbstractFunction;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSource;
import okio.GzipSource;
import okio.InflaterSource;
import okio.Okio;

/**
* RESTful based functions REST.get, REST.post, REST.put, REST.patch, REST.delete
Expand Down Expand Up @@ -67,7 +75,7 @@ public static RESTfulFunctions getInstance() {
return instance;
}

private final OkHttpClient client = new OkHttpClient();
private final OkHttpClient client = buildClient();
private final Gson gson = new Gson();

@Override
Expand Down Expand Up @@ -236,6 +244,72 @@ private Object executeClientCall(String functionName, Request request, boolean f
}
}

private OkHttpClient buildClient() {
return new OkHttpClient.Builder()
.addInterceptor(
(Interceptor.Chain chain) -> {
var oldRequest = chain.request();

// If the macro has passed its own Accept-Encoding
// it's indicating it expects to somehow handle it itself.
if (oldRequest.header("Accept-Encoding") != null) {
return chain.proceed(oldRequest);
}

// Augment request saying we accept multiple content encodings
var newHeaders =
oldRequest
.headers()
.newBuilder()
.add("Accept-Encoding", "deflate")
.add("Accept-Encoding", "gzip")
.build();

var newRequest = oldRequest.newBuilder().headers(newHeaders).build();

var oldResponse = chain.proceed(newRequest);

// Replace the response's request with the original one
var responseBuilder = oldResponse.newBuilder().request(oldRequest);

// We might not have a body to decompress
var body = oldResponse.body();
if (body != null) {
BufferedSource source = body.source();
// The body may have been wrapped in an arbitrary encoding sequence
// and the server returns them in the order it encoded them
// so we wrap them with decoders in reverse order.
var encodings = oldResponse.headers().values("Content-Encoding");
Collections.reverse(encodings);
for (var encoding : encodings) {
if ("deflate".equalsIgnoreCase(encoding)) {
var inflater = new Inflater(true);
source = Okio.buffer(new InflaterSource(source, inflater));
} else if ("gzip".equalsIgnoreCase(encoding)) {
source = Okio.buffer(new GzipSource(source));
}
}

// Strip encoding and length headers as we've already handled them
var strippedHeaders =
oldResponse
.headers()
.newBuilder()
.removeAll("Content-Encoding")
.removeAll("Content-Length")
.build();
responseBuilder.headers(strippedHeaders);
var contentType = MediaType.parse(oldResponse.header("Content-Type"));
// Construct a new body with an inferred Content-Length
var newBody = ResponseBody.create(contentType, -1L, source);
responseBuilder.body(newBody);
}

return responseBuilder.build();
})
.build();
}

private Headers buildHeaders(Map<String, List<String>> headerMap) {
Headers.Builder headerBuilder = new Headers.Builder();

Expand Down

0 comments on commit cf668a3

Please sign in to comment.