Skip to content

Commit 29e9e02

Browse files
AlexanderGolovlevcopybara-github
authored andcommitted
Enable more HTTP decompression methods for remote cache
Bazel has support for compressed transfers from/to gRPC remote caches (#14041). However, this is not fully supported for HTTP protocol. This feature would allow to significantly decrease the network traffic for remote cache. The related issue is #23463. In general, the `HTTPCacheClient` class can decompress the incoming HTTP content because it uses internally the `HttpContentDecompressor` from Netty library. But current implementation allows only "gzip" as acceptable encoding. The version of Netty library used in Bazel has been updated recently to 4.1.110. This version supports much more compression methods than before. The suggested change allows using the new compression options with HTTP remote cache. "Zstd" compression is of particular interest because it is used in popular `bazel-remote` software. Note: The suggested change forces the `bazel-remote` to send HTTP content with "zstd" encoding. For compatibility we may consider applying the `--remote_cache_compression` option to enable this functionality. I leaved it as is for now because "gzip" was used unconditionally. Closes #27271. PiperOrigin-RevId: 823203959 Change-Id: I5d8bf11cf3cddad688084bf1e6f53b8782f92f12
1 parent b2cd7af commit 29e9e02

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

src/main/java/com/google/devtools/build/lib/remote/http/HttpDownloadHandler.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
import static com.google.common.base.Preconditions.checkState;
1717

1818
import com.google.auth.Credentials;
19+
import com.google.common.base.Joiner;
1920
import com.google.common.collect.ImmutableList;
21+
import com.google.common.collect.Lists;
2022
import io.netty.buffer.ByteBuf;
2123
import io.netty.channel.ChannelHandlerContext;
2224
import io.netty.channel.ChannelPromise;
25+
import io.netty.handler.codec.compression.Zstd;
2326
import io.netty.handler.codec.http.DefaultFullHttpRequest;
2427
import io.netty.handler.codec.http.HttpContent;
2528
import io.netty.handler.codec.http.HttpHeaderNames;
@@ -33,15 +36,19 @@
3336
import io.netty.handler.codec.http.HttpVersion;
3437
import io.netty.handler.codec.http.LastHttpContent;
3538
import io.netty.handler.timeout.ReadTimeoutException;
39+
import io.netty.util.AsciiString;
3640
import io.netty.util.internal.StringUtil;
3741
import java.io.ByteArrayOutputStream;
3842
import java.io.IOException;
3943
import java.io.OutputStream;
44+
import java.util.ArrayList;
4045
import java.util.Map.Entry;
4146

4247
/** ChannelHandler for downloads. */
4348
final class HttpDownloadHandler extends AbstractHttpHandler<HttpObject> {
4449

50+
private static final String ACCEPT_ENCODING = getAcceptEncoding();
51+
4552
private OutputStream out;
4653
private boolean keepAlive = HttpVersion.HTTP_1_1.isKeepAliveDefault();
4754
private boolean downloadSucceeded;
@@ -180,7 +187,7 @@ private HttpRequest buildRequest(String path, String host) {
180187
httpRequest.headers().set(HttpHeaderNames.HOST, host);
181188
httpRequest.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
182189
httpRequest.headers().set(HttpHeaderNames.ACCEPT, "*/*");
183-
httpRequest.headers().set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
190+
httpRequest.headers().set(HttpHeaderNames.ACCEPT_ENCODING, ACCEPT_ENCODING);
184191
return httpRequest;
185192
}
186193

@@ -232,4 +239,14 @@ private void reset(ChannelHandlerContext ctx) {
232239
response = null;
233240
}
234241
}
242+
243+
private static String getAcceptEncoding() {
244+
ArrayList<AsciiString> acceptEncoding =
245+
Lists.newArrayList(
246+
HttpHeaderValues.GZIP, HttpHeaderValues.DEFLATE, HttpHeaderValues.SNAPPY);
247+
if (Zstd.isAvailable()) {
248+
acceptEncoding.add(HttpHeaderValues.ZSTD);
249+
}
250+
return Joiner.on(",").join(acceptEncoding);
251+
}
235252
}

0 commit comments

Comments
 (0)