Limit request/response body to 100kb to address #457 (#617)

Summary:
As previously reported in https://github.com/facebook/flipper/issues/457, I immediately started to see crashes with Flipper integrated due to large responses (e.g., >= 100MB). This will only write the first 100KB of the response or request body into `RequestInfo` objects.

## Changelog

- Limits request/response body in network request info to 100KB max.
Pull Request resolved: https://github.com/facebook/flipper/pull/617

Test Plan:
- Make a network request which has a response size of < 100kb, verify that it is visible in its entirety
- Make a network request w/ response size > 100kb, verify that it is truncated
- Ideally, use your application with the Network plugin running, and do not see OOMs

Reviewed By: mweststrate

Differential Revision: D19412075

Pulled By: passy

fbshipit-source-id: c93662dba7a5f24820287e56e889576b5bcb5a72
This commit is contained in:
Eric O'Connell
2020-01-17 03:48:33 -08:00
committed by Facebook Github Bot
parent 73e0f9035a
commit b24c2e0b52

View File

@@ -25,6 +25,11 @@ import okio.BufferedSource;
public class FlipperOkhttpInterceptor implements Interceptor { public class FlipperOkhttpInterceptor implements Interceptor {
// By default, limit body size (request or response) reporting to 100KB to avoid OOM
private static final long DEFAULT_MAX_BODY_BYTES = 100 * 1024;
private long maxBodyBytes = DEFAULT_MAX_BODY_BYTES;
public @Nullable NetworkFlipperPlugin plugin; public @Nullable NetworkFlipperPlugin plugin;
public FlipperOkhttpInterceptor() { public FlipperOkhttpInterceptor() {
@@ -35,6 +40,12 @@ public class FlipperOkhttpInterceptor implements Interceptor {
this.plugin = plugin; this.plugin = plugin;
} }
/** If you want to change the number of bytes displayed for the body, use this constructor */
public FlipperOkhttpInterceptor(NetworkFlipperPlugin plugin, long maxBodyBytes) {
this.plugin = plugin;
this.maxBodyBytes = maxBodyBytes;
}
@Override @Override
public Response intercept(Interceptor.Chain chain) throws IOException { public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request(); Request request = chain.request();
@@ -47,10 +58,11 @@ public class FlipperOkhttpInterceptor implements Interceptor {
return response; return response;
} }
private static byte[] bodyToByteArray(final Request request) throws IOException { private static byte[] bodyToByteArray(final Request request, final long maxBodyBytes)
throws IOException {
final Buffer buffer = new Buffer(); final Buffer buffer = new Buffer();
request.body().writeTo(buffer); request.body().writeTo(buffer);
return buffer.readByteArray(); return buffer.readByteArray(Math.min(buffer.size(), maxBodyBytes));
} }
private RequestInfo convertRequest(Request request, String identifier) throws IOException { private RequestInfo convertRequest(Request request, String identifier) throws IOException {
@@ -62,7 +74,7 @@ public class FlipperOkhttpInterceptor implements Interceptor {
info.method = request.method(); info.method = request.method();
info.uri = request.url().toString(); info.uri = request.url().toString();
if (request.body() != null) { if (request.body() != null) {
info.body = bodyToByteArray(request); info.body = bodyToByteArray(request, maxBodyBytes);
} }
return info; return info;
@@ -77,7 +89,7 @@ public class FlipperOkhttpInterceptor implements Interceptor {
info.statusCode = response.code(); info.statusCode = response.code();
info.headers = headers; info.headers = headers;
BufferedSource source = body.source(); BufferedSource source = body.source();
source.request(Long.MAX_VALUE); source.request(maxBodyBytes);
Buffer buffer = source.buffer().clone(); Buffer buffer = source.buffer().clone();
info.body = buffer.readByteArray(); info.body = buffer.readByteArray();
return info; return info;